summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.mailmap1
-rw-r--r--Documentation/DocBook/device-drivers.tmpl10
-rw-r--r--Documentation/DocBook/drm.tmpl5
-rw-r--r--Documentation/devicetree/bindings/arm/marvell,kirkwood.txt97
-rw-r--r--Documentation/devicetree/bindings/i2c/trivial-devices.txt16
-rw-r--r--Documentation/devicetree/bindings/net/broadcom-systemport.txt29
-rw-r--r--Documentation/devicetree/bindings/net/ieee802154/at86rf230.txt23
-rw-r--r--Documentation/devicetree/bindings/net/via-rhine.txt17
-rw-r--r--Documentation/devicetree/bindings/pinctrl/brcm,bcm11351-pinctrl.txt2
-rw-r--r--Documentation/devicetree/bindings/serial/efm32-uart.txt4
-rw-r--r--Documentation/devicetree/bindings/vendor-prefixes.txt18
-rw-r--r--Documentation/ja_JP/HOWTO2
-rw-r--r--Documentation/ja_JP/stable_kernel_rules.txt6
-rw-r--r--Documentation/kernel-parameters.txt13
-rw-r--r--Documentation/magic-number.txt12
-rw-r--r--Documentation/networking/bonding.txt44
-rw-r--r--Documentation/networking/filter.txt13
-rw-r--r--Documentation/networking/scaling.txt2
-rw-r--r--Documentation/serial/00-INDEX8
-rw-r--r--Documentation/serial/digiepca.txt98
-rw-r--r--Documentation/serial/riscom8.txt36
-rw-r--r--Documentation/serial/specialix.txt383
-rw-r--r--Documentation/serial/sx.txt294
-rw-r--r--Documentation/stable_kernel_rules.txt2
-rw-r--r--Documentation/vm/numa_memory_policy.txt5
-rw-r--r--Documentation/zh_CN/HOWTO2
-rw-r--r--Documentation/zh_CN/io_ordering.txt67
-rw-r--r--Documentation/zh_CN/magic-number.txt12
-rw-r--r--Documentation/zh_CN/stable_kernel_rules.txt2
-rw-r--r--MAINTAINERS11
-rw-r--r--arch/arc/include/asm/barrier.h37
-rw-r--r--arch/arm/boot/dts/spear320-hmi.dts2
-rw-r--r--arch/arm/boot/dts/vt8500.dtsi6
-rw-r--r--arch/arm/boot/dts/wm8650.dtsi6
-rw-r--r--arch/arm/boot/dts/wm8850.dtsi6
-rw-r--r--arch/arm/configs/bcm_defconfig2
-rw-r--r--arch/arm/mach-spear/headsmp.S2
-rw-r--r--arch/arm/mach-spear/platsmp.c2
-rw-r--r--arch/arm/mach-spear/time.c2
-rw-r--r--arch/ia64/kernel/head.S2
-rw-r--r--arch/ia64/kernel/ivt.S2
-rw-r--r--arch/ia64/kvm/vmm_ivt.S2
-rw-r--r--arch/mips/mm/cache.c4
-rw-r--r--arch/parisc/include/asm/shmparam.h5
-rw-r--r--arch/parisc/kernel/cache.c3
-rw-r--r--arch/parisc/kernel/sys_parisc.c14
-rw-r--r--arch/parisc/kernel/syscall_table.S2
-rw-r--r--arch/parisc/lib/memcpy.c2
-rw-r--r--arch/parisc/mm/fault.c2
-rw-r--r--arch/powerpc/kernel/pci_64.c10
-rw-r--r--arch/powerpc/mm/numa.c1
-rw-r--r--arch/s390/include/asm/sigp.h19
-rw-r--r--arch/s390/include/asm/smp.h13
-rw-r--r--arch/s390/include/uapi/asm/unistd.h3
-rw-r--r--arch/s390/kernel/compat_wrapper.c3
-rw-r--r--arch/s390/kernel/dumpstack.c8
-rw-r--r--arch/s390/kernel/ptrace.c2
-rw-r--r--arch/s390/kernel/setup.c32
-rw-r--r--arch/s390/kernel/smp.c15
-rw-r--r--arch/s390/kernel/syscalls.S1
-rw-r--r--arch/s390/lib/uaccess.c5
-rw-r--r--arch/s390/mm/fault.c140
-rw-r--r--arch/x86/Makefile4
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce.c4
-rw-r--r--arch/x86/kernel/cpu/mcheck/mce_intel.c18
-rw-r--r--arch/x86/kernel/cpu/perf_event_intel_rapl.c45
-rw-r--r--arch/x86/kernel/early-quirks.c2
-rw-r--r--arch/x86/kernel/kprobes/core.c16
-rw-r--r--arch/x86/kernel/reboot.c72
-rw-r--r--arch/x86/syscalls/Makefile2
-rw-r--r--arch/x86/syscalls/syscall_32.tbl1
-rw-r--r--arch/x86/tools/Makefile2
-rw-r--r--arch/x86/xen/smp.c3
-rw-r--r--arch/x86/xen/spinlock.c5
-rw-r--r--arch/x86/xen/xen-asm_32.S25
-rw-r--r--drivers/Makefile4
-rw-r--r--drivers/base/core.c33
-rw-r--r--drivers/base/dd.c4
-rw-r--r--drivers/base/topology.c3
-rw-r--r--drivers/char/Kconfig2
-rw-r--r--drivers/char/ipmi/Kconfig12
-rw-r--r--drivers/char/ipmi/ipmi_bt_sm.c2
-rw-r--r--drivers/char/ipmi/ipmi_kcs_sm.c5
-rw-r--r--drivers/char/ipmi/ipmi_msghandler.c239
-rw-r--r--drivers/char/ipmi/ipmi_si_intf.c145
-rw-r--r--drivers/char/pcmcia/Kconfig2
-rw-r--r--drivers/char/ttyprintk.c15
-rw-r--r--drivers/gpio/gpio-spear-spics.c4
-rw-r--r--drivers/gpu/drm/Makefile2
-rw-r--r--drivers/gpu/drm/ast/ast_post.c2
-rw-r--r--drivers/gpu/drm/bochs/bochs.h3
-rw-r--r--drivers/gpu/drm/bochs/bochs_drv.c44
-rw-r--r--drivers/gpu/drm/bochs/bochs_fbdev.c1
-rw-r--r--drivers/gpu/drm/cirrus/cirrus_drv.c42
-rw-r--r--drivers/gpu/drm/cirrus/cirrus_mode.c3
-rw-r--r--drivers/gpu/drm/drm_crtc_helper.c370
-rw-r--r--drivers/gpu/drm/drm_dp_helper.c55
-rw-r--r--drivers/gpu/drm/drm_mm.c2
-rw-r--r--drivers/gpu/drm/drm_plane_helper.c33
-rw-r--r--drivers/gpu/drm/drm_probe_helper.c426
-rw-r--r--drivers/gpu/drm/i915/i915_drv.h9
-rw-r--r--drivers/gpu/drm/i915/i915_gem.c2
-rw-r--r--drivers/gpu/drm/i915/i915_gem_context.c218
-rw-r--r--drivers/gpu/drm/i915/i915_gem_execbuffer.c2
-rw-r--r--drivers/gpu/drm/i915/intel_bios.c10
-rw-r--r--drivers/gpu/drm/i915/intel_bios.h3
-rw-r--r--drivers/gpu/drm/i915/intel_dp.c7
-rw-r--r--drivers/gpu/drm/i915/intel_panel.c5
-rw-r--r--drivers/gpu/drm/i915/intel_pm.c10
-rw-r--r--drivers/gpu/drm/nouveau/core/subdev/bios/base.c2
-rw-r--r--drivers/gpu/drm/omapdrm/omap_crtc.c100
-rw-r--r--drivers/gpu/drm/omapdrm/omap_drv.c32
-rw-r--r--drivers/gpu/drm/omapdrm/omap_drv.h1
-rw-r--r--drivers/gpu/drm/omapdrm/omap_fb.c14
-rw-r--r--drivers/gpu/drm/omapdrm/omap_fbdev.c3
-rw-r--r--drivers/gpu/drm/omapdrm/omap_gem.c9
-rw-r--r--drivers/gpu/drm/omapdrm/omap_plane.c16
-rw-r--r--drivers/gpu/drm/radeon/atombios_dp.c140
-rw-r--r--drivers/gpu/drm/radeon/ci_dpm.c33
-rw-r--r--drivers/gpu/drm/radeon/cik.c28
-rw-r--r--drivers/gpu/drm/radeon/dce6_afmt.c14
-rw-r--r--drivers/gpu/drm/radeon/radeon.h6
-rw-r--r--drivers/gpu/drm/radeon/radeon_atpx_handler.c2
-rw-r--r--drivers/gpu/drm/radeon/radeon_connectors.c44
-rw-r--r--drivers/gpu/drm/radeon/radeon_device.c19
-rw-r--r--drivers/gpu/drm/radeon/radeon_display.c27
-rw-r--r--drivers/gpu/drm/radeon/radeon_drv.c26
-rw-r--r--drivers/gpu/drm/radeon/radeon_family.h1
-rw-r--r--drivers/gpu/drm/radeon/radeon_i2c.c60
-rw-r--r--drivers/gpu/drm/radeon/radeon_kms.c23
-rw-r--r--drivers/gpu/drm/radeon/radeon_mode.h12
-rw-r--r--drivers/gpu/drm/radeon/radeon_ucode.h7
-rw-r--r--drivers/gpu/drm/radeon/radeon_vce.c2
-rw-r--r--drivers/gpu/drm/radeon/si.c37
-rw-r--r--drivers/gpu/drm/tegra/dpaux.c44
-rw-r--r--drivers/gpu/drm/tegra/dpaux.h1
-rw-r--r--drivers/gpu/host1x/hw/intr_hw.c4
-rw-r--r--drivers/hid/hid-core.c5
-rw-r--r--drivers/hid/hid-ids.h5
-rw-r--r--drivers/hid/hid-microsoft.c4
-rw-r--r--drivers/hid/hid-sensor-hub.c7
-rw-r--r--drivers/hid/hid-sony.c2
-rw-r--r--drivers/hv/connection.c5
-rw-r--r--drivers/infiniband/hw/cxgb4/cm.c89
-rw-r--r--drivers/infiniband/hw/cxgb4/cq.c24
-rw-r--r--drivers/infiniband/hw/cxgb4/device.c41
-rw-r--r--drivers/infiniband/hw/cxgb4/iw_cxgb4.h2
-rw-r--r--drivers/infiniband/hw/cxgb4/mem.c6
-rw-r--r--drivers/infiniband/hw/cxgb4/provider.c2
-rw-r--r--drivers/infiniband/hw/cxgb4/qp.c70
-rw-r--r--drivers/infiniband/hw/cxgb4/resource.c10
-rw-r--r--drivers/infiniband/hw/cxgb4/t4.h72
-rw-r--r--drivers/infiniband/hw/mlx5/main.c2
-rw-r--r--drivers/infiniband/hw/mlx5/qp.c12
-rw-r--r--drivers/infiniband/hw/mthca/mthca_main.c8
-rw-r--r--drivers/infiniband/hw/qib/qib_pcie.c55
-rw-r--r--drivers/irqchip/irq-vic.c6
-rw-r--r--drivers/irqchip/spear-shirq.c2
-rw-r--r--drivers/isdn/hisax/icc.c2
-rw-r--r--drivers/mcb/mcb-parse.c1
-rw-r--r--drivers/md/raid5.c3
-rw-r--r--drivers/misc/Kconfig4
-rw-r--r--drivers/misc/genwqe/card_base.h58
-rw-r--r--drivers/misc/genwqe/card_ddcb.c6
-rw-r--r--drivers/misc/genwqe/card_dev.c44
-rw-r--r--drivers/misc/genwqe/card_utils.c170
-rw-r--r--drivers/misc/genwqe/genwqe_driver.h2
-rw-r--r--drivers/misc/mei/hw-me-regs.h5
-rw-r--r--drivers/misc/mei/interrupt.c3
-rw-r--r--drivers/misc/mei/main.c3
-rw-r--r--drivers/misc/mei/pci-me.c30
-rw-r--r--drivers/mtd/devices/spear_smi.c4
-rw-r--r--drivers/net/bonding/bond_3ad.c2
-rw-r--r--drivers/net/bonding/bond_alb.c116
-rw-r--r--drivers/net/bonding/bond_alb.h1
-rw-r--r--drivers/net/bonding/bond_main.c20
-rw-r--r--drivers/net/bonding/bond_options.c29
-rw-r--r--drivers/net/bonding/bond_options.h1
-rw-r--r--drivers/net/bonding/bond_sysfs.c29
-rw-r--r--drivers/net/bonding/bonding.h3
-rw-r--r--drivers/net/can/Kconfig8
-rw-r--r--drivers/net/can/Makefile2
-rw-r--r--drivers/net/can/c_can/c_can_pci.c51
-rw-r--r--drivers/net/can/softing/softing_main.c20
-rw-r--r--drivers/net/can/spi/Kconfig10
-rw-r--r--drivers/net/can/spi/Makefile8
-rw-r--r--drivers/net/can/spi/mcp251x.c (renamed from drivers/net/can/mcp251x.c)93
-rw-r--r--drivers/net/can/usb/Kconfig4
-rw-r--r--drivers/net/can/usb/kvaser_usb.c53
-rw-r--r--drivers/net/dsa/mv88e6123_61_65.c2
-rw-r--r--drivers/net/dsa/mv88e6131.c4
-rw-r--r--drivers/net/dsa/mv88e6xxx.c12
-rw-r--r--drivers/net/ethernet/altera/altera_msgdma.c15
-rw-r--r--drivers/net/ethernet/altera/altera_sgdma.c37
-rw-r--r--drivers/net/ethernet/arc/emac_main.c21
-rw-r--r--drivers/net/ethernet/broadcom/Kconfig11
-rw-r--r--drivers/net/ethernet/broadcom/Makefile1
-rw-r--r--drivers/net/ethernet/broadcom/bcm63xx_enet.c3
-rw-r--r--drivers/net/ethernet/broadcom/bcmsysport.c1614
-rw-r--r--drivers/net/ethernet/broadcom/bcmsysport.h677
-rw-r--r--drivers/net/ethernet/broadcom/tg3.c4
-rw-r--r--drivers/net/ethernet/emulex/benet/be.h12
-rw-r--r--drivers/net/ethernet/emulex/benet/be_cmds.c7
-rw-r--r--drivers/net/ethernet/emulex/benet/be_cmds.h2
-rw-r--r--drivers/net/ethernet/emulex/benet/be_ethtool.c92
-rw-r--r--drivers/net/ethernet/emulex/benet/be_main.c31
-rw-r--r--drivers/net/ethernet/ethoc.c6
-rw-r--r--drivers/net/ethernet/intel/e1000e/e1000.h8
-rw-r--r--drivers/net/ethernet/intel/e1000e/ethtool.c11
-rw-r--r--drivers/net/ethernet/intel/e1000e/ich8lan.c1
-rw-r--r--drivers/net/ethernet/intel/e1000e/netdev.c25
-rw-r--r--drivers/net/ethernet/intel/e1000e/nvm.c1
-rw-r--r--drivers/net/ethernet/intel/e1000e/param.c4
-rw-r--r--drivers/net/ethernet/intel/e1000e/phy.c1
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e.h2
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_adminq.c23
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_adminq.h1
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h41
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_common.c50
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_debugfs.c6
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_ethtool.c14
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_lan_hmc.c1
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_lan_hmc.h1
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_main.c287
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_nvm.c2
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_prototype.h7
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_ptp.c38
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_txrx.c25
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_type.h4
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c111
-rw-r--r--drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h1
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40e_adminq.c22
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40e_adminq.h1
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40e_adminq_cmd.h41
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40e_lan_hmc.h1
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40e_type.h4
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c316
-rw-r--r--drivers/net/ethernet/intel/i40evf/i40evf_main.c15
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_82575.c93
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_82575.h72
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_defines.h96
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_hw.h96
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_i210.c50
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_i210.h47
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_mac.c69
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_mac.h47
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_mbx.c47
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_mbx.h47
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_nvm.c47
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_nvm.h49
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_phy.c52
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_phy.h47
-rw-r--r--drivers/net/ethernet/intel/igb/e1000_regs.h54
-rw-r--r--drivers/net/ethernet/intel/igb/igb.h49
-rw-r--r--drivers/net/ethernet/intel/igb/igb_ethtool.c112
-rw-r--r--drivers/net/ethernet/intel/igb/igb_hwmon.c47
-rw-r--r--drivers/net/ethernet/intel/igb/igb_main.c165
-rw-r--r--drivers/net/ethernet/intel/igb/igb_ptp.c4
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe.h39
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c27
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_common.c37
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_common.h15
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82598.c2
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82599.c2
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.h2
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_main.c322
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c6
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c40
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c49
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.h2
-rw-r--r--drivers/net/ethernet/intel/ixgbe/ixgbe_type.h2
-rw-r--r--drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c2
-rw-r--r--drivers/net/ethernet/neterion/s2io.c9
-rw-r--r--drivers/net/ethernet/qlogic/Kconfig11
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic.h19
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c13
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c2
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c13
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c19
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c31
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c35
-rw-r--r--drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c68
-rw-r--r--drivers/net/ethernet/qlogic/qlge/qlge_main.c2
-rw-r--r--drivers/net/ethernet/samsung/sxgbe/sxgbe_desc.c4
-rw-r--r--drivers/net/ethernet/samsung/sxgbe/sxgbe_desc.h39
-rw-r--r--drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c50
-rw-r--r--drivers/net/ethernet/samsung/sxgbe/sxgbe_mdio.c14
-rw-r--r--drivers/net/ethernet/smsc/smc91x.c25
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_main.c22
-rw-r--r--drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c7
-rw-r--r--drivers/net/ethernet/ti/cpmac.c14
-rw-r--r--drivers/net/ethernet/via/Kconfig2
-rw-r--r--drivers/net/ethernet/via/via-rhine.c445
-rw-r--r--drivers/net/hyperv/hyperv_net.h159
-rw-r--r--drivers/net/hyperv/netvsc.c529
-rw-r--r--drivers/net/hyperv/netvsc_drv.c114
-rw-r--r--drivers/net/hyperv/rndis_filter.c193
-rw-r--r--drivers/net/ieee802154/at86rf230.c133
-rw-r--r--drivers/net/macvlan.c119
-rw-r--r--drivers/net/phy/at803x.c39
-rw-r--r--drivers/net/phy/micrel.c6
-rw-r--r--drivers/net/phy/phy_device.c3
-rw-r--r--drivers/net/phy/smsc.c3
-rw-r--r--drivers/net/phy/vitesse.c3
-rw-r--r--drivers/net/virtio_net.c9
-rw-r--r--drivers/net/vxlan.c101
-rw-r--r--drivers/of/base.c10
-rw-r--r--drivers/of/fdt.c2
-rw-r--r--drivers/pci/host/pci-rcar-gen2.c8
-rw-r--r--drivers/pci/host/pci-tegra.c7
-rw-r--r--drivers/pci/host/pcie-designware.c20
-rw-r--r--drivers/pinctrl/Kconfig8
-rw-r--r--drivers/pinctrl/Makefile2
-rw-r--r--drivers/pinctrl/pinctrl-bcm281xx.c1461
-rw-r--r--drivers/pinctrl/pinctrl-capri.c1454
-rw-r--r--drivers/pinctrl/pinctrl-msm.c6
-rw-r--r--drivers/pinctrl/pinctrl-msm.h1
-rw-r--r--drivers/pinctrl/pinctrl-nomadik.c1
-rw-r--r--drivers/pinctrl/pinctrl-rockchip.c48
-rw-r--r--drivers/ptp/ptp_clock.c5
-rw-r--r--drivers/pwm/pwm-spear.c4
-rw-r--r--drivers/s390/char/sclp.c2
-rw-r--r--drivers/s390/char/sclp_cmd.c2
-rw-r--r--drivers/s390/char/sclp_vt220.c14
-rw-r--r--drivers/s390/net/claw.c2
-rw-r--r--drivers/s390/net/ctcm_main.c2
-rw-r--r--drivers/s390/net/lcs.c2
-rw-r--r--drivers/s390/net/qeth_core.h6
-rw-r--r--drivers/s390/net/qeth_core_main.c77
-rw-r--r--drivers/s390/net/qeth_core_sys.c22
-rw-r--r--drivers/s390/net/qeth_l2_main.c11
-rw-r--r--drivers/s390/net/qeth_l3_main.c7
-rw-r--r--drivers/staging/Kconfig2
-rw-r--r--drivers/staging/Makefile1
-rw-r--r--drivers/staging/comedi/comedi_buf.c37
-rw-r--r--drivers/staging/comedi/comedi_fops.c18
-rw-r--r--drivers/staging/comedi/comedi_internal.h2
-rw-r--r--drivers/staging/goldfish/goldfish_audio.c1
-rw-r--r--drivers/staging/gs_fpgaboot/Makefile2
-rw-r--r--drivers/staging/gs_fpgaboot/gs_fpgaboot.c1
-rw-r--r--drivers/staging/rtl8187se/Kconfig10
-rw-r--r--drivers/staging/rtl8187se/Makefile38
-rw-r--r--drivers/staging/rtl8187se/Module.symvers0
-rw-r--r--drivers/staging/rtl8187se/TODO13
-rw-r--r--drivers/staging/rtl8187se/ieee80211/dot11d.c189
-rw-r--r--drivers/staging/rtl8187se/ieee80211/dot11d.h71
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211.h1496
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c240
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.h86
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c455
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_tkip.c740
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_wep.c277
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211_module.c203
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c1486
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c2711
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c567
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c591
-rw-r--r--drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c713
-rw-r--r--drivers/staging/rtl8187se/r8180.h640
-rw-r--r--drivers/staging/rtl8187se/r8180_93cx6.h54
-rw-r--r--drivers/staging/rtl8187se/r8180_core.c3775
-rw-r--r--drivers/staging/rtl8187se/r8180_dm.c1139
-rw-r--r--drivers/staging/rtl8187se/r8180_dm.h23
-rw-r--r--drivers/staging/rtl8187se/r8180_hw.h588
-rw-r--r--drivers/staging/rtl8187se/r8180_rtl8225.h34
-rw-r--r--drivers/staging/rtl8187se/r8180_rtl8225z2.c811
-rw-r--r--drivers/staging/rtl8187se/r8180_wx.c1409
-rw-r--r--drivers/staging/rtl8187se/r8180_wx.h21
-rw-r--r--drivers/staging/rtl8187se/r8185b_init.c1464
-rw-r--r--drivers/staging/rtl8188eu/core/rtw_recv.c19
-rw-r--r--drivers/staging/rtl8188eu/os_dep/ioctl_linux.c74
-rw-r--r--drivers/staging/rtl8712/rtl871x_recv.c13
-rw-r--r--drivers/staging/rtl8723au/core/rtw_ieee80211.c46
-rw-r--r--drivers/staging/rtl8723au/core/rtw_mlme_ext.c2
-rw-r--r--drivers/staging/rtl8723au/core/rtw_p2p.c4
-rw-r--r--drivers/staging/rtl8723au/core/rtw_wlan_util.c4
-rw-r--r--drivers/staging/rtl8821ae/base.c10
-rw-r--r--drivers/staging/speakup/main.c18
-rw-r--r--drivers/staging/unisys/uislib/uislib.c4
-rw-r--r--drivers/staging/unisys/visorchipset/visorchipset.h4
-rw-r--r--drivers/staging/unisys/visorchipset/visorchipset_main.c8
-rw-r--r--drivers/staging/usbip/userspace/libsrc/usbip_host_driver.c7
-rw-r--r--drivers/staging/usbip/vhci_sysfs.c2
-rw-r--r--drivers/staging/vme/devices/vme_user.c9
-rw-r--r--drivers/staging/xgifb/vb_def.h2
-rw-r--r--drivers/staging/xgifb/vb_struct.h2
-rw-r--r--drivers/staging/xgifb/vgatypes.h4
-rw-r--r--drivers/tty/serial/Kconfig1
-rw-r--r--drivers/tty/serial/amba-pl011.c8
-rw-r--r--drivers/tty/serial/clps711x.c20
-rw-r--r--drivers/tty/serial/efm32-uart.c3
-rw-r--r--drivers/tty/serial/omap-serial.c30
-rw-r--r--drivers/tty/serial/serial_core.c5
-rw-r--r--drivers/tty/serial/st-asc.c4
-rw-r--r--drivers/tty/tty_io.c4
-rw-r--r--drivers/usb/class/cdc-acm.c34
-rw-r--r--drivers/usb/core/hcd-pci.c2
-rw-r--r--drivers/usb/host/ehci-exynos.c2
-rw-r--r--drivers/usb/host/ehci-platform.c2
-rw-r--r--drivers/usb/host/ehci-tegra.c23
-rw-r--r--drivers/usb/host/ohci-jz4740.c6
-rw-r--r--drivers/usb/serial/cp210x.c1
-rw-r--r--drivers/usb/serial/ftdi_sio.c33
-rw-r--r--drivers/usb/serial/ftdi_sio_ids.h37
-rw-r--r--drivers/usb/serial/option.c2
-rw-r--r--drivers/usb/serial/pl2303.c3
-rw-r--r--drivers/usb/serial/pl2303.h5
-rw-r--r--drivers/usb/serial/sierra.c1
-rw-r--r--drivers/usb/serial/usb_wwan.c9
-rw-r--r--drivers/usb/storage/uas.c13
-rw-r--r--drivers/usb/usb-common.c2
-rw-r--r--drivers/uwb/drp.c5
-rw-r--r--drivers/video/Kconfig2478
-rw-r--r--drivers/video/Makefile166
-rw-r--r--drivers/video/console/sticon.c2
-rw-r--r--drivers/video/console/sticore.c2
-rw-r--r--drivers/video/fbdev/68328fb.c (renamed from drivers/video/68328fb.c)0
-rw-r--r--drivers/video/fbdev/Kconfig2474
-rw-r--r--drivers/video/fbdev/Makefile152
-rw-r--r--drivers/video/fbdev/acornfb.c (renamed from drivers/video/acornfb.c)0
-rw-r--r--drivers/video/fbdev/acornfb.h (renamed from drivers/video/acornfb.h)0
-rw-r--r--drivers/video/fbdev/amba-clcd.c (renamed from drivers/video/amba-clcd.c)0
-rw-r--r--drivers/video/fbdev/amifb.c (renamed from drivers/video/amifb.c)0
-rw-r--r--drivers/video/fbdev/arcfb.c (renamed from drivers/video/arcfb.c)0
-rw-r--r--drivers/video/fbdev/arkfb.c (renamed from drivers/video/arkfb.c)0
-rw-r--r--drivers/video/fbdev/asiliantfb.c (renamed from drivers/video/asiliantfb.c)0
-rw-r--r--drivers/video/fbdev/atafb.c (renamed from drivers/video/atafb.c)0
-rw-r--r--drivers/video/fbdev/atafb.h (renamed from drivers/video/atafb.h)0
-rw-r--r--drivers/video/fbdev/atafb_iplan2p2.c (renamed from drivers/video/atafb_iplan2p2.c)0
-rw-r--r--drivers/video/fbdev/atafb_iplan2p4.c (renamed from drivers/video/atafb_iplan2p4.c)0
-rw-r--r--drivers/video/fbdev/atafb_iplan2p8.c (renamed from drivers/video/atafb_iplan2p8.c)0
-rw-r--r--drivers/video/fbdev/atafb_mfb.c (renamed from drivers/video/atafb_mfb.c)0
-rw-r--r--drivers/video/fbdev/atafb_utils.h (renamed from drivers/video/atafb_utils.h)0
-rw-r--r--drivers/video/fbdev/atmel_lcdfb.c (renamed from drivers/video/atmel_lcdfb.c)0
-rw-r--r--drivers/video/fbdev/aty/Makefile (renamed from drivers/video/aty/Makefile)0
-rw-r--r--drivers/video/fbdev/aty/ati_ids.h (renamed from drivers/video/aty/ati_ids.h)0
-rw-r--r--drivers/video/fbdev/aty/aty128fb.c (renamed from drivers/video/aty/aty128fb.c)0
-rw-r--r--drivers/video/fbdev/aty/atyfb.h (renamed from drivers/video/aty/atyfb.h)0
-rw-r--r--drivers/video/fbdev/aty/atyfb_base.c (renamed from drivers/video/aty/atyfb_base.c)0
-rw-r--r--drivers/video/fbdev/aty/mach64_accel.c (renamed from drivers/video/aty/mach64_accel.c)0
-rw-r--r--drivers/video/fbdev/aty/mach64_ct.c (renamed from drivers/video/aty/mach64_ct.c)0
-rw-r--r--drivers/video/fbdev/aty/mach64_cursor.c (renamed from drivers/video/aty/mach64_cursor.c)2
-rw-r--r--drivers/video/fbdev/aty/mach64_gx.c (renamed from drivers/video/aty/mach64_gx.c)0
-rw-r--r--drivers/video/fbdev/aty/radeon_accel.c (renamed from drivers/video/aty/radeon_accel.c)0
-rw-r--r--drivers/video/fbdev/aty/radeon_backlight.c (renamed from drivers/video/aty/radeon_backlight.c)0
-rw-r--r--drivers/video/fbdev/aty/radeon_base.c (renamed from drivers/video/aty/radeon_base.c)0
-rw-r--r--drivers/video/fbdev/aty/radeon_i2c.c (renamed from drivers/video/aty/radeon_i2c.c)0
-rw-r--r--drivers/video/fbdev/aty/radeon_monitor.c (renamed from drivers/video/aty/radeon_monitor.c)0
-rw-r--r--drivers/video/fbdev/aty/radeon_pm.c (renamed from drivers/video/aty/radeon_pm.c)0
-rw-r--r--drivers/video/fbdev/aty/radeonfb.h (renamed from drivers/video/aty/radeonfb.h)0
-rw-r--r--drivers/video/fbdev/au1100fb.c (renamed from drivers/video/au1100fb.c)0
-rw-r--r--drivers/video/fbdev/au1100fb.h (renamed from drivers/video/au1100fb.h)0
-rw-r--r--drivers/video/fbdev/au1200fb.c (renamed from drivers/video/au1200fb.c)0
-rw-r--r--drivers/video/fbdev/au1200fb.h (renamed from drivers/video/au1200fb.h)0
-rw-r--r--drivers/video/fbdev/auo_k1900fb.c (renamed from drivers/video/auo_k1900fb.c)0
-rw-r--r--drivers/video/fbdev/auo_k1901fb.c (renamed from drivers/video/auo_k1901fb.c)0
-rw-r--r--drivers/video/fbdev/auo_k190x.c (renamed from drivers/video/auo_k190x.c)0
-rw-r--r--drivers/video/fbdev/auo_k190x.h (renamed from drivers/video/auo_k190x.h)0
-rw-r--r--drivers/video/fbdev/bf537-lq035.c (renamed from drivers/video/bf537-lq035.c)0
-rw-r--r--drivers/video/fbdev/bf54x-lq043fb.c (renamed from drivers/video/bf54x-lq043fb.c)2
-rw-r--r--drivers/video/fbdev/bfin-lq035q1-fb.c (renamed from drivers/video/bfin-lq035q1-fb.c)0
-rw-r--r--drivers/video/fbdev/bfin-t350mcqb-fb.c (renamed from drivers/video/bfin-t350mcqb-fb.c)0
-rw-r--r--drivers/video/fbdev/bfin_adv7393fb.c (renamed from drivers/video/bfin_adv7393fb.c)0
-rw-r--r--drivers/video/fbdev/bfin_adv7393fb.h (renamed from drivers/video/bfin_adv7393fb.h)0
-rw-r--r--drivers/video/fbdev/broadsheetfb.c (renamed from drivers/video/broadsheetfb.c)0
-rw-r--r--drivers/video/fbdev/bt431.h (renamed from drivers/video/bt431.h)0
-rw-r--r--drivers/video/fbdev/bt455.h (renamed from drivers/video/bt455.h)0
-rw-r--r--drivers/video/fbdev/bw2.c (renamed from drivers/video/bw2.c)0
-rw-r--r--drivers/video/fbdev/c2p.h (renamed from drivers/video/c2p.h)0
-rw-r--r--drivers/video/fbdev/c2p_core.h (renamed from drivers/video/c2p_core.h)0
-rw-r--r--drivers/video/fbdev/c2p_iplan2.c (renamed from drivers/video/c2p_iplan2.c)0
-rw-r--r--drivers/video/fbdev/c2p_planar.c (renamed from drivers/video/c2p_planar.c)0
-rw-r--r--drivers/video/fbdev/carminefb.c (renamed from drivers/video/carminefb.c)0
-rw-r--r--drivers/video/fbdev/carminefb.h (renamed from drivers/video/carminefb.h)0
-rw-r--r--drivers/video/fbdev/carminefb_regs.h (renamed from drivers/video/carminefb_regs.h)0
-rw-r--r--drivers/video/fbdev/cg14.c (renamed from drivers/video/cg14.c)0
-rw-r--r--drivers/video/fbdev/cg3.c (renamed from drivers/video/cg3.c)0
-rw-r--r--drivers/video/fbdev/cg6.c (renamed from drivers/video/cg6.c)0
-rw-r--r--drivers/video/fbdev/chipsfb.c (renamed from drivers/video/chipsfb.c)0
-rw-r--r--drivers/video/fbdev/cirrusfb.c (renamed from drivers/video/cirrusfb.c)0
-rw-r--r--drivers/video/fbdev/clps711xfb.c (renamed from drivers/video/clps711xfb.c)0
-rw-r--r--drivers/video/fbdev/cobalt_lcdfb.c (renamed from drivers/video/cobalt_lcdfb.c)0
-rw-r--r--drivers/video/fbdev/controlfb.c (renamed from drivers/video/controlfb.c)0
-rw-r--r--drivers/video/fbdev/controlfb.h (renamed from drivers/video/controlfb.h)0
-rw-r--r--drivers/video/fbdev/core/Makefile16
-rw-r--r--drivers/video/fbdev/core/cfbcopyarea.c (renamed from drivers/video/cfbcopyarea.c)0
-rw-r--r--drivers/video/fbdev/core/cfbfillrect.c (renamed from drivers/video/cfbfillrect.c)0
-rw-r--r--drivers/video/fbdev/core/cfbimgblt.c (renamed from drivers/video/cfbimgblt.c)0
-rw-r--r--drivers/video/fbdev/core/fb_ddc.c (renamed from drivers/video/fb_ddc.c)2
-rw-r--r--drivers/video/fbdev/core/fb_defio.c (renamed from drivers/video/fb_defio.c)0
-rw-r--r--drivers/video/fbdev/core/fb_draw.h (renamed from drivers/video/fb_draw.h)0
-rw-r--r--drivers/video/fbdev/core/fb_notify.c (renamed from drivers/video/fb_notify.c)0
-rw-r--r--drivers/video/fbdev/core/fb_sys_fops.c (renamed from drivers/video/fb_sys_fops.c)0
-rw-r--r--drivers/video/fbdev/core/fbcmap.c (renamed from drivers/video/fbcmap.c)0
-rw-r--r--drivers/video/fbdev/core/fbcvt.c (renamed from drivers/video/fbcvt.c)0
-rw-r--r--drivers/video/fbdev/core/fbmem.c (renamed from drivers/video/fbmem.c)0
-rw-r--r--drivers/video/fbdev/core/fbmon.c (renamed from drivers/video/fbmon.c)2
-rw-r--r--drivers/video/fbdev/core/fbsysfs.c (renamed from drivers/video/fbsysfs.c)0
-rw-r--r--drivers/video/fbdev/core/modedb.c (renamed from drivers/video/modedb.c)0
-rw-r--r--drivers/video/fbdev/core/svgalib.c (renamed from drivers/video/svgalib.c)0
-rw-r--r--drivers/video/fbdev/core/syscopyarea.c (renamed from drivers/video/syscopyarea.c)0
-rw-r--r--drivers/video/fbdev/core/sysfillrect.c (renamed from drivers/video/sysfillrect.c)0
-rw-r--r--drivers/video/fbdev/core/sysimgblt.c (renamed from drivers/video/sysimgblt.c)0
-rw-r--r--drivers/video/fbdev/cyber2000fb.c (renamed from drivers/video/cyber2000fb.c)0
-rw-r--r--drivers/video/fbdev/cyber2000fb.h (renamed from drivers/video/cyber2000fb.h)0
-rw-r--r--drivers/video/fbdev/da8xx-fb.c (renamed from drivers/video/da8xx-fb.c)10
-rw-r--r--drivers/video/fbdev/dnfb.c (renamed from drivers/video/dnfb.c)0
-rw-r--r--drivers/video/fbdev/edid.h (renamed from drivers/video/edid.h)0
-rw-r--r--drivers/video/fbdev/efifb.c (renamed from drivers/video/efifb.c)0
-rw-r--r--drivers/video/fbdev/ep93xx-fb.c (renamed from drivers/video/ep93xx-fb.c)0
-rw-r--r--drivers/video/fbdev/exynos/Kconfig (renamed from drivers/video/exynos/Kconfig)0
-rw-r--r--drivers/video/fbdev/exynos/Makefile (renamed from drivers/video/exynos/Makefile)0
-rw-r--r--drivers/video/fbdev/exynos/exynos_mipi_dsi.c (renamed from drivers/video/exynos/exynos_mipi_dsi.c)0
-rw-r--r--drivers/video/fbdev/exynos/exynos_mipi_dsi_common.c (renamed from drivers/video/exynos/exynos_mipi_dsi_common.c)0
-rw-r--r--drivers/video/fbdev/exynos/exynos_mipi_dsi_common.h (renamed from drivers/video/exynos/exynos_mipi_dsi_common.h)0
-rw-r--r--drivers/video/fbdev/exynos/exynos_mipi_dsi_lowlevel.c (renamed from drivers/video/exynos/exynos_mipi_dsi_lowlevel.c)0
-rw-r--r--drivers/video/fbdev/exynos/exynos_mipi_dsi_lowlevel.h (renamed from drivers/video/exynos/exynos_mipi_dsi_lowlevel.h)0
-rw-r--r--drivers/video/fbdev/exynos/exynos_mipi_dsi_regs.h (renamed from drivers/video/exynos/exynos_mipi_dsi_regs.h)0
-rw-r--r--drivers/video/fbdev/exynos/s6e8ax0.c (renamed from drivers/video/exynos/s6e8ax0.c)0
-rw-r--r--drivers/video/fbdev/fb-puv3.c (renamed from drivers/video/fb-puv3.c)0
-rw-r--r--drivers/video/fbdev/ffb.c (renamed from drivers/video/ffb.c)0
-rw-r--r--drivers/video/fbdev/fm2fb.c (renamed from drivers/video/fm2fb.c)0
-rw-r--r--drivers/video/fbdev/fsl-diu-fb.c (renamed from drivers/video/fsl-diu-fb.c)0
-rw-r--r--drivers/video/fbdev/g364fb.c (renamed from drivers/video/g364fb.c)0
-rw-r--r--drivers/video/fbdev/gbefb.c (renamed from drivers/video/gbefb.c)0
-rw-r--r--drivers/video/fbdev/geode/Kconfig (renamed from drivers/video/geode/Kconfig)0
-rw-r--r--drivers/video/fbdev/geode/Makefile (renamed from drivers/video/geode/Makefile)0
-rw-r--r--drivers/video/fbdev/geode/display_gx.c (renamed from drivers/video/geode/display_gx.c)0
-rw-r--r--drivers/video/fbdev/geode/display_gx1.c (renamed from drivers/video/geode/display_gx1.c)0
-rw-r--r--drivers/video/fbdev/geode/display_gx1.h (renamed from drivers/video/geode/display_gx1.h)0
-rw-r--r--drivers/video/fbdev/geode/geodefb.h (renamed from drivers/video/geode/geodefb.h)0
-rw-r--r--drivers/video/fbdev/geode/gx1fb_core.c (renamed from drivers/video/geode/gx1fb_core.c)0
-rw-r--r--drivers/video/fbdev/geode/gxfb.h (renamed from drivers/video/geode/gxfb.h)0
-rw-r--r--drivers/video/fbdev/geode/gxfb_core.c (renamed from drivers/video/geode/gxfb_core.c)0
-rw-r--r--drivers/video/fbdev/geode/lxfb.h (renamed from drivers/video/geode/lxfb.h)0
-rw-r--r--drivers/video/fbdev/geode/lxfb_core.c (renamed from drivers/video/geode/lxfb_core.c)0
-rw-r--r--drivers/video/fbdev/geode/lxfb_ops.c (renamed from drivers/video/geode/lxfb_ops.c)0
-rw-r--r--drivers/video/fbdev/geode/suspend_gx.c (renamed from drivers/video/geode/suspend_gx.c)0
-rw-r--r--drivers/video/fbdev/geode/video_cs5530.c (renamed from drivers/video/geode/video_cs5530.c)0
-rw-r--r--drivers/video/fbdev/geode/video_cs5530.h (renamed from drivers/video/geode/video_cs5530.h)0
-rw-r--r--drivers/video/fbdev/geode/video_gx.c (renamed from drivers/video/geode/video_gx.c)0
-rw-r--r--drivers/video/fbdev/goldfishfb.c (renamed from drivers/video/goldfishfb.c)0
-rw-r--r--drivers/video/fbdev/grvga.c (renamed from drivers/video/grvga.c)0
-rw-r--r--drivers/video/fbdev/gxt4500.c (renamed from drivers/video/gxt4500.c)0
-rw-r--r--drivers/video/fbdev/hecubafb.c (renamed from drivers/video/hecubafb.c)0
-rw-r--r--drivers/video/fbdev/hgafb.c (renamed from drivers/video/hgafb.c)0
-rw-r--r--drivers/video/fbdev/hitfb.c (renamed from drivers/video/hitfb.c)0
-rw-r--r--drivers/video/fbdev/hpfb.c (renamed from drivers/video/hpfb.c)0
-rw-r--r--drivers/video/fbdev/hyperv_fb.c (renamed from drivers/video/hyperv_fb.c)0
-rw-r--r--drivers/video/fbdev/i740_reg.h (renamed from drivers/video/i740_reg.h)0
-rw-r--r--drivers/video/fbdev/i740fb.c (renamed from drivers/video/i740fb.c)0
-rw-r--r--drivers/video/fbdev/i810/Makefile (renamed from drivers/video/i810/Makefile)0
-rw-r--r--drivers/video/fbdev/i810/i810-i2c.c (renamed from drivers/video/i810/i810-i2c.c)0
-rw-r--r--drivers/video/fbdev/i810/i810.h (renamed from drivers/video/i810/i810.h)0
-rw-r--r--drivers/video/fbdev/i810/i810_accel.c (renamed from drivers/video/i810/i810_accel.c)0
-rw-r--r--drivers/video/fbdev/i810/i810_dvt.c (renamed from drivers/video/i810/i810_dvt.c)0
-rw-r--r--drivers/video/fbdev/i810/i810_gtf.c (renamed from drivers/video/i810/i810_gtf.c)0
-rw-r--r--drivers/video/fbdev/i810/i810_main.c (renamed from drivers/video/i810/i810_main.c)0
-rw-r--r--drivers/video/fbdev/i810/i810_main.h (renamed from drivers/video/i810/i810_main.h)0
-rw-r--r--drivers/video/fbdev/i810/i810_regs.h (renamed from drivers/video/i810/i810_regs.h)0
-rw-r--r--drivers/video/fbdev/igafb.c (renamed from drivers/video/igafb.c)0
-rw-r--r--drivers/video/fbdev/imsttfb.c (renamed from drivers/video/imsttfb.c)0
-rw-r--r--drivers/video/fbdev/imxfb.c (renamed from drivers/video/imxfb.c)0
-rw-r--r--drivers/video/fbdev/intelfb/Makefile (renamed from drivers/video/intelfb/Makefile)0
-rw-r--r--drivers/video/fbdev/intelfb/intelfb.h (renamed from drivers/video/intelfb/intelfb.h)0
-rw-r--r--drivers/video/fbdev/intelfb/intelfb_i2c.c (renamed from drivers/video/intelfb/intelfb_i2c.c)0
-rw-r--r--drivers/video/fbdev/intelfb/intelfbdrv.c (renamed from drivers/video/intelfb/intelfbdrv.c)0
-rw-r--r--drivers/video/fbdev/intelfb/intelfbhw.c (renamed from drivers/video/intelfb/intelfbhw.c)0
-rw-r--r--drivers/video/fbdev/intelfb/intelfbhw.h (renamed from drivers/video/intelfb/intelfbhw.h)0
-rw-r--r--drivers/video/fbdev/jz4740_fb.c (renamed from drivers/video/jz4740_fb.c)0
-rw-r--r--drivers/video/fbdev/kyro/Makefile (renamed from drivers/video/kyro/Makefile)0
-rw-r--r--drivers/video/fbdev/kyro/STG4000InitDevice.c (renamed from drivers/video/kyro/STG4000InitDevice.c)0
-rw-r--r--drivers/video/fbdev/kyro/STG4000Interface.h (renamed from drivers/video/kyro/STG4000Interface.h)0
-rw-r--r--drivers/video/fbdev/kyro/STG4000OverlayDevice.c (renamed from drivers/video/kyro/STG4000OverlayDevice.c)0
-rw-r--r--drivers/video/fbdev/kyro/STG4000Ramdac.c (renamed from drivers/video/kyro/STG4000Ramdac.c)0
-rw-r--r--drivers/video/fbdev/kyro/STG4000Reg.h (renamed from drivers/video/kyro/STG4000Reg.h)0
-rw-r--r--drivers/video/fbdev/kyro/STG4000VTG.c (renamed from drivers/video/kyro/STG4000VTG.c)0
-rw-r--r--drivers/video/fbdev/kyro/fbdev.c (renamed from drivers/video/kyro/fbdev.c)0
-rw-r--r--drivers/video/fbdev/leo.c (renamed from drivers/video/leo.c)0
-rw-r--r--drivers/video/fbdev/macfb.c (renamed from drivers/video/macfb.c)0
-rw-r--r--drivers/video/fbdev/macmodes.c (renamed from drivers/video/macmodes.c)0
-rw-r--r--drivers/video/fbdev/macmodes.h (renamed from drivers/video/macmodes.h)0
-rw-r--r--drivers/video/fbdev/matrox/Makefile (renamed from drivers/video/matrox/Makefile)0
-rw-r--r--drivers/video/fbdev/matrox/g450_pll.c (renamed from drivers/video/matrox/g450_pll.c)0
-rw-r--r--drivers/video/fbdev/matrox/g450_pll.h (renamed from drivers/video/matrox/g450_pll.h)0
-rw-r--r--drivers/video/fbdev/matrox/i2c-matroxfb.c (renamed from drivers/video/matrox/i2c-matroxfb.c)0
-rw-r--r--drivers/video/fbdev/matrox/matroxfb_DAC1064.c (renamed from drivers/video/matrox/matroxfb_DAC1064.c)0
-rw-r--r--drivers/video/fbdev/matrox/matroxfb_DAC1064.h (renamed from drivers/video/matrox/matroxfb_DAC1064.h)0
-rw-r--r--drivers/video/fbdev/matrox/matroxfb_Ti3026.c (renamed from drivers/video/matrox/matroxfb_Ti3026.c)0
-rw-r--r--drivers/video/fbdev/matrox/matroxfb_Ti3026.h (renamed from drivers/video/matrox/matroxfb_Ti3026.h)0
-rw-r--r--drivers/video/fbdev/matrox/matroxfb_accel.c (renamed from drivers/video/matrox/matroxfb_accel.c)0
-rw-r--r--drivers/video/fbdev/matrox/matroxfb_accel.h (renamed from drivers/video/matrox/matroxfb_accel.h)0
-rw-r--r--drivers/video/fbdev/matrox/matroxfb_base.c (renamed from drivers/video/matrox/matroxfb_base.c)0
-rw-r--r--drivers/video/fbdev/matrox/matroxfb_base.h (renamed from drivers/video/matrox/matroxfb_base.h)0
-rw-r--r--drivers/video/fbdev/matrox/matroxfb_crtc2.c (renamed from drivers/video/matrox/matroxfb_crtc2.c)0
-rw-r--r--drivers/video/fbdev/matrox/matroxfb_crtc2.h (renamed from drivers/video/matrox/matroxfb_crtc2.h)0
-rw-r--r--drivers/video/fbdev/matrox/matroxfb_g450.c (renamed from drivers/video/matrox/matroxfb_g450.c)0
-rw-r--r--drivers/video/fbdev/matrox/matroxfb_g450.h (renamed from drivers/video/matrox/matroxfb_g450.h)0
-rw-r--r--drivers/video/fbdev/matrox/matroxfb_maven.c (renamed from drivers/video/matrox/matroxfb_maven.c)0
-rw-r--r--drivers/video/fbdev/matrox/matroxfb_maven.h (renamed from drivers/video/matrox/matroxfb_maven.h)0
-rw-r--r--drivers/video/fbdev/matrox/matroxfb_misc.c (renamed from drivers/video/matrox/matroxfb_misc.c)0
-rw-r--r--drivers/video/fbdev/matrox/matroxfb_misc.h (renamed from drivers/video/matrox/matroxfb_misc.h)0
-rw-r--r--drivers/video/fbdev/maxinefb.c (renamed from drivers/video/maxinefb.c)0
-rw-r--r--drivers/video/fbdev/mb862xx/Makefile (renamed from drivers/video/mb862xx/Makefile)0
-rw-r--r--drivers/video/fbdev/mb862xx/mb862xx-i2c.c (renamed from drivers/video/mb862xx/mb862xx-i2c.c)0
-rw-r--r--drivers/video/fbdev/mb862xx/mb862xx_reg.h (renamed from drivers/video/mb862xx/mb862xx_reg.h)0
-rw-r--r--drivers/video/fbdev/mb862xx/mb862xxfb.h (renamed from drivers/video/mb862xx/mb862xxfb.h)0
-rw-r--r--drivers/video/fbdev/mb862xx/mb862xxfb_accel.c (renamed from drivers/video/mb862xx/mb862xxfb_accel.c)0
-rw-r--r--drivers/video/fbdev/mb862xx/mb862xxfb_accel.h (renamed from drivers/video/mb862xx/mb862xxfb_accel.h)0
-rw-r--r--drivers/video/fbdev/mb862xx/mb862xxfbdrv.c (renamed from drivers/video/mb862xx/mb862xxfbdrv.c)0
-rw-r--r--drivers/video/fbdev/mbx/Makefile (renamed from drivers/video/mbx/Makefile)0
-rw-r--r--drivers/video/fbdev/mbx/mbxdebugfs.c (renamed from drivers/video/mbx/mbxdebugfs.c)0
-rw-r--r--drivers/video/fbdev/mbx/mbxfb.c (renamed from drivers/video/mbx/mbxfb.c)0
-rw-r--r--drivers/video/fbdev/mbx/reg_bits.h (renamed from drivers/video/mbx/reg_bits.h)0
-rw-r--r--drivers/video/fbdev/mbx/regs.h (renamed from drivers/video/mbx/regs.h)0
-rw-r--r--drivers/video/fbdev/metronomefb.c (renamed from drivers/video/metronomefb.c)0
-rw-r--r--drivers/video/fbdev/mmp/Kconfig (renamed from drivers/video/mmp/Kconfig)6
-rw-r--r--drivers/video/fbdev/mmp/Makefile (renamed from drivers/video/mmp/Makefile)0
-rw-r--r--drivers/video/fbdev/mmp/core.c (renamed from drivers/video/mmp/core.c)0
-rw-r--r--drivers/video/fbdev/mmp/fb/Kconfig (renamed from drivers/video/mmp/fb/Kconfig)0
-rw-r--r--drivers/video/fbdev/mmp/fb/Makefile (renamed from drivers/video/mmp/fb/Makefile)0
-rw-r--r--drivers/video/fbdev/mmp/fb/mmpfb.c (renamed from drivers/video/mmp/fb/mmpfb.c)0
-rw-r--r--drivers/video/fbdev/mmp/fb/mmpfb.h (renamed from drivers/video/mmp/fb/mmpfb.h)0
-rw-r--r--drivers/video/fbdev/mmp/hw/Kconfig (renamed from drivers/video/mmp/hw/Kconfig)0
-rw-r--r--drivers/video/fbdev/mmp/hw/Makefile (renamed from drivers/video/mmp/hw/Makefile)0
-rw-r--r--drivers/video/fbdev/mmp/hw/mmp_ctrl.c (renamed from drivers/video/mmp/hw/mmp_ctrl.c)0
-rw-r--r--drivers/video/fbdev/mmp/hw/mmp_ctrl.h (renamed from drivers/video/mmp/hw/mmp_ctrl.h)0
-rw-r--r--drivers/video/fbdev/mmp/hw/mmp_spi.c (renamed from drivers/video/mmp/hw/mmp_spi.c)0
-rw-r--r--drivers/video/fbdev/mmp/panel/Kconfig (renamed from drivers/video/mmp/panel/Kconfig)0
-rw-r--r--drivers/video/fbdev/mmp/panel/Makefile (renamed from drivers/video/mmp/panel/Makefile)0
-rw-r--r--drivers/video/fbdev/mmp/panel/tpo_tj032md01bw.c (renamed from drivers/video/mmp/panel/tpo_tj032md01bw.c)0
-rw-r--r--drivers/video/fbdev/msm/Makefile (renamed from drivers/video/msm/Makefile)0
-rw-r--r--drivers/video/fbdev/msm/mddi.c (renamed from drivers/video/msm/mddi.c)0
-rw-r--r--drivers/video/fbdev/msm/mddi_client_dummy.c (renamed from drivers/video/msm/mddi_client_dummy.c)0
-rw-r--r--drivers/video/fbdev/msm/mddi_client_nt35399.c (renamed from drivers/video/msm/mddi_client_nt35399.c)0
-rw-r--r--drivers/video/fbdev/msm/mddi_client_toshiba.c (renamed from drivers/video/msm/mddi_client_toshiba.c)0
-rw-r--r--drivers/video/fbdev/msm/mddi_hw.h (renamed from drivers/video/msm/mddi_hw.h)0
-rw-r--r--drivers/video/fbdev/msm/mdp.c (renamed from drivers/video/msm/mdp.c)0
-rw-r--r--drivers/video/fbdev/msm/mdp_csc_table.h (renamed from drivers/video/msm/mdp_csc_table.h)0
-rw-r--r--drivers/video/fbdev/msm/mdp_hw.h (renamed from drivers/video/msm/mdp_hw.h)0
-rw-r--r--drivers/video/fbdev/msm/mdp_ppp.c (renamed from drivers/video/msm/mdp_ppp.c)0
-rw-r--r--drivers/video/fbdev/msm/mdp_scale_tables.c (renamed from drivers/video/msm/mdp_scale_tables.c)0
-rw-r--r--drivers/video/fbdev/msm/mdp_scale_tables.h (renamed from drivers/video/msm/mdp_scale_tables.h)0
-rw-r--r--drivers/video/fbdev/msm/msm_fb.c (renamed from drivers/video/msm/msm_fb.c)0
-rw-r--r--drivers/video/fbdev/mx3fb.c (renamed from drivers/video/mx3fb.c)0
-rw-r--r--drivers/video/fbdev/mxsfb.c (renamed from drivers/video/mxsfb.c)0
-rw-r--r--drivers/video/fbdev/n411.c (renamed from drivers/video/n411.c)0
-rw-r--r--drivers/video/fbdev/neofb.c (renamed from drivers/video/neofb.c)0
-rw-r--r--drivers/video/fbdev/nuc900fb.c (renamed from drivers/video/nuc900fb.c)0
-rw-r--r--drivers/video/fbdev/nuc900fb.h (renamed from drivers/video/nuc900fb.h)0
-rw-r--r--drivers/video/fbdev/nvidia/Makefile (renamed from drivers/video/nvidia/Makefile)0
-rw-r--r--drivers/video/fbdev/nvidia/nv_accel.c (renamed from drivers/video/nvidia/nv_accel.c)0
-rw-r--r--drivers/video/fbdev/nvidia/nv_backlight.c (renamed from drivers/video/nvidia/nv_backlight.c)0
-rw-r--r--drivers/video/fbdev/nvidia/nv_dma.h (renamed from drivers/video/nvidia/nv_dma.h)0
-rw-r--r--drivers/video/fbdev/nvidia/nv_hw.c (renamed from drivers/video/nvidia/nv_hw.c)0
-rw-r--r--drivers/video/fbdev/nvidia/nv_i2c.c (renamed from drivers/video/nvidia/nv_i2c.c)0
-rw-r--r--drivers/video/fbdev/nvidia/nv_local.h (renamed from drivers/video/nvidia/nv_local.h)0
-rw-r--r--drivers/video/fbdev/nvidia/nv_of.c (renamed from drivers/video/nvidia/nv_of.c)0
-rw-r--r--drivers/video/fbdev/nvidia/nv_proto.h (renamed from drivers/video/nvidia/nv_proto.h)0
-rw-r--r--drivers/video/fbdev/nvidia/nv_setup.c (renamed from drivers/video/nvidia/nv_setup.c)0
-rw-r--r--drivers/video/fbdev/nvidia/nv_type.h (renamed from drivers/video/nvidia/nv_type.h)0
-rw-r--r--drivers/video/fbdev/nvidia/nvidia.c (renamed from drivers/video/nvidia/nvidia.c)0
-rw-r--r--drivers/video/fbdev/ocfb.c (renamed from drivers/video/ocfb.c)0
-rw-r--r--drivers/video/fbdev/offb.c (renamed from drivers/video/offb.c)0
-rw-r--r--drivers/video/fbdev/omap/Kconfig (renamed from drivers/video/omap/Kconfig)0
-rw-r--r--drivers/video/fbdev/omap/Makefile (renamed from drivers/video/omap/Makefile)0
-rw-r--r--drivers/video/fbdev/omap/hwa742.c (renamed from drivers/video/omap/hwa742.c)0
-rw-r--r--drivers/video/fbdev/omap/lcd_ams_delta.c (renamed from drivers/video/omap/lcd_ams_delta.c)0
-rw-r--r--drivers/video/fbdev/omap/lcd_h3.c (renamed from drivers/video/omap/lcd_h3.c)0
-rw-r--r--drivers/video/fbdev/omap/lcd_htcherald.c (renamed from drivers/video/omap/lcd_htcherald.c)0
-rw-r--r--drivers/video/fbdev/omap/lcd_inn1510.c (renamed from drivers/video/omap/lcd_inn1510.c)0
-rw-r--r--drivers/video/fbdev/omap/lcd_inn1610.c (renamed from drivers/video/omap/lcd_inn1610.c)0
-rw-r--r--drivers/video/fbdev/omap/lcd_mipid.c (renamed from drivers/video/omap/lcd_mipid.c)0
-rw-r--r--drivers/video/fbdev/omap/lcd_osk.c (renamed from drivers/video/omap/lcd_osk.c)0
-rw-r--r--drivers/video/fbdev/omap/lcd_palmte.c (renamed from drivers/video/omap/lcd_palmte.c)0
-rw-r--r--drivers/video/fbdev/omap/lcd_palmtt.c (renamed from drivers/video/omap/lcd_palmtt.c)0
-rw-r--r--drivers/video/fbdev/omap/lcd_palmz71.c (renamed from drivers/video/omap/lcd_palmz71.c)0
-rw-r--r--drivers/video/fbdev/omap/lcdc.c (renamed from drivers/video/omap/lcdc.c)0
-rw-r--r--drivers/video/fbdev/omap/lcdc.h (renamed from drivers/video/omap/lcdc.h)0
-rw-r--r--drivers/video/fbdev/omap/omapfb.h (renamed from drivers/video/omap/omapfb.h)0
-rw-r--r--drivers/video/fbdev/omap/omapfb_main.c (renamed from drivers/video/omap/omapfb_main.c)0
-rw-r--r--drivers/video/fbdev/omap/sossi.c (renamed from drivers/video/omap/sossi.c)0
-rw-r--r--drivers/video/fbdev/omap2/Kconfig10
-rw-r--r--drivers/video/fbdev/omap2/Makefile (renamed from drivers/video/omap2/Makefile)0
-rw-r--r--drivers/video/fbdev/omap2/displays-new/Kconfig (renamed from drivers/video/omap2/displays-new/Kconfig)0
-rw-r--r--drivers/video/fbdev/omap2/displays-new/Makefile (renamed from drivers/video/omap2/displays-new/Makefile)0
-rw-r--r--drivers/video/fbdev/omap2/displays-new/connector-analog-tv.c (renamed from drivers/video/omap2/displays-new/connector-analog-tv.c)0
-rw-r--r--drivers/video/fbdev/omap2/displays-new/connector-dvi.c (renamed from drivers/video/omap2/displays-new/connector-dvi.c)0
-rw-r--r--drivers/video/fbdev/omap2/displays-new/connector-hdmi.c (renamed from drivers/video/omap2/displays-new/connector-hdmi.c)0
-rw-r--r--drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c (renamed from drivers/video/omap2/displays-new/encoder-tfp410.c)0
-rw-r--r--drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c (renamed from drivers/video/omap2/displays-new/encoder-tpd12s015.c)0
-rw-r--r--drivers/video/fbdev/omap2/displays-new/panel-dpi.c (renamed from drivers/video/omap2/displays-new/panel-dpi.c)0
-rw-r--r--drivers/video/fbdev/omap2/displays-new/panel-dsi-cm.c (renamed from drivers/video/omap2/displays-new/panel-dsi-cm.c)0
-rw-r--r--drivers/video/fbdev/omap2/displays-new/panel-lgphilips-lb035q02.c (renamed from drivers/video/omap2/displays-new/panel-lgphilips-lb035q02.c)0
-rw-r--r--drivers/video/fbdev/omap2/displays-new/panel-nec-nl8048hl11.c (renamed from drivers/video/omap2/displays-new/panel-nec-nl8048hl11.c)0
-rw-r--r--drivers/video/fbdev/omap2/displays-new/panel-sharp-ls037v7dw01.c (renamed from drivers/video/omap2/displays-new/panel-sharp-ls037v7dw01.c)0
-rw-r--r--drivers/video/fbdev/omap2/displays-new/panel-sony-acx565akm.c (renamed from drivers/video/omap2/displays-new/panel-sony-acx565akm.c)0
-rw-r--r--drivers/video/fbdev/omap2/displays-new/panel-tpo-td028ttec1.c (renamed from drivers/video/omap2/displays-new/panel-tpo-td028ttec1.c)0
-rw-r--r--drivers/video/fbdev/omap2/displays-new/panel-tpo-td043mtea1.c (renamed from drivers/video/omap2/displays-new/panel-tpo-td043mtea1.c)0
-rw-r--r--drivers/video/fbdev/omap2/dss/Kconfig (renamed from drivers/video/omap2/dss/Kconfig)0
-rw-r--r--drivers/video/fbdev/omap2/dss/Makefile (renamed from drivers/video/omap2/dss/Makefile)0
-rw-r--r--drivers/video/fbdev/omap2/dss/apply.c (renamed from drivers/video/omap2/dss/apply.c)0
-rw-r--r--drivers/video/fbdev/omap2/dss/core.c (renamed from drivers/video/omap2/dss/core.c)0
-rw-r--r--drivers/video/fbdev/omap2/dss/dispc-compat.c (renamed from drivers/video/omap2/dss/dispc-compat.c)0
-rw-r--r--drivers/video/fbdev/omap2/dss/dispc-compat.h (renamed from drivers/video/omap2/dss/dispc-compat.h)0
-rw-r--r--drivers/video/fbdev/omap2/dss/dispc.c (renamed from drivers/video/omap2/dss/dispc.c)67
-rw-r--r--drivers/video/fbdev/omap2/dss/dispc.h (renamed from drivers/video/omap2/dss/dispc.h)0
-rw-r--r--drivers/video/fbdev/omap2/dss/dispc_coefs.c (renamed from drivers/video/omap2/dss/dispc_coefs.c)0
-rw-r--r--drivers/video/fbdev/omap2/dss/display-sysfs.c (renamed from drivers/video/omap2/dss/display-sysfs.c)0
-rw-r--r--drivers/video/fbdev/omap2/dss/display.c (renamed from drivers/video/omap2/dss/display.c)0
-rw-r--r--drivers/video/fbdev/omap2/dss/dpi.c (renamed from drivers/video/omap2/dss/dpi.c)0
-rw-r--r--drivers/video/fbdev/omap2/dss/dsi.c (renamed from drivers/video/omap2/dss/dsi.c)20
-rw-r--r--drivers/video/fbdev/omap2/dss/dss-of.c (renamed from drivers/video/omap2/dss/dss-of.c)0
-rw-r--r--drivers/video/fbdev/omap2/dss/dss.c (renamed from drivers/video/omap2/dss/dss.c)4
-rw-r--r--drivers/video/fbdev/omap2/dss/dss.h (renamed from drivers/video/omap2/dss/dss.h)6
-rw-r--r--drivers/video/fbdev/omap2/dss/dss_features.c (renamed from drivers/video/omap2/dss/dss_features.c)0
-rw-r--r--drivers/video/fbdev/omap2/dss/dss_features.h (renamed from drivers/video/omap2/dss/dss_features.h)0
-rw-r--r--drivers/video/fbdev/omap2/dss/hdmi.h (renamed from drivers/video/omap2/dss/hdmi.h)0
-rw-r--r--drivers/video/fbdev/omap2/dss/hdmi4.c (renamed from drivers/video/omap2/dss/hdmi4.c)0
-rw-r--r--drivers/video/fbdev/omap2/dss/hdmi4_core.c (renamed from drivers/video/omap2/dss/hdmi4_core.c)0
-rw-r--r--drivers/video/fbdev/omap2/dss/hdmi4_core.h (renamed from drivers/video/omap2/dss/hdmi4_core.h)0
-rw-r--r--drivers/video/fbdev/omap2/dss/hdmi_common.c (renamed from drivers/video/omap2/dss/hdmi_common.c)8
-rw-r--r--drivers/video/fbdev/omap2/dss/hdmi_phy.c (renamed from drivers/video/omap2/dss/hdmi_phy.c)0
-rw-r--r--drivers/video/fbdev/omap2/dss/hdmi_pll.c (renamed from drivers/video/omap2/dss/hdmi_pll.c)0
-rw-r--r--drivers/video/fbdev/omap2/dss/hdmi_wp.c (renamed from drivers/video/omap2/dss/hdmi_wp.c)0
-rw-r--r--drivers/video/fbdev/omap2/dss/manager-sysfs.c (renamed from drivers/video/omap2/dss/manager-sysfs.c)0
-rw-r--r--drivers/video/fbdev/omap2/dss/manager.c (renamed from drivers/video/omap2/dss/manager.c)0
-rw-r--r--drivers/video/fbdev/omap2/dss/output.c (renamed from drivers/video/omap2/dss/output.c)0
-rw-r--r--drivers/video/fbdev/omap2/dss/overlay-sysfs.c (renamed from drivers/video/omap2/dss/overlay-sysfs.c)0
-rw-r--r--drivers/video/fbdev/omap2/dss/overlay.c (renamed from drivers/video/omap2/dss/overlay.c)0
-rw-r--r--drivers/video/fbdev/omap2/dss/rfbi.c (renamed from drivers/video/omap2/dss/rfbi.c)0
-rw-r--r--drivers/video/fbdev/omap2/dss/sdi.c (renamed from drivers/video/omap2/dss/sdi.c)0
-rw-r--r--drivers/video/fbdev/omap2/dss/venc.c (renamed from drivers/video/omap2/dss/venc.c)0
-rw-r--r--drivers/video/fbdev/omap2/dss/venc_panel.c (renamed from drivers/video/omap2/dss/venc_panel.c)0
-rw-r--r--drivers/video/fbdev/omap2/omapfb/Kconfig (renamed from drivers/video/omap2/omapfb/Kconfig)0
-rw-r--r--drivers/video/fbdev/omap2/omapfb/Makefile (renamed from drivers/video/omap2/omapfb/Makefile)0
-rw-r--r--drivers/video/fbdev/omap2/omapfb/omapfb-ioctl.c (renamed from drivers/video/omap2/omapfb/omapfb-ioctl.c)0
-rw-r--r--drivers/video/fbdev/omap2/omapfb/omapfb-main.c (renamed from drivers/video/omap2/omapfb/omapfb-main.c)0
-rw-r--r--drivers/video/fbdev/omap2/omapfb/omapfb-sysfs.c (renamed from drivers/video/omap2/omapfb/omapfb-sysfs.c)0
-rw-r--r--drivers/video/fbdev/omap2/omapfb/omapfb.h (renamed from drivers/video/omap2/omapfb/omapfb.h)0
-rw-r--r--drivers/video/fbdev/omap2/vrfb.c (renamed from drivers/video/omap2/vrfb.c)0
-rw-r--r--drivers/video/fbdev/p9100.c (renamed from drivers/video/p9100.c)0
-rw-r--r--drivers/video/fbdev/platinumfb.c (renamed from drivers/video/platinumfb.c)0
-rw-r--r--drivers/video/fbdev/platinumfb.h (renamed from drivers/video/platinumfb.h)0
-rw-r--r--drivers/video/fbdev/pm2fb.c (renamed from drivers/video/pm2fb.c)0
-rw-r--r--drivers/video/fbdev/pm3fb.c (renamed from drivers/video/pm3fb.c)0
-rw-r--r--drivers/video/fbdev/pmag-aa-fb.c (renamed from drivers/video/pmag-aa-fb.c)0
-rw-r--r--drivers/video/fbdev/pmag-ba-fb.c (renamed from drivers/video/pmag-ba-fb.c)0
-rw-r--r--drivers/video/fbdev/pmagb-b-fb.c (renamed from drivers/video/pmagb-b-fb.c)0
-rw-r--r--drivers/video/fbdev/ps3fb.c (renamed from drivers/video/ps3fb.c)0
-rw-r--r--drivers/video/fbdev/pvr2fb.c (renamed from drivers/video/pvr2fb.c)0
-rw-r--r--drivers/video/fbdev/pxa168fb.c (renamed from drivers/video/pxa168fb.c)0
-rw-r--r--drivers/video/fbdev/pxa168fb.h (renamed from drivers/video/pxa168fb.h)0
-rw-r--r--drivers/video/fbdev/pxa3xx-gcu.c (renamed from drivers/video/pxa3xx-gcu.c)0
-rw-r--r--drivers/video/fbdev/pxa3xx-gcu.h (renamed from drivers/video/pxa3xx-gcu.h)0
-rw-r--r--drivers/video/fbdev/pxafb.c (renamed from drivers/video/pxafb.c)0
-rw-r--r--drivers/video/fbdev/pxafb.h (renamed from drivers/video/pxafb.h)0
-rw-r--r--drivers/video/fbdev/q40fb.c (renamed from drivers/video/q40fb.c)0
-rw-r--r--drivers/video/fbdev/riva/Makefile (renamed from drivers/video/riva/Makefile)0
-rw-r--r--drivers/video/fbdev/riva/fbdev.c (renamed from drivers/video/riva/fbdev.c)0
-rw-r--r--drivers/video/fbdev/riva/nv_driver.c (renamed from drivers/video/riva/nv_driver.c)0
-rw-r--r--drivers/video/fbdev/riva/nv_type.h (renamed from drivers/video/riva/nv_type.h)0
-rw-r--r--drivers/video/fbdev/riva/nvreg.h (renamed from drivers/video/riva/nvreg.h)0
-rw-r--r--drivers/video/fbdev/riva/riva_hw.c (renamed from drivers/video/riva/riva_hw.c)0
-rw-r--r--drivers/video/fbdev/riva/riva_hw.h (renamed from drivers/video/riva/riva_hw.h)0
-rw-r--r--drivers/video/fbdev/riva/riva_tbl.h (renamed from drivers/video/riva/riva_tbl.h)0
-rw-r--r--drivers/video/fbdev/riva/rivafb-i2c.c (renamed from drivers/video/riva/rivafb-i2c.c)0
-rw-r--r--drivers/video/fbdev/riva/rivafb.h (renamed from drivers/video/riva/rivafb.h)0
-rw-r--r--drivers/video/fbdev/s1d13xxxfb.c (renamed from drivers/video/s1d13xxxfb.c)0
-rw-r--r--drivers/video/fbdev/s3c-fb.c (renamed from drivers/video/s3c-fb.c)0
-rw-r--r--drivers/video/fbdev/s3c2410fb.c (renamed from drivers/video/s3c2410fb.c)0
-rw-r--r--drivers/video/fbdev/s3c2410fb.h (renamed from drivers/video/s3c2410fb.h)0
-rw-r--r--drivers/video/fbdev/s3fb.c (renamed from drivers/video/s3fb.c)0
-rw-r--r--drivers/video/fbdev/sa1100fb.c (renamed from drivers/video/sa1100fb.c)0
-rw-r--r--drivers/video/fbdev/sa1100fb.h (renamed from drivers/video/sa1100fb.h)0
-rw-r--r--drivers/video/fbdev/savage/Makefile (renamed from drivers/video/savage/Makefile)0
-rw-r--r--drivers/video/fbdev/savage/savagefb-i2c.c (renamed from drivers/video/savage/savagefb-i2c.c)0
-rw-r--r--drivers/video/fbdev/savage/savagefb.h (renamed from drivers/video/savage/savagefb.h)0
-rw-r--r--drivers/video/fbdev/savage/savagefb_accel.c (renamed from drivers/video/savage/savagefb_accel.c)0
-rw-r--r--drivers/video/fbdev/savage/savagefb_driver.c (renamed from drivers/video/savage/savagefb_driver.c)0
-rw-r--r--drivers/video/fbdev/sbuslib.c (renamed from drivers/video/sbuslib.c)0
-rw-r--r--drivers/video/fbdev/sbuslib.h (renamed from drivers/video/sbuslib.h)0
-rw-r--r--drivers/video/fbdev/sh7760fb.c (renamed from drivers/video/sh7760fb.c)0
-rw-r--r--drivers/video/fbdev/sh_mipi_dsi.c (renamed from drivers/video/sh_mipi_dsi.c)0
-rw-r--r--drivers/video/fbdev/sh_mobile_hdmi.c (renamed from drivers/video/sh_mobile_hdmi.c)0
-rw-r--r--drivers/video/fbdev/sh_mobile_lcdcfb.c (renamed from drivers/video/sh_mobile_lcdcfb.c)0
-rw-r--r--drivers/video/fbdev/sh_mobile_lcdcfb.h (renamed from drivers/video/sh_mobile_lcdcfb.h)0
-rw-r--r--drivers/video/fbdev/sh_mobile_meram.c (renamed from drivers/video/sh_mobile_meram.c)0
-rw-r--r--drivers/video/fbdev/simplefb.c (renamed from drivers/video/simplefb.c)0
-rw-r--r--drivers/video/fbdev/sis/300vtbl.h (renamed from drivers/video/sis/300vtbl.h)0
-rw-r--r--drivers/video/fbdev/sis/310vtbl.h (renamed from drivers/video/sis/310vtbl.h)0
-rw-r--r--drivers/video/fbdev/sis/Makefile (renamed from drivers/video/sis/Makefile)0
-rw-r--r--drivers/video/fbdev/sis/init.c (renamed from drivers/video/sis/init.c)0
-rw-r--r--drivers/video/fbdev/sis/init.h (renamed from drivers/video/sis/init.h)0
-rw-r--r--drivers/video/fbdev/sis/init301.c (renamed from drivers/video/sis/init301.c)0
-rw-r--r--drivers/video/fbdev/sis/init301.h (renamed from drivers/video/sis/init301.h)0
-rw-r--r--drivers/video/fbdev/sis/initdef.h (renamed from drivers/video/sis/initdef.h)0
-rw-r--r--drivers/video/fbdev/sis/initextlfb.c (renamed from drivers/video/sis/initextlfb.c)0
-rw-r--r--drivers/video/fbdev/sis/oem300.h (renamed from drivers/video/sis/oem300.h)0
-rw-r--r--drivers/video/fbdev/sis/oem310.h (renamed from drivers/video/sis/oem310.h)0
-rw-r--r--drivers/video/fbdev/sis/sis.h (renamed from drivers/video/sis/sis.h)0
-rw-r--r--drivers/video/fbdev/sis/sis_accel.c (renamed from drivers/video/sis/sis_accel.c)0
-rw-r--r--drivers/video/fbdev/sis/sis_accel.h (renamed from drivers/video/sis/sis_accel.h)0
-rw-r--r--drivers/video/fbdev/sis/sis_main.c (renamed from drivers/video/sis/sis_main.c)0
-rw-r--r--drivers/video/fbdev/sis/sis_main.h (renamed from drivers/video/sis/sis_main.h)0
-rw-r--r--drivers/video/fbdev/sis/vgatypes.h (renamed from drivers/video/sis/vgatypes.h)0
-rw-r--r--drivers/video/fbdev/sis/vstruct.h (renamed from drivers/video/sis/vstruct.h)0
-rw-r--r--drivers/video/fbdev/skeletonfb.c (renamed from drivers/video/skeletonfb.c)0
-rw-r--r--drivers/video/fbdev/sm501fb.c (renamed from drivers/video/sm501fb.c)0
-rw-r--r--drivers/video/fbdev/smscufx.c (renamed from drivers/video/smscufx.c)0
-rw-r--r--drivers/video/fbdev/ssd1307fb.c (renamed from drivers/video/ssd1307fb.c)0
-rw-r--r--drivers/video/fbdev/sstfb.c (renamed from drivers/video/sstfb.c)0
-rw-r--r--drivers/video/fbdev/sticore.h (renamed from drivers/video/sticore.h)0
-rw-r--r--drivers/video/fbdev/stifb.c (renamed from drivers/video/stifb.c)0
-rw-r--r--drivers/video/fbdev/sunxvr1000.c (renamed from drivers/video/sunxvr1000.c)0
-rw-r--r--drivers/video/fbdev/sunxvr2500.c (renamed from drivers/video/sunxvr2500.c)0
-rw-r--r--drivers/video/fbdev/sunxvr500.c (renamed from drivers/video/sunxvr500.c)0
-rw-r--r--drivers/video/fbdev/tcx.c (renamed from drivers/video/tcx.c)0
-rw-r--r--drivers/video/fbdev/tdfxfb.c (renamed from drivers/video/tdfxfb.c)0
-rw-r--r--drivers/video/fbdev/tgafb.c (renamed from drivers/video/tgafb.c)0
-rw-r--r--drivers/video/fbdev/tmiofb.c (renamed from drivers/video/tmiofb.c)0
-rw-r--r--drivers/video/fbdev/tridentfb.c (renamed from drivers/video/tridentfb.c)0
-rw-r--r--drivers/video/fbdev/udlfb.c (renamed from drivers/video/udlfb.c)0
-rw-r--r--drivers/video/fbdev/uvesafb.c (renamed from drivers/video/uvesafb.c)0
-rw-r--r--drivers/video/fbdev/valkyriefb.c (renamed from drivers/video/valkyriefb.c)0
-rw-r--r--drivers/video/fbdev/valkyriefb.h (renamed from drivers/video/valkyriefb.h)0
-rw-r--r--drivers/video/fbdev/vermilion/Makefile (renamed from drivers/video/vermilion/Makefile)0
-rw-r--r--drivers/video/fbdev/vermilion/cr_pll.c (renamed from drivers/video/vermilion/cr_pll.c)0
-rw-r--r--drivers/video/fbdev/vermilion/vermilion.c (renamed from drivers/video/vermilion/vermilion.c)0
-rw-r--r--drivers/video/fbdev/vermilion/vermilion.h (renamed from drivers/video/vermilion/vermilion.h)0
-rw-r--r--drivers/video/fbdev/vesafb.c (renamed from drivers/video/vesafb.c)0
-rw-r--r--drivers/video/fbdev/vfb.c (renamed from drivers/video/vfb.c)0
-rw-r--r--drivers/video/fbdev/vga16fb.c (renamed from drivers/video/vga16fb.c)0
-rw-r--r--drivers/video/fbdev/via/Makefile (renamed from drivers/video/via/Makefile)0
-rw-r--r--drivers/video/fbdev/via/accel.c (renamed from drivers/video/via/accel.c)0
-rw-r--r--drivers/video/fbdev/via/accel.h (renamed from drivers/video/via/accel.h)0
-rw-r--r--drivers/video/fbdev/via/chip.h (renamed from drivers/video/via/chip.h)0
-rw-r--r--drivers/video/fbdev/via/debug.h (renamed from drivers/video/via/debug.h)0
-rw-r--r--drivers/video/fbdev/via/dvi.c (renamed from drivers/video/via/dvi.c)0
-rw-r--r--drivers/video/fbdev/via/dvi.h (renamed from drivers/video/via/dvi.h)0
-rw-r--r--drivers/video/fbdev/via/global.c (renamed from drivers/video/via/global.c)0
-rw-r--r--drivers/video/fbdev/via/global.h (renamed from drivers/video/via/global.h)0
-rw-r--r--drivers/video/fbdev/via/hw.c (renamed from drivers/video/via/hw.c)0
-rw-r--r--drivers/video/fbdev/via/hw.h (renamed from drivers/video/via/hw.h)0
-rw-r--r--drivers/video/fbdev/via/ioctl.c (renamed from drivers/video/via/ioctl.c)0
-rw-r--r--drivers/video/fbdev/via/ioctl.h (renamed from drivers/video/via/ioctl.h)0
-rw-r--r--drivers/video/fbdev/via/lcd.c (renamed from drivers/video/via/lcd.c)0
-rw-r--r--drivers/video/fbdev/via/lcd.h (renamed from drivers/video/via/lcd.h)0
-rw-r--r--drivers/video/fbdev/via/share.h (renamed from drivers/video/via/share.h)0
-rw-r--r--drivers/video/fbdev/via/tblDPASetting.c (renamed from drivers/video/via/tblDPASetting.c)0
-rw-r--r--drivers/video/fbdev/via/tblDPASetting.h (renamed from drivers/video/via/tblDPASetting.h)0
-rw-r--r--drivers/video/fbdev/via/via-core.c (renamed from drivers/video/via/via-core.c)0
-rw-r--r--drivers/video/fbdev/via/via-gpio.c (renamed from drivers/video/via/via-gpio.c)0
-rw-r--r--drivers/video/fbdev/via/via_aux.c (renamed from drivers/video/via/via_aux.c)0
-rw-r--r--drivers/video/fbdev/via/via_aux.h (renamed from drivers/video/via/via_aux.h)0
-rw-r--r--drivers/video/fbdev/via/via_aux_ch7301.c (renamed from drivers/video/via/via_aux_ch7301.c)0
-rw-r--r--drivers/video/fbdev/via/via_aux_edid.c (renamed from drivers/video/via/via_aux_edid.c)0
-rw-r--r--drivers/video/fbdev/via/via_aux_sii164.c (renamed from drivers/video/via/via_aux_sii164.c)0
-rw-r--r--drivers/video/fbdev/via/via_aux_vt1621.c (renamed from drivers/video/via/via_aux_vt1621.c)0
-rw-r--r--drivers/video/fbdev/via/via_aux_vt1622.c (renamed from drivers/video/via/via_aux_vt1622.c)0
-rw-r--r--drivers/video/fbdev/via/via_aux_vt1625.c (renamed from drivers/video/via/via_aux_vt1625.c)0
-rw-r--r--drivers/video/fbdev/via/via_aux_vt1631.c (renamed from drivers/video/via/via_aux_vt1631.c)0
-rw-r--r--drivers/video/fbdev/via/via_aux_vt1632.c (renamed from drivers/video/via/via_aux_vt1632.c)0
-rw-r--r--drivers/video/fbdev/via/via_aux_vt1636.c (renamed from drivers/video/via/via_aux_vt1636.c)0
-rw-r--r--drivers/video/fbdev/via/via_clock.c (renamed from drivers/video/via/via_clock.c)0
-rw-r--r--drivers/video/fbdev/via/via_clock.h (renamed from drivers/video/via/via_clock.h)0
-rw-r--r--drivers/video/fbdev/via/via_i2c.c (renamed from drivers/video/via/via_i2c.c)0
-rw-r--r--drivers/video/fbdev/via/via_modesetting.c (renamed from drivers/video/via/via_modesetting.c)0
-rw-r--r--drivers/video/fbdev/via/via_modesetting.h (renamed from drivers/video/via/via_modesetting.h)0
-rw-r--r--drivers/video/fbdev/via/via_utility.c (renamed from drivers/video/via/via_utility.c)0
-rw-r--r--drivers/video/fbdev/via/via_utility.h (renamed from drivers/video/via/via_utility.h)0
-rw-r--r--drivers/video/fbdev/via/viafbdev.c (renamed from drivers/video/via/viafbdev.c)0
-rw-r--r--drivers/video/fbdev/via/viafbdev.h (renamed from drivers/video/via/viafbdev.h)0
-rw-r--r--drivers/video/fbdev/via/viamode.c (renamed from drivers/video/via/viamode.c)0
-rw-r--r--drivers/video/fbdev/via/viamode.h (renamed from drivers/video/via/viamode.h)0
-rw-r--r--drivers/video/fbdev/via/vt1636.c (renamed from drivers/video/via/vt1636.c)0
-rw-r--r--drivers/video/fbdev/via/vt1636.h (renamed from drivers/video/via/vt1636.h)0
-rw-r--r--drivers/video/fbdev/vt8500lcdfb.c (renamed from drivers/video/vt8500lcdfb.c)0
-rw-r--r--drivers/video/fbdev/vt8500lcdfb.h (renamed from drivers/video/vt8500lcdfb.h)0
-rw-r--r--drivers/video/fbdev/vt8623fb.c (renamed from drivers/video/vt8623fb.c)0
-rw-r--r--drivers/video/fbdev/w100fb.c (renamed from drivers/video/w100fb.c)0
-rw-r--r--drivers/video/fbdev/w100fb.h (renamed from drivers/video/w100fb.h)0
-rw-r--r--drivers/video/fbdev/wm8505fb.c (renamed from drivers/video/wm8505fb.c)0
-rw-r--r--drivers/video/fbdev/wm8505fb_regs.h (renamed from drivers/video/wm8505fb_regs.h)0
-rw-r--r--drivers/video/fbdev/wmt_ge_rops.c (renamed from drivers/video/wmt_ge_rops.c)2
-rw-r--r--drivers/video/fbdev/wmt_ge_rops.h (renamed from drivers/video/wmt_ge_rops.h)0
-rw-r--r--drivers/video/fbdev/xen-fbfront.c (renamed from drivers/video/xen-fbfront.c)0
-rw-r--r--drivers/video/fbdev/xilinxfb.c (renamed from drivers/video/xilinxfb.c)0
-rw-r--r--drivers/video/omap2/Kconfig10
-rw-r--r--drivers/vme/bridges/vme_tsi148.c22
-rw-r--r--drivers/w1/w1.c32
-rw-r--r--drivers/w1/w1_netlink.c44
-rw-r--r--drivers/xen/manage.c32
-rw-r--r--drivers/xen/xen-pciback/pciback_ops.c3
-rw-r--r--drivers/xen/xen-pciback/vpci.c2
-rw-r--r--drivers/xen/xenbus/xenbus_xs.c44
-rw-r--r--firmware/WHENCE10
-rw-r--r--fs/cifs/cifsfs.c14
-rw-r--r--fs/cifs/cifsglob.h8
-rw-r--r--fs/cifs/cifsproto.h3
-rw-r--r--fs/cifs/cifssmb.c3
-rw-r--r--fs/cifs/file.c35
-rw-r--r--fs/cifs/misc.c74
-rw-r--r--fs/cifs/smb1ops.c11
-rw-r--r--fs/cifs/smb2misc.c18
-rw-r--r--fs/cifs/smb2ops.c14
-rw-r--r--fs/cifs/smb2pdu.c2
-rw-r--r--fs/kernfs/inode.c14
-rw-r--r--fs/super.c5
-rw-r--r--fs/sysfs/file.c92
-rw-r--r--fs/xfs/xfs_aops.c51
-rw-r--r--fs/xfs/xfs_bmap.c17
-rw-r--r--fs/xfs/xfs_bmap_util.c13
-rw-r--r--fs/xfs/xfs_buf.c16
-rw-r--r--fs/xfs/xfs_file.c2
-rw-r--r--fs/xfs/xfs_inode.c5
-rw-r--r--fs/xfs/xfs_inode.h2
-rw-r--r--fs/xfs/xfs_iops.c20
-rw-r--r--fs/xfs/xfs_log.c53
-rw-r--r--fs/xfs/xfs_trace.h1
-rw-r--r--include/asm-generic/pgtable.h31
-rw-r--r--include/drm/drm_crtc_helper.h6
-rw-r--r--include/drm/drm_dp_helper.h4
-rw-r--r--include/linux/device.h11
-rw-r--r--include/linux/ethtool.h13
-rw-r--r--include/linux/filter.h1
-rw-r--r--include/linux/hyperv.h4
-rw-r--r--include/linux/ipmi.h2
-rw-r--r--include/linux/ipmi_smi.h11
-rw-r--r--include/linux/mlx5/device.h1
-rw-r--r--include/linux/mlx5/qp.h1
-rw-r--r--include/linux/mtd/spear_smi.h2
-rw-r--r--include/linux/netdevice.h1
-rw-r--r--include/linux/netlink.h3
-rw-r--r--include/linux/of.h5
-rw-r--r--include/linux/phy.h1
-rw-r--r--include/linux/reboot.h14
-rw-r--r--include/linux/sock_diag.h2
-rw-r--r--include/linux/spi/at86rf230.h14
-rw-r--r--include/linux/sysfs.h9
-rw-r--r--include/linux/wait.h14
-rw-r--r--include/net/6lowpan.h1
-rw-r--r--include/net/addrconf.h5
-rw-r--r--include/net/dsa.h5
-rw-r--r--include/net/ipv6.h19
-rw-r--r--include/net/net_namespace.h8
-rw-r--r--include/net/pkt_cls.h2
-rw-r--r--include/net/sch_generic.h2
-rw-r--r--include/net/sctp/structs.h4
-rw-r--r--include/net/tcp.h1
-rw-r--r--include/net/vxlan.h2
-rw-r--r--include/uapi/drm/tegra_drm.h1
-rw-r--r--include/uapi/linux/audit.h8
-rw-r--r--include/uapi/linux/capability.h7
-rw-r--r--include/uapi/linux/ethtool.h32
-rw-r--r--include/uapi/linux/filter.h3
-rw-r--r--include/uapi/linux/hyperv.h1
-rw-r--r--include/uapi/linux/if_fddi.h90
-rw-r--r--include/uapi/linux/tipc.h23
-rw-r--r--include/uapi/linux/tipc_config.h10
-rw-r--r--init/Kconfig24
-rw-r--r--kernel/audit.c64
-rw-r--r--kernel/locking/mutex-debug.c19
-rw-r--r--kernel/sched/deadline.c11
-rw-r--r--kernel/sched/fair.c16
-rw-r--r--kernel/sched/rt.c7
-rw-r--r--kernel/sched/sched.h9
-rw-r--r--kernel/time/tick-common.c2
-rw-r--r--kernel/time/tick-sched.c5
-rw-r--r--kernel/trace/trace_functions.c16
-rw-r--r--kernel/trace/trace_uprobe.c6
-rw-r--r--kernel/watchdog.c6
-rw-r--r--lib/Kconfig.debug3
-rw-r--r--mm/filemap.c1
-rw-r--r--mm/huge_memory.c13
-rw-r--r--mm/hugetlb.c1
-rw-r--r--mm/vmscan.c2
-rw-r--r--net/8021q/vlan_dev.c104
-rw-r--r--net/core/dev.c43
-rw-r--r--net/core/ethtool.c223
-rw-r--r--net/core/filter.c26
-rw-r--r--net/core/net_namespace.c2
-rw-r--r--net/core/sock_diag.c4
-rw-r--r--net/ieee802154/reassembly.c48
-rw-r--r--net/ipv4/inetpeer.c2
-rw-r--r--net/ipv4/ip_gre.c6
-rw-r--r--net/ipv4/ip_options.c6
-rw-r--r--net/ipv4/tcp.c8
-rw-r--r--net/ipv4/tcp_input.c22
-rw-r--r--net/ipv4/tcp_output.c56
-rw-r--r--net/ipv6/addrconf.c20
-rw-r--r--net/ipv6/icmp.c14
-rw-r--r--net/ipv6/ip6_flowlabel.c1
-rw-r--r--net/ipv6/ip6_gre.c52
-rw-r--r--net/ipv6/ping.c7
-rw-r--r--net/ipv6/raw.c10
-rw-r--r--net/ipv6/udp.c10
-rw-r--r--net/l2tp/l2tp_ip6.c10
-rw-r--r--net/netfilter/nfnetlink.c10
-rw-r--r--net/netlink/af_netlink.c70
-rw-r--r--net/netlink/af_netlink.h6
-rw-r--r--net/openvswitch/vport-vxlan.c3
-rw-r--r--net/packet/diag.c2
-rw-r--r--net/sched/cls_api.c23
-rw-r--r--net/sched/cls_basic.c10
-rw-r--r--net/sched/cls_bpf.c10
-rw-r--r--net/sched/cls_cgroup.c4
-rw-r--r--net/sched/cls_flow.c4
-rw-r--r--net/sched/cls_fw.c10
-rw-r--r--net/sched/cls_route.c11
-rw-r--r--net/sched/cls_rsvp.h4
-rw-r--r--net/sched/cls_tcindex.c8
-rw-r--r--net/sched/cls_u32.c10
-rw-r--r--net/sctp/auth.c17
-rw-r--r--net/sctp/endpointola.c3
-rw-r--r--net/sctp/sm_make_chunk.c32
-rw-r--r--net/sctp/sm_statefuns.c6
-rw-r--r--net/sctp/socket.c59
-rw-r--r--net/sctp/sysctl.c36
-rw-r--r--net/sctp/ulpqueue.c4
-rw-r--r--net/tipc/bcast.c37
-rw-r--r--net/tipc/bcast.h5
-rw-r--r--net/tipc/bearer.c117
-rw-r--r--net/tipc/bearer.h12
-rw-r--r--net/tipc/config.c6
-rw-r--r--net/tipc/core.h2
-rw-r--r--net/tipc/discover.c66
-rw-r--r--net/tipc/discover.h1
-rw-r--r--net/tipc/link.c89
-rw-r--r--net/tipc/link.h6
-rw-r--r--net/tipc/name_distr.c20
-rw-r--r--net/tipc/name_distr.h5
-rw-r--r--net/tipc/name_table.c14
-rw-r--r--net/tipc/net.c61
-rw-r--r--net/tipc/net.h2
-rw-r--r--net/tipc/node.c43
-rw-r--r--net/tipc/node.h1
-rw-r--r--net/tipc/socket.c29
-rw-r--r--security/selinux/include/classmap.h2
-rw-r--r--sound/isa/es18xx.c10
-rw-r--r--sound/pci/hda/patch_realtek.c5
-rw-r--r--tools/hv/hv_fcopy_daemon.c4
-rw-r--r--tools/lib/lockdep/Makefile15
-rw-r--r--tools/lib/lockdep/uinclude/linux/lockdep.h3
-rw-r--r--tools/lib/traceevent/event-parse.c109
-rw-r--r--tools/net/bpf_exp.l1
-rw-r--r--tools/net/bpf_exp.y11
-rw-r--r--tools/perf/Documentation/perf-bench.txt22
-rw-r--r--tools/perf/Documentation/perf-top.txt1
-rw-r--r--tools/perf/Makefile.perf4
-rw-r--r--tools/perf/bench/numa.c4
-rw-r--r--tools/perf/builtin-stat.c11
-rw-r--r--tools/perf/config/Makefile7
-rw-r--r--tools/perf/tests/code-reading.c1
-rw-r--r--tools/perf/util/probe-finder.c15
1055 files changed, 15310 insertions, 29844 deletions
diff --git a/.mailmap b/.mailmap
index 658003a..df1baba 100644
--- a/.mailmap
+++ b/.mailmap
@@ -99,6 +99,7 @@ Sachin P Sant <ssant@in.ibm.com>
Sam Ravnborg <sam@mars.ravnborg.org>
Sascha Hauer <s.hauer@pengutronix.de>
S.Çağlar Onur <caglar@pardus.org.tr>
+Shiraz Hashim <shiraz.linux.kernel@gmail.com> <shiraz.hashim@st.com>
Simon Kelley <simon@thekelleys.org.uk>
Stéphane Witzmann <stephane.witzmann@ubpmes.univ-bpclermont.fr>
Stephen Hemminger <shemminger@osdl.org>
diff --git a/Documentation/DocBook/device-drivers.tmpl b/Documentation/DocBook/device-drivers.tmpl
index f517008..cc63f30 100644
--- a/Documentation/DocBook/device-drivers.tmpl
+++ b/Documentation/DocBook/device-drivers.tmpl
@@ -276,7 +276,7 @@ X!Isound/sound_firmware.c
</para>
<sect1><title>Frame Buffer Memory</title>
-!Edrivers/video/fbmem.c
+!Edrivers/video/fbdev/core/fbmem.c
</sect1>
<!--
<sect1><title>Frame Buffer Console</title>
@@ -284,7 +284,7 @@ X!Edrivers/video/console/fbcon.c
</sect1>
-->
<sect1><title>Frame Buffer Colormap</title>
-!Edrivers/video/fbcmap.c
+!Edrivers/video/fbdev/core/fbcmap.c
</sect1>
<!-- FIXME:
drivers/video/fbgen.c has no docs, which stuffs up the sgml. Comment
@@ -294,11 +294,11 @@ X!Idrivers/video/fbgen.c
</sect1>
KAO -->
<sect1><title>Frame Buffer Video Mode Database</title>
-!Idrivers/video/modedb.c
-!Edrivers/video/modedb.c
+!Idrivers/video/fbdev/core/modedb.c
+!Edrivers/video/fbdev/core/modedb.c
</sect1>
<sect1><title>Frame Buffer Macintosh Video Mode Database</title>
-!Edrivers/video/macmodes.c
+!Edrivers/video/fbdev/macmodes.c
</sect1>
<sect1><title>Frame Buffer Fonts</title>
<para>
diff --git a/Documentation/DocBook/drm.tmpl b/Documentation/DocBook/drm.tmpl
index 702c4474..677a025 100644
--- a/Documentation/DocBook/drm.tmpl
+++ b/Documentation/DocBook/drm.tmpl
@@ -2287,6 +2287,11 @@ void intel_crt_init(struct drm_device *dev)
!Edrivers/gpu/drm/drm_crtc_helper.c
</sect2>
<sect2>
+ <title>Output Probing Helper Functions Reference</title>
+!Pdrivers/gpu/drm/drm_probe_helper.c output probing helper overview
+!Edrivers/gpu/drm/drm_probe_helper.c
+ </sect2>
+ <sect2>
<title>fbdev Helper Functions Reference</title>
!Pdrivers/gpu/drm/drm_fb_helper.c fbdev helpers
!Edrivers/gpu/drm/drm_fb_helper.c
diff --git a/Documentation/devicetree/bindings/arm/marvell,kirkwood.txt b/Documentation/devicetree/bindings/arm/marvell,kirkwood.txt
new file mode 100644
index 0000000..925ecbf
--- /dev/null
+++ b/Documentation/devicetree/bindings/arm/marvell,kirkwood.txt
@@ -0,0 +1,97 @@
+Marvell Kirkwood SoC Family Device Tree Bindings
+------------------------------------------------
+
+Boards with a SoC of the Marvell Kirkwook family, eg 88f6281
+
+* Required root node properties:
+compatible: must contain "marvell,kirkwood"
+
+In addition, the above compatible shall be extended with the specific
+SoC. Currently known SoC compatibles are:
+
+"marvell,kirkwood-88f6192"
+"marvell,kirkwood-88f6281"
+"marvell,kirkwood-88f6282"
+"marvell,kirkwood-88f6283"
+"marvell,kirkwood-88f6702"
+"marvell,kirkwood-98DX4122"
+
+And in addition, the compatible shall be extended with the specific
+board. Currently known boards are:
+
+"buffalo,lschlv2"
+"buffalo,lsxhl"
+"buffalo,lsxl"
+"dlink,dns-320"
+"dlink,dns-320-a1"
+"dlink,dns-325"
+"dlink,dns-325-a1"
+"dlink,dns-kirkwood"
+"excito,b3"
+"globalscale,dreamplug-003-ds2001"
+"globalscale,guruplug"
+"globalscale,guruplug-server-plus"
+"globalscale,sheevaplug"
+"globalscale,sheevaplug"
+"globalscale,sheevaplug-esata"
+"globalscale,sheevaplug-esata-rev13"
+"iom,iconnect"
+"iom,iconnect-1.1"
+"iom,ix2-200"
+"keymile,km_kirkwood"
+"lacie,cloudbox"
+"lacie,inetspace_v2"
+"lacie,laplug"
+"lacie,netspace_lite_v2"
+"lacie,netspace_max_v2"
+"lacie,netspace_mini_v2"
+"lacie,netspace_v2"
+"marvell,db-88f6281-bp"
+"marvell,db-88f6282-bp"
+"marvell,mv88f6281gtw-ge"
+"marvell,rd88f6281"
+"marvell,rd88f6281"
+"marvell,rd88f6281-a0"
+"marvell,rd88f6281-a1"
+"mpl,cec4"
+"mpl,cec4-10"
+"netgear,readynas"
+"netgear,readynas"
+"netgear,readynas-duo-v2"
+"netgear,readynas-nv+-v2"
+"plathome,openblocks-a6"
+"plathome,openblocks-a7"
+"raidsonic,ib-nas6210"
+"raidsonic,ib-nas6210-b"
+"raidsonic,ib-nas6220"
+"raidsonic,ib-nas6220-b"
+"raidsonic,ib-nas62x0"
+"seagate,dockstar"
+"seagate,goflexnet"
+"synology,ds109"
+"synology,ds110jv10"
+"synology,ds110jv20"
+"synology,ds110jv30"
+"synology,ds111"
+"synology,ds209"
+"synology,ds210jv10"
+"synology,ds210jv20"
+"synology,ds212"
+"synology,ds212jv10"
+"synology,ds212jv20"
+"synology,ds212pv10"
+"synology,ds409"
+"synology,ds409slim"
+"synology,ds410j"
+"synology,ds411"
+"synology,ds411j"
+"synology,ds411slim"
+"synology,ds413jv10"
+"synology,rs212"
+"synology,rs409"
+"synology,rs411"
+"synology,rs812"
+"usi,topkick"
+"usi,topkick-1281P2"
+"zyxel,nsa310"
+"zyxel,nsa310a"
diff --git a/Documentation/devicetree/bindings/i2c/trivial-devices.txt b/Documentation/devicetree/bindings/i2c/trivial-devices.txt
index 71724d0..bef86e5 100644
--- a/Documentation/devicetree/bindings/i2c/trivial-devices.txt
+++ b/Documentation/devicetree/bindings/i2c/trivial-devices.txt
@@ -13,8 +13,22 @@ ad,ad7414 SMBus/I2C Digital Temperature Sensor in 6-Pin SOT with SMBus Alert an
ad,adm9240 ADM9240: Complete System Hardware Monitor for uProcessor-Based Systems
adi,adt7461 +/-1C TDM Extended Temp Range I.C
adt7461 +/-1C TDM Extended Temp Range I.C
+adi,adt7473 +/-1C TDM Extended Temp Range I.C
+adi,adt7475 +/-1C TDM Extended Temp Range I.C
+adi,adt7476 +/-1C TDM Extended Temp Range I.C
+adi,adt7490 +/-1C TDM Extended Temp Range I.C
at,24c08 i2c serial eeprom (24cxx)
+atmel,24c00 i2c serial eeprom (24cxx)
+atmel,24c01 i2c serial eeprom (24cxx)
atmel,24c02 i2c serial eeprom (24cxx)
+atmel,24c04 i2c serial eeprom (24cxx)
+atmel,24c16 i2c serial eeprom (24cxx)
+atmel,24c32 i2c serial eeprom (24cxx)
+atmel,24c64 i2c serial eeprom (24cxx)
+atmel,24c128 i2c serial eeprom (24cxx)
+atmel,24c256 i2c serial eeprom (24cxx)
+atmel,24c512 i2c serial eeprom (24cxx)
+atmel,24c1024 i2c serial eeprom (24cxx)
atmel,at97sc3204t i2c trusted platform module (TPM)
capella,cm32181 CM32181: Ambient Light Sensor
catalyst,24c32 i2c serial eeprom
@@ -46,8 +60,10 @@ maxim,ds1050 5 Bit Programmable, Pulse-Width Modulator
maxim,max1237 Low-Power, 4-/12-Channel, 2-Wire Serial, 12-Bit ADCs
maxim,max6625 9-Bit/12-Bit Temperature Sensors with I²C-Compatible Serial Interface
mc,rv3029c2 Real Time Clock Module with I2C-Bus
+national,lm63 Temperature sensor with integrated fan control
national,lm75 I2C TEMP SENSOR
national,lm80 Serial Interface ACPI-Compatible Microprocessor System Hardware Monitor
+national,lm85 Temperature sensor with integrated fan control
national,lm92 ±0.33°C Accurate, 12-Bit + Sign Temperature Sensor and Thermal Window Comparator with Two-Wire Interface
nuvoton,npct501 i2c trusted platform module (TPM)
nxp,pca9556 Octal SMBus and I2C registered interface
diff --git a/Documentation/devicetree/bindings/net/broadcom-systemport.txt b/Documentation/devicetree/bindings/net/broadcom-systemport.txt
new file mode 100644
index 0000000..1b7600e
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/broadcom-systemport.txt
@@ -0,0 +1,29 @@
+* Broadcom BCM7xxx Ethernet Systemport Controller (SYSTEMPORT)
+
+Required properties:
+- compatible: should be one of "brcm,systemport-v1.00" or "brcm,systemport"
+- reg: address and length of the register set for the device.
+- interrupts: interrupts for the device, first cell must be for the the rx
+ interrupts, and the second cell should be for the transmit queues
+- local-mac-address: Ethernet MAC address (48 bits) of this adapter
+- phy-mode: Should be a string describing the PHY interface to the
+ Ethernet switch/PHY, see Documentation/devicetree/bindings/net/ethernet.txt
+- fixed-link: see Documentation/devicetree/bindings/net/fsl-tsec-phy.txt for
+ the property specific details
+
+Optional properties:
+- systemport,num-tier2-arb: number of tier 2 arbiters, an integer
+- systemport,num-tier1-arb: number of tier 1 arbiters, an integer
+- systemport,num-txq: number of HW transmit queues, an integer
+- systemport,num-rxq: number of HW receive queues, an integer
+
+Example:
+ethernet@f04a0000 {
+ compatible = "brcm,systemport-v1.00";
+ reg = <0xf04a0000 0x4650>;
+ local-mac-address = [ 00 11 22 33 44 55 ];
+ fixed-link = <0 1 1000 0 0>;
+ phy-mode = "gmii";
+ interrupts = <0x0 0x16 0x0>,
+ <0x0 0x17 0x0>;
+};
diff --git a/Documentation/devicetree/bindings/net/ieee802154/at86rf230.txt b/Documentation/devicetree/bindings/net/ieee802154/at86rf230.txt
new file mode 100644
index 0000000..d3bbdded
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/ieee802154/at86rf230.txt
@@ -0,0 +1,23 @@
+* AT86RF230 IEEE 802.15.4 *
+
+Required properties:
+ - compatible: should be "atmel,at86rf230", "atmel,at86rf231",
+ "atmel,at86rf233" or "atmel,at86rf212"
+ - spi-max-frequency: maximal bus speed, should be set to 7500000 depends
+ sync or async operation mode
+ - reg: the chipselect index
+ - interrupts: the interrupt generated by the device
+
+Optional properties:
+ - reset-gpio: GPIO spec for the rstn pin
+ - sleep-gpio: GPIO spec for the slp_tr pin
+
+Example:
+
+ at86rf231@0 {
+ compatible = "atmel,at86rf231";
+ spi-max-frequency = <7500000>;
+ reg = <0>;
+ interrupts = <19 1>;
+ interrupt-parent = <&gpio3>;
+ };
diff --git a/Documentation/devicetree/bindings/net/via-rhine.txt b/Documentation/devicetree/bindings/net/via-rhine.txt
new file mode 100644
index 0000000..334eca2
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/via-rhine.txt
@@ -0,0 +1,17 @@
+* VIA Rhine 10/100 Network Controller
+
+Required properties:
+- compatible : Should be "via,vt8500-rhine" for integrated
+ Rhine controllers found in VIA VT8500, WonderMedia WM8950
+ and similar. These are listed as 1106:3106 rev. 0x84 on the
+ virtual PCI bus under vendor-provided kernels
+- reg : Address and length of the io space
+- interrupts : Should contain the controller interrupt line
+
+Examples:
+
+ethernet@d8004000 {
+ compatible = "via,vt8500-rhine";
+ reg = <0xd8004000 0x100>;
+ interrupts = <10>;
+};
diff --git a/Documentation/devicetree/bindings/pinctrl/brcm,bcm11351-pinctrl.txt b/Documentation/devicetree/bindings/pinctrl/brcm,bcm11351-pinctrl.txt
index c119deb..67a5db9 100644
--- a/Documentation/devicetree/bindings/pinctrl/brcm,bcm11351-pinctrl.txt
+++ b/Documentation/devicetree/bindings/pinctrl/brcm,bcm11351-pinctrl.txt
@@ -119,7 +119,7 @@ Optional Properties (for HDMI pins):
Example:
// pin controller node
pinctrl@35004800 {
- compatible = "brcmbcm11351-pinctrl";
+ compatible = "brcm,bcm11351-pinctrl";
reg = <0x35004800 0x430>;
// pin configuration node
diff --git a/Documentation/devicetree/bindings/serial/efm32-uart.txt b/Documentation/devicetree/bindings/serial/efm32-uart.txt
index 1984bdf..3ca0133 100644
--- a/Documentation/devicetree/bindings/serial/efm32-uart.txt
+++ b/Documentation/devicetree/bindings/serial/efm32-uart.txt
@@ -1,7 +1,7 @@
* Energymicro efm32 UART
Required properties:
-- compatible : Should be "efm32,uart"
+- compatible : Should be "energymicro,efm32-uart"
- reg : Address and length of the register set
- interrupts : Should contain uart interrupt
@@ -13,7 +13,7 @@ Optional properties:
Example:
uart@0x4000c400 {
- compatible = "efm32,uart";
+ compatible = "energymicro,efm32-uart";
reg = <0x4000c400 0x400>;
interrupts = <15>;
efm32,location = <0>;
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index 0f01c9b..abc3080 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -22,6 +22,7 @@ auo AU Optronics Corporation
avago Avago Technologies
bosch Bosch Sensortec GmbH
brcm Broadcom Corporation
+buffalo Buffalo, Inc.
calxeda Calxeda
capella Capella Microsystems, Inc
cavium Cavium, Inc.
@@ -33,15 +34,18 @@ cortina Cortina Systems, Inc.
crystalfontz Crystalfontz America, Inc.
dallas Maxim Integrated Products (formerly Dallas Semiconductor)
davicom DAVICOM Semiconductor, Inc.
-dlink D-Link Systems, Inc.
denx Denx Software Engineering
+digi Digi International Inc.
+dlink D-Link Corporation
dmo Data Modul AG
+ebv EBV Elektronik
edt Emerging Display Technologies
emmicro EM Microelectronic
epfl Ecole Polytechnique Fédérale de Lausanne
epson Seiko Epson Corp.
est ESTeem Wireless Modems
eukrea Eukréa Electromatique
+excito Excito
fsl Freescale Semiconductor
GEFanuc GE Fanuc Intelligent Platforms Embedded Systems, Inc.
gef GE Fanuc Intelligent Platforms Embedded Systems, Inc.
@@ -53,13 +57,17 @@ haoyu Haoyu Microelectronic Co. Ltd.
hisilicon Hisilicon Limited.
honeywell Honeywell
hp Hewlett Packard
+i2se I2SE GmbH
ibm International Business Machines (IBM)
idt Integrated Device Technologies, Inc.
+iom Iomega Corporation
img Imagination Technologies Ltd.
intel Intel Corporation
intercontrol Inter Control Group
+isee ISEE 2007 S.L.
isl Intersil
karo Ka-Ro electronics GmbH
+keymile Keymile GmbH
lacie LaCie
lantiq Lantiq Semiconductor
lg LG Corporation
@@ -70,9 +78,12 @@ maxim Maxim Integrated Products
microchip Microchip Technology Inc.
mosaixtech Mosaix Technologies, Inc.
moxa Moxa
+mpl MPL AG
+mxicy Macronix International Co., Ltd.
national National Semiconductor
neonode Neonode Inc.
netgear NETGEAR
+newhaven Newhaven Display International
nintendo Nintendo
nokia Nokia
nvidia NVIDIA
@@ -82,10 +93,12 @@ opencores OpenCores.org
panasonic Panasonic Corporation
phytec PHYTEC Messtechnik GmbH
picochip Picochip Ltd
+plathome Plat'Home Co., Ltd.
powervr PowerVR (deprecated, use img)
qca Qualcomm Atheros, Inc.
qcom Qualcomm Technologies, Inc
qnap QNAP Systems, Inc.
+raidsonic RaidSonic Technology GmbH
ralink Mediatek/Ralink Technology Corp.
ramtron Ramtron International
realtek Realtek Semiconductor Corp.
@@ -95,6 +108,7 @@ rockchip Fuzhou Rockchip Electronics Co., Ltd
samsung Samsung Semiconductor
sbs Smart Battery System
schindler Schindler
+seagate Seagate Technology PLC
sil Silicon Image
silabs Silicon Laboratories
simtek
@@ -111,6 +125,7 @@ ti Texas Instruments
tlm Trusted Logic Mobility
toshiba Toshiba Corporation
toumaz Toumaz
+usi Universal Scientifc Industrial Co., Ltd.
v3 V3 Semiconductor
via VIA Technologies, Inc.
voipac Voipac Technologies s.r.o.
@@ -119,3 +134,4 @@ wlf Wolfson Microelectronics
wm Wondermedia Technologies, Inc.
xes Extreme Engineering Solutions (X-ES)
xlnx Xilinx
+zyxel ZyXEL Communications Corp.
diff --git a/Documentation/ja_JP/HOWTO b/Documentation/ja_JP/HOWTO
index 0091a82..b61885c 100644
--- a/Documentation/ja_JP/HOWTO
+++ b/Documentation/ja_JP/HOWTO
@@ -315,7 +315,7 @@ Andrew Morton ㌠Linux-kernel メーリングリストã«ã‚«ãƒ¼ãƒãƒ«ãƒªãƒªãƒ¼ã
ã‚‚ã—ã€3.x.y カーãƒãƒ«ãŒå­˜åœ¨ã—ãªã„å ´åˆã«ã¯ã€ç•ªå·ãŒä¸€ç•ªå¤§ãã„ 3.x ãŒ
最新ã®å®‰å®šç‰ˆã‚«ãƒ¼ãƒãƒ«ã§ã™ã€‚
-3.x.y 㯠"stable" ãƒãƒ¼ãƒ  <stable@kernel.org> ã§ãƒ¡ãƒ³ãƒ†ã•ã‚Œã¦ãŠã‚Šã€å¿…
+3.x.y 㯠"stable" ãƒãƒ¼ãƒ  <stable@vger.kernel.org> ã§ãƒ¡ãƒ³ãƒ†ã•ã‚Œã¦ãŠã‚Šã€å¿…
è¦ã«å¿œã˜ã¦ãƒªãƒªãƒ¼ã‚¹ã•ã‚Œã¾ã™ã€‚通常ã®ãƒªãƒªãƒ¼ã‚¹æœŸé–“㯠2週間毎ã§ã™ãŒã€å·®ã—è¿«ã£
ãŸå•é¡ŒãŒãªã‘ã‚Œã°ã‚‚ã†å°‘ã—é•·ããªã‚‹ã“ã¨ã‚‚ã‚ã‚Šã¾ã™ã€‚セキュリティ関連ã®å•é¡Œ
ã®å ´åˆã¯ã“ã‚Œã«å¯¾ã—ã¦ã ã„ãŸã„ã®å ´åˆã€ã™ãã«ãƒªãƒªãƒ¼ã‚¹ãŒã•ã‚Œã¾ã™ã€‚
diff --git a/Documentation/ja_JP/stable_kernel_rules.txt b/Documentation/ja_JP/stable_kernel_rules.txt
index 1426583..9dbda9b 100644
--- a/Documentation/ja_JP/stable_kernel_rules.txt
+++ b/Documentation/ja_JP/stable_kernel_rules.txt
@@ -50,16 +50,16 @@ linux-2.6.29/Documentation/stable_kernel_rules.txt
-stable ツリーã«ãƒ‘ッãƒã‚’é€ä»˜ã™ã‚‹æ‰‹ç¶šã-
- - 上記ã®è¦å‰‡ã«å¾“ã£ã¦ã„ã‚‹ã‹ã‚’確èªã—ãŸå¾Œã«ã€stable@kernel.org ã«ãƒ‘ッãƒ
+ - 上記ã®è¦å‰‡ã«å¾“ã£ã¦ã„ã‚‹ã‹ã‚’確èªã—ãŸå¾Œã«ã€stable@vger.kernel.org ã«ãƒ‘ッãƒ
ã‚’é€ã‚‹ã€‚
- é€ä¿¡è€…ã¯ãƒ‘ッãƒãŒã‚­ãƒ¥ãƒ¼ã«å—ã‘付ã‘られãŸéš›ã«ã¯ ACK ã‚’ã€å´ä¸‹ã•ã‚ŒãŸå ´åˆ
ã«ã¯ NAK ã‚’å—ã‘å–る。ã“ã®åå¿œã¯é–‹ç™ºè€…ãŸã¡ã®ã‚¹ã‚±ã‚¸ãƒ¥ãƒ¼ãƒ«ã«ã‚ˆã£ã¦ã€æ•°
æ—¥ã‹ã‹ã‚‹å ´åˆãŒã‚る。
- ã‚‚ã—å—ã‘å–られãŸã‚‰ã€ãƒ‘ッãƒã¯ä»–ã®é–‹ç™ºè€…ãŸã¡ã¨é–¢é€£ã™ã‚‹ã‚µãƒ–システムã®
メンテナーã«ã‚ˆã‚‹ãƒ¬ãƒ“ューã®ãŸã‚ã« -stable キューã«è¿½åŠ ã•ã‚Œã‚‹ã€‚
- - パッãƒã« stable@kernel.org ã®ã‚¢ãƒ‰ãƒ¬ã‚¹ãŒä»˜åŠ ã•ã‚Œã¦ã„ã‚‹ã¨ãã«ã¯ã€ãã‚Œ
+ - パッãƒã« stable@vger.kernel.org ã®ã‚¢ãƒ‰ãƒ¬ã‚¹ãŒä»˜åŠ ã•ã‚Œã¦ã„ã‚‹ã¨ãã«ã¯ã€ãã‚Œ
㌠Linus ã®ãƒ„リーã«å…¥ã‚‹æ™‚ã«è‡ªå‹•çš„ã« stable ãƒãƒ¼ãƒ ã« email ã•ã‚Œã‚‹ã€‚
- - セキュリティパッãƒã¯ã“ã®ã‚¨ã‚¤ãƒªã‚¢ã‚¹ (stable@kernel.org) ã«é€ã‚‰ã‚Œã‚‹ã¹
+ - セキュリティパッãƒã¯ã“ã®ã‚¨ã‚¤ãƒªã‚¢ã‚¹ (stable@vger.kernel.org) ã«é€ã‚‰ã‚Œã‚‹ã¹
ãã§ã¯ãªãã€ä»£ã‚ã‚Šã« security@kernel.org ã®ã‚¢ãƒ‰ãƒ¬ã‚¹ã«é€ã‚‰ã‚Œã‚‹ã€‚
レビューサイクル-
diff --git a/Documentation/kernel-parameters.txt b/Documentation/kernel-parameters.txt
index 03e50b4..4384217 100644
--- a/Documentation/kernel-parameters.txt
+++ b/Documentation/kernel-parameters.txt
@@ -804,13 +804,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
dhash_entries= [KNL]
Set number of hash buckets for dentry cache.
- digi= [HW,SERIAL]
- IO parameters + enable/disable command.
-
- digiepca= [HW,SERIAL]
- See drivers/char/README.epca and
- Documentation/serial/digiepca.txt.
-
disable= [IPV6]
See Documentation/networking/ipv6.txt.
@@ -2939,9 +2932,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
rhash_entries= [KNL,NET]
Set number of hash buckets for route cache
- riscom8= [HW,SERIAL]
- Format: <io_board1>[,<io_board2>[,...<io_boardN>]]
-
ro [KNL] Mount root device read-only on boot
root= [KNL] Root filesystem
@@ -3083,9 +3073,6 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
sonypi.*= [HW] Sony Programmable I/O Control Device driver
See Documentation/laptops/sonypi.txt
- specialix= [HW,SERIAL] Specialix multi-serial port adapter
- See Documentation/serial/specialix.txt.
-
spia_io_base= [HW,MTD]
spia_fio_base=
spia_pedr=
diff --git a/Documentation/magic-number.txt b/Documentation/magic-number.txt
index 76d80a6..4c8e142 100644
--- a/Documentation/magic-number.txt
+++ b/Documentation/magic-number.txt
@@ -63,8 +63,6 @@ Magic Name Number Structure File
PG_MAGIC 'P' pg_{read,write}_hdr include/linux/pg.h
CMAGIC 0x0111 user include/linux/a.out.h
MKISS_DRIVER_MAGIC 0x04bf mkiss_channel drivers/net/mkiss.h
-RISCOM8_MAGIC 0x0907 riscom_port drivers/char/riscom8.h
-SPECIALIX_MAGIC 0x0907 specialix_port drivers/char/specialix_io8.h
HDLC_MAGIC 0x239e n_hdlc drivers/char/n_hdlc.c
APM_BIOS_MAGIC 0x4101 apm_user arch/x86/kernel/apm_32.c
CYCLADES_MAGIC 0x4359 cyclades_port include/linux/cyclades.h
@@ -82,7 +80,6 @@ STRIP_MAGIC 0x5303 strip drivers/net/strip.c
X25_ASY_MAGIC 0x5303 x25_asy drivers/net/x25_asy.h
SIXPACK_MAGIC 0x5304 sixpack drivers/net/hamradio/6pack.h
AX25_MAGIC 0x5316 ax_disp drivers/net/mkiss.h
-ESP_MAGIC 0x53ee esp_struct drivers/char/esp.h
TTY_MAGIC 0x5401 tty_struct include/linux/tty.h
MGSL_MAGIC 0x5401 mgsl_info drivers/char/synclink.c
TTY_DRIVER_MAGIC 0x5402 tty_driver include/linux/tty_driver.h
@@ -94,13 +91,10 @@ USB_BLUETOOTH_MAGIC 0x6d02 usb_bluetooth drivers/usb/class/bluetty.c
RFCOMM_TTY_MAGIC 0x6d02 net/bluetooth/rfcomm/tty.c
USB_SERIAL_PORT_MAGIC 0x7301 usb_serial_port drivers/usb/serial/usb-serial.h
CG_MAGIC 0x00090255 ufs_cylinder_group include/linux/ufs_fs.h
-A2232_MAGIC 0x000a2232 gs_port drivers/char/ser_a2232.h
RPORT_MAGIC 0x00525001 r_port drivers/char/rocket_int.h
LSEMAGIC 0x05091998 lse drivers/fc4/fc.c
GDTIOCTL_MAGIC 0x06030f07 gdth_iowr_str drivers/scsi/gdth_ioctl.h
RIEBL_MAGIC 0x09051990 drivers/net/atarilance.c
-RIO_MAGIC 0x12345678 gs_port drivers/char/rio/rio_linux.c
-SX_MAGIC 0x12345678 gs_port drivers/char/sx.h
NBD_REQUEST_MAGIC 0x12560953 nbd_request include/linux/nbd.h
RED_MAGIC2 0x170fc2a5 (any) mm/slab.c
BAYCOM_MAGIC 0x19730510 baycom_state drivers/net/baycom_epp.c
@@ -116,7 +110,6 @@ ISDN_ASYNC_MAGIC 0x49344C01 modem_info include/linux/isdn.h
CTC_ASYNC_MAGIC 0x49344C01 ctc_tty_info drivers/s390/net/ctctty.c
ISDN_NET_MAGIC 0x49344C02 isdn_net_local_s drivers/isdn/i4l/isdn_net_lib.h
SAVEKMSG_MAGIC2 0x4B4D5347 savekmsg arch/*/amiga/config.c
-STLI_BOARDMAGIC 0x4bc6c825 stlibrd include/linux/istallion.h
CS_STATE_MAGIC 0x4c4f4749 cs_state sound/oss/cs46xx.c
SLAB_C_MAGIC 0x4f17a36d kmem_cache mm/slab.c
COW_MAGIC 0x4f4f4f4d cow_header_v1 arch/um/drivers/ubd_user.c
@@ -127,10 +120,8 @@ SCC_MAGIC 0x52696368 gs_port drivers/char/scc.h
SAVEKMSG_MAGIC1 0x53415645 savekmsg arch/*/amiga/config.c
GDA_MAGIC 0x58464552 gda arch/mips/include/asm/sn/gda.h
RED_MAGIC1 0x5a2cf071 (any) mm/slab.c
-STL_PORTMAGIC 0x5a7182c9 stlport include/linux/stallion.h
EEPROM_MAGIC_VALUE 0x5ab478d2 lanai_dev drivers/atm/lanai.c
HDLCDRV_MAGIC 0x5ac6e778 hdlcdrv_state include/linux/hdlcdrv.h
-EPCA_MAGIC 0x5c6df104 channel include/linux/epca.h
PCXX_MAGIC 0x5c6df104 channel drivers/char/pcxx.h
KV_MAGIC 0x5f4b565f kernel_vars_s arch/mips/include/asm/sn/klkernvars.h
I810_STATE_MAGIC 0x63657373 i810_state sound/oss/i810_audio.c
@@ -142,17 +133,14 @@ SLOT_MAGIC 0x67267322 slot drivers/hotplug/acpiphp.h
LO_MAGIC 0x68797548 nbd_device include/linux/nbd.h
OPROFILE_MAGIC 0x6f70726f super_block drivers/oprofile/oprofilefs.h
M3_STATE_MAGIC 0x734d724d m3_state sound/oss/maestro3.c
-STL_PANELMAGIC 0x7ef621a1 stlpanel include/linux/stallion.h
VMALLOC_MAGIC 0x87654320 snd_alloc_track sound/core/memory.c
KMALLOC_MAGIC 0x87654321 snd_alloc_track sound/core/memory.c
PWC_MAGIC 0x89DC10AB pwc_device drivers/usb/media/pwc.h
NBD_REPLY_MAGIC 0x96744668 nbd_reply include/linux/nbd.h
-STL_BOARDMAGIC 0xa2267f52 stlbrd include/linux/stallion.h
ENI155_MAGIC 0xa54b872d midway_eprom drivers/atm/eni.h
SCI_MAGIC 0xbabeface gs_port drivers/char/sh-sci.h
CODA_MAGIC 0xC0DAC0DA coda_file_info fs/coda/coda_fs_i.h
DPMEM_MAGIC 0xc0ffee11 gdt_pci_sram drivers/scsi/gdth.h
-STLI_PORTMAGIC 0xe671c7a1 stliport include/linux/istallion.h
YAM_MAGIC 0xF10A7654 yam_port drivers/net/hamradio/yam.c
CCB_MAGIC 0xf2691ad2 ccb drivers/scsi/ncr53c8xx.c
QUEUE_MAGIC_FREE 0xf7e1c9a3 queue_entry drivers/scsi/arm/queue.c
diff --git a/Documentation/networking/bonding.txt b/Documentation/networking/bonding.txt
index a383c00..9c723ec 100644
--- a/Documentation/networking/bonding.txt
+++ b/Documentation/networking/bonding.txt
@@ -585,13 +585,19 @@ mode
balance-tlb or 5
Adaptive transmit load balancing: channel bonding that
- does not require any special switch support. The
- outgoing traffic is distributed according to the
- current load (computed relative to the speed) on each
- slave. Incoming traffic is received by the current
- slave. If the receiving slave fails, another slave
- takes over the MAC address of the failed receiving
- slave.
+ does not require any special switch support.
+
+ In tlb_dynamic_lb=1 mode; the outgoing traffic is
+ distributed according to the current load (computed
+ relative to the speed) on each slave.
+
+ In tlb_dynamic_lb=0 mode; the load balancing based on
+ current load is disabled and the load is distributed
+ only using the hash distribution.
+
+ Incoming traffic is received by the current slave.
+ If the receiving slave fails, another slave takes over
+ the MAC address of the failed receiving slave.
Prerequisite:
@@ -736,6 +742,28 @@ primary_reselect
This option was added for bonding version 3.6.0.
+tlb_dynamic_lb
+
+ Specifies if dynamic shuffling of flows is enabled in tlb
+ mode. The value has no effect on any other modes.
+
+ The default behavior of tlb mode is to shuffle active flows across
+ slaves based on the load in that interval. This gives nice lb
+ characteristics but can cause packet reordering. If re-ordering is
+ a concern use this variable to disable flow shuffling and rely on
+ load balancing provided solely by the hash distribution.
+ xmit-hash-policy can be used to select the appropriate hashing for
+ the setup.
+
+ The sysfs entry can be used to change the setting per bond device
+ and the initial value is derived from the module parameter. The
+ sysfs entry is allowed to be changed only if the bond device is
+ down.
+
+ The default value is "1" that enables flow shuffling while value "0"
+ disables it. This option was added in bonding driver 3.7.1
+
+
updelay
Specifies the time, in milliseconds, to wait before enabling a
@@ -769,7 +797,7 @@ use_carrier
xmit_hash_policy
Selects the transmit hash policy to use for slave selection in
- balance-xor and 802.3ad modes. Possible values are:
+ balance-xor, 802.3ad, and tlb modes. Possible values are:
layer2
diff --git a/Documentation/networking/filter.txt b/Documentation/networking/filter.txt
index 81f940f..82e1cb0 100644
--- a/Documentation/networking/filter.txt
+++ b/Documentation/networking/filter.txt
@@ -281,6 +281,7 @@ Possible BPF extensions are shown in the following table:
cpu raw_smp_processor_id()
vlan_tci vlan_tx_tag_get(skb)
vlan_pr vlan_tx_tag_present(skb)
+ rand prandom_u32()
These extensions can also be prefixed with '#'.
Examples for low-level BPF:
@@ -308,6 +309,18 @@ Examples for low-level BPF:
ret #-1
drop: ret #0
+** icmp random packet sampling, 1 in 4
+ ldh [12]
+ jne #0x800, drop
+ ldb [23]
+ jneq #1, drop
+ # get a random uint32 number
+ ld rand
+ mod #4
+ jneq #1, drop
+ ret #-1
+ drop: ret #0
+
** SECCOMP filter example:
ld [4] /* offsetof(struct seccomp_data, arch) */
diff --git a/Documentation/networking/scaling.txt b/Documentation/networking/scaling.txt
index ca6977f..99ca40e 100644
--- a/Documentation/networking/scaling.txt
+++ b/Documentation/networking/scaling.txt
@@ -429,7 +429,7 @@ RPS and RFS were introduced in kernel 2.6.35. XPS was incorporated into
(therbert@google.com)
Accelerated RFS was introduced in 2.6.35. Original patches were
-submitted by Ben Hutchings (bhutchings@solarflare.com)
+submitted by Ben Hutchings (bwh@kernel.org)
Authors:
Tom Herbert (therbert@google.com)
diff --git a/Documentation/serial/00-INDEX b/Documentation/serial/00-INDEX
index f9c6b5e..8021a9f 100644
--- a/Documentation/serial/00-INDEX
+++ b/Documentation/serial/00-INDEX
@@ -2,23 +2,15 @@
- this file.
README.cycladesZ
- info on Cyclades-Z firmware loading.
-digiepca.txt
- - info on Digi Intl. {PC,PCI,EISA}Xx and Xem series cards.
driver
- intro to the low level serial driver.
moxa-smartio
- file with info on installing/using Moxa multiport serial driver.
n_gsm.txt
- GSM 0710 tty multiplexer howto.
-riscom8.txt
- - notes on using the RISCom/8 multi-port serial driver.
rocket.txt
- info on the Comtrol RocketPort multiport serial driver.
serial-rs485.txt
- info about RS485 structures and support in the kernel.
-specialix.txt
- - info on hardware/driver for specialix IO8+ multiport serial card.
-sx.txt
- - info on the Specialix SX/SI multiport serial driver.
tty.txt
- guide to the locking policies of the tty layer.
diff --git a/Documentation/serial/digiepca.txt b/Documentation/serial/digiepca.txt
deleted file mode 100644
index f2560e2..0000000
--- a/Documentation/serial/digiepca.txt
+++ /dev/null
@@ -1,98 +0,0 @@
-NOTE: This driver is obsolete. Digi provides a 2.6 driver (dgdm) at
-http://www.digi.com for PCI cards. They no longer maintain this driver,
-and have no 2.6 driver for ISA cards.
-
-This driver requires a number of user-space tools. They can be acquired from
-http://www.digi.com, but only works with 2.4 kernels.
-
-
-The Digi Intl. epca driver.
-----------------------------
-The Digi Intl. epca driver for Linux supports the following boards:
-
-Digi PC/Xem, PC/Xr, PC/Xe, PC/Xi, PC/Xeve
-Digi EISA/Xem, PCI/Xem, PCI/Xr
-
-Limitations:
-------------
-Currently the driver only autoprobes for supported PCI boards.
-
-The Linux MAKEDEV command does not support generating the Digiboard
-Devices. Users executing digiConfig to setup EISA and PC series cards
-will have their device nodes automatically constructed (cud?? for ~CLOCAL,
-and ttyD?? for CLOCAL). Users wishing to boot their board from the LILO
-prompt, or those users booting PCI cards may use buildDIGI to construct
-the necessary nodes.
-
-Notes:
-------
-This driver may be configured via LILO. For users who have already configured
-their driver using digiConfig, configuring from LILO will override previous
-settings. Multiple boards may be configured by issuing multiple LILO command
-lines. For examples see the bottom of this document.
-
-Device names start at 0 and continue up. Beware of this as previous Digi
-drivers started device names with 1.
-
-PCI boards are auto-detected and configured by the driver. PCI boards will
-be allocated device numbers (internally) beginning with the lowest PCI slot
-first. In other words a PCI card in slot 3 will always have higher device
-nodes than a PCI card in slot 1.
-
-LILO config examples:
----------------------
-Using LILO's APPEND command, a string of comma separated identifiers or
-integers can be used to configure supported boards. The six values in order
-are:
-
- Enable/Disable this card or Override,
- Type of card: PC/Xe (AccelePort) (0), PC/Xeve (1), PC/Xem or PC/Xr (2),
- EISA/Xem (3), PC/64Xe (4), PC/Xi (5),
- Enable/Disable alternate pin arrangement,
- Number of ports on this card,
- I/O Port where card is configured (in HEX if using string identifiers),
- Base of memory window (in HEX if using string identifiers),
-
-NOTE : PCI boards are auto-detected and configured. Do not attempt to
-configure PCI boards with the LILO append command. If you wish to override
-previous configuration data (As set by digiConfig), but you do not wish to
-configure any specific card (Example if there are PCI cards in the system)
-the following override command will accomplish this:
--> append="digi=2"
-
-Samples:
- append="digiepca=E,PC/Xe,D,16,200,D0000"
- or
- append="digi=1,0,0,16,512,851968"
-
-Supporting Tools:
------------------
-Supporting tools include digiDload, digiConfig, buildPCI, and ditty. See
-drivers/char/README.epca for more details. Note,
-this driver REQUIRES that digiDload be executed prior to it being used.
-Failure to do this will result in an ENODEV error.
-
-Documentation:
---------------
-Complete documentation for this product may be found in the tool package.
-
-Sources of information and support:
------------------------------------
-Digi Intl. support site for this product:
-
--> http://www.digi.com
-
-Acknowledgments:
-----------------
-Much of this work (And even text) was derived from a similar document
-supporting the original public domain DigiBoard driver Copyright (C)
-1994,1995 Troy De Jongh. Many thanks to Christoph Lameter
-(christoph@lameter.com) and Mike McLagan (mike.mclagan@linux.org) who authored
-and contributed to the original document.
-
-Changelog:
-----------
-10-29-04: Update status of driver, remove dead links in document
- James Nelson <james4765@gmail.com>
-
-2000 (?) Original Document
diff --git a/Documentation/serial/riscom8.txt b/Documentation/serial/riscom8.txt
deleted file mode 100644
index 14f61fd..0000000
--- a/Documentation/serial/riscom8.txt
+++ /dev/null
@@ -1,36 +0,0 @@
-* NOTE - this is an unmaintained driver. The original author cannot be located.
-
-SDL Communications is now SBS Technologies, and does not have any
-information on these ancient ISA cards on their website.
-
-James Nelson <james4765@gmail.com> - 12-12-2004
-
- This is the README for RISCom/8 multi-port serial driver
- (C) 1994-1996 D.Gorodchanin
- See file LICENSE for terms and conditions.
-
-NOTE: English is not my native language.
- I'm sorry for any mistakes in this text.
-
-Misc. notes for RISCom/8 serial driver, in no particular order :)
-
-1) This driver can support up to 4 boards at time.
- Use string "riscom8=0xXXX,0xXXX,0xXXX,0xXXX" at LILO prompt, for
- setting I/O base addresses for boards. If you compile driver
- as module use modprobe options "iobase=0xXXX iobase1=0xXXX iobase2=..."
-
-2) The driver partially supports famous 'setserial' program, you can use almost
- any of its options, excluding port & irq settings.
-
-3) There are some misc. defines at the beginning of riscom8.c, please read the
- comments and try to change some of them in case of problems.
-
-4) I consider the current state of the driver as BETA.
-
-5) SDL Communications WWW page is http://www.sdlcomm.com.
-
-6) You can use the MAKEDEV program to create RISCom/8 /dev/ttyL* entries.
-
-7) Minor numbers for first board are 0-7, for second 8-15, etc.
-
-22 Apr 1996.
diff --git a/Documentation/serial/specialix.txt b/Documentation/serial/specialix.txt
deleted file mode 100644
index 6eb6f3a..0000000
--- a/Documentation/serial/specialix.txt
+++ /dev/null
@@ -1,383 +0,0 @@
-
- specialix.txt -- specialix IO8+ multiport serial driver readme.
-
-
-
- Copyright (C) 1997 Roger Wolff (R.E.Wolff@BitWizard.nl)
-
- Specialix pays for the development and support of this driver.
- Please DO contact io8-linux@specialix.co.uk if you require
- support.
-
- This driver was developed in the BitWizard linux device
- driver service. If you require a linux device driver for your
- product, please contact devices@BitWizard.nl for a quote.
-
- This code is firmly based on the riscom/8 serial driver,
- written by Dmitry Gorodchanin. The specialix IO8+ card
- programming information was obtained from the CL-CD1865 Data
- Book, and Specialix document number 6200059: IO8+ Hardware
- Functional Specification, augmented by document number 6200088:
- Merak Hardware Functional Specification. (IO8+/PCI is also
- called Merak)
-
-
- 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.
-
-
-Intro
-=====
-
-
-This file contains some random information, that I like to have online
-instead of in a manual that can get lost. Ever misplace your Linux
-kernel sources? And the manual of one of the boards in your computer?
-
-
-Addresses and interrupts
-========================
-
-Address dip switch settings:
-The dip switch sets bits 2-9 of the IO address.
-
- 9 8 7 6 5 4 3 2
- +-----------------+
- 0 | X X X X X X X |
- | | = IoBase = 0x100
- 1 | X |
- +-----------------+ ------ RS232 connectors ---->
-
- | | |
- edge connector
- | | |
- V V V
-
-Base address 0x100 caused a conflict in one of my computers once. I
-haven't the foggiest why. My Specialix card is now at 0x180. My
-other computer runs just fine with the Specialix card at 0x100....
-The card occupies 4 addresses, but actually only two are really used.
-
-The PCI version doesn't have any dip switches. The BIOS assigns
-an IO address.
-
-The driver now still autoprobes at 0x100, 0x180, 0x250 and 0x260. If
-that causes trouble for you, please report that. I'll remove
-autoprobing then.
-
-The driver will tell the card what IRQ to use, so you don't have to
-change any jumpers to change the IRQ. Just use a command line
-argument (irq=xx) to the insmod program to set the interrupt.
-
-The BIOS assigns the IRQ on the PCI version. You have no say in what
-IRQ to use in that case.
-
-If your specialix cards are not at the default locations, you can use
-the kernel command line argument "specialix=io0,irq0,io1,irq1...".
-Here "io0" is the io address for the first card, and "irq0" is the
-irq line that the first card should use. And so on.
-
-Examples.
-
-You use the driver as a module and have three cards at 0x100, 0x250
-and 0x180. And some way or another you want them detected in that
-order. Moreover irq 12 is taken (e.g. by your PS/2 mouse).
-
- insmod specialix.o iobase=0x100,0x250,0x180 irq=9,11,15
-
-The same three cards, but now in the kernel would require you to
-add
-
- specialix=0x100,9,0x250,11,0x180,15
-
-to the command line. This would become
-
- append="specialix=0x100,9,0x250,11,0x180,15"
-
-in your /etc/lilo.conf file if you use lilo.
-
-The Specialix driver is slightly odd: It allows you to have the second
-or third card detected without having a first card. This has
-advantages and disadvantages. A slot that isn't filled by an ISA card,
-might be filled if a PCI card is detected. Thus if you have an ISA
-card at 0x250 and a PCI card, you would get:
-
-sx0: specialix IO8+ Board at 0x100 not found.
-sx1: specialix IO8+ Board at 0x180 not found.
-sx2: specialix IO8+ board detected at 0x250, IRQ 12, CD1865 Rev. B.
-sx3: specialix IO8+ Board at 0x260 not found.
-sx0: specialix IO8+ board detected at 0xd800, IRQ 9, CD1865 Rev. B.
-
-This would happen if you don't give any probe hints to the driver.
-If you would specify:
-
- specialix=0x250,11
-
-you'd get the following messages:
-
-sx0: specialix IO8+ board detected at 0x250, IRQ 11, CD1865 Rev. B.
-sx1: specialix IO8+ board detected at 0xd800, IRQ 9, CD1865 Rev. B.
-
-ISA probing is aborted after the IO address you gave is exhausted, and
-the PCI card is now detected as the second card. The ISA card is now
-also forced to IRQ11....
-
-
-Baud rates
-==========
-
-The rev 1.2 and below boards use a CL-CD1864. These chips can only
-do 64kbit. The rev 1.3 and newer boards use a CL-CD1865. These chips
-are officially capable of 115k2.
-
-The Specialix card uses a 25MHz crystal (in times two mode, which in
-fact is a divided by two mode). This is not enough to reach the rated
-115k2 on all ports at the same time. With this clock rate you can only
-do 37% of this rate. This means that at 115k2 on all ports you are
-going to lose characters (The chip cannot handle that many incoming
-bits at this clock rate.) (Yes, you read that correctly: there is a
-limit to the number of -=bits=- per second that the chip can handle.)
-
-If you near the "limit" you will first start to see a graceful
-degradation in that the chip cannot keep the transmitter busy at all
-times. However with a central clock this slow, you can also get it to
-miss incoming characters. The driver will print a warning message when
-you are outside the official specs. The messages usually show up in
-the file /var/log/messages .
-
-The specialix card cannot reliably do 115k2. If you use it, you have
-to do "extensive testing" (*) to verify if it actually works.
-
-When "mgetty" communicates with my modem at 115k2 it reports:
-got: +++[0d]ATQ0V1H0[0d][0d][8a]O[cb][0d][8a]
- ^^^^ ^^^^ ^^^^
-
-The three characters that have the "^^^" under them have suffered a
-bit error in the highest bit. In conclusion: I've tested it, and found
-that it simply DOESN'T work for me. I also suspect that this is also
-caused by the baud rate being just a little bit out of tune.
-
-I upgraded the crystal to 66Mhz on one of my Specialix cards. Works
-great! Contact me for details. (Voids warranty, requires a steady hand
-and more such restrictions....)
-
-
-(*) Cirrus logic CD1864 databook, page 40.
-
-
-Cables for the Specialix IO8+
-=============================
-
-The pinout of the connectors on the IO8+ is:
-
- pin short direction long name
- name
- Pin 1 DCD input Data Carrier Detect
- Pin 2 RXD input Receive
- Pin 3 DTR/RTS output Data Terminal Ready/Ready To Send
- Pin 4 GND - Ground
- Pin 5 TXD output Transmit
- Pin 6 CTS input Clear To Send
-
-
- -- 6 5 4 3 2 1 --
- | |
- | |
- | |
- | |
- +----- -----+
- |__________|
- clip
-
- Front view of an RJ12 connector. Cable moves "into" the paper.
- (the plug is ready to plug into your mouth this way...)
-
-
- NULL cable. I don't know who is going to use these except for
- testing purposes, but I tested the cards with this cable. (It
- took quite a while to figure out, so I'm not going to delete
- it. So there! :-)
-
-
- This end goes This end needs
- straight into the some twists in
- RJ12 plug. the wiring.
- IO8+ RJ12 IO8+ RJ12
- 1 DCD white -
- - - 1 DCD
- 2 RXD black 5 TXD
- 3 DTR/RTS red 6 CTS
- 4 GND green 4 GND
- 5 TXD yellow 2 RXD
- 6 CTS blue 3 DTR/RTS
-
-
- Same NULL cable, but now sorted on the second column.
-
- 1 DCD white -
- - - 1 DCD
- 5 TXD yellow 2 RXD
- 6 CTS blue 3 DTR/RTS
- 4 GND green 4 GND
- 2 RXD black 5 TXD
- 3 DTR/RTS red 6 CTS
-
-
-
- This is a modem cable usable for hardware handshaking:
- RJ12 DB25 DB9
- 1 DCD white 8 DCD 1 DCD
- 2 RXD black 3 RXD 2 RXD
- 3 DTR/RTS red 4 RTS 7 RTS
- 4 GND green 7 GND 5 GND
- 5 TXD yellow 2 TXD 3 TXD
- 6 CTS blue 5 CTS 8 CTS
- +---- 6 DSR 6 DSR
- +---- 20 DTR 4 DTR
-
- This is a modem cable usable for software handshaking:
- It allows you to reset the modem using the DTR ioctls.
- I (REW) have never tested this, "but xxxxxxxxxxxxx
- says that it works." If you test this, please
- tell me and I'll fill in your name on the xxx's.
-
- RJ12 DB25 DB9
- 1 DCD white 8 DCD 1 DCD
- 2 RXD black 3 RXD 2 RXD
- 3 DTR/RTS red 20 DTR 4 DTR
- 4 GND green 7 GND 5 GND
- 5 TXD yellow 2 TXD 3 TXD
- 6 CTS blue 5 CTS 8 CTS
- +---- 6 DSR 6 DSR
- +---- 4 RTS 7 RTS
-
- I bought a 6 wire flat cable. It was colored as indicated.
- Check that yours is the same before you trust me on this.
-
-
-Hardware handshaking issues.
-============================
-
-The driver can be told to operate in two different ways. The default
-behaviour is specialix.sx_rtscts = 0 where the pin behaves as DTR when
-hardware handshaking is off. It behaves as the RTS hardware
-handshaking signal when hardware handshaking is selected.
-
-When you use this, you have to use the appropriate cable. The
-cable will either be compatible with hardware handshaking or with
-software handshaking. So switching on the fly is not really an
-option.
-
-I actually prefer to use the "specialix.sx_rtscts=1" option.
-This makes the DTR/RTS pin always an RTS pin, and ioctls to
-change DTR are always ignored. I have a cable that is configured
-for this.
-
-
-Ports and devices
-=================
-
-Port 0 is the one furthest from the card-edge connector.
-
-Devices:
-
-You should make the devices as follows:
-
-bash
-cd /dev
-for i in 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
-do
- echo -n "$i "
- mknod /dev/ttyW$i c 75 $i
- mknod /dev/cuw$i c 76 $i
-done
-echo ""
-
-If your system doesn't come with these devices preinstalled, bug your
-linux-vendor about this. They have had ample time to get this
-implemented by now.
-
-You cannot have more than 4 boards in one computer. The card only
-supports 4 different interrupts. If you really want this, contact me
-about this and I'll give you a few tips (requires soldering iron)....
-
-If you have enough PCI slots, you can probably use more than 4 PCI
-versions of the card though....
-
-The PCI version of the card cannot adhere to the mechanical part of
-the PCI spec because the 8 serial connectors are simply too large. If
-it doesn't fit in your computer, bring back the card.
-
-
-------------------------------------------------------------------------
-
-
- Fixed bugs and restrictions:
- - During initialization, interrupts are blindly turned on.
- Having a shadow variable would cause an extra memory
- access on every IO instruction.
- - The interrupt (on the card) should be disabled when we
- don't allocate the Linux end of the interrupt. This allows
- a different driver/card to use it while all ports are not in
- use..... (a la standard serial port)
- == An extra _off variant of the sx_in and sx_out macros are
- now available. They don't set the interrupt enable bit.
- These are used during initialization. Normal operation uses
- the old variant which enables the interrupt line.
- - RTS/DTR issue needs to be implemented according to
- specialix' spec.
- I kind of like the "determinism" of the current
- implementation. Compile time flag?
- == Ok. Compile time flag! Default is how Specialix likes it.
- == Now a config time flag! Gets saved in your config file. Neat!
- - Can you set the IO address from the lilo command line?
- If you need this, bug me about it, I'll make it.
- == Hah! No bugging needed. Fixed! :-)
- - Cirrus logic hasn't gotten back to me yet why the CD1865 can
- and the CD1864 can't do 115k2. I suspect that this is
- because the CD1864 is not rated for 33MHz operation.
- Therefore the CD1864 versions of the card can't do 115k2 on
- all ports just like the CD1865 versions. The driver does
- not block 115k2 on CD1864 cards.
- == I called the Cirrus Logic representative here in Holland.
- The CD1864 databook is identical to the CD1865 databook,
- except for an extra warning at the end. Similar Bit errors
- have been observed in testing at 115k2 on both an 1865 and
- a 1864 chip. I see no reason why I would prohibit 115k2 on
- 1864 chips and not do it on 1865 chips. Actually there is
- reason to prohibit it on BOTH chips. I print a warning.
- If you use 115k2, you're on your own.
- - A spiky CD may send spurious HUPs. Also in CLOCAL???
- -- A fix for this turned out to be counter productive.
- Different fix? Current behaviour is acceptable?
- -- Maybe the current implementation is correct. If anybody
- gets bitten by this, please report, and it will get fixed.
-
- -- Testing revealed that when in CLOCAL, the problem doesn't
- occur. As warned for in the CD1865 manual, the chip may
- send modem intr's on a spike. We could filter those out,
- but that would be a cludge anyway (You'd still risk getting
- a spurious HUP when two spikes occur.).....
-
-
-
- Bugs & restrictions:
- - This is a difficult card to autoprobe.
- You have to WRITE to the address register to even
- read-probe a CD186x register. Disable autodetection?
- -- Specialix: any suggestions?
-
-
diff --git a/Documentation/serial/sx.txt b/Documentation/serial/sx.txt
deleted file mode 100644
index cb4efa0..0000000
--- a/Documentation/serial/sx.txt
+++ /dev/null
@@ -1,294 +0,0 @@
-
- sx.txt -- specialix SX/SI multiport serial driver readme.
-
-
-
- Copyright (C) 1997 Roger Wolff (R.E.Wolff@BitWizard.nl)
-
- Specialix pays for the development and support of this driver.
- Please DO contact support@specialix.co.uk if you require
- support.
-
- This driver was developed in the BitWizard linux device
- driver service. If you require a linux device driver for your
- product, please contact devices@BitWizard.nl for a quote.
-
- (History)
- There used to be an SI driver by Simon Allan. This is a complete
- rewrite from scratch. Just a few lines-of-code have been snatched.
-
- (Sources)
- Specialix document number 6210028: SX Host Card and Download Code
- Software Functional Specification.
-
- (Copying)
- 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.
-
- (Addendum)
- I'd appreciate it that if you have fixes, that you send them
- to me first.
-
-
-Introduction
-============
-
-This file contains some random information, that I like to have online
-instead of in a manual that can get lost. Ever misplace your Linux
-kernel sources? And the manual of one of the boards in your computer?
-
-
-Theory of operation
-===================
-
-An important thing to know is that the driver itself doesn't have the
-firmware for the card. This means that you need the separate package
-"sx_firmware". For now you can get the source at
-
- ftp://ftp.bitwizard.nl/specialix/sx_firmware_<version>.tgz
-
-The firmware load needs a "misc" device, so you'll need to enable the
-"Support for user misc device modules" in your kernel configuration.
-The misc device needs to be called "/dev/specialix_sxctl". It needs
-misc major 10, and minor number 167 (assigned by HPA). The section
-on creating device files below also creates this device.
-
-After loading the sx.o module into your kernel, the driver will report
-the number of cards detected, but because it doesn't have any
-firmware, it will not be able to determine the number of ports. Only
-when you then run "sx_firmware" will the firmware be downloaded and
-the rest of the driver initialized. At that time the sx_firmware
-program will report the number of ports installed.
-
-In contrast with many other multi port serial cards, some of the data
-structures are only allocated when the card knows the number of ports
-that are connected. This means we won't waste memory for 120 port
-descriptor structures when you only have 8 ports. If you experience
-problems due to this, please report them: I haven't seen any.
-
-
-Interrupts
-==========
-
-A multi port serial card, would generate a horrendous amount of
-interrupts if it would interrupt the CPU for every received
-character. Even more than 10 years ago, the trick not to use
-interrupts but to poll the serial cards was invented.
-
-The SX card allow us to do this two ways. First the card limits its
-own interrupt rate to a rate that won't overwhelm the CPU. Secondly,
-we could forget about the cards interrupt completely and use the
-internal timer for this purpose.
-
-Polling the card can take up to a few percent of your CPU. Using the
-interrupts would be better if you have most of the ports idle. Using
-timer-based polling is better if your card almost always has work to
-do. You save the separate interrupt in that case.
-
-In any case, it doesn't really matter all that much.
-
-The most common problem with interrupts is that for ISA cards in a PCI
-system the BIOS has to be told to configure that interrupt as "legacy
-ISA". Otherwise the card can pull on the interrupt line all it wants
-but the CPU won't see this.
-
-If you can't get the interrupt to work, remember that polling mode is
-more efficient (provided you actually use the card intensively).
-
-
-Allowed Configurations
-======================
-
-Some configurations are disallowed. Even though at a glance they might
-seem to work, they are known to lockup the bus between the host card
-and the device concentrators. You should respect the drivers decision
-not to support certain configurations. It's there for a reason.
-
-Warning: Seriously technical stuff ahead. Executive summary: Don't use
-SX cards except configured at a 64k boundary. Skip the next paragraph.
-
-The SX cards can theoretically be placed at a 32k boundary. So for
-instance you can put an SX card at 0xc8000-0xd7fff. This is not a
-"recommended configuration". ISA cards have to tell the bus controller
-how they like their timing. Due to timing issues they have to do this
-based on which 64k window the address falls into. This means that the
-32k window below and above the SX card have to use exactly the same
-timing as the SX card. That reportedly works for other SX cards. But
-you're still left with two useless 32k windows that should not be used
-by anybody else.
-
-
-Configuring the driver
-======================
-
-PCI cards are always detected. The driver auto-probes for ISA cards at
-some sensible addresses. Please report if the auto-probe causes trouble
-in your system, or when a card isn't detected.
-
-I'm afraid I haven't implemented "kernel command line parameters" yet.
-This means that if the default doesn't work for you, you shouldn't use
-the compiled-into-the-kernel version of the driver. Use a module
-instead. If you convince me that you need this, I'll make it for
-you. Deal?
-
-I'm afraid that the module parameters are a bit clumsy. If you have a
-better idea, please tell me.
-
-You can specify several parameters:
-
- sx_poll: number of jiffies between timer-based polls.
-
- Set this to "0" to disable timer based polls.
- Initialization of cards without a working interrupt
- will fail.
-
- Set this to "1" if you want a polling driver.
- (on Intel: 100 polls per second). If you don't use
- fast baud rates, you might consider a value like "5".
- (If you don't know how to do the math, use 1).
-
- sx_slowpoll: Number of jiffies between timer-based polls.
- Set this to "100" to poll once a second.
- This should get the card out of a stall if the driver
- ever misses an interrupt. I've never seen this happen,
- and if it does, that's a bug. Tell me.
-
- sx_maxints: Number of interrupts to request from the card.
- The card normally limits interrupts to about 100 per
- second to offload the host CPU. You can increase this
- number to reduce latency on the card a little.
- Note that if you give a very high number you can overload
- your CPU as well as the CPU on the host card. This setting
- is inaccurate and not recommended for SI cards (But it
- works).
-
- sx_irqmask: The mask of allowable IRQs to use. I suggest you set
- this to 0 (disable IRQs all together) and use polling if
- the assignment of IRQs becomes problematic. This is defined
- as the sum of (1 << irq) 's that you want to allow. So
- sx_irqmask of 8 (1 << 3) specifies that only irq 3 may
- be used by the SX driver. If you want to specify to the
- driver: "Either irq 11 or 12 is ok for you to use", then
- specify (1 << 11) | (1 << 12) = 0x1800 .
-
- sx_debug: You can enable different sorts of debug traces with this.
- At "-1" all debugging traces are active. You'll get several
- times more debugging output than you'll get characters
- transmitted.
-
-
-Baud rates
-==========
-
-Theoretically new SXDCs should be capable of more than 460k
-baud. However the line drivers usually give up before that. Also the
-CPU on the card may not be able to handle 8 channels going at full
-blast at that speed. Moreover, the buffers are not large enough to
-allow operation with 100 interrupts per second. You'll have to realize
-that the card has a 256 byte buffer, so you'll have to increase the
-number of interrupts per second if you have more than 256*100 bytes
-per second to transmit. If you do any performance testing in this
-area, I'd be glad to hear from you...
-
-(Psst Linux users..... I think the Linux driver is more efficient than
-the driver for other OSes. If you can and want to benchmark them
-against each other, be my guest, and report your findings...... :-)
-
-
-Ports and devices
-=================
-
-Port 0 is the top connector on the module closest to the host
-card. Oh, the ports on the SXDCs and TAs are labelled from 1 to 8
-instead of from 0 to 7, as they are numbered by linux. I'm stubborn in
-this: I know for sure that I wouldn't be able to calculate which port
-is which anymore if I would change that....
-
-
-Devices:
-
-You should make the device files as follows:
-
-#!/bin/sh
-# (I recommend that you cut-and-paste this into a file and run that)
-cd /dev
-t=0
-mknod specialix_sxctl c 10 167
-while [ $t -lt 64 ]
- do
- echo -n "$t "
- mknod ttyX$t c 32 $t
- mknod cux$t c 33 $t
- t=`expr $t + 1`
-done
-echo ""
-rm /etc/psdevtab
-ps > /dev/null
-
-
-This creates 64 devices. If you have more, increase the constant on
-the line with "while". The devices start at 0, as is customary on
-Linux. Specialix seems to like starting the numbering at 1.
-
-If your system doesn't come with these devices pre-installed, bug your
-linux-vendor about this. They should have these devices
-"pre-installed" before the new millennium. The "ps" stuff at the end
-is to "tell" ps that the new devices exist.
-
-Officially the maximum number of cards per computer is 4. This driver
-however supports as many cards in one machine as you want. You'll run
-out of interrupts after a few, but you can switch to polled operation
-then. At about 256 ports (More than 8 cards), we run out of minor
-device numbers. Sorry. I suggest you buy a second computer.... (Or
-switch to RIO).
-
-------------------------------------------------------------------------
-
-
- Fixed bugs and restrictions:
- - Hangup processing.
- -- Done.
-
- - the write path in generic_serial (lockup / oops).
- -- Done (Ugly: not the way I want it. Copied from serial.c).
-
- - write buffer isn't flushed at close.
- -- Done. I still seem to lose a few chars at close.
- Sorry. I think that this is a firmware issue. (-> Specialix)
-
- - drain hardware before changing termios
- - Change debug on the fly.
- - ISA free irq -1. (no firmware loaded).
- - adding c8000 as a probe address. Added warning.
- - Add a RAMtest for the RAM on the card.c
- - Crash when opening a port "way" of the number of allowed ports.
- (for example opening port 60 when there are only 24 ports attached)
- - Sometimes the use-count strays a bit. After a few hours of
- testing the use count is sometimes "3". If you are not like
- me and can remember what you did to get it that way, I'd
- appreciate an Email. Possibly fixed. Tell me if anyone still
- sees this.
- - TAs don't work right if you don't connect all the modem control
- signals. SXDCs do. T225 firmware problem -> Specialix.
- (Mostly fixed now, I think. Tell me if you encounter this!)
-
- Bugs & restrictions:
-
- - Arbitrary baud rates. Requires firmware update. (-> Specialix)
-
- - Low latency (mostly firmware, -> Specialix)
-
-
-
diff --git a/Documentation/stable_kernel_rules.txt b/Documentation/stable_kernel_rules.txt
index b0714d8..cbc2f03 100644
--- a/Documentation/stable_kernel_rules.txt
+++ b/Documentation/stable_kernel_rules.txt
@@ -39,7 +39,7 @@ Procedure for submitting patches to the -stable tree:
the stable tree without anything else needing to be done by the author
or subsystem maintainer.
- If the patch requires other patches as prerequisites which can be
- cherry-picked than this can be specified in the following format in
+ cherry-picked, then this can be specified in the following format in
the sign-off area:
Cc: <stable@vger.kernel.org> # 3.3.x: a1f84a3: sched: Check for idle
diff --git a/Documentation/vm/numa_memory_policy.txt b/Documentation/vm/numa_memory_policy.txt
index 4e7da65..badb050 100644
--- a/Documentation/vm/numa_memory_policy.txt
+++ b/Documentation/vm/numa_memory_policy.txt
@@ -174,7 +174,6 @@ Components of Memory Policies
allocation fails, the kernel will search other nodes, in order of
increasing distance from the preferred node based on information
provided by the platform firmware.
- containing the cpu where the allocation takes place.
Internally, the Preferred policy uses a single node--the
preferred_node member of struct mempolicy. When the internal
@@ -275,9 +274,9 @@ Components of Memory Policies
For example, consider a task that is attached to a cpuset with
mems 2-5 that sets an Interleave policy over the same set with
MPOL_F_RELATIVE_NODES. If the cpuset's mems change to 3-7, the
- interleave now occurs over nodes 3,5-6. If the cpuset's mems
+ interleave now occurs over nodes 3,5-7. If the cpuset's mems
then change to 0,2-3,5, then the interleave occurs over nodes
- 0,3,5.
+ 0,2-3,5.
Thanks to the consistent remapping, applications preparing
nodemasks to specify memory policies using this flag should
diff --git a/Documentation/zh_CN/HOWTO b/Documentation/zh_CN/HOWTO
index 6c914aa..54ea24f 100644
--- a/Documentation/zh_CN/HOWTO
+++ b/Documentation/zh_CN/HOWTO
@@ -237,7 +237,7 @@ kernel.org网站的pub/linux/kernel/v2.6/目录下找到它。它的开å‘éµå¾ª
如果没有2.6.x.y版本内核存在,那么最新的2.6.x版本内核就相当于是当å‰çš„稳定
版内核。
-2.6.x.y版本由“稳定版â€å°ç»„(邮件地å€<stable@kernel.org>)维护,一般隔周å‘
+2.6.x.y版本由“稳定版â€å°ç»„(邮件地å€<stable@vger.kernel.org>)维护,一般隔周å‘
布新版本。
内核æºç ä¸­çš„Documentation/stable_kernel_rules.txt文件具体æ述了å¯è¢«ç¨³å®š
diff --git a/Documentation/zh_CN/io_ordering.txt b/Documentation/zh_CN/io_ordering.txt
new file mode 100644
index 0000000..e592daf
--- /dev/null
+++ b/Documentation/zh_CN/io_ordering.txt
@@ -0,0 +1,67 @@
+Chinese translated version of Documentation/io_orderings.txt
+
+If you have any comment or update to the content, please contact the
+original document maintainer directly. However, if you have a problem
+communicating in English you can also ask the Chinese maintainer for
+help. Contact the Chinese maintainer if this translation is outdated
+or if there is a problem with the translation.
+
+Chinese maintainer: Lin Yongting <linyongting@gmail.com>
+---------------------------------------------------------------------
+Documentation/io_ordering.txt 的中文翻译
+
+如果想评论或更新本文的内容,请直接è”系原文档的维护者。如果你使用英文
+交æµæœ‰å›°éš¾çš„è¯ï¼Œä¹Ÿå¯ä»¥å‘中文版维护者求助。如果本翻译更新ä¸åŠæ—¶æˆ–者翻
+译存在问题,请è”系中文版维护者。
+
+中文版维护者: æž—æ°¸å¬ Lin Yongting <linyongting@gmail.com>
+中文版翻译者: æž—æ°¸å¬ Lin Yongting <linyongting@gmail.com>
+中文版校译者: æž—æ°¸å¬ Lin Yongting <linyongting@gmail.com>
+
+
+以下为正文
+---------------------------------------------------------------------
+
+在æŸäº›å¹³å°ä¸Šï¼Œæ‰€è°“的内存映射I/O是弱顺åºã€‚在这些平å°ä¸Šï¼Œé©±åŠ¨å¼€å‘者有责任
+ä¿è¯I/O内存映射地å€çš„写æ“作按程åºå›¾æ„的顺åºè¾¾åˆ°è®¾å¤‡ã€‚通常读å–一个“安全â€
+设备寄存器或桥寄存器,触å‘IO芯片清刷未处ç†çš„写æ“作到达设备åŽæ‰å¤„ç†è¯»æ“作,
+而达到ä¿è¯ç›®çš„。驱动程åºé€šå¸¸åœ¨spinlockä¿æŠ¤çš„临界区退出之å‰ä½¿ç”¨è¿™ç§æŠ€æœ¯ã€‚
+这也å¯ä»¥ä¿è¯åŽé¢çš„写æ“作åªåœ¨å‰é¢çš„写æ“作之åŽåˆ°è¾¾è®¾å¤‡ï¼ˆè¿™éžå¸¸ç±»ä¼¼äºŽå†…å­˜
+å±éšœæ“作,mb(),ä¸è¿‡ä»…适用于I/O)。
+
+å‡è®¾ä¸€ä¸ªè®¾å¤‡é©±åŠ¨ç¨‹çš„具体例å­ï¼š
+
+ ...
+CPU A: spin_lock_irqsave(&dev_lock, flags)
+CPU A: val = readl(my_status);
+CPU A: ...
+CPU A: writel(newval, ring_ptr);
+CPU A: spin_unlock_irqrestore(&dev_lock, flags)
+ ...
+CPU B: spin_lock_irqsave(&dev_lock, flags)
+CPU B: val = readl(my_status);
+CPU B: ...
+CPU B: writel(newval2, ring_ptr);
+CPU B: spin_unlock_irqrestore(&dev_lock, flags)
+ ...
+
+上述例å­ä¸­ï¼Œè®¾å¤‡å¯èƒ½ä¼šå…ˆæŽ¥æ”¶åˆ°newval2的值,然åŽæŽ¥æ”¶åˆ°newval的值,问题就
+å‘生了。ä¸è¿‡å¾ˆå®¹æ˜“通过下é¢æ–¹æ³•æ¥ä¿®å¤ï¼š
+
+ ...
+CPU A: spin_lock_irqsave(&dev_lock, flags)
+CPU A: val = readl(my_status);
+CPU A: ...
+CPU A: writel(newval, ring_ptr);
+CPU A: (void)readl(safe_register); /* é…置寄存器?*/
+CPU A: spin_unlock_irqrestore(&dev_lock, flags)
+ ...
+CPU B: spin_lock_irqsave(&dev_lock, flags)
+CPU B: val = readl(my_status);
+CPU B: ...
+CPU B: writel(newval2, ring_ptr);
+CPU B: (void)readl(safe_register); /* é…置寄存器?*/
+CPU B: spin_unlock_irqrestore(&dev_lock, flags)
+
+在解决方案中,读å–safe_register寄存器,触å‘IO芯片清刷未处ç†çš„写æ“作,
+å†å¤„ç†åŽé¢çš„读æ“作,防止引å‘æ•°æ®ä¸ä¸€è‡´é—®é¢˜ã€‚
diff --git a/Documentation/zh_CN/magic-number.txt b/Documentation/zh_CN/magic-number.txt
index 2ebe539..dfb72a5 100644
--- a/Documentation/zh_CN/magic-number.txt
+++ b/Documentation/zh_CN/magic-number.txt
@@ -63,8 +63,6 @@ struct tty_ldisc {
PG_MAGIC 'P' pg_{read,write}_hdr include/linux/pg.h
CMAGIC 0x0111 user include/linux/a.out.h
MKISS_DRIVER_MAGIC 0x04bf mkiss_channel drivers/net/mkiss.h
-RISCOM8_MAGIC 0x0907 riscom_port drivers/char/riscom8.h
-SPECIALIX_MAGIC 0x0907 specialix_port drivers/char/specialix_io8.h
HDLC_MAGIC 0x239e n_hdlc drivers/char/n_hdlc.c
APM_BIOS_MAGIC 0x4101 apm_user arch/x86/kernel/apm_32.c
CYCLADES_MAGIC 0x4359 cyclades_port include/linux/cyclades.h
@@ -82,7 +80,6 @@ STRIP_MAGIC 0x5303 strip drivers/net/strip.c
X25_ASY_MAGIC 0x5303 x25_asy drivers/net/x25_asy.h
SIXPACK_MAGIC 0x5304 sixpack drivers/net/hamradio/6pack.h
AX25_MAGIC 0x5316 ax_disp drivers/net/mkiss.h
-ESP_MAGIC 0x53ee esp_struct drivers/char/esp.h
TTY_MAGIC 0x5401 tty_struct include/linux/tty.h
MGSL_MAGIC 0x5401 mgsl_info drivers/char/synclink.c
TTY_DRIVER_MAGIC 0x5402 tty_driver include/linux/tty_driver.h
@@ -94,13 +91,10 @@ USB_BLUETOOTH_MAGIC 0x6d02 usb_bluetooth drivers/usb/class/bluetty.c
RFCOMM_TTY_MAGIC 0x6d02 net/bluetooth/rfcomm/tty.c
USB_SERIAL_PORT_MAGIC 0x7301 usb_serial_port drivers/usb/serial/usb-serial.h
CG_MAGIC 0x00090255 ufs_cylinder_group include/linux/ufs_fs.h
-A2232_MAGIC 0x000a2232 gs_port drivers/char/ser_a2232.h
RPORT_MAGIC 0x00525001 r_port drivers/char/rocket_int.h
LSEMAGIC 0x05091998 lse drivers/fc4/fc.c
GDTIOCTL_MAGIC 0x06030f07 gdth_iowr_str drivers/scsi/gdth_ioctl.h
RIEBL_MAGIC 0x09051990 drivers/net/atarilance.c
-RIO_MAGIC 0x12345678 gs_port drivers/char/rio/rio_linux.c
-SX_MAGIC 0x12345678 gs_port drivers/char/sx.h
NBD_REQUEST_MAGIC 0x12560953 nbd_request include/linux/nbd.h
RED_MAGIC2 0x170fc2a5 (any) mm/slab.c
BAYCOM_MAGIC 0x19730510 baycom_state drivers/net/baycom_epp.c
@@ -116,7 +110,6 @@ ISDN_ASYNC_MAGIC 0x49344C01 modem_info include/linux/isdn.h
CTC_ASYNC_MAGIC 0x49344C01 ctc_tty_info drivers/s390/net/ctctty.c
ISDN_NET_MAGIC 0x49344C02 isdn_net_local_s drivers/isdn/i4l/isdn_net_lib.h
SAVEKMSG_MAGIC2 0x4B4D5347 savekmsg arch/*/amiga/config.c
-STLI_BOARDMAGIC 0x4bc6c825 stlibrd include/linux/istallion.h
CS_STATE_MAGIC 0x4c4f4749 cs_state sound/oss/cs46xx.c
SLAB_C_MAGIC 0x4f17a36d kmem_cache mm/slab.c
COW_MAGIC 0x4f4f4f4d cow_header_v1 arch/um/drivers/ubd_user.c
@@ -127,10 +120,8 @@ SCC_MAGIC 0x52696368 gs_port drivers/char/scc.h
SAVEKMSG_MAGIC1 0x53415645 savekmsg arch/*/amiga/config.c
GDA_MAGIC 0x58464552 gda arch/mips/include/asm/sn/gda.h
RED_MAGIC1 0x5a2cf071 (any) mm/slab.c
-STL_PORTMAGIC 0x5a7182c9 stlport include/linux/stallion.h
EEPROM_MAGIC_VALUE 0x5ab478d2 lanai_dev drivers/atm/lanai.c
HDLCDRV_MAGIC 0x5ac6e778 hdlcdrv_state include/linux/hdlcdrv.h
-EPCA_MAGIC 0x5c6df104 channel include/linux/epca.h
PCXX_MAGIC 0x5c6df104 channel drivers/char/pcxx.h
KV_MAGIC 0x5f4b565f kernel_vars_s arch/mips/include/asm/sn/klkernvars.h
I810_STATE_MAGIC 0x63657373 i810_state sound/oss/i810_audio.c
@@ -142,17 +133,14 @@ SLOT_MAGIC 0x67267322 slot drivers/hotplug/acpiphp.h
LO_MAGIC 0x68797548 nbd_device include/linux/nbd.h
OPROFILE_MAGIC 0x6f70726f super_block drivers/oprofile/oprofilefs.h
M3_STATE_MAGIC 0x734d724d m3_state sound/oss/maestro3.c
-STL_PANELMAGIC 0x7ef621a1 stlpanel include/linux/stallion.h
VMALLOC_MAGIC 0x87654320 snd_alloc_track sound/core/memory.c
KMALLOC_MAGIC 0x87654321 snd_alloc_track sound/core/memory.c
PWC_MAGIC 0x89DC10AB pwc_device drivers/usb/media/pwc.h
NBD_REPLY_MAGIC 0x96744668 nbd_reply include/linux/nbd.h
-STL_BOARDMAGIC 0xa2267f52 stlbrd include/linux/stallion.h
ENI155_MAGIC 0xa54b872d midway_eprom drivers/atm/eni.h
SCI_MAGIC 0xbabeface gs_port drivers/char/sh-sci.h
CODA_MAGIC 0xC0DAC0DA coda_file_info include/linux/coda_fs_i.h
DPMEM_MAGIC 0xc0ffee11 gdt_pci_sram drivers/scsi/gdth.h
-STLI_PORTMAGIC 0xe671c7a1 stliport include/linux/istallion.h
YAM_MAGIC 0xF10A7654 yam_port drivers/net/hamradio/yam.c
CCB_MAGIC 0xf2691ad2 ccb drivers/scsi/ncr53c8xx.c
QUEUE_MAGIC_FREE 0xf7e1c9a3 queue_entry drivers/scsi/arm/queue.c
diff --git a/Documentation/zh_CN/stable_kernel_rules.txt b/Documentation/zh_CN/stable_kernel_rules.txt
index b5b9b0a..26ea5ed 100644
--- a/Documentation/zh_CN/stable_kernel_rules.txt
+++ b/Documentation/zh_CN/stable_kernel_rules.txt
@@ -42,7 +42,7 @@ Documentation/stable_kernel_rules.txt 的中文翻译
å‘稳定版代ç æ ‘æ交补ä¸çš„过程:
- - 在确认了补ä¸ç¬¦åˆä»¥ä¸Šçš„规则åŽï¼Œå°†è¡¥ä¸å‘é€åˆ°stable@kernel.org。
+ - 在确认了补ä¸ç¬¦åˆä»¥ä¸Šçš„规则åŽï¼Œå°†è¡¥ä¸å‘é€åˆ°stable@vger.kernel.org。
- 如果补ä¸è¢«æŽ¥å—到队列里,å‘é€è€…会收到一个ACK回å¤ï¼Œå¦‚果没有被接å—,收
到的是NAK回å¤ã€‚回å¤éœ€è¦å‡ å¤©çš„时间,这å–决于开å‘者的时间安排。
- 被接å—çš„è¡¥ä¸ä¼šè¢«åŠ åˆ°ç¨³å®šç‰ˆæœ¬é˜Ÿåˆ—里,等待其他开å‘者的审查。
diff --git a/MAINTAINERS b/MAINTAINERS
index 6dc67b1..7bb7ead 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -1967,6 +1967,12 @@ S: Maintained
F: drivers/bcma/
F: include/linux/bcma/
+BROADCOM SYSTEMPORT ETHERNET DRIVER
+M: Florian Fainelli <f.fainelli@gmail.com>
+L: netdev@vger.kernel.org
+S: Supported
+F: drivers/net/ethernet/broadcom/bcmsysport.*
+
BROCADE BFA FC SCSI DRIVER
M: Anil Gurumurthy <anil.gurumurthy@qlogic.com>
M: Sudarsana Kalluru <sudarsana.kalluru@qlogic.com>
@@ -6782,7 +6788,7 @@ PERFORMANCE EVENTS SUBSYSTEM
M: Peter Zijlstra <a.p.zijlstra@chello.nl>
M: Paul Mackerras <paulus@samba.org>
M: Ingo Molnar <mingo@redhat.com>
-M: Arnaldo Carvalho de Melo <acme@ghostprotocols.net>
+M: Arnaldo Carvalho de Melo <acme@kernel.org>
L: linux-kernel@vger.kernel.org
T: git git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip.git perf/core
S: Supported
@@ -7674,7 +7680,6 @@ F: drivers/clk/samsung/
SAMSUNG SXGBE DRIVERS
M: Byungho An <bh74.an@samsung.com>
M: Girish K S <ks.giri@samsung.com>
-M: Siva Reddy Kallam <siva.kallam@samsung.com>
M: Vipul Pandya <vipul.pandya@samsung.com>
S: Supported
L: netdev@vger.kernel.org
@@ -8315,7 +8320,7 @@ F: include/linux/compiler.h
SPEAR PLATFORM SUPPORT
M: Viresh Kumar <viresh.linux@gmail.com>
-M: Shiraz Hashim <shiraz.hashim@st.com>
+M: Shiraz Hashim <shiraz.linux.kernel@gmail.com>
L: spear-devel@list.st.com
L: linux-arm-kernel@lists.infradead.org (moderated for non-subscribers)
W: http://www.st.com/spear
diff --git a/arch/arc/include/asm/barrier.h b/arch/arc/include/asm/barrier.h
deleted file mode 100644
index c32245c..0000000
--- a/arch/arc/include/asm/barrier.h
+++ /dev/null
@@ -1,37 +0,0 @@
-/*
- * Copyright (C) 2004, 2007-2010, 2011-2012 Synopsys, Inc. (www.synopsys.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 __ASM_BARRIER_H
-#define __ASM_BARRIER_H
-
-#ifndef __ASSEMBLY__
-
-/* TODO-vineetg: Need to see what this does, don't we need sync anywhere */
-#define mb() __asm__ __volatile__ ("" : : : "memory")
-#define rmb() mb()
-#define wmb() mb()
-#define set_mb(var, value) do { var = value; mb(); } while (0)
-#define set_wmb(var, value) do { var = value; wmb(); } while (0)
-#define read_barrier_depends() mb()
-
-/* TODO-vineetg verify the correctness of macros here */
-#ifdef CONFIG_SMP
-#define smp_mb() mb()
-#define smp_rmb() rmb()
-#define smp_wmb() wmb()
-#else
-#define smp_mb() barrier()
-#define smp_rmb() barrier()
-#define smp_wmb() barrier()
-#endif
-
-#define smp_read_barrier_depends() do { } while (0)
-
-#endif
-
-#endif
diff --git a/arch/arm/boot/dts/spear320-hmi.dts b/arch/arm/boot/dts/spear320-hmi.dts
index 3075d2d..0aa6fef 100644
--- a/arch/arm/boot/dts/spear320-hmi.dts
+++ b/arch/arm/boot/dts/spear320-hmi.dts
@@ -1,7 +1,7 @@
/*
* DTS file for SPEAr320 Evaluation Baord
*
- * Copyright 2012 Shiraz Hashim <shiraz.hashim@st.com>
+ * Copyright 2012 Shiraz Hashim <shiraz.linux.kernel@gmail.com>
*
* The code contained herein is licensed under the GNU General Public
* License. You may obtain a copy of the GNU General Public License
diff --git a/arch/arm/boot/dts/vt8500.dtsi b/arch/arm/boot/dts/vt8500.dtsi
index 51d0e91..1929ad3 100644
--- a/arch/arm/boot/dts/vt8500.dtsi
+++ b/arch/arm/boot/dts/vt8500.dtsi
@@ -165,5 +165,11 @@
reg = <0xd8100000 0x10000>;
interrupts = <48>;
};
+
+ ethernet@d8004000 {
+ compatible = "via,vt8500-rhine";
+ reg = <0xd8004000 0x100>;
+ interrupts = <10>;
+ };
};
};
diff --git a/arch/arm/boot/dts/wm8650.dtsi b/arch/arm/boot/dts/wm8650.dtsi
index 7525982..b1c59a7 100644
--- a/arch/arm/boot/dts/wm8650.dtsi
+++ b/arch/arm/boot/dts/wm8650.dtsi
@@ -218,5 +218,11 @@
reg = <0xd8100000 0x10000>;
interrupts = <48>;
};
+
+ ethernet@d8004000 {
+ compatible = "via,vt8500-rhine";
+ reg = <0xd8004000 0x100>;
+ interrupts = <10>;
+ };
};
};
diff --git a/arch/arm/boot/dts/wm8850.dtsi b/arch/arm/boot/dts/wm8850.dtsi
index d98386d..8fbccfbe 100644
--- a/arch/arm/boot/dts/wm8850.dtsi
+++ b/arch/arm/boot/dts/wm8850.dtsi
@@ -298,5 +298,11 @@
bus-width = <4>;
sdon-inverted;
};
+
+ ethernet@d8004000 {
+ compatible = "via,vt8500-rhine";
+ reg = <0xd8004000 0x100>;
+ interrupts = <10>;
+ };
};
};
diff --git a/arch/arm/configs/bcm_defconfig b/arch/arm/configs/bcm_defconfig
index 0100464..3df3f3a 100644
--- a/arch/arm/configs/bcm_defconfig
+++ b/arch/arm/configs/bcm_defconfig
@@ -132,7 +132,7 @@ CONFIG_CRC_ITU_T=y
CONFIG_CRC7=y
CONFIG_XZ_DEC=y
CONFIG_AVERAGE=y
-CONFIG_PINCTRL_CAPRI=y
+CONFIG_PINCTRL_BCM281XX=y
CONFIG_WATCHDOG=y
CONFIG_BCM_KONA_WDT=y
CONFIG_BCM_KONA_WDT_DEBUG=y
diff --git a/arch/arm/mach-spear/headsmp.S b/arch/arm/mach-spear/headsmp.S
index ed85473..c52192d 100644
--- a/arch/arm/mach-spear/headsmp.S
+++ b/arch/arm/mach-spear/headsmp.S
@@ -3,7 +3,7 @@
*
* Picked from realview
* Copyright (c) 2012 ST Microelectronics Limited
- * Shiraz Hashim <shiraz.hashim@st.com>
+ * Shiraz Hashim <shiraz.linux.kernel@gmail.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/arch/arm/mach-spear/platsmp.c b/arch/arm/mach-spear/platsmp.c
index 5c4a198..c19751f 100644
--- a/arch/arm/mach-spear/platsmp.c
+++ b/arch/arm/mach-spear/platsmp.c
@@ -4,7 +4,7 @@
* based upon linux/arch/arm/mach-realview/platsmp.c
*
* Copyright (C) 2012 ST Microelectronics Ltd.
- * Shiraz Hashim <shiraz.hashim@st.com>
+ * Shiraz Hashim <shiraz.linux.kernel@gmail.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/arch/arm/mach-spear/time.c b/arch/arm/mach-spear/time.c
index 218ba5b..6479035 100644
--- a/arch/arm/mach-spear/time.c
+++ b/arch/arm/mach-spear/time.c
@@ -2,7 +2,7 @@
* arch/arm/plat-spear/time.c
*
* Copyright (C) 2010 ST Microelectronics
- * Shiraz Hashim<shiraz.hashim@st.com>
+ * Shiraz Hashim<shiraz.linux.kernel@gmail.com>
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
diff --git a/arch/ia64/kernel/head.S b/arch/ia64/kernel/head.S
index e6f80fc..a4acdda 100644
--- a/arch/ia64/kernel/head.S
+++ b/arch/ia64/kernel/head.S
@@ -259,7 +259,7 @@ start_ap:
* Switch into virtual mode:
*/
movl r16=(IA64_PSR_IT|IA64_PSR_IC|IA64_PSR_DT|IA64_PSR_RT|IA64_PSR_DFH|IA64_PSR_BN \
- |IA64_PSR_DI|IA64_PSR_AC)
+ |IA64_PSR_DI)
;;
mov cr.ipsr=r16
movl r17=1f
diff --git a/arch/ia64/kernel/ivt.S b/arch/ia64/kernel/ivt.S
index 689ffca..18e794a 100644
--- a/arch/ia64/kernel/ivt.S
+++ b/arch/ia64/kernel/ivt.S
@@ -58,7 +58,7 @@
#include <asm/unistd.h>
#include <asm/errno.h>
-#if 1
+#if 0
# define PSR_DEFAULT_BITS psr.ac
#else
# define PSR_DEFAULT_BITS 0
diff --git a/arch/ia64/kvm/vmm_ivt.S b/arch/ia64/kvm/vmm_ivt.S
index 2401848..397e34a 100644
--- a/arch/ia64/kvm/vmm_ivt.S
+++ b/arch/ia64/kvm/vmm_ivt.S
@@ -64,7 +64,7 @@
#include "kvm_minstate.h"
#include "vti.h"
-#if 1
+#if 0
# define PSR_DEFAULT_BITS psr.ac
#else
# define PSR_DEFAULT_BITS 0
diff --git a/arch/mips/mm/cache.c b/arch/mips/mm/cache.c
index e422b38..9e67cde 100644
--- a/arch/mips/mm/cache.c
+++ b/arch/mips/mm/cache.c
@@ -29,15 +29,15 @@ void (*flush_cache_range)(struct vm_area_struct *vma, unsigned long start,
void (*flush_cache_page)(struct vm_area_struct *vma, unsigned long page,
unsigned long pfn);
void (*flush_icache_range)(unsigned long start, unsigned long end);
+EXPORT_SYMBOL_GPL(flush_icache_range);
void (*local_flush_icache_range)(unsigned long start, unsigned long end);
void (*__flush_cache_vmap)(void);
void (*__flush_cache_vunmap)(void);
void (*__flush_kernel_vmap_range)(unsigned long vaddr, int size);
-void (*__invalidate_kernel_vmap_range)(unsigned long vaddr, int size);
-
EXPORT_SYMBOL_GPL(__flush_kernel_vmap_range);
+void (*__invalidate_kernel_vmap_range)(unsigned long vaddr, int size);
/* MIPS specific cache operations */
void (*flush_cache_sigtramp)(unsigned long addr);
diff --git a/arch/parisc/include/asm/shmparam.h b/arch/parisc/include/asm/shmparam.h
index 628ddc2..afe1300 100644
--- a/arch/parisc/include/asm/shmparam.h
+++ b/arch/parisc/include/asm/shmparam.h
@@ -1,8 +1,7 @@
#ifndef _ASMPARISC_SHMPARAM_H
#define _ASMPARISC_SHMPARAM_H
-#define __ARCH_FORCE_SHMLBA 1
-
-#define SHMLBA 0x00400000 /* attach addr needs to be 4 Mb aligned */
+#define SHMLBA PAGE_SIZE /* attach addr a multiple of this */
+#define SHM_COLOUR 0x00400000 /* shared mappings colouring */
#endif /* _ASMPARISC_SHMPARAM_H */
diff --git a/arch/parisc/kernel/cache.c b/arch/parisc/kernel/cache.c
index a6ffc77..f6448c7 100644
--- a/arch/parisc/kernel/cache.c
+++ b/arch/parisc/kernel/cache.c
@@ -323,7 +323,8 @@ void flush_dcache_page(struct page *page)
* specifically accesses it, of course) */
flush_tlb_page(mpnt, addr);
- if (old_addr == 0 || (old_addr & (SHMLBA - 1)) != (addr & (SHMLBA - 1))) {
+ if (old_addr == 0 || (old_addr & (SHM_COLOUR - 1))
+ != (addr & (SHM_COLOUR - 1))) {
__flush_cache_page(mpnt, addr, page_to_phys(page));
if (old_addr)
printk(KERN_ERR "INEQUIVALENT ALIASES 0x%lx and 0x%lx in file %s\n", old_addr, addr, mpnt->vm_file ? (char *)mpnt->vm_file->f_path.dentry->d_name.name : "(null)");
diff --git a/arch/parisc/kernel/sys_parisc.c b/arch/parisc/kernel/sys_parisc.c
index b7cadc4..31ffa9b 100644
--- a/arch/parisc/kernel/sys_parisc.c
+++ b/arch/parisc/kernel/sys_parisc.c
@@ -45,7 +45,7 @@
static int get_offset(unsigned int last_mmap)
{
- return (last_mmap & (SHMLBA-1)) >> PAGE_SHIFT;
+ return (last_mmap & (SHM_COLOUR-1)) >> PAGE_SHIFT;
}
static unsigned long shared_align_offset(unsigned int last_mmap,
@@ -57,8 +57,8 @@ static unsigned long shared_align_offset(unsigned int last_mmap,
static inline unsigned long COLOR_ALIGN(unsigned long addr,
unsigned int last_mmap, unsigned long pgoff)
{
- unsigned long base = (addr+SHMLBA-1) & ~(SHMLBA-1);
- unsigned long off = (SHMLBA-1) &
+ unsigned long base = (addr+SHM_COLOUR-1) & ~(SHM_COLOUR-1);
+ unsigned long off = (SHM_COLOUR-1) &
(shared_align_offset(last_mmap, pgoff) << PAGE_SHIFT);
return base + off;
@@ -101,7 +101,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
if (flags & MAP_FIXED) {
if ((flags & MAP_SHARED) && last_mmap &&
(addr - shared_align_offset(last_mmap, pgoff))
- & (SHMLBA - 1))
+ & (SHM_COLOUR - 1))
return -EINVAL;
goto found_addr;
}
@@ -122,7 +122,7 @@ unsigned long arch_get_unmapped_area(struct file *filp, unsigned long addr,
info.length = len;
info.low_limit = mm->mmap_legacy_base;
info.high_limit = mmap_upper_limit();
- info.align_mask = last_mmap ? (PAGE_MASK & (SHMLBA - 1)) : 0;
+ info.align_mask = last_mmap ? (PAGE_MASK & (SHM_COLOUR - 1)) : 0;
info.align_offset = shared_align_offset(last_mmap, pgoff);
addr = vm_unmapped_area(&info);
@@ -161,7 +161,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
if (flags & MAP_FIXED) {
if ((flags & MAP_SHARED) && last_mmap &&
(addr - shared_align_offset(last_mmap, pgoff))
- & (SHMLBA - 1))
+ & (SHM_COLOUR - 1))
return -EINVAL;
goto found_addr;
}
@@ -182,7 +182,7 @@ arch_get_unmapped_area_topdown(struct file *filp, const unsigned long addr0,
info.length = len;
info.low_limit = PAGE_SIZE;
info.high_limit = mm->mmap_base;
- info.align_mask = last_mmap ? (PAGE_MASK & (SHMLBA - 1)) : 0;
+ info.align_mask = last_mmap ? (PAGE_MASK & (SHM_COLOUR - 1)) : 0;
info.align_offset = shared_align_offset(last_mmap, pgoff);
addr = vm_unmapped_area(&info);
if (!(addr & ~PAGE_MASK))
diff --git a/arch/parisc/kernel/syscall_table.S b/arch/parisc/kernel/syscall_table.S
index 80e5dd2..83ead0e 100644
--- a/arch/parisc/kernel/syscall_table.S
+++ b/arch/parisc/kernel/syscall_table.S
@@ -392,7 +392,7 @@
ENTRY_COMP(vmsplice)
ENTRY_COMP(move_pages) /* 295 */
ENTRY_SAME(getcpu)
- ENTRY_SAME(epoll_pwait)
+ ENTRY_COMP(epoll_pwait)
ENTRY_COMP(statfs64)
ENTRY_COMP(fstatfs64)
ENTRY_COMP(kexec_load) /* 300 */
diff --git a/arch/parisc/lib/memcpy.c b/arch/parisc/lib/memcpy.c
index 413dc17..b2b441b 100644
--- a/arch/parisc/lib/memcpy.c
+++ b/arch/parisc/lib/memcpy.c
@@ -470,7 +470,7 @@ static unsigned long pa_memcpy(void *dstp, const void *srcp, unsigned long len)
return 0;
/* if a load or store fault occured we can get the faulty addr */
- d = &__get_cpu_var(exception_data);
+ d = this_cpu_ptr(&exception_data);
fault_addr = d->fault_addr;
/* error in load or store? */
diff --git a/arch/parisc/mm/fault.c b/arch/parisc/mm/fault.c
index 9d08c71..7475507 100644
--- a/arch/parisc/mm/fault.c
+++ b/arch/parisc/mm/fault.c
@@ -151,7 +151,7 @@ int fixup_exception(struct pt_regs *regs)
fix = search_exception_tables(regs->iaoq[0]);
if (fix) {
struct exception_data *d;
- d = &__get_cpu_var(exception_data);
+ d = this_cpu_ptr(&exception_data);
d->fault_ip = regs->iaoq[0];
d->fault_space = regs->isr;
d->fault_addr = regs->ior;
diff --git a/arch/powerpc/kernel/pci_64.c b/arch/powerpc/kernel/pci_64.c
index 2a47790..155013d 100644
--- a/arch/powerpc/kernel/pci_64.c
+++ b/arch/powerpc/kernel/pci_64.c
@@ -208,7 +208,7 @@ long sys_pciconfig_iobase(long which, unsigned long in_bus,
unsigned long in_devfn)
{
struct pci_controller* hose;
- struct pci_bus *bus = NULL;
+ struct pci_bus *tmp_bus, *bus = NULL;
struct device_node *hose_node;
/* Argh ! Please forgive me for that hack, but that's the
@@ -229,10 +229,12 @@ long sys_pciconfig_iobase(long which, unsigned long in_bus,
* used on pre-domains setup. We return the first match
*/
- list_for_each_entry(bus, &pci_root_buses, node) {
- if (in_bus >= bus->number && in_bus <= bus->busn_res.end)
+ list_for_each_entry(tmp_bus, &pci_root_buses, node) {
+ if (in_bus >= tmp_bus->number &&
+ in_bus <= tmp_bus->busn_res.end) {
+ bus = tmp_bus;
break;
- bus = NULL;
+ }
}
if (bus == NULL || bus->dev.of_node == NULL)
return -ENODEV;
diff --git a/arch/powerpc/mm/numa.c b/arch/powerpc/mm/numa.c
index 4ebbb9e..3b181b2 100644
--- a/arch/powerpc/mm/numa.c
+++ b/arch/powerpc/mm/numa.c
@@ -232,6 +232,7 @@ int __node_distance(int a, int b)
return distance;
}
+EXPORT_SYMBOL(__node_distance);
static void initialize_distance_lookup_table(int nid,
const __be32 *associativity)
diff --git a/arch/s390/include/asm/sigp.h b/arch/s390/include/asm/sigp.h
index d091aa1..bf9c823 100644
--- a/arch/s390/include/asm/sigp.h
+++ b/arch/s390/include/asm/sigp.h
@@ -31,4 +31,23 @@
#define SIGP_STATUS_INCORRECT_STATE 0x00000200UL
#define SIGP_STATUS_NOT_RUNNING 0x00000400UL
+#ifndef __ASSEMBLY__
+
+static inline int __pcpu_sigp(u16 addr, u8 order, u32 parm, u32 *status)
+{
+ register unsigned int reg1 asm ("1") = parm;
+ int cc;
+
+ asm volatile(
+ " sigp %1,%2,0(%3)\n"
+ " ipm %0\n"
+ " srl %0,28\n"
+ : "=d" (cc), "+d" (reg1) : "d" (addr), "a" (order) : "cc");
+ if (status && cc == 1)
+ *status = reg1;
+ return cc;
+}
+
+#endif /* __ASSEMBLY__ */
+
#endif /* __S390_ASM_SIGP_H */
diff --git a/arch/s390/include/asm/smp.h b/arch/s390/include/asm/smp.h
index 1607793..21703f8 100644
--- a/arch/s390/include/asm/smp.h
+++ b/arch/s390/include/asm/smp.h
@@ -7,6 +7,8 @@
#ifndef __ASM_SMP_H
#define __ASM_SMP_H
+#include <asm/sigp.h>
+
#ifdef CONFIG_SMP
#include <asm/lowcore.h>
@@ -50,9 +52,18 @@ static inline int smp_store_status(int cpu) { return 0; }
static inline int smp_vcpu_scheduled(int cpu) { return 1; }
static inline void smp_yield_cpu(int cpu) { }
static inline void smp_yield(void) { }
-static inline void smp_stop_cpu(void) { }
static inline void smp_fill_possible_mask(void) { }
+static inline void smp_stop_cpu(void)
+{
+ u16 pcpu = stap();
+
+ for (;;) {
+ __pcpu_sigp(pcpu, SIGP_STOP, 0, NULL);
+ cpu_relax();
+ }
+}
+
#endif /* CONFIG_SMP */
#ifdef CONFIG_HOTPLUG_CPU
diff --git a/arch/s390/include/uapi/asm/unistd.h b/arch/s390/include/uapi/asm/unistd.h
index 5eb5c9d..3802d2d 100644
--- a/arch/s390/include/uapi/asm/unistd.h
+++ b/arch/s390/include/uapi/asm/unistd.h
@@ -282,7 +282,8 @@
#define __NR_finit_module 344
#define __NR_sched_setattr 345
#define __NR_sched_getattr 346
-#define NR_syscalls 345
+#define __NR_renameat2 347
+#define NR_syscalls 348
/*
* There are some system calls that are not present on 64 bit, some
diff --git a/arch/s390/kernel/compat_wrapper.c b/arch/s390/kernel/compat_wrapper.c
index 824c39d..45cdb37 100644
--- a/arch/s390/kernel/compat_wrapper.c
+++ b/arch/s390/kernel/compat_wrapper.c
@@ -1,5 +1,5 @@
/*
- * Compat sytem call wrappers.
+ * Compat system call wrappers.
*
* Copyright IBM Corp. 2014
*/
@@ -213,3 +213,4 @@ COMPAT_SYSCALL_WRAP5(kcmp, pid_t, pid1, pid_t, pid2, int, type, unsigned long, i
COMPAT_SYSCALL_WRAP3(finit_module, int, fd, const char __user *, uargs, int, flags);
COMPAT_SYSCALL_WRAP3(sched_setattr, pid_t, pid, struct sched_attr __user *, attr, unsigned int, flags);
COMPAT_SYSCALL_WRAP4(sched_getattr, pid_t, pid, struct sched_attr __user *, attr, unsigned int, size, unsigned int, flags);
+COMPAT_SYSCALL_WRAP5(renameat2, int, olddfd, const char __user *, oldname, int, newdfd, const char __user *, newname, unsigned int, flags);
diff --git a/arch/s390/kernel/dumpstack.c b/arch/s390/kernel/dumpstack.c
index e6af940..acb4124 100644
--- a/arch/s390/kernel/dumpstack.c
+++ b/arch/s390/kernel/dumpstack.c
@@ -144,10 +144,10 @@ void show_registers(struct pt_regs *regs)
char *mode;
mode = user_mode(regs) ? "User" : "Krnl";
- printk("%s PSW : %p %p (%pSR)\n",
- mode, (void *) regs->psw.mask,
- (void *) regs->psw.addr,
- (void *) regs->psw.addr);
+ printk("%s PSW : %p %p", mode, (void *)regs->psw.mask, (void *)regs->psw.addr);
+ if (!user_mode(regs))
+ printk(" (%pSR)", (void *)regs->psw.addr);
+ printk("\n");
printk(" R:%x T:%x IO:%x EX:%x Key:%x M:%x W:%x "
"P:%x AS:%x CC:%x PM:%x", mask_bits(regs, PSW_MASK_PER),
mask_bits(regs, PSW_MASK_DAT), mask_bits(regs, PSW_MASK_IO),
diff --git a/arch/s390/kernel/ptrace.c b/arch/s390/kernel/ptrace.c
index 4ac8faf..1c82619 100644
--- a/arch/s390/kernel/ptrace.c
+++ b/arch/s390/kernel/ptrace.c
@@ -64,7 +64,7 @@ void update_cr_regs(struct task_struct *task)
if (task->thread.per_flags & PER_FLAG_NO_TE)
cr_new &= ~(1UL << 55);
if (cr_new != cr)
- __ctl_load(cr, 0, 0);
+ __ctl_load(cr_new, 0, 0);
/* Set or clear transaction execution TDC bits 62 and 63. */
__ctl_store(cr, 2, 2);
cr_new = cr & ~3UL;
diff --git a/arch/s390/kernel/setup.c b/arch/s390/kernel/setup.c
index f70f248..88d1ca8 100644
--- a/arch/s390/kernel/setup.c
+++ b/arch/s390/kernel/setup.c
@@ -1027,3 +1027,35 @@ void __init setup_arch(char **cmdline_p)
/* Setup zfcpdump support */
setup_zfcpdump();
}
+
+#ifdef CONFIG_32BIT
+static int no_removal_warning __initdata;
+
+static int __init parse_no_removal_warning(char *str)
+{
+ no_removal_warning = 1;
+ return 0;
+}
+__setup("no_removal_warning", parse_no_removal_warning);
+
+static int __init removal_warning(void)
+{
+ if (no_removal_warning)
+ return 0;
+ printk(KERN_ALERT "\n\n");
+ printk(KERN_CONT "Warning - you are using a 31 bit kernel!\n\n");
+ printk(KERN_CONT "We plan to remove 31 bit kernel support from the kernel sources in March 2015.\n");
+ printk(KERN_CONT "Currently we assume that nobody is using the 31 bit kernel on old 31 bit\n");
+ printk(KERN_CONT "hardware anymore. If you think that the code should not be removed and also\n");
+ printk(KERN_CONT "future versions of the Linux kernel should be able to run in 31 bit mode\n");
+ printk(KERN_CONT "please let us know. Please write to:\n");
+ printk(KERN_CONT "linux390@de.ibm.com (mail address) and/or\n");
+ printk(KERN_CONT "linux-s390@vger.kernel.org (mailing list).\n\n");
+ printk(KERN_CONT "Thank you!\n\n");
+ printk(KERN_CONT "If this kernel runs on a 64 bit machine you may consider using a 64 bit kernel.\n");
+ printk(KERN_CONT "This message can be disabled with the \"no_removal_warning\" kernel parameter.\n");
+ schedule_timeout_uninterruptible(300 * HZ);
+ return 0;
+}
+early_initcall(removal_warning);
+#endif
diff --git a/arch/s390/kernel/smp.c b/arch/s390/kernel/smp.c
index 512ce1c..86e65ec 100644
--- a/arch/s390/kernel/smp.c
+++ b/arch/s390/kernel/smp.c
@@ -82,21 +82,6 @@ DEFINE_MUTEX(smp_cpu_state_mutex);
/*
* Signal processor helper functions.
*/
-static inline int __pcpu_sigp(u16 addr, u8 order, u32 parm, u32 *status)
-{
- register unsigned int reg1 asm ("1") = parm;
- int cc;
-
- asm volatile(
- " sigp %1,%2,0(%3)\n"
- " ipm %0\n"
- " srl %0,28\n"
- : "=d" (cc), "+d" (reg1) : "d" (addr), "a" (order) : "cc");
- if (status && cc == 1)
- *status = reg1;
- return cc;
-}
-
static inline int __pcpu_sigp_relax(u16 addr, u8 order, u32 parm, u32 *status)
{
int cc;
diff --git a/arch/s390/kernel/syscalls.S b/arch/s390/kernel/syscalls.S
index 542ef48..fe5cdf2 100644
--- a/arch/s390/kernel/syscalls.S
+++ b/arch/s390/kernel/syscalls.S
@@ -355,3 +355,4 @@ SYSCALL(sys_kcmp,sys_kcmp,compat_sys_kcmp)
SYSCALL(sys_finit_module,sys_finit_module,compat_sys_finit_module)
SYSCALL(sys_sched_setattr,sys_sched_setattr,compat_sys_sched_setattr) /* 345 */
SYSCALL(sys_sched_getattr,sys_sched_getattr,compat_sys_sched_getattr)
+SYSCALL(sys_renameat2,sys_renameat2,compat_sys_renameat2)
diff --git a/arch/s390/lib/uaccess.c b/arch/s390/lib/uaccess.c
index 23f866b..7416efe 100644
--- a/arch/s390/lib/uaccess.c
+++ b/arch/s390/lib/uaccess.c
@@ -338,9 +338,6 @@ static inline unsigned long strnlen_user_srst(const char __user *src,
register unsigned long reg0 asm("0") = 0;
unsigned long tmp1, tmp2;
- if (unlikely(!size))
- return 0;
- update_primary_asce(current);
asm volatile(
" la %2,0(%1)\n"
" la %3,0(%0,%1)\n"
@@ -359,6 +356,8 @@ static inline unsigned long strnlen_user_srst(const char __user *src,
unsigned long __strnlen_user(const char __user *src, unsigned long size)
{
+ if (unlikely(!size))
+ return 0;
update_primary_asce(current);
return strnlen_user_srst(src, size);
}
diff --git a/arch/s390/mm/fault.c b/arch/s390/mm/fault.c
index 19f623f..2f51a99 100644
--- a/arch/s390/mm/fault.c
+++ b/arch/s390/mm/fault.c
@@ -126,6 +126,133 @@ static inline int user_space_fault(struct pt_regs *regs)
return 0;
}
+static int bad_address(void *p)
+{
+ unsigned long dummy;
+
+ return probe_kernel_address((unsigned long *)p, dummy);
+}
+
+#ifdef CONFIG_64BIT
+static void dump_pagetable(unsigned long asce, unsigned long address)
+{
+ unsigned long *table = __va(asce & PAGE_MASK);
+
+ pr_alert("AS:%016lx ", asce);
+ switch (asce & _ASCE_TYPE_MASK) {
+ case _ASCE_TYPE_REGION1:
+ table = table + ((address >> 53) & 0x7ff);
+ if (bad_address(table))
+ goto bad;
+ pr_cont("R1:%016lx ", *table);
+ if (*table & _REGION_ENTRY_INVALID)
+ goto out;
+ table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN);
+ /* fallthrough */
+ case _ASCE_TYPE_REGION2:
+ table = table + ((address >> 42) & 0x7ff);
+ if (bad_address(table))
+ goto bad;
+ pr_cont("R2:%016lx ", *table);
+ if (*table & _REGION_ENTRY_INVALID)
+ goto out;
+ table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN);
+ /* fallthrough */
+ case _ASCE_TYPE_REGION3:
+ table = table + ((address >> 31) & 0x7ff);
+ if (bad_address(table))
+ goto bad;
+ pr_cont("R3:%016lx ", *table);
+ if (*table & (_REGION_ENTRY_INVALID | _REGION3_ENTRY_LARGE))
+ goto out;
+ table = (unsigned long *)(*table & _REGION_ENTRY_ORIGIN);
+ /* fallthrough */
+ case _ASCE_TYPE_SEGMENT:
+ table = table + ((address >> 20) & 0x7ff);
+ if (bad_address(table))
+ goto bad;
+ pr_cont(KERN_CONT "S:%016lx ", *table);
+ if (*table & (_SEGMENT_ENTRY_INVALID | _SEGMENT_ENTRY_LARGE))
+ goto out;
+ table = (unsigned long *)(*table & _SEGMENT_ENTRY_ORIGIN);
+ }
+ table = table + ((address >> 12) & 0xff);
+ if (bad_address(table))
+ goto bad;
+ pr_cont("P:%016lx ", *table);
+out:
+ pr_cont("\n");
+ return;
+bad:
+ pr_cont("BAD\n");
+}
+
+#else /* CONFIG_64BIT */
+
+static void dump_pagetable(unsigned long asce, unsigned long address)
+{
+ unsigned long *table = __va(asce & PAGE_MASK);
+
+ pr_alert("AS:%08lx ", asce);
+ table = table + ((address >> 20) & 0x7ff);
+ if (bad_address(table))
+ goto bad;
+ pr_cont("S:%08lx ", *table);
+ if (*table & _SEGMENT_ENTRY_INVALID)
+ goto out;
+ table = (unsigned long *)(*table & _SEGMENT_ENTRY_ORIGIN);
+ table = table + ((address >> 12) & 0xff);
+ if (bad_address(table))
+ goto bad;
+ pr_cont("P:%08lx ", *table);
+out:
+ pr_cont("\n");
+ return;
+bad:
+ pr_cont("BAD\n");
+}
+
+#endif /* CONFIG_64BIT */
+
+static void dump_fault_info(struct pt_regs *regs)
+{
+ unsigned long asce;
+
+ pr_alert("Fault in ");
+ switch (regs->int_parm_long & 3) {
+ case 3:
+ pr_cont("home space ");
+ break;
+ case 2:
+ pr_cont("secondary space ");
+ break;
+ case 1:
+ pr_cont("access register ");
+ break;
+ case 0:
+ pr_cont("primary space ");
+ break;
+ }
+ pr_cont("mode while using ");
+ if (!user_space_fault(regs)) {
+ asce = S390_lowcore.kernel_asce;
+ pr_cont("kernel ");
+ }
+#ifdef CONFIG_PGSTE
+ else if ((current->flags & PF_VCPU) && S390_lowcore.gmap) {
+ struct gmap *gmap = (struct gmap *)S390_lowcore.gmap;
+ asce = gmap->asce;
+ pr_cont("gmap ");
+ }
+#endif
+ else {
+ asce = S390_lowcore.user_asce;
+ pr_cont("user ");
+ }
+ pr_cont("ASCE.\n");
+ dump_pagetable(asce, regs->int_parm_long & __FAIL_ADDR_MASK);
+}
+
static inline void report_user_fault(struct pt_regs *regs, long signr)
{
if ((task_pid_nr(current) > 1) && !show_unhandled_signals)
@@ -138,8 +265,9 @@ static inline void report_user_fault(struct pt_regs *regs, long signr)
regs->int_code);
print_vma_addr(KERN_CONT "in ", regs->psw.addr & PSW_ADDR_INSN);
printk(KERN_CONT "\n");
- printk(KERN_ALERT "failing address: %lX\n",
- regs->int_parm_long & __FAIL_ADDR_MASK);
+ printk(KERN_ALERT "failing address: %016lx TEID: %016lx\n",
+ regs->int_parm_long & __FAIL_ADDR_MASK, regs->int_parm_long);
+ dump_fault_info(regs);
show_regs(regs);
}
@@ -177,11 +305,13 @@ static noinline void do_no_context(struct pt_regs *regs)
address = regs->int_parm_long & __FAIL_ADDR_MASK;
if (!user_space_fault(regs))
printk(KERN_ALERT "Unable to handle kernel pointer dereference"
- " at virtual kernel address %p\n", (void *)address);
+ " in virtual kernel address space\n");
else
printk(KERN_ALERT "Unable to handle kernel paging request"
- " at virtual user address %p\n", (void *)address);
-
+ " in virtual user address space\n");
+ printk(KERN_ALERT "failing address: %016lx TEID: %016lx\n",
+ regs->int_parm_long & __FAIL_ADDR_MASK, regs->int_parm_long);
+ dump_fault_info(regs);
die(regs, "Oops");
do_exit(SIGKILL);
}
diff --git a/arch/x86/Makefile b/arch/x86/Makefile
index 602f57e..d1b7c37 100644
--- a/arch/x86/Makefile
+++ b/arch/x86/Makefile
@@ -250,8 +250,8 @@ archclean:
PHONY += kvmconfig
kvmconfig:
$(if $(wildcard $(objtree)/.config),, $(error You need an existing .config for this target))
- $(Q)$(CONFIG_SHELL) $(srctree)/scripts/kconfig/merge_config.sh -m -O $(objtree) $(objtree)/.config arch/x86/configs/kvm_guest.config
- $(Q)yes "" | $(MAKE) oldconfig
+ $(Q)$(CONFIG_SHELL) $(srctree)/scripts/kconfig/merge_config.sh -m -O $(objtree) $(objtree)/.config $(srctree)/arch/x86/configs/kvm_guest.config
+ $(Q)yes "" | $(MAKE) -f $(srctree)/Makefile oldconfig
define archhelp
echo '* bzImage - Compressed kernel image (arch/x86/boot/bzImage)'
diff --git a/arch/x86/kernel/cpu/mcheck/mce.c b/arch/x86/kernel/cpu/mcheck/mce.c
index eeee23f..68317c8 100644
--- a/arch/x86/kernel/cpu/mcheck/mce.c
+++ b/arch/x86/kernel/cpu/mcheck/mce.c
@@ -598,7 +598,6 @@ void machine_check_poll(enum mcp_flags flags, mce_banks_t *b)
{
struct mce m;
int i;
- unsigned long *v;
this_cpu_inc(mce_poll_count);
@@ -618,8 +617,7 @@ void machine_check_poll(enum mcp_flags flags, mce_banks_t *b)
if (!(m.status & MCI_STATUS_VAL))
continue;
- v = &get_cpu_var(mce_polled_error);
- set_bit(0, v);
+ this_cpu_write(mce_polled_error, 1);
/*
* Uncorrected or signalled events are handled by the exception
* handler when it is enabled, so don't process those here.
diff --git a/arch/x86/kernel/cpu/mcheck/mce_intel.c b/arch/x86/kernel/cpu/mcheck/mce_intel.c
index 3bdb95a..9a316b2 100644
--- a/arch/x86/kernel/cpu/mcheck/mce_intel.c
+++ b/arch/x86/kernel/cpu/mcheck/mce_intel.c
@@ -42,7 +42,7 @@ static DEFINE_PER_CPU(mce_banks_t, mce_banks_owned);
* cmci_discover_lock protects against parallel discovery attempts
* which could race against each other.
*/
-static DEFINE_RAW_SPINLOCK(cmci_discover_lock);
+static DEFINE_SPINLOCK(cmci_discover_lock);
#define CMCI_THRESHOLD 1
#define CMCI_POLL_INTERVAL (30 * HZ)
@@ -144,14 +144,14 @@ static void cmci_storm_disable_banks(void)
int bank;
u64 val;
- raw_spin_lock_irqsave(&cmci_discover_lock, flags);
+ spin_lock_irqsave(&cmci_discover_lock, flags);
owned = __get_cpu_var(mce_banks_owned);
for_each_set_bit(bank, owned, MAX_NR_BANKS) {
rdmsrl(MSR_IA32_MCx_CTL2(bank), val);
val &= ~MCI_CTL2_CMCI_EN;
wrmsrl(MSR_IA32_MCx_CTL2(bank), val);
}
- raw_spin_unlock_irqrestore(&cmci_discover_lock, flags);
+ spin_unlock_irqrestore(&cmci_discover_lock, flags);
}
static bool cmci_storm_detect(void)
@@ -211,7 +211,7 @@ static void cmci_discover(int banks)
int i;
int bios_wrong_thresh = 0;
- raw_spin_lock_irqsave(&cmci_discover_lock, flags);
+ spin_lock_irqsave(&cmci_discover_lock, flags);
for (i = 0; i < banks; i++) {
u64 val;
int bios_zero_thresh = 0;
@@ -266,7 +266,7 @@ static void cmci_discover(int banks)
WARN_ON(!test_bit(i, __get_cpu_var(mce_poll_banks)));
}
}
- raw_spin_unlock_irqrestore(&cmci_discover_lock, flags);
+ spin_unlock_irqrestore(&cmci_discover_lock, flags);
if (mca_cfg.bios_cmci_threshold && bios_wrong_thresh) {
pr_info_once(
"bios_cmci_threshold: Some banks do not have valid thresholds set\n");
@@ -316,10 +316,10 @@ void cmci_clear(void)
if (!cmci_supported(&banks))
return;
- raw_spin_lock_irqsave(&cmci_discover_lock, flags);
+ spin_lock_irqsave(&cmci_discover_lock, flags);
for (i = 0; i < banks; i++)
__cmci_disable_bank(i);
- raw_spin_unlock_irqrestore(&cmci_discover_lock, flags);
+ spin_unlock_irqrestore(&cmci_discover_lock, flags);
}
static void cmci_rediscover_work_func(void *arg)
@@ -360,9 +360,9 @@ void cmci_disable_bank(int bank)
if (!cmci_supported(&banks))
return;
- raw_spin_lock_irqsave(&cmci_discover_lock, flags);
+ spin_lock_irqsave(&cmci_discover_lock, flags);
__cmci_disable_bank(bank);
- raw_spin_unlock_irqrestore(&cmci_discover_lock, flags);
+ spin_unlock_irqrestore(&cmci_discover_lock, flags);
}
static void intel_init_cmci(void)
diff --git a/arch/x86/kernel/cpu/perf_event_intel_rapl.c b/arch/x86/kernel/cpu/perf_event_intel_rapl.c
index 059218e..7c87424 100644
--- a/arch/x86/kernel/cpu/perf_event_intel_rapl.c
+++ b/arch/x86/kernel/cpu/perf_event_intel_rapl.c
@@ -59,7 +59,7 @@
#define INTEL_RAPL_PKG 0x2 /* pseudo-encoding */
#define RAPL_IDX_RAM_NRG_STAT 2 /* DRAM */
#define INTEL_RAPL_RAM 0x3 /* pseudo-encoding */
-#define RAPL_IDX_PP1_NRG_STAT 3 /* DRAM */
+#define RAPL_IDX_PP1_NRG_STAT 3 /* gpu */
#define INTEL_RAPL_PP1 0x4 /* pseudo-encoding */
/* Clients have PP0, PKG */
@@ -72,6 +72,12 @@
1<<RAPL_IDX_PKG_NRG_STAT|\
1<<RAPL_IDX_RAM_NRG_STAT)
+/* Servers have PP0, PKG, RAM, PP1 */
+#define RAPL_IDX_HSW (1<<RAPL_IDX_PP0_NRG_STAT|\
+ 1<<RAPL_IDX_PKG_NRG_STAT|\
+ 1<<RAPL_IDX_RAM_NRG_STAT|\
+ 1<<RAPL_IDX_PP1_NRG_STAT)
+
/*
* event code: LSB 8 bits, passed in attr->config
* any other bit is reserved
@@ -425,6 +431,24 @@ static struct attribute *rapl_events_cln_attr[] = {
NULL,
};
+static struct attribute *rapl_events_hsw_attr[] = {
+ EVENT_PTR(rapl_cores),
+ EVENT_PTR(rapl_pkg),
+ EVENT_PTR(rapl_gpu),
+ EVENT_PTR(rapl_ram),
+
+ EVENT_PTR(rapl_cores_unit),
+ EVENT_PTR(rapl_pkg_unit),
+ EVENT_PTR(rapl_gpu_unit),
+ EVENT_PTR(rapl_ram_unit),
+
+ EVENT_PTR(rapl_cores_scale),
+ EVENT_PTR(rapl_pkg_scale),
+ EVENT_PTR(rapl_gpu_scale),
+ EVENT_PTR(rapl_ram_scale),
+ NULL,
+};
+
static struct attribute_group rapl_pmu_events_group = {
.name = "events",
.attrs = NULL, /* patched at runtime */
@@ -511,6 +535,7 @@ static int rapl_cpu_prepare(int cpu)
struct rapl_pmu *pmu = per_cpu(rapl_pmu, cpu);
int phys_id = topology_physical_package_id(cpu);
u64 ms;
+ u64 msr_rapl_power_unit_bits;
if (pmu)
return 0;
@@ -518,6 +543,9 @@ static int rapl_cpu_prepare(int cpu)
if (phys_id < 0)
return -1;
+ if (!rdmsrl_safe(MSR_RAPL_POWER_UNIT, &msr_rapl_power_unit_bits))
+ return -1;
+
pmu = kzalloc_node(sizeof(*pmu), GFP_KERNEL, cpu_to_node(cpu));
if (!pmu)
return -1;
@@ -531,8 +559,7 @@ static int rapl_cpu_prepare(int cpu)
*
* we cache in local PMU instance
*/
- rdmsrl(MSR_RAPL_POWER_UNIT, pmu->hw_unit);
- pmu->hw_unit = (pmu->hw_unit >> 8) & 0x1FULL;
+ pmu->hw_unit = (msr_rapl_power_unit_bits >> 8) & 0x1FULL;
pmu->pmu = &rapl_pmu_class;
/*
@@ -631,11 +658,14 @@ static int __init rapl_pmu_init(void)
switch (boot_cpu_data.x86_model) {
case 42: /* Sandy Bridge */
case 58: /* Ivy Bridge */
- case 60: /* Haswell */
- case 69: /* Haswell-Celeron */
rapl_cntr_mask = RAPL_IDX_CLN;
rapl_pmu_events_group.attrs = rapl_events_cln_attr;
break;
+ case 60: /* Haswell */
+ case 69: /* Haswell-Celeron */
+ rapl_cntr_mask = RAPL_IDX_HSW;
+ rapl_pmu_events_group.attrs = rapl_events_hsw_attr;
+ break;
case 45: /* Sandy Bridge-EP */
case 62: /* IvyTown */
rapl_cntr_mask = RAPL_IDX_SRV;
@@ -650,7 +680,9 @@ static int __init rapl_pmu_init(void)
cpu_notifier_register_begin();
for_each_online_cpu(cpu) {
- rapl_cpu_prepare(cpu);
+ ret = rapl_cpu_prepare(cpu);
+ if (ret)
+ goto out;
rapl_cpu_init(cpu);
}
@@ -673,6 +705,7 @@ static int __init rapl_pmu_init(void)
hweight32(rapl_cntr_mask),
ktime_to_ms(pmu->timer_interval));
+out:
cpu_notifier_register_done();
return 0;
diff --git a/arch/x86/kernel/early-quirks.c b/arch/x86/kernel/early-quirks.c
index b0cc380..6e2537c 100644
--- a/arch/x86/kernel/early-quirks.c
+++ b/arch/x86/kernel/early-quirks.c
@@ -240,7 +240,7 @@ static u32 __init intel_stolen_base(int num, int slot, int func, size_t stolen_s
return base;
}
-#define KB(x) ((x) * 1024)
+#define KB(x) ((x) * 1024UL)
#define MB(x) (KB (KB (x)))
#define GB(x) (MB (KB (x)))
diff --git a/arch/x86/kernel/kprobes/core.c b/arch/x86/kernel/kprobes/core.c
index 79a3f96..61b17dc 100644
--- a/arch/x86/kernel/kprobes/core.c
+++ b/arch/x86/kernel/kprobes/core.c
@@ -897,9 +897,10 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
struct kprobe *cur = kprobe_running();
struct kprobe_ctlblk *kcb = get_kprobe_ctlblk();
- switch (kcb->kprobe_status) {
- case KPROBE_HIT_SS:
- case KPROBE_REENTER:
+ if (unlikely(regs->ip == (unsigned long)cur->ainsn.insn)) {
+ /* This must happen on single-stepping */
+ WARN_ON(kcb->kprobe_status != KPROBE_HIT_SS &&
+ kcb->kprobe_status != KPROBE_REENTER);
/*
* We are here because the instruction being single
* stepped caused a page fault. We reset the current
@@ -914,9 +915,8 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
else
reset_current_kprobe();
preempt_enable_no_resched();
- break;
- case KPROBE_HIT_ACTIVE:
- case KPROBE_HIT_SSDONE:
+ } else if (kcb->kprobe_status == KPROBE_HIT_ACTIVE ||
+ kcb->kprobe_status == KPROBE_HIT_SSDONE) {
/*
* We increment the nmissed count for accounting,
* we can also use npre/npostfault count for accounting
@@ -945,10 +945,8 @@ int __kprobes kprobe_fault_handler(struct pt_regs *regs, int trapnr)
* fixup routine could not handle it,
* Let do_page_fault() fix it.
*/
- break;
- default:
- break;
}
+
return 0;
}
diff --git a/arch/x86/kernel/reboot.c b/arch/x86/kernel/reboot.c
index 654b465..3399d3a 100644
--- a/arch/x86/kernel/reboot.c
+++ b/arch/x86/kernel/reboot.c
@@ -114,8 +114,8 @@ EXPORT_SYMBOL(machine_real_restart);
*/
static int __init set_pci_reboot(const struct dmi_system_id *d)
{
- if (reboot_type != BOOT_CF9) {
- reboot_type = BOOT_CF9;
+ if (reboot_type != BOOT_CF9_FORCE) {
+ reboot_type = BOOT_CF9_FORCE;
pr_info("%s series board detected. Selecting %s-method for reboots.\n",
d->ident, "PCI");
}
@@ -458,20 +458,23 @@ void __attribute__((weak)) mach_reboot_fixups(void)
}
/*
- * Windows compatible x86 hardware expects the following on reboot:
+ * To the best of our knowledge Windows compatible x86 hardware expects
+ * the following on reboot:
*
* 1) If the FADT has the ACPI reboot register flag set, try it
* 2) If still alive, write to the keyboard controller
* 3) If still alive, write to the ACPI reboot register again
* 4) If still alive, write to the keyboard controller again
* 5) If still alive, call the EFI runtime service to reboot
- * 6) If still alive, write to the PCI IO port 0xCF9 to reboot
- * 7) If still alive, inform BIOS to do a proper reboot
+ * 6) If no EFI runtime service, call the BIOS to do a reboot
*
- * If the machine is still alive at this stage, it gives up. We default to
- * following the same pattern, except that if we're still alive after (7) we'll
- * try to force a triple fault and then cycle between hitting the keyboard
- * controller and doing that
+ * We default to following the same pattern. We also have
+ * two other reboot methods: 'triple fault' and 'PCI', which
+ * can be triggered via the reboot= kernel boot option or
+ * via quirks.
+ *
+ * This means that this function can never return, it can misbehave
+ * by not rebooting properly and hanging.
*/
static void native_machine_emergency_restart(void)
{
@@ -492,6 +495,11 @@ static void native_machine_emergency_restart(void)
for (;;) {
/* Could also try the reset bit in the Hammer NB */
switch (reboot_type) {
+ case BOOT_ACPI:
+ acpi_reboot();
+ reboot_type = BOOT_KBD;
+ break;
+
case BOOT_KBD:
mach_reboot_fixups(); /* For board specific fixups */
@@ -509,43 +517,29 @@ static void native_machine_emergency_restart(void)
}
break;
- case BOOT_TRIPLE:
- load_idt(&no_idt);
- __asm__ __volatile__("int3");
-
- /* We're probably dead after this, but... */
- reboot_type = BOOT_KBD;
- break;
-
- case BOOT_BIOS:
- machine_real_restart(MRR_BIOS);
-
- /* We're probably dead after this, but... */
- reboot_type = BOOT_TRIPLE;
- break;
-
- case BOOT_ACPI:
- acpi_reboot();
- reboot_type = BOOT_KBD;
- break;
-
case BOOT_EFI:
if (efi_enabled(EFI_RUNTIME_SERVICES))
efi.reset_system(reboot_mode == REBOOT_WARM ?
EFI_RESET_WARM :
EFI_RESET_COLD,
EFI_SUCCESS, 0, NULL);
- reboot_type = BOOT_CF9_COND;
+ reboot_type = BOOT_BIOS;
+ break;
+
+ case BOOT_BIOS:
+ machine_real_restart(MRR_BIOS);
+
+ /* We're probably dead after this, but... */
+ reboot_type = BOOT_CF9_SAFE;
break;
- case BOOT_CF9:
+ case BOOT_CF9_FORCE:
port_cf9_safe = true;
/* Fall through */
- case BOOT_CF9_COND:
+ case BOOT_CF9_SAFE:
if (port_cf9_safe) {
- u8 reboot_code = reboot_mode == REBOOT_WARM ?
- 0x06 : 0x0E;
+ u8 reboot_code = reboot_mode == REBOOT_WARM ? 0x06 : 0x0E;
u8 cf9 = inb(0xcf9) & ~reboot_code;
outb(cf9|2, 0xcf9); /* Request hard reset */
udelay(50);
@@ -553,7 +547,15 @@ static void native_machine_emergency_restart(void)
outb(cf9|reboot_code, 0xcf9);
udelay(50);
}
- reboot_type = BOOT_BIOS;
+ reboot_type = BOOT_TRIPLE;
+ break;
+
+ case BOOT_TRIPLE:
+ load_idt(&no_idt);
+ __asm__ __volatile__("int3");
+
+ /* We're probably dead after this, but... */
+ reboot_type = BOOT_KBD;
break;
}
}
diff --git a/arch/x86/syscalls/Makefile b/arch/x86/syscalls/Makefile
index f325af2..3323c27 100644
--- a/arch/x86/syscalls/Makefile
+++ b/arch/x86/syscalls/Makefile
@@ -54,5 +54,7 @@ syshdr-$(CONFIG_X86_64) += syscalls_64.h
targets += $(uapisyshdr-y) $(syshdr-y)
+PHONY += all
all: $(addprefix $(uapi)/,$(uapisyshdr-y))
all: $(addprefix $(out)/,$(syshdr-y))
+ @:
diff --git a/arch/x86/syscalls/syscall_32.tbl b/arch/x86/syscalls/syscall_32.tbl
index 96bc506..d6b8679 100644
--- a/arch/x86/syscalls/syscall_32.tbl
+++ b/arch/x86/syscalls/syscall_32.tbl
@@ -359,3 +359,4 @@
350 i386 finit_module sys_finit_module
351 i386 sched_setattr sys_sched_setattr
352 i386 sched_getattr sys_sched_getattr
+353 i386 renameat2 sys_renameat2
diff --git a/arch/x86/tools/Makefile b/arch/x86/tools/Makefile
index e812034..604a37e 100644
--- a/arch/x86/tools/Makefile
+++ b/arch/x86/tools/Makefile
@@ -40,4 +40,6 @@ $(obj)/insn_sanity.o: $(srctree)/arch/x86/lib/insn.c $(srctree)/arch/x86/lib/ina
HOST_EXTRACFLAGS += -I$(srctree)/tools/include
hostprogs-y += relocs
relocs-objs := relocs_32.o relocs_64.o relocs_common.o
+PHONY += relocs
relocs: $(obj)/relocs
+ @:
diff --git a/arch/x86/xen/smp.c b/arch/x86/xen/smp.c
index a18eadd..7005974 100644
--- a/arch/x86/xen/smp.c
+++ b/arch/x86/xen/smp.c
@@ -441,10 +441,11 @@ static int xen_cpu_up(unsigned int cpu, struct task_struct *idle)
irq_ctx_init(cpu);
#else
clear_tsk_thread_flag(idle, TIF_FORK);
+#endif
per_cpu(kernel_stack, cpu) =
(unsigned long)task_stack_page(idle) -
KERNEL_STACK_OFFSET + THREAD_SIZE;
-#endif
+
xen_setup_runstate_info(cpu);
xen_setup_timer(cpu);
xen_init_lock_cpu(cpu);
diff --git a/arch/x86/xen/spinlock.c b/arch/x86/xen/spinlock.c
index 4d3acc3..0ba5f3b 100644
--- a/arch/x86/xen/spinlock.c
+++ b/arch/x86/xen/spinlock.c
@@ -274,7 +274,7 @@ void __init xen_init_spinlocks(void)
printk(KERN_DEBUG "xen: PV spinlocks disabled\n");
return;
}
-
+ printk(KERN_DEBUG "xen: PV spinlocks enabled\n");
pv_lock_ops.lock_spinning = PV_CALLEE_SAVE(xen_lock_spinning);
pv_lock_ops.unlock_kick = xen_unlock_kick;
}
@@ -290,6 +290,9 @@ static __init int xen_init_spinlocks_jump(void)
if (!xen_pvspin)
return 0;
+ if (!xen_domain())
+ return 0;
+
static_key_slow_inc(&paravirt_ticketlocks_enabled);
return 0;
}
diff --git a/arch/x86/xen/xen-asm_32.S b/arch/x86/xen/xen-asm_32.S
index 33ca6e4..fd92a64 100644
--- a/arch/x86/xen/xen-asm_32.S
+++ b/arch/x86/xen/xen-asm_32.S
@@ -75,6 +75,17 @@ ENDPROC(xen_sysexit)
* stack state in whatever form its in, we keep things simple by only
* using a single register which is pushed/popped on the stack.
*/
+
+.macro POP_FS
+1:
+ popw %fs
+.pushsection .fixup, "ax"
+2: movw $0, (%esp)
+ jmp 1b
+.popsection
+ _ASM_EXTABLE(1b,2b)
+.endm
+
ENTRY(xen_iret)
/* test eflags for special cases */
testl $(X86_EFLAGS_VM | XEN_EFLAGS_NMI), 8(%esp)
@@ -83,15 +94,13 @@ ENTRY(xen_iret)
push %eax
ESP_OFFSET=4 # bytes pushed onto stack
- /*
- * Store vcpu_info pointer for easy access. Do it this way to
- * avoid having to reload %fs
- */
+ /* Store vcpu_info pointer for easy access */
#ifdef CONFIG_SMP
- GET_THREAD_INFO(%eax)
- movl %ss:TI_cpu(%eax), %eax
- movl %ss:__per_cpu_offset(,%eax,4), %eax
- mov %ss:xen_vcpu(%eax), %eax
+ pushw %fs
+ movl $(__KERNEL_PERCPU), %eax
+ movl %eax, %fs
+ movl %fs:xen_vcpu, %eax
+ POP_FS
#else
movl %ss:xen_vcpu, %eax
#endif
diff --git a/drivers/Makefile b/drivers/Makefile
index e3ced91..d05d81b 100644
--- a/drivers/Makefile
+++ b/drivers/Makefile
@@ -53,8 +53,8 @@ obj-y += gpu/
obj-$(CONFIG_CONNECTOR) += connector/
# i810fb and intelfb depend on char/agp/
-obj-$(CONFIG_FB_I810) += video/i810/
-obj-$(CONFIG_FB_INTEL) += video/intelfb/
+obj-$(CONFIG_FB_I810) += video/fbdev/i810/
+obj-$(CONFIG_FB_INTEL) += video/fbdev/intelfb/
obj-$(CONFIG_PARPORT) += parport/
obj-y += base/ block/ misc/ mfd/ nfc/
diff --git a/drivers/base/core.c b/drivers/base/core.c
index 0dd6528..20da3ad 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -614,39 +614,6 @@ void device_remove_bin_file(struct device *dev,
}
EXPORT_SYMBOL_GPL(device_remove_bin_file);
-/**
- * device_schedule_callback_owner - helper to schedule a callback for a device
- * @dev: device.
- * @func: callback function to invoke later.
- * @owner: module owning the callback routine
- *
- * Attribute methods must not unregister themselves or their parent device
- * (which would amount to the same thing). Attempts to do so will deadlock,
- * since unregistration is mutually exclusive with driver callbacks.
- *
- * Instead methods can call this routine, which will attempt to allocate
- * and schedule a workqueue request to call back @func with @dev as its
- * argument in the workqueue's process context. @dev will be pinned until
- * @func returns.
- *
- * This routine is usually called via the inline device_schedule_callback(),
- * which automatically sets @owner to THIS_MODULE.
- *
- * Returns 0 if the request was submitted, -ENOMEM if storage could not
- * be allocated, -ENODEV if a reference to @owner isn't available.
- *
- * NOTE: This routine won't work if CONFIG_SYSFS isn't set! It uses an
- * underlying sysfs routine (since it is intended for use by attribute
- * methods), and if sysfs isn't available you'll get nothing but -ENOSYS.
- */
-int device_schedule_callback_owner(struct device *dev,
- void (*func)(struct device *), struct module *owner)
-{
- return sysfs_schedule_callback(&dev->kobj,
- (void (*)(void *)) func, dev, owner);
-}
-EXPORT_SYMBOL_GPL(device_schedule_callback_owner);
-
static void klist_children_get(struct klist_node *n)
{
struct device_private *p = to_device_private_parent(n);
diff --git a/drivers/base/dd.c b/drivers/base/dd.c
index 0605176..8986b9f 100644
--- a/drivers/base/dd.c
+++ b/drivers/base/dd.c
@@ -187,8 +187,8 @@ static void driver_bound(struct device *dev)
return;
}
- pr_debug("driver: '%s': %s: bound to device '%s'\n", dev_name(dev),
- __func__, dev->driver->name);
+ pr_debug("driver: '%s': %s: bound to device '%s'\n", dev->driver->name,
+ __func__, dev_name(dev));
klist_add_tail(&dev->p->knode_driver, &dev->driver->p->klist_devices);
diff --git a/drivers/base/topology.c b/drivers/base/topology.c
index bbcbd3c..be7c1fb 100644
--- a/drivers/base/topology.c
+++ b/drivers/base/topology.c
@@ -39,8 +39,7 @@
static ssize_t show_##name(struct device *dev, \
struct device_attribute *attr, char *buf) \
{ \
- unsigned int cpu = dev->id; \
- return sprintf(buf, "%d\n", topology_##name(cpu)); \
+ return sprintf(buf, "%d\n", topology_##name(dev->id)); \
}
#if defined(topology_thread_cpumask) || defined(topology_core_cpumask) || \
diff --git a/drivers/char/Kconfig b/drivers/char/Kconfig
index fbae63e..6e9f74a 100644
--- a/drivers/char/Kconfig
+++ b/drivers/char/Kconfig
@@ -40,7 +40,7 @@ config SGI_MBCS
source "drivers/tty/serial/Kconfig"
config TTY_PRINTK
- bool "TTY driver to output user messages via printk"
+ tristate "TTY driver to output user messages via printk"
depends on EXPERT && TTY
default n
---help---
diff --git a/drivers/char/ipmi/Kconfig b/drivers/char/ipmi/Kconfig
index 0baa8fa..db1c9b7 100644
--- a/drivers/char/ipmi/Kconfig
+++ b/drivers/char/ipmi/Kconfig
@@ -50,6 +50,18 @@ config IPMI_SI
Currently, only KCS and SMIC are supported. If
you are using IPMI, you should probably say "y" here.
+config IPMI_SI_PROBE_DEFAULTS
+ bool 'Probe for all possible IPMI system interfaces by default'
+ default n
+ depends on IPMI_SI
+ help
+ Modern systems will usually expose IPMI interfaces via a discoverable
+ firmware mechanism such as ACPI or DMI. Older systems do not, and so
+ the driver is forced to probe hardware manually. This may cause boot
+ delays. Say "n" here to disable this manual probing. IPMI will then
+ only be available on older systems if the "ipmi_si_intf.trydefaults=1"
+ boot argument is passed.
+
config IPMI_WATCHDOG
tristate 'IPMI Watchdog Timer'
help
diff --git a/drivers/char/ipmi/ipmi_bt_sm.c b/drivers/char/ipmi/ipmi_bt_sm.c
index f5e4cd7..61e7161 100644
--- a/drivers/char/ipmi/ipmi_bt_sm.c
+++ b/drivers/char/ipmi/ipmi_bt_sm.c
@@ -352,7 +352,7 @@ static inline void write_all_bytes(struct si_sm_data *bt)
static inline int read_all_bytes(struct si_sm_data *bt)
{
- unsigned char i;
+ unsigned int i;
/*
* length is "framing info", minimum = 4: NetFn, Seq, Cmd, cCode.
diff --git a/drivers/char/ipmi/ipmi_kcs_sm.c b/drivers/char/ipmi/ipmi_kcs_sm.c
index 6a4bdc1..8c25f59 100644
--- a/drivers/char/ipmi/ipmi_kcs_sm.c
+++ b/drivers/char/ipmi/ipmi_kcs_sm.c
@@ -251,8 +251,9 @@ static inline int check_obf(struct si_sm_data *kcs, unsigned char status,
if (!GET_STATUS_OBF(status)) {
kcs->obf_timeout -= time;
if (kcs->obf_timeout < 0) {
- start_error_recovery(kcs, "OBF not ready in time");
- return 1;
+ kcs->obf_timeout = OBF_RETRY_TIMEOUT;
+ start_error_recovery(kcs, "OBF not ready in time");
+ return 1;
}
return 0;
}
diff --git a/drivers/char/ipmi/ipmi_msghandler.c b/drivers/char/ipmi/ipmi_msghandler.c
index ec4e10f..e6db938 100644
--- a/drivers/char/ipmi/ipmi_msghandler.c
+++ b/drivers/char/ipmi/ipmi_msghandler.c
@@ -55,6 +55,7 @@ static struct ipmi_recv_msg *ipmi_alloc_recv_msg(void);
static int ipmi_init_msghandler(void);
static void smi_recv_tasklet(unsigned long);
static void handle_new_recv_msgs(ipmi_smi_t intf);
+static void need_waiter(ipmi_smi_t intf);
static int initialized;
@@ -73,14 +74,28 @@ static struct proc_dir_entry *proc_ipmi_root;
*/
#define MAX_MSG_TIMEOUT 60000
+/* Call every ~1000 ms. */
+#define IPMI_TIMEOUT_TIME 1000
+
+/* How many jiffies does it take to get to the timeout time. */
+#define IPMI_TIMEOUT_JIFFIES ((IPMI_TIMEOUT_TIME * HZ) / 1000)
+
+/*
+ * Request events from the queue every second (this is the number of
+ * IPMI_TIMEOUT_TIMES between event requests). Hopefully, in the
+ * future, IPMI will add a way to know immediately if an event is in
+ * the queue and this silliness can go away.
+ */
+#define IPMI_REQUEST_EV_TIME (1000 / (IPMI_TIMEOUT_TIME))
+
/*
* The main "user" data structure.
*/
struct ipmi_user {
struct list_head link;
- /* Set to "0" when the user is destroyed. */
- int valid;
+ /* Set to false when the user is destroyed. */
+ bool valid;
struct kref refcount;
@@ -92,7 +107,7 @@ struct ipmi_user {
ipmi_smi_t intf;
/* Does this interface receive IPMI events? */
- int gets_events;
+ bool gets_events;
};
struct cmd_rcvr {
@@ -383,6 +398,9 @@ struct ipmi_smi {
unsigned int waiting_events_count; /* How many events in queue? */
char delivering_events;
char event_msg_printed;
+ atomic_t event_waiters;
+ unsigned int ticks_to_req_ev;
+ int last_needs_timer;
/*
* The event receiver for my BMC, only really used at panic
@@ -395,7 +413,7 @@ struct ipmi_smi {
/* For handling of maintenance mode. */
int maintenance_mode;
- int maintenance_mode_enable;
+ bool maintenance_mode_enable;
int auto_maintenance_timeout;
spinlock_t maintenance_mode_lock; /* Used in a timer... */
@@ -451,7 +469,6 @@ static DEFINE_MUTEX(ipmi_interfaces_mutex);
static LIST_HEAD(smi_watchers);
static DEFINE_MUTEX(smi_watchers_mutex);
-
#define ipmi_inc_stat(intf, stat) \
atomic_inc(&(intf)->stats[IPMI_STAT_ ## stat])
#define ipmi_get_stat(intf, stat) \
@@ -772,6 +789,7 @@ static int intf_next_seq(ipmi_smi_t intf,
*seq = i;
*seqid = intf->seq_table[i].seqid;
intf->curr_seq = (i+1)%IPMI_IPMB_NUM_SEQ;
+ need_waiter(intf);
} else {
rv = -EAGAIN;
}
@@ -941,7 +959,7 @@ int ipmi_create_user(unsigned int if_num,
new_user->handler = handler;
new_user->handler_data = handler_data;
new_user->intf = intf;
- new_user->gets_events = 0;
+ new_user->gets_events = false;
if (!try_module_get(intf->handlers->owner)) {
rv = -ENODEV;
@@ -962,10 +980,15 @@ int ipmi_create_user(unsigned int if_num,
*/
mutex_unlock(&ipmi_interfaces_mutex);
- new_user->valid = 1;
+ new_user->valid = true;
spin_lock_irqsave(&intf->seq_lock, flags);
list_add_rcu(&new_user->link, &intf->users);
spin_unlock_irqrestore(&intf->seq_lock, flags);
+ if (handler->ipmi_watchdog_pretimeout) {
+ /* User wants pretimeouts, so make sure to watch for them. */
+ if (atomic_inc_return(&intf->event_waiters) == 1)
+ need_waiter(intf);
+ }
*user = new_user;
return 0;
@@ -1019,7 +1042,13 @@ int ipmi_destroy_user(ipmi_user_t user)
struct cmd_rcvr *rcvr;
struct cmd_rcvr *rcvrs = NULL;
- user->valid = 0;
+ user->valid = false;
+
+ if (user->handler->ipmi_watchdog_pretimeout)
+ atomic_dec(&intf->event_waiters);
+
+ if (user->gets_events)
+ atomic_dec(&intf->event_waiters);
/* Remove the user from the interface's sequence table. */
spin_lock_irqsave(&intf->seq_lock, flags);
@@ -1155,25 +1184,23 @@ int ipmi_set_maintenance_mode(ipmi_user_t user, int mode)
if (intf->maintenance_mode != mode) {
switch (mode) {
case IPMI_MAINTENANCE_MODE_AUTO:
- intf->maintenance_mode = mode;
intf->maintenance_mode_enable
= (intf->auto_maintenance_timeout > 0);
break;
case IPMI_MAINTENANCE_MODE_OFF:
- intf->maintenance_mode = mode;
- intf->maintenance_mode_enable = 0;
+ intf->maintenance_mode_enable = false;
break;
case IPMI_MAINTENANCE_MODE_ON:
- intf->maintenance_mode = mode;
- intf->maintenance_mode_enable = 1;
+ intf->maintenance_mode_enable = true;
break;
default:
rv = -EINVAL;
goto out_unlock;
}
+ intf->maintenance_mode = mode;
maintenance_mode_update(intf);
}
@@ -1184,7 +1211,7 @@ int ipmi_set_maintenance_mode(ipmi_user_t user, int mode)
}
EXPORT_SYMBOL(ipmi_set_maintenance_mode);
-int ipmi_set_gets_events(ipmi_user_t user, int val)
+int ipmi_set_gets_events(ipmi_user_t user, bool val)
{
unsigned long flags;
ipmi_smi_t intf = user->intf;
@@ -1194,8 +1221,18 @@ int ipmi_set_gets_events(ipmi_user_t user, int val)
INIT_LIST_HEAD(&msgs);
spin_lock_irqsave(&intf->events_lock, flags);
+ if (user->gets_events == val)
+ goto out;
+
user->gets_events = val;
+ if (val) {
+ if (atomic_inc_return(&intf->event_waiters) == 1)
+ need_waiter(intf);
+ } else {
+ atomic_dec(&intf->event_waiters);
+ }
+
if (intf->delivering_events)
/*
* Another thread is delivering events for this, so
@@ -1289,6 +1326,9 @@ int ipmi_register_for_cmd(ipmi_user_t user,
goto out_unlock;
}
+ if (atomic_inc_return(&intf->event_waiters) == 1)
+ need_waiter(intf);
+
list_add_rcu(&rcvr->link, &intf->cmd_rcvrs);
out_unlock:
@@ -1330,6 +1370,7 @@ int ipmi_unregister_for_cmd(ipmi_user_t user,
mutex_unlock(&intf->cmd_rcvrs_mutex);
synchronize_rcu();
while (rcvrs) {
+ atomic_dec(&intf->event_waiters);
rcvr = rcvrs;
rcvrs = rcvr->next;
kfree(rcvr);
@@ -1535,7 +1576,7 @@ static int i_ipmi_request(ipmi_user_t user,
= IPMI_MAINTENANCE_MODE_TIMEOUT;
if (!intf->maintenance_mode
&& !intf->maintenance_mode_enable) {
- intf->maintenance_mode_enable = 1;
+ intf->maintenance_mode_enable = true;
maintenance_mode_update(intf);
}
spin_unlock_irqrestore(&intf->maintenance_mode_lock,
@@ -2876,6 +2917,8 @@ int ipmi_register_smi(struct ipmi_smi_handlers *handlers,
(unsigned long) intf);
atomic_set(&intf->watchdog_pretimeouts_to_deliver, 0);
spin_lock_init(&intf->events_lock);
+ atomic_set(&intf->event_waiters, 0);
+ intf->ticks_to_req_ev = IPMI_REQUEST_EV_TIME;
INIT_LIST_HEAD(&intf->waiting_events);
intf->waiting_events_count = 0;
mutex_init(&intf->cmd_rcvrs_mutex);
@@ -3965,7 +4008,8 @@ smi_from_recv_msg(ipmi_smi_t intf, struct ipmi_recv_msg *recv_msg,
static void check_msg_timeout(ipmi_smi_t intf, struct seq_table *ent,
struct list_head *timeouts, long timeout_period,
- int slot, unsigned long *flags)
+ int slot, unsigned long *flags,
+ unsigned int *waiting_msgs)
{
struct ipmi_recv_msg *msg;
struct ipmi_smi_handlers *handlers;
@@ -3977,8 +4021,10 @@ static void check_msg_timeout(ipmi_smi_t intf, struct seq_table *ent,
return;
ent->timeout -= timeout_period;
- if (ent->timeout > 0)
+ if (ent->timeout > 0) {
+ (*waiting_msgs)++;
return;
+ }
if (ent->retries_left == 0) {
/* The message has used all its retries. */
@@ -3995,6 +4041,8 @@ static void check_msg_timeout(ipmi_smi_t intf, struct seq_table *ent,
struct ipmi_smi_msg *smi_msg;
/* More retries, send again. */
+ (*waiting_msgs)++;
+
/*
* Start with the max timer, set to normal timer after
* the message is sent.
@@ -4040,117 +4088,118 @@ static void check_msg_timeout(ipmi_smi_t intf, struct seq_table *ent,
}
}
-static void ipmi_timeout_handler(long timeout_period)
+static unsigned int ipmi_timeout_handler(ipmi_smi_t intf, long timeout_period)
{
- ipmi_smi_t intf;
struct list_head timeouts;
struct ipmi_recv_msg *msg, *msg2;
unsigned long flags;
int i;
+ unsigned int waiting_msgs = 0;
- rcu_read_lock();
- list_for_each_entry_rcu(intf, &ipmi_interfaces, link) {
- tasklet_schedule(&intf->recv_tasklet);
-
- /*
- * Go through the seq table and find any messages that
- * have timed out, putting them in the timeouts
- * list.
- */
- INIT_LIST_HEAD(&timeouts);
- spin_lock_irqsave(&intf->seq_lock, flags);
- for (i = 0; i < IPMI_IPMB_NUM_SEQ; i++)
- check_msg_timeout(intf, &(intf->seq_table[i]),
- &timeouts, timeout_period, i,
- &flags);
- spin_unlock_irqrestore(&intf->seq_lock, flags);
+ /*
+ * Go through the seq table and find any messages that
+ * have timed out, putting them in the timeouts
+ * list.
+ */
+ INIT_LIST_HEAD(&timeouts);
+ spin_lock_irqsave(&intf->seq_lock, flags);
+ for (i = 0; i < IPMI_IPMB_NUM_SEQ; i++)
+ check_msg_timeout(intf, &(intf->seq_table[i]),
+ &timeouts, timeout_period, i,
+ &flags, &waiting_msgs);
+ spin_unlock_irqrestore(&intf->seq_lock, flags);
- list_for_each_entry_safe(msg, msg2, &timeouts, link)
- deliver_err_response(msg, IPMI_TIMEOUT_COMPLETION_CODE);
+ list_for_each_entry_safe(msg, msg2, &timeouts, link)
+ deliver_err_response(msg, IPMI_TIMEOUT_COMPLETION_CODE);
- /*
- * Maintenance mode handling. Check the timeout
- * optimistically before we claim the lock. It may
- * mean a timeout gets missed occasionally, but that
- * only means the timeout gets extended by one period
- * in that case. No big deal, and it avoids the lock
- * most of the time.
- */
+ /*
+ * Maintenance mode handling. Check the timeout
+ * optimistically before we claim the lock. It may
+ * mean a timeout gets missed occasionally, but that
+ * only means the timeout gets extended by one period
+ * in that case. No big deal, and it avoids the lock
+ * most of the time.
+ */
+ if (intf->auto_maintenance_timeout > 0) {
+ spin_lock_irqsave(&intf->maintenance_mode_lock, flags);
if (intf->auto_maintenance_timeout > 0) {
- spin_lock_irqsave(&intf->maintenance_mode_lock, flags);
- if (intf->auto_maintenance_timeout > 0) {
- intf->auto_maintenance_timeout
- -= timeout_period;
- if (!intf->maintenance_mode
- && (intf->auto_maintenance_timeout <= 0)) {
- intf->maintenance_mode_enable = 0;
- maintenance_mode_update(intf);
- }
+ intf->auto_maintenance_timeout
+ -= timeout_period;
+ if (!intf->maintenance_mode
+ && (intf->auto_maintenance_timeout <= 0)) {
+ intf->maintenance_mode_enable = false;
+ maintenance_mode_update(intf);
}
- spin_unlock_irqrestore(&intf->maintenance_mode_lock,
- flags);
}
+ spin_unlock_irqrestore(&intf->maintenance_mode_lock,
+ flags);
}
- rcu_read_unlock();
+
+ tasklet_schedule(&intf->recv_tasklet);
+
+ return waiting_msgs;
}
-static void ipmi_request_event(void)
+static void ipmi_request_event(ipmi_smi_t intf)
{
- ipmi_smi_t intf;
struct ipmi_smi_handlers *handlers;
- rcu_read_lock();
- /*
- * Called from the timer, no need to check if handlers is
- * valid.
- */
- list_for_each_entry_rcu(intf, &ipmi_interfaces, link) {
- /* No event requests when in maintenance mode. */
- if (intf->maintenance_mode_enable)
- continue;
+ /* No event requests when in maintenance mode. */
+ if (intf->maintenance_mode_enable)
+ return;
- handlers = intf->handlers;
- if (handlers)
- handlers->request_events(intf->send_info);
- }
- rcu_read_unlock();
+ handlers = intf->handlers;
+ if (handlers)
+ handlers->request_events(intf->send_info);
}
static struct timer_list ipmi_timer;
-/* Call every ~1000 ms. */
-#define IPMI_TIMEOUT_TIME 1000
-
-/* How many jiffies does it take to get to the timeout time. */
-#define IPMI_TIMEOUT_JIFFIES ((IPMI_TIMEOUT_TIME * HZ) / 1000)
-
-/*
- * Request events from the queue every second (this is the number of
- * IPMI_TIMEOUT_TIMES between event requests). Hopefully, in the
- * future, IPMI will add a way to know immediately if an event is in
- * the queue and this silliness can go away.
- */
-#define IPMI_REQUEST_EV_TIME (1000 / (IPMI_TIMEOUT_TIME))
-
static atomic_t stop_operation;
-static unsigned int ticks_to_req_ev = IPMI_REQUEST_EV_TIME;
static void ipmi_timeout(unsigned long data)
{
+ ipmi_smi_t intf;
+ int nt = 0;
+
if (atomic_read(&stop_operation))
return;
- ticks_to_req_ev--;
- if (ticks_to_req_ev == 0) {
- ipmi_request_event();
- ticks_to_req_ev = IPMI_REQUEST_EV_TIME;
- }
+ rcu_read_lock();
+ list_for_each_entry_rcu(intf, &ipmi_interfaces, link) {
+ int lnt = 0;
+
+ if (atomic_read(&intf->event_waiters)) {
+ intf->ticks_to_req_ev--;
+ if (intf->ticks_to_req_ev == 0) {
+ ipmi_request_event(intf);
+ intf->ticks_to_req_ev = IPMI_REQUEST_EV_TIME;
+ }
+ lnt++;
+ }
- ipmi_timeout_handler(IPMI_TIMEOUT_TIME);
+ lnt += ipmi_timeout_handler(intf, IPMI_TIMEOUT_TIME);
- mod_timer(&ipmi_timer, jiffies + IPMI_TIMEOUT_JIFFIES);
+ lnt = !!lnt;
+ if (lnt != intf->last_needs_timer &&
+ intf->handlers->set_need_watch)
+ intf->handlers->set_need_watch(intf->send_info, lnt);
+ intf->last_needs_timer = lnt;
+
+ nt += lnt;
+ }
+ rcu_read_unlock();
+
+ if (nt)
+ mod_timer(&ipmi_timer, jiffies + IPMI_TIMEOUT_JIFFIES);
}
+static void need_waiter(ipmi_smi_t intf)
+{
+ /* Racy, but worst case we start the timer twice. */
+ if (!timer_pending(&ipmi_timer))
+ mod_timer(&ipmi_timer, jiffies + IPMI_TIMEOUT_JIFFIES);
+}
static atomic_t smi_msg_inuse_count = ATOMIC_INIT(0);
static atomic_t recv_msg_inuse_count = ATOMIC_INIT(0);
diff --git a/drivers/char/ipmi/ipmi_si_intf.c b/drivers/char/ipmi/ipmi_si_intf.c
index b7efd3c..1c4bb4f 100644
--- a/drivers/char/ipmi/ipmi_si_intf.c
+++ b/drivers/char/ipmi/ipmi_si_intf.c
@@ -217,7 +217,7 @@ struct smi_info {
unsigned char msg_flags;
/* Does the BMC have an event buffer? */
- char has_event_buffer;
+ bool has_event_buffer;
/*
* If set to true, this will request events the next time the
@@ -230,7 +230,7 @@ struct smi_info {
* call. Generally used after a panic to make sure stuff goes
* out.
*/
- int run_to_completion;
+ bool run_to_completion;
/* The I/O port of an SI interface. */
int port;
@@ -248,19 +248,25 @@ struct smi_info {
/* The timer for this si. */
struct timer_list si_timer;
+ /* This flag is set, if the timer is running (timer_pending() isn't enough) */
+ bool timer_running;
+
/* The time (in jiffies) the last timeout occurred at. */
unsigned long last_timeout_jiffies;
/* Used to gracefully stop the timer without race conditions. */
atomic_t stop_operation;
+ /* Are we waiting for the events, pretimeouts, received msgs? */
+ atomic_t need_watch;
+
/*
* The driver will disable interrupts when it gets into a
* situation where it cannot handle messages due to lack of
* memory. Once that situation clears up, it will re-enable
* interrupts.
*/
- int interrupt_disabled;
+ bool interrupt_disabled;
/* From the get device id response... */
struct ipmi_device_id device_id;
@@ -273,7 +279,7 @@ struct smi_info {
* True if we allocated the device, false if it came from
* someplace else (like PCI).
*/
- int dev_registered;
+ bool dev_registered;
/* Slave address, could be reported from DMI. */
unsigned char slave_addr;
@@ -297,19 +303,19 @@ struct smi_info {
static int force_kipmid[SI_MAX_PARMS];
static int num_force_kipmid;
#ifdef CONFIG_PCI
-static int pci_registered;
+static bool pci_registered;
#endif
#ifdef CONFIG_ACPI
-static int pnp_registered;
+static bool pnp_registered;
#endif
#ifdef CONFIG_PARISC
-static int parisc_registered;
+static bool parisc_registered;
#endif
static unsigned int kipmid_max_busy_us[SI_MAX_PARMS];
static int num_max_busy_us;
-static int unload_when_empty = 1;
+static bool unload_when_empty = true;
static int add_smi(struct smi_info *smi);
static int try_smi_init(struct smi_info *smi);
@@ -434,6 +440,13 @@ static void start_clear_flags(struct smi_info *smi_info)
smi_info->si_state = SI_CLEARING_FLAGS;
}
+static void smi_mod_timer(struct smi_info *smi_info, unsigned long new_val)
+{
+ smi_info->last_timeout_jiffies = jiffies;
+ mod_timer(&smi_info->si_timer, new_val);
+ smi_info->timer_running = true;
+}
+
/*
* When we have a situtaion where we run out of memory and cannot
* allocate messages, we just leave them in the BMC and run the system
@@ -444,10 +457,9 @@ static inline void disable_si_irq(struct smi_info *smi_info)
{
if ((smi_info->irq) && (!smi_info->interrupt_disabled)) {
start_disable_irq(smi_info);
- smi_info->interrupt_disabled = 1;
+ smi_info->interrupt_disabled = true;
if (!atomic_read(&smi_info->stop_operation))
- mod_timer(&smi_info->si_timer,
- jiffies + SI_TIMEOUT_JIFFIES);
+ smi_mod_timer(smi_info, jiffies + SI_TIMEOUT_JIFFIES);
}
}
@@ -455,7 +467,7 @@ static inline void enable_si_irq(struct smi_info *smi_info)
{
if ((smi_info->irq) && (smi_info->interrupt_disabled)) {
start_enable_irq(smi_info);
- smi_info->interrupt_disabled = 0;
+ smi_info->interrupt_disabled = false;
}
}
@@ -700,7 +712,7 @@ static void handle_transaction_done(struct smi_info *smi_info)
dev_warn(smi_info->dev,
"Maybe ok, but ipmi might run very slowly.\n");
} else
- smi_info->interrupt_disabled = 0;
+ smi_info->interrupt_disabled = false;
smi_info->si_state = SI_NORMAL;
break;
}
@@ -853,6 +865,19 @@ static enum si_sm_result smi_event_handler(struct smi_info *smi_info,
return si_sm_result;
}
+static void check_start_timer_thread(struct smi_info *smi_info)
+{
+ if (smi_info->si_state == SI_NORMAL && smi_info->curr_msg == NULL) {
+ smi_mod_timer(smi_info, jiffies + SI_TIMEOUT_JIFFIES);
+
+ if (smi_info->thread)
+ wake_up_process(smi_info->thread);
+
+ start_next_msg(smi_info);
+ smi_event_handler(smi_info, 0);
+ }
+}
+
static void sender(void *send_info,
struct ipmi_smi_msg *msg,
int priority)
@@ -906,27 +931,11 @@ static void sender(void *send_info,
else
list_add_tail(&msg->link, &smi_info->xmit_msgs);
- if (smi_info->si_state == SI_NORMAL && smi_info->curr_msg == NULL) {
- /*
- * last_timeout_jiffies is updated here to avoid
- * smi_timeout() handler passing very large time_diff
- * value to smi_event_handler() that causes
- * the send command to abort.
- */
- smi_info->last_timeout_jiffies = jiffies;
-
- mod_timer(&smi_info->si_timer, jiffies + SI_TIMEOUT_JIFFIES);
-
- if (smi_info->thread)
- wake_up_process(smi_info->thread);
-
- start_next_msg(smi_info);
- smi_event_handler(smi_info, 0);
- }
+ check_start_timer_thread(smi_info);
spin_unlock_irqrestore(&smi_info->si_lock, flags);
}
-static void set_run_to_completion(void *send_info, int i_run_to_completion)
+static void set_run_to_completion(void *send_info, bool i_run_to_completion)
{
struct smi_info *smi_info = send_info;
enum si_sm_result result;
@@ -1004,6 +1013,17 @@ static int ipmi_thread(void *data)
spin_lock_irqsave(&(smi_info->si_lock), flags);
smi_result = smi_event_handler(smi_info, 0);
+
+ /*
+ * If the driver is doing something, there is a possible
+ * race with the timer. If the timer handler see idle,
+ * and the thread here sees something else, the timer
+ * handler won't restart the timer even though it is
+ * required. So start it here if necessary.
+ */
+ if (smi_result != SI_SM_IDLE && !smi_info->timer_running)
+ smi_mod_timer(smi_info, jiffies + SI_TIMEOUT_JIFFIES);
+
spin_unlock_irqrestore(&(smi_info->si_lock), flags);
busy_wait = ipmi_thread_busy_wait(smi_result, smi_info,
&busy_until);
@@ -1011,9 +1031,15 @@ static int ipmi_thread(void *data)
; /* do nothing */
else if (smi_result == SI_SM_CALL_WITH_DELAY && busy_wait)
schedule();
- else if (smi_result == SI_SM_IDLE)
- schedule_timeout_interruptible(100);
- else
+ else if (smi_result == SI_SM_IDLE) {
+ if (atomic_read(&smi_info->need_watch)) {
+ schedule_timeout_interruptible(100);
+ } else {
+ /* Wait to be woken up when we are needed. */
+ __set_current_state(TASK_INTERRUPTIBLE);
+ schedule();
+ }
+ } else
schedule_timeout_interruptible(1);
}
return 0;
@@ -1024,7 +1050,7 @@ static void poll(void *send_info)
{
struct smi_info *smi_info = send_info;
unsigned long flags = 0;
- int run_to_completion = smi_info->run_to_completion;
+ bool run_to_completion = smi_info->run_to_completion;
/*
* Make sure there is some delay in the poll loop so we can
@@ -1049,6 +1075,17 @@ static void request_events(void *send_info)
atomic_set(&smi_info->req_events, 1);
}
+static void set_need_watch(void *send_info, bool enable)
+{
+ struct smi_info *smi_info = send_info;
+ unsigned long flags;
+
+ atomic_set(&smi_info->need_watch, enable);
+ spin_lock_irqsave(&smi_info->si_lock, flags);
+ check_start_timer_thread(smi_info);
+ spin_unlock_irqrestore(&smi_info->si_lock, flags);
+}
+
static int initialized;
static void smi_timeout(unsigned long data)
@@ -1073,10 +1110,6 @@ static void smi_timeout(unsigned long data)
* SI_USEC_PER_JIFFY);
smi_result = smi_event_handler(smi_info, time_diff);
- spin_unlock_irqrestore(&(smi_info->si_lock), flags);
-
- smi_info->last_timeout_jiffies = jiffies_now;
-
if ((smi_info->irq) && (!smi_info->interrupt_disabled)) {
/* Running with interrupts, only do long timeouts. */
timeout = jiffies + SI_TIMEOUT_JIFFIES;
@@ -1098,7 +1131,10 @@ static void smi_timeout(unsigned long data)
do_mod_timer:
if (smi_result != SI_SM_IDLE)
- mod_timer(&(smi_info->si_timer), timeout);
+ smi_mod_timer(smi_info, timeout);
+ else
+ smi_info->timer_running = false;
+ spin_unlock_irqrestore(&(smi_info->si_lock), flags);
}
static irqreturn_t si_irq_handler(int irq, void *data)
@@ -1146,8 +1182,7 @@ static int smi_start_processing(void *send_info,
/* Set up the timer that drives the interface. */
setup_timer(&new_smi->si_timer, smi_timeout, (long)new_smi);
- new_smi->last_timeout_jiffies = jiffies;
- mod_timer(&new_smi->si_timer, jiffies + SI_TIMEOUT_JIFFIES);
+ smi_mod_timer(new_smi, jiffies + SI_TIMEOUT_JIFFIES);
/*
* Check if the user forcefully enabled the daemon.
@@ -1188,7 +1223,7 @@ static int get_smi_info(void *send_info, struct ipmi_smi_info *data)
return 0;
}
-static void set_maintenance_mode(void *send_info, int enable)
+static void set_maintenance_mode(void *send_info, bool enable)
{
struct smi_info *smi_info = send_info;
@@ -1202,6 +1237,7 @@ static struct ipmi_smi_handlers handlers = {
.get_smi_info = get_smi_info,
.sender = sender,
.request_events = request_events,
+ .set_need_watch = set_need_watch,
.set_maintenance_mode = set_maintenance_mode,
.set_run_to_completion = set_run_to_completion,
.poll = poll,
@@ -1229,7 +1265,7 @@ static bool si_tryplatform = 1;
#ifdef CONFIG_PCI
static bool si_trypci = 1;
#endif
-static bool si_trydefaults = 1;
+static bool si_trydefaults = IS_ENABLED(CONFIG_IPMI_SI_PROBE_DEFAULTS);
static char *si_type[SI_MAX_PARMS];
#define MAX_SI_TYPE_STR 30
static char si_type_str[MAX_SI_TYPE_STR];
@@ -1328,7 +1364,7 @@ module_param_array(force_kipmid, int, &num_force_kipmid, 0);
MODULE_PARM_DESC(force_kipmid, "Force the kipmi daemon to be enabled (1) or"
" disabled(0). Normally the IPMI driver auto-detects"
" this, but the value may be overridden by this parm.");
-module_param(unload_when_empty, int, 0);
+module_param(unload_when_empty, bool, 0);
MODULE_PARM_DESC(unload_when_empty, "Unload the module if no interfaces are"
" specified or found, default is 1. Setting to 0"
" is useful for hot add of devices using hotmod.");
@@ -3336,18 +3372,19 @@ static int try_smi_init(struct smi_info *new_smi)
INIT_LIST_HEAD(&(new_smi->hp_xmit_msgs));
new_smi->curr_msg = NULL;
atomic_set(&new_smi->req_events, 0);
- new_smi->run_to_completion = 0;
+ new_smi->run_to_completion = false;
for (i = 0; i < SI_NUM_STATS; i++)
atomic_set(&new_smi->stats[i], 0);
- new_smi->interrupt_disabled = 1;
+ new_smi->interrupt_disabled = true;
atomic_set(&new_smi->stop_operation, 0);
+ atomic_set(&new_smi->need_watch, 0);
new_smi->intf_num = smi_num;
smi_num++;
rv = try_enable_event_buffer(new_smi);
if (rv == 0)
- new_smi->has_event_buffer = 1;
+ new_smi->has_event_buffer = true;
/*
* Start clearing the flags before we enable interrupts or the
@@ -3381,7 +3418,7 @@ static int try_smi_init(struct smi_info *new_smi)
rv);
goto out_err;
}
- new_smi->dev_registered = 1;
+ new_smi->dev_registered = true;
}
rv = ipmi_register_smi(&handlers,
@@ -3430,7 +3467,7 @@ static int try_smi_init(struct smi_info *new_smi)
wait_for_timer_and_thread(new_smi);
out_err:
- new_smi->interrupt_disabled = 1;
+ new_smi->interrupt_disabled = true;
if (new_smi->intf) {
ipmi_unregister_smi(new_smi->intf);
@@ -3466,7 +3503,7 @@ static int try_smi_init(struct smi_info *new_smi)
if (new_smi->dev_registered) {
platform_device_unregister(new_smi->pdev);
- new_smi->dev_registered = 0;
+ new_smi->dev_registered = false;
}
return rv;
@@ -3521,14 +3558,14 @@ static int init_ipmi_si(void)
printk(KERN_ERR PFX "Unable to register "
"PCI driver: %d\n", rv);
else
- pci_registered = 1;
+ pci_registered = true;
}
#endif
#ifdef CONFIG_ACPI
if (si_tryacpi) {
pnp_register_driver(&ipmi_pnp_driver);
- pnp_registered = 1;
+ pnp_registered = true;
}
#endif
@@ -3544,7 +3581,7 @@ static int init_ipmi_si(void)
#ifdef CONFIG_PARISC
register_parisc_driver(&ipmi_parisc_driver);
- parisc_registered = 1;
+ parisc_registered = true;
/* poking PC IO addresses will crash machine, don't do it */
si_trydefaults = 0;
#endif
diff --git a/drivers/char/pcmcia/Kconfig b/drivers/char/pcmcia/Kconfig
index b27f534..8d3dfb0 100644
--- a/drivers/char/pcmcia/Kconfig
+++ b/drivers/char/pcmcia/Kconfig
@@ -15,7 +15,7 @@ config SYNCLINK_CS
This driver may be built as a module ( = code which can be
inserted in and removed from the running kernel whenever you want).
- The module will be called synclinkmp. If you want to do that, say M
+ The module will be called synclink_cs. If you want to do that, say M
here.
config CARDMAN_4000
diff --git a/drivers/char/ttyprintk.c b/drivers/char/ttyprintk.c
index daea84c..a15ce4e 100644
--- a/drivers/char/ttyprintk.c
+++ b/drivers/char/ttyprintk.c
@@ -17,7 +17,7 @@
#include <linux/device.h>
#include <linux/serial.h>
#include <linux/tty.h>
-#include <linux/export.h>
+#include <linux/module.h>
struct ttyprintk_port {
struct tty_port port;
@@ -210,10 +210,19 @@ static int __init ttyprintk_init(void)
return 0;
error:
- tty_unregister_driver(ttyprintk_driver);
put_tty_driver(ttyprintk_driver);
tty_port_destroy(&tpk_port.port);
- ttyprintk_driver = NULL;
return ret;
}
+
+static void __exit ttyprintk_exit(void)
+{
+ tty_unregister_driver(ttyprintk_driver);
+ put_tty_driver(ttyprintk_driver);
+ tty_port_destroy(&tpk_port.port);
+}
+
device_initcall(ttyprintk_init);
+module_exit(ttyprintk_exit);
+
+MODULE_LICENSE("GPL");
diff --git a/drivers/gpio/gpio-spear-spics.c b/drivers/gpio/gpio-spear-spics.c
index e9a0415..30bcc53 100644
--- a/drivers/gpio/gpio-spear-spics.c
+++ b/drivers/gpio/gpio-spear-spics.c
@@ -2,7 +2,7 @@
* SPEAr platform SPI chipselect abstraction over gpiolib
*
* Copyright (C) 2012 ST Microelectronics
- * Shiraz Hashim <shiraz.hashim@st.com>
+ * Shiraz Hashim <shiraz.linux.kernel@gmail.com>
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
@@ -205,6 +205,6 @@ static int __init spics_gpio_init(void)
}
subsys_initcall(spics_gpio_init);
-MODULE_AUTHOR("Shiraz Hashim <shiraz.hashim@st.com>");
+MODULE_AUTHOR("Shiraz Hashim <shiraz.linux.kernel@gmail.com>");
MODULE_DESCRIPTION("ST Microlectronics SPEAr SPI Chip Select Abstraction");
MODULE_LICENSE("GPL");
diff --git a/drivers/gpu/drm/Makefile b/drivers/gpu/drm/Makefile
index 9d25dbb..48e38ba 100644
--- a/drivers/gpu/drm/Makefile
+++ b/drivers/gpu/drm/Makefile
@@ -23,7 +23,7 @@ drm-$(CONFIG_DRM_PANEL) += drm_panel.o
drm-usb-y := drm_usb.o
-drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o
+drm_kms_helper-y := drm_crtc_helper.o drm_dp_helper.o drm_probe_helper.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
diff --git a/drivers/gpu/drm/ast/ast_post.c b/drivers/gpu/drm/ast/ast_post.c
index 977cfb3..635f6ff 100644
--- a/drivers/gpu/drm/ast/ast_post.c
+++ b/drivers/gpu/drm/ast/ast_post.c
@@ -572,7 +572,7 @@ static u32 cbr_scan2(struct ast_private *ast)
for (loop = 0; loop < CBR_PASSNUM2; loop++) {
if ((data = cbr_test2(ast)) != 0) {
data2 &= data;
- if (!data)
+ if (!data2)
return 0;
break;
}
diff --git a/drivers/gpu/drm/bochs/bochs.h b/drivers/gpu/drm/bochs/bochs.h
index 741965c..7eb52dd 100644
--- a/drivers/gpu/drm/bochs/bochs.h
+++ b/drivers/gpu/drm/bochs/bochs.h
@@ -1,5 +1,6 @@
#include <linux/io.h>
#include <linux/fb.h>
+#include <linux/console.h>
#include <drm/drmP.h>
#include <drm/drm_crtc.h>
@@ -87,8 +88,6 @@ struct bochs_device {
struct bochs_framebuffer gfb;
struct drm_fb_helper helper;
int size;
- int x1, y1, x2, y2; /* dirty rect */
- spinlock_t dirty_lock;
bool initialized;
} fb;
};
diff --git a/drivers/gpu/drm/bochs/bochs_drv.c b/drivers/gpu/drm/bochs/bochs_drv.c
index 395bba2..9c13df2 100644
--- a/drivers/gpu/drm/bochs/bochs_drv.c
+++ b/drivers/gpu/drm/bochs/bochs_drv.c
@@ -95,6 +95,49 @@ static struct drm_driver bochs_driver = {
};
/* ---------------------------------------------------------------------- */
+/* pm interface */
+
+static int bochs_pm_suspend(struct device *dev)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct drm_device *drm_dev = pci_get_drvdata(pdev);
+ struct bochs_device *bochs = drm_dev->dev_private;
+
+ drm_kms_helper_poll_disable(drm_dev);
+
+ if (bochs->fb.initialized) {
+ console_lock();
+ fb_set_suspend(bochs->fb.helper.fbdev, 1);
+ console_unlock();
+ }
+
+ return 0;
+}
+
+static int bochs_pm_resume(struct device *dev)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct drm_device *drm_dev = pci_get_drvdata(pdev);
+ struct bochs_device *bochs = drm_dev->dev_private;
+
+ drm_helper_resume_force_mode(drm_dev);
+
+ if (bochs->fb.initialized) {
+ console_lock();
+ fb_set_suspend(bochs->fb.helper.fbdev, 0);
+ console_unlock();
+ }
+
+ drm_kms_helper_poll_enable(drm_dev);
+ return 0;
+}
+
+static const struct dev_pm_ops bochs_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(bochs_pm_suspend,
+ bochs_pm_resume)
+};
+
+/* ---------------------------------------------------------------------- */
/* pci interface */
static int bochs_kick_out_firmware_fb(struct pci_dev *pdev)
@@ -155,6 +198,7 @@ static struct pci_driver bochs_pci_driver = {
.id_table = bochs_pci_tbl,
.probe = bochs_pci_probe,
.remove = bochs_pci_remove,
+ .driver.pm = &bochs_pm_ops,
};
/* ---------------------------------------------------------------------- */
diff --git a/drivers/gpu/drm/bochs/bochs_fbdev.c b/drivers/gpu/drm/bochs/bochs_fbdev.c
index 4da5206..561b844 100644
--- a/drivers/gpu/drm/bochs/bochs_fbdev.c
+++ b/drivers/gpu/drm/bochs/bochs_fbdev.c
@@ -190,7 +190,6 @@ int bochs_fbdev_init(struct bochs_device *bochs)
int ret;
bochs->fb.helper.funcs = &bochs_fb_helper_funcs;
- spin_lock_init(&bochs->fb.dirty_lock);
ret = drm_fb_helper_init(bochs->dev, &bochs->fb.helper,
1, 1);
diff --git a/drivers/gpu/drm/cirrus/cirrus_drv.c b/drivers/gpu/drm/cirrus/cirrus_drv.c
index 953fc8a..08ce520 100644
--- a/drivers/gpu/drm/cirrus/cirrus_drv.c
+++ b/drivers/gpu/drm/cirrus/cirrus_drv.c
@@ -11,6 +11,7 @@
#include <linux/module.h>
#include <linux/console.h>
#include <drm/drmP.h>
+#include <drm/drm_crtc_helper.h>
#include "cirrus_drv.h"
@@ -75,6 +76,41 @@ static void cirrus_pci_remove(struct pci_dev *pdev)
drm_put_dev(dev);
}
+static int cirrus_pm_suspend(struct device *dev)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct drm_device *drm_dev = pci_get_drvdata(pdev);
+ struct cirrus_device *cdev = drm_dev->dev_private;
+
+ drm_kms_helper_poll_disable(drm_dev);
+
+ if (cdev->mode_info.gfbdev) {
+ console_lock();
+ fb_set_suspend(cdev->mode_info.gfbdev->helper.fbdev, 1);
+ console_unlock();
+ }
+
+ return 0;
+}
+
+static int cirrus_pm_resume(struct device *dev)
+{
+ struct pci_dev *pdev = to_pci_dev(dev);
+ struct drm_device *drm_dev = pci_get_drvdata(pdev);
+ struct cirrus_device *cdev = drm_dev->dev_private;
+
+ drm_helper_resume_force_mode(drm_dev);
+
+ if (cdev->mode_info.gfbdev) {
+ console_lock();
+ fb_set_suspend(cdev->mode_info.gfbdev->helper.fbdev, 0);
+ console_unlock();
+ }
+
+ drm_kms_helper_poll_enable(drm_dev);
+ return 0;
+}
+
static const struct file_operations cirrus_driver_fops = {
.owner = THIS_MODULE,
.open = drm_open,
@@ -103,11 +139,17 @@ static struct drm_driver driver = {
.dumb_destroy = drm_gem_dumb_destroy,
};
+static const struct dev_pm_ops cirrus_pm_ops = {
+ SET_SYSTEM_SLEEP_PM_OPS(cirrus_pm_suspend,
+ cirrus_pm_resume)
+};
+
static struct pci_driver cirrus_pci_driver = {
.name = DRIVER_NAME,
.id_table = pciidlist,
.probe = cirrus_pci_probe,
.remove = cirrus_pci_remove,
+ .driver.pm = &cirrus_pm_ops,
};
static int __init cirrus_init(void)
diff --git a/drivers/gpu/drm/cirrus/cirrus_mode.c b/drivers/gpu/drm/cirrus/cirrus_mode.c
index 2d64aea..f59433b 100644
--- a/drivers/gpu/drm/cirrus/cirrus_mode.c
+++ b/drivers/gpu/drm/cirrus/cirrus_mode.c
@@ -308,6 +308,9 @@ static int cirrus_crtc_mode_set(struct drm_crtc *crtc,
WREG_HDR(hdr);
cirrus_crtc_do_set_base(crtc, old_fb, x, y, 0);
+
+ /* Unblank (needed on S3 resume, vgabios doesn't do it then) */
+ outb(0x20, 0x3c0);
return 0;
}
diff --git a/drivers/gpu/drm/drm_crtc_helper.c b/drivers/gpu/drm/drm_crtc_helper.c
index c43825e..df281b5 100644
--- a/drivers/gpu/drm/drm_crtc_helper.c
+++ b/drivers/gpu/drm/drm_crtc_helper.c
@@ -72,147 +72,6 @@ void drm_helper_move_panel_connectors_to_head(struct drm_device *dev)
}
EXPORT_SYMBOL(drm_helper_move_panel_connectors_to_head);
-static bool drm_kms_helper_poll = true;
-module_param_named(poll, drm_kms_helper_poll, bool, 0600);
-
-static void drm_mode_validate_flag(struct drm_connector *connector,
- int flags)
-{
- struct drm_display_mode *mode;
-
- if (flags == (DRM_MODE_FLAG_DBLSCAN | DRM_MODE_FLAG_INTERLACE |
- DRM_MODE_FLAG_3D_MASK))
- return;
-
- list_for_each_entry(mode, &connector->modes, head) {
- if ((mode->flags & DRM_MODE_FLAG_INTERLACE) &&
- !(flags & DRM_MODE_FLAG_INTERLACE))
- mode->status = MODE_NO_INTERLACE;
- if ((mode->flags & DRM_MODE_FLAG_DBLSCAN) &&
- !(flags & DRM_MODE_FLAG_DBLSCAN))
- mode->status = MODE_NO_DBLESCAN;
- if ((mode->flags & DRM_MODE_FLAG_3D_MASK) &&
- !(flags & DRM_MODE_FLAG_3D_MASK))
- mode->status = MODE_NO_STEREO;
- }
-
- return;
-}
-
-/**
- * drm_helper_probe_single_connector_modes - get complete set of display modes
- * @connector: connector to probe
- * @maxX: max width for modes
- * @maxY: max height for modes
- *
- * Based on the helper callbacks implemented by @connector try to detect all
- * valid modes. Modes will first be added to the connector's probed_modes list,
- * then culled (based on validity and the @maxX, @maxY parameters) and put into
- * the normal modes list.
- *
- * Intended to be use as a generic implementation of the ->fill_modes()
- * @connector vfunc for drivers that use the crtc helpers for output mode
- * filtering and detection.
- *
- * Returns:
- * The number of modes found on @connector.
- */
-int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
- uint32_t maxX, uint32_t maxY)
-{
- struct drm_device *dev = connector->dev;
- struct drm_display_mode *mode;
- struct drm_connector_helper_funcs *connector_funcs =
- connector->helper_private;
- int count = 0;
- int mode_flags = 0;
- bool verbose_prune = true;
-
- WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
-
- DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id,
- drm_get_connector_name(connector));
- /* set all modes to the unverified state */
- list_for_each_entry(mode, &connector->modes, head)
- mode->status = MODE_UNVERIFIED;
-
- if (connector->force) {
- if (connector->force == DRM_FORCE_ON)
- connector->status = connector_status_connected;
- else
- connector->status = connector_status_disconnected;
- if (connector->funcs->force)
- connector->funcs->force(connector);
- } else {
- connector->status = connector->funcs->detect(connector, true);
- }
-
- /* Re-enable polling in case the global poll config changed. */
- if (drm_kms_helper_poll != dev->mode_config.poll_running)
- drm_kms_helper_poll_enable(dev);
-
- dev->mode_config.poll_running = drm_kms_helper_poll;
-
- if (connector->status == connector_status_disconnected) {
- DRM_DEBUG_KMS("[CONNECTOR:%d:%s] disconnected\n",
- connector->base.id, drm_get_connector_name(connector));
- drm_mode_connector_update_edid_property(connector, NULL);
- verbose_prune = false;
- goto prune;
- }
-
-#ifdef CONFIG_DRM_LOAD_EDID_FIRMWARE
- count = drm_load_edid_firmware(connector);
- if (count == 0)
-#endif
- count = (*connector_funcs->get_modes)(connector);
-
- if (count == 0 && connector->status == connector_status_connected)
- count = drm_add_modes_noedid(connector, 1024, 768);
- if (count == 0)
- goto prune;
-
- drm_mode_connector_list_update(connector);
-
- if (maxX && maxY)
- drm_mode_validate_size(dev, &connector->modes, maxX, maxY);
-
- if (connector->interlace_allowed)
- mode_flags |= DRM_MODE_FLAG_INTERLACE;
- if (connector->doublescan_allowed)
- mode_flags |= DRM_MODE_FLAG_DBLSCAN;
- if (connector->stereo_allowed)
- mode_flags |= DRM_MODE_FLAG_3D_MASK;
- drm_mode_validate_flag(connector, mode_flags);
-
- list_for_each_entry(mode, &connector->modes, head) {
- if (mode->status == MODE_OK)
- mode->status = connector_funcs->mode_valid(connector,
- mode);
- }
-
-prune:
- drm_mode_prune_invalid(dev, &connector->modes, verbose_prune);
-
- if (list_empty(&connector->modes))
- return 0;
-
- list_for_each_entry(mode, &connector->modes, head)
- mode->vrefresh = drm_mode_vrefresh(mode);
-
- drm_mode_sort(&connector->modes);
-
- DRM_DEBUG_KMS("[CONNECTOR:%d:%s] probed modes :\n", connector->base.id,
- drm_get_connector_name(connector));
- list_for_each_entry(mode, &connector->modes, head) {
- drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
- drm_mode_debug_printmodeline(mode);
- }
-
- return count;
-}
-EXPORT_SYMBOL(drm_helper_probe_single_connector_modes);
-
/**
* drm_helper_encoder_in_use - check if a given encoder is in use
* @encoder: encoder to check
@@ -1020,232 +879,3 @@ void drm_helper_resume_force_mode(struct drm_device *dev)
drm_modeset_unlock_all(dev);
}
EXPORT_SYMBOL(drm_helper_resume_force_mode);
-
-/**
- * drm_kms_helper_hotplug_event - fire off KMS hotplug events
- * @dev: drm_device whose connector state changed
- *
- * This function fires off the uevent for userspace and also calls the
- * output_poll_changed function, which is most commonly used to inform the fbdev
- * emulation code and allow it to update the fbcon output configuration.
- *
- * Drivers should call this from their hotplug handling code when a change is
- * detected. Note that this function does not do any output detection of its
- * own, like drm_helper_hpd_irq_event() does - this is assumed to be done by the
- * driver already.
- *
- * This function must be called from process context with no mode
- * setting locks held.
- */
-void drm_kms_helper_hotplug_event(struct drm_device *dev)
-{
- /* send a uevent + call fbdev */
- drm_sysfs_hotplug_event(dev);
- if (dev->mode_config.funcs->output_poll_changed)
- dev->mode_config.funcs->output_poll_changed(dev);
-}
-EXPORT_SYMBOL(drm_kms_helper_hotplug_event);
-
-#define DRM_OUTPUT_POLL_PERIOD (10*HZ)
-static void output_poll_execute(struct work_struct *work)
-{
- struct delayed_work *delayed_work = to_delayed_work(work);
- struct drm_device *dev = container_of(delayed_work, struct drm_device, mode_config.output_poll_work);
- struct drm_connector *connector;
- enum drm_connector_status old_status;
- bool repoll = false, changed = false;
-
- if (!drm_kms_helper_poll)
- return;
-
- mutex_lock(&dev->mode_config.mutex);
- list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
-
- /* Ignore forced connectors. */
- if (connector->force)
- continue;
-
- /* Ignore HPD capable connectors and connectors where we don't
- * want any hotplug detection at all for polling. */
- if (!connector->polled || connector->polled == DRM_CONNECTOR_POLL_HPD)
- continue;
-
- repoll = true;
-
- old_status = connector->status;
- /* if we are connected and don't want to poll for disconnect
- skip it */
- if (old_status == connector_status_connected &&
- !(connector->polled & DRM_CONNECTOR_POLL_DISCONNECT))
- continue;
-
- connector->status = connector->funcs->detect(connector, false);
- if (old_status != connector->status) {
- const char *old, *new;
-
- old = drm_get_connector_status_name(old_status);
- new = drm_get_connector_status_name(connector->status);
-
- DRM_DEBUG_KMS("[CONNECTOR:%d:%s] "
- "status updated from %s to %s\n",
- connector->base.id,
- drm_get_connector_name(connector),
- old, new);
-
- changed = true;
- }
- }
-
- mutex_unlock(&dev->mode_config.mutex);
-
- if (changed)
- drm_kms_helper_hotplug_event(dev);
-
- if (repoll)
- schedule_delayed_work(delayed_work, DRM_OUTPUT_POLL_PERIOD);
-}
-
-/**
- * drm_kms_helper_poll_disable - disable output polling
- * @dev: drm_device
- *
- * This function disables the output polling work.
- *
- * Drivers can call this helper from their device suspend implementation. It is
- * not an error to call this even when output polling isn't enabled or arlready
- * disabled.
- */
-void drm_kms_helper_poll_disable(struct drm_device *dev)
-{
- if (!dev->mode_config.poll_enabled)
- return;
- cancel_delayed_work_sync(&dev->mode_config.output_poll_work);
-}
-EXPORT_SYMBOL(drm_kms_helper_poll_disable);
-
-/**
- * drm_kms_helper_poll_enable - re-enable output polling.
- * @dev: drm_device
- *
- * This function re-enables the output polling work.
- *
- * Drivers can call this helper from their device resume implementation. It is
- * an error to call this when the output polling support has not yet been set
- * up.
- */
-void drm_kms_helper_poll_enable(struct drm_device *dev)
-{
- bool poll = false;
- struct drm_connector *connector;
-
- if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll)
- return;
-
- list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
- if (connector->polled & (DRM_CONNECTOR_POLL_CONNECT |
- DRM_CONNECTOR_POLL_DISCONNECT))
- poll = true;
- }
-
- if (poll)
- schedule_delayed_work(&dev->mode_config.output_poll_work, DRM_OUTPUT_POLL_PERIOD);
-}
-EXPORT_SYMBOL(drm_kms_helper_poll_enable);
-
-/**
- * drm_kms_helper_poll_init - initialize and enable output polling
- * @dev: drm_device
- *
- * This function intializes and then also enables output polling support for
- * @dev. Drivers which do not have reliable hotplug support in hardware can use
- * this helper infrastructure to regularly poll such connectors for changes in
- * their connection state.
- *
- * Drivers can control which connectors are polled by setting the
- * DRM_CONNECTOR_POLL_CONNECT and DRM_CONNECTOR_POLL_DISCONNECT flags. On
- * connectors where probing live outputs can result in visual distortion drivers
- * should not set the DRM_CONNECTOR_POLL_DISCONNECT flag to avoid this.
- * Connectors which have no flag or only DRM_CONNECTOR_POLL_HPD set are
- * completely ignored by the polling logic.
- *
- * Note that a connector can be both polled and probed from the hotplug handler,
- * in case the hotplug interrupt is known to be unreliable.
- */
-void drm_kms_helper_poll_init(struct drm_device *dev)
-{
- INIT_DELAYED_WORK(&dev->mode_config.output_poll_work, output_poll_execute);
- dev->mode_config.poll_enabled = true;
-
- drm_kms_helper_poll_enable(dev);
-}
-EXPORT_SYMBOL(drm_kms_helper_poll_init);
-
-/**
- * drm_kms_helper_poll_fini - disable output polling and clean it up
- * @dev: drm_device
- */
-void drm_kms_helper_poll_fini(struct drm_device *dev)
-{
- drm_kms_helper_poll_disable(dev);
-}
-EXPORT_SYMBOL(drm_kms_helper_poll_fini);
-
-/**
- * drm_helper_hpd_irq_event - hotplug processing
- * @dev: drm_device
- *
- * Drivers can use this helper function to run a detect cycle on all connectors
- * which have the DRM_CONNECTOR_POLL_HPD flag set in their &polled member. All
- * other connectors are ignored, which is useful to avoid reprobing fixed
- * panels.
- *
- * This helper function is useful for drivers which can't or don't track hotplug
- * interrupts for each connector.
- *
- * Drivers which support hotplug interrupts for each connector individually and
- * which have a more fine-grained detect logic should bypass this code and
- * directly call drm_kms_helper_hotplug_event() in case the connector state
- * changed.
- *
- * This function must be called from process context with no mode
- * setting locks held.
- *
- * Note that a connector can be both polled and probed from the hotplug handler,
- * in case the hotplug interrupt is known to be unreliable.
- */
-bool drm_helper_hpd_irq_event(struct drm_device *dev)
-{
- struct drm_connector *connector;
- enum drm_connector_status old_status;
- bool changed = false;
-
- if (!dev->mode_config.poll_enabled)
- return false;
-
- mutex_lock(&dev->mode_config.mutex);
- list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
-
- /* Only handle HPD capable connectors. */
- if (!(connector->polled & DRM_CONNECTOR_POLL_HPD))
- continue;
-
- old_status = connector->status;
-
- connector->status = connector->funcs->detect(connector, false);
- DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %s to %s\n",
- connector->base.id,
- drm_get_connector_name(connector),
- drm_get_connector_status_name(old_status),
- drm_get_connector_status_name(connector->status));
- if (old_status != connector->status)
- changed = true;
- }
-
- mutex_unlock(&dev->mode_config.mutex);
-
- if (changed)
- drm_kms_helper_hotplug_event(dev);
-
- return changed;
-}
-EXPORT_SYMBOL(drm_helper_hpd_irq_event);
diff --git a/drivers/gpu/drm/drm_dp_helper.c b/drivers/gpu/drm/drm_dp_helper.c
index 2767148..4b6e6f3 100644
--- a/drivers/gpu/drm/drm_dp_helper.c
+++ b/drivers/gpu/drm/drm_dp_helper.c
@@ -577,7 +577,9 @@ static u32 drm_dp_i2c_functionality(struct i2c_adapter *adapter)
/*
* Transfer a single I2C-over-AUX message and handle various error conditions,
- * retrying the transaction as appropriate.
+ * retrying the transaction as appropriate. It is assumed that the
+ * aux->transfer function does not modify anything in the msg other than the
+ * reply field.
*/
static int drm_dp_i2c_do_msg(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
{
@@ -665,11 +667,26 @@ static int drm_dp_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs,
{
struct drm_dp_aux *aux = adapter->algo_data;
unsigned int i, j;
+ struct drm_dp_aux_msg msg;
+ int err = 0;
- for (i = 0; i < num; i++) {
- struct drm_dp_aux_msg msg;
- int err;
+ memset(&msg, 0, sizeof(msg));
+ for (i = 0; i < num; i++) {
+ msg.address = msgs[i].addr;
+ msg.request = (msgs[i].flags & I2C_M_RD) ?
+ DP_AUX_I2C_READ :
+ DP_AUX_I2C_WRITE;
+ msg.request |= DP_AUX_I2C_MOT;
+ /* Send a bare address packet to start the transaction.
+ * Zero sized messages specify an address only (bare
+ * address) transaction.
+ */
+ msg.buffer = NULL;
+ msg.size = 0;
+ err = drm_dp_i2c_do_msg(aux, &msg);
+ if (err < 0)
+ break;
/*
* Many hardware implementations support FIFOs larger than a
* single byte, but it has been empirically determined that
@@ -678,30 +695,28 @@ static int drm_dp_i2c_xfer(struct i2c_adapter *adapter, struct i2c_msg *msgs,
* transferred byte-by-byte.
*/
for (j = 0; j < msgs[i].len; j++) {
- memset(&msg, 0, sizeof(msg));
- msg.address = msgs[i].addr;
-
- msg.request = (msgs[i].flags & I2C_M_RD) ?
- DP_AUX_I2C_READ :
- DP_AUX_I2C_WRITE;
-
- /*
- * All messages except the last one are middle-of-
- * transfer messages.
- */
- if ((i < num - 1) || (j < msgs[i].len - 1))
- msg.request |= DP_AUX_I2C_MOT;
-
msg.buffer = msgs[i].buf + j;
msg.size = 1;
err = drm_dp_i2c_do_msg(aux, &msg);
if (err < 0)
- return err;
+ break;
}
+ if (err < 0)
+ break;
}
+ if (err >= 0)
+ err = num;
+ /* Send a bare address packet to close out the transaction.
+ * Zero sized messages specify an address only (bare
+ * address) transaction.
+ */
+ msg.request &= ~DP_AUX_I2C_MOT;
+ msg.buffer = NULL;
+ msg.size = 0;
+ (void)drm_dp_i2c_do_msg(aux, &msg);
- return num;
+ return err;
}
static const struct i2c_algorithm drm_dp_i2c_algo = {
diff --git a/drivers/gpu/drm/drm_mm.c b/drivers/gpu/drm/drm_mm.c
index 71e2d3f..04a209e 100644
--- a/drivers/gpu/drm/drm_mm.c
+++ b/drivers/gpu/drm/drm_mm.c
@@ -207,8 +207,6 @@ int drm_mm_reserve_node(struct drm_mm *mm, struct drm_mm_node *node)
return 0;
}
- WARN(1, "no hole found for node 0x%lx + 0x%lx\n",
- node->start, node->size);
return -ENOSPC;
}
EXPORT_SYMBOL(drm_mm_reserve_node);
diff --git a/drivers/gpu/drm/drm_plane_helper.c b/drivers/gpu/drm/drm_plane_helper.c
index e768d35..d2b1c03 100644
--- a/drivers/gpu/drm/drm_plane_helper.c
+++ b/drivers/gpu/drm/drm_plane_helper.c
@@ -203,9 +203,9 @@ EXPORT_SYMBOL(drm_primary_helper_update);
*
* Provides a default plane disable handler for primary planes. This is handler
* is called in response to a userspace SetPlane operation on the plane with a
- * NULL framebuffer parameter. We call the driver's modeset handler with a NULL
- * framebuffer to disable the CRTC if no other planes are currently enabled.
- * If other planes are still enabled on the same CRTC, we return -EBUSY.
+ * NULL framebuffer parameter. It unconditionally fails the disable call with
+ * -EINVAL the only way to disable the primary plane without driver support is
+ * to disable the entier CRTC. Which does not match the plane ->disable hook.
*
* Note that some hardware may be able to disable the primary plane without
* disabling the whole CRTC. Drivers for such hardware should provide their
@@ -214,34 +214,11 @@ EXPORT_SYMBOL(drm_primary_helper_update);
* disabled primary plane).
*
* RETURNS:
- * Zero on success, error code on failure
+ * Unconditionally returns -EINVAL.
*/
int drm_primary_helper_disable(struct drm_plane *plane)
{
- struct drm_plane *p;
- struct drm_mode_set set = {
- .crtc = plane->crtc,
- .fb = NULL,
- };
-
- if (plane->crtc == NULL || plane->fb == NULL)
- /* Already disabled */
- return 0;
-
- list_for_each_entry(p, &plane->dev->mode_config.plane_list, head)
- if (p != plane && p->fb) {
- DRM_DEBUG_KMS("Cannot disable primary plane while other planes are still active on CRTC.\n");
- return -EBUSY;
- }
-
- /*
- * N.B. We call set_config() directly here rather than
- * drm_mode_set_config_internal() since drm_mode_setplane() already
- * handles the basic refcounting and we don't need the special
- * cross-CRTC refcounting (no chance of stealing connectors from
- * other CRTC's with this update).
- */
- return plane->crtc->funcs->set_config(&set);
+ return -EINVAL;
}
EXPORT_SYMBOL(drm_primary_helper_disable);
diff --git a/drivers/gpu/drm/drm_probe_helper.c b/drivers/gpu/drm/drm_probe_helper.c
new file mode 100644
index 0000000..e70f54d
--- /dev/null
+++ b/drivers/gpu/drm/drm_probe_helper.c
@@ -0,0 +1,426 @@
+/*
+ * Copyright (c) 2006-2008 Intel Corporation
+ * Copyright (c) 2007 Dave Airlie <airlied@linux.ie>
+ *
+ * DRM core CRTC related functions
+ *
+ * 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.
+ *
+ * Authors:
+ * Keith Packard
+ * Eric Anholt <eric@anholt.net>
+ * Dave Airlie <airlied@linux.ie>
+ * Jesse Barnes <jesse.barnes@intel.com>
+ */
+
+#include <linux/export.h>
+#include <linux/moduleparam.h>
+
+#include <drm/drmP.h>
+#include <drm/drm_crtc.h>
+#include <drm/drm_fourcc.h>
+#include <drm/drm_crtc_helper.h>
+#include <drm/drm_fb_helper.h>
+#include <drm/drm_edid.h>
+
+/**
+ * DOC: output probing helper overview
+ *
+ * This library provides some helper code for output probing. It provides an
+ * implementation of the core connector->fill_modes interface with
+ * drm_helper_probe_single_connector_modes.
+ *
+ * It also provides support for polling connectors with a work item and for
+ * generic hotplug interrupt handling where the driver doesn't or cannot keep
+ * track of a per-connector hpd interrupt.
+ *
+ * This helper library can be used independently of the modeset helper library.
+ * Drivers can also overwrite different parts e.g. use their own hotplug
+ * handling code to avoid probing unrelated outputs.
+ */
+
+static bool drm_kms_helper_poll = true;
+module_param_named(poll, drm_kms_helper_poll, bool, 0600);
+
+static void drm_mode_validate_flag(struct drm_connector *connector,
+ int flags)
+{
+ struct drm_display_mode *mode;
+
+ if (flags == (DRM_MODE_FLAG_DBLSCAN | DRM_MODE_FLAG_INTERLACE |
+ DRM_MODE_FLAG_3D_MASK))
+ return;
+
+ list_for_each_entry(mode, &connector->modes, head) {
+ if ((mode->flags & DRM_MODE_FLAG_INTERLACE) &&
+ !(flags & DRM_MODE_FLAG_INTERLACE))
+ mode->status = MODE_NO_INTERLACE;
+ if ((mode->flags & DRM_MODE_FLAG_DBLSCAN) &&
+ !(flags & DRM_MODE_FLAG_DBLSCAN))
+ mode->status = MODE_NO_DBLESCAN;
+ if ((mode->flags & DRM_MODE_FLAG_3D_MASK) &&
+ !(flags & DRM_MODE_FLAG_3D_MASK))
+ mode->status = MODE_NO_STEREO;
+ }
+
+ return;
+}
+
+/**
+ * drm_helper_probe_single_connector_modes - get complete set of display modes
+ * @connector: connector to probe
+ * @maxX: max width for modes
+ * @maxY: max height for modes
+ *
+ * Based on the helper callbacks implemented by @connector try to detect all
+ * valid modes. Modes will first be added to the connector's probed_modes list,
+ * then culled (based on validity and the @maxX, @maxY parameters) and put into
+ * the normal modes list.
+ *
+ * Intended to be use as a generic implementation of the ->fill_modes()
+ * @connector vfunc for drivers that use the crtc helpers for output mode
+ * filtering and detection.
+ *
+ * Returns:
+ * The number of modes found on @connector.
+ */
+int drm_helper_probe_single_connector_modes(struct drm_connector *connector,
+ uint32_t maxX, uint32_t maxY)
+{
+ struct drm_device *dev = connector->dev;
+ struct drm_display_mode *mode;
+ struct drm_connector_helper_funcs *connector_funcs =
+ connector->helper_private;
+ int count = 0;
+ int mode_flags = 0;
+ bool verbose_prune = true;
+
+ WARN_ON(!mutex_is_locked(&dev->mode_config.mutex));
+
+ DRM_DEBUG_KMS("[CONNECTOR:%d:%s]\n", connector->base.id,
+ drm_get_connector_name(connector));
+ /* set all modes to the unverified state */
+ list_for_each_entry(mode, &connector->modes, head)
+ mode->status = MODE_UNVERIFIED;
+
+ if (connector->force) {
+ if (connector->force == DRM_FORCE_ON)
+ connector->status = connector_status_connected;
+ else
+ connector->status = connector_status_disconnected;
+ if (connector->funcs->force)
+ connector->funcs->force(connector);
+ } else {
+ connector->status = connector->funcs->detect(connector, true);
+ }
+
+ /* Re-enable polling in case the global poll config changed. */
+ if (drm_kms_helper_poll != dev->mode_config.poll_running)
+ drm_kms_helper_poll_enable(dev);
+
+ dev->mode_config.poll_running = drm_kms_helper_poll;
+
+ if (connector->status == connector_status_disconnected) {
+ DRM_DEBUG_KMS("[CONNECTOR:%d:%s] disconnected\n",
+ connector->base.id, drm_get_connector_name(connector));
+ drm_mode_connector_update_edid_property(connector, NULL);
+ verbose_prune = false;
+ goto prune;
+ }
+
+#ifdef CONFIG_DRM_LOAD_EDID_FIRMWARE
+ count = drm_load_edid_firmware(connector);
+ if (count == 0)
+#endif
+ count = (*connector_funcs->get_modes)(connector);
+
+ if (count == 0 && connector->status == connector_status_connected)
+ count = drm_add_modes_noedid(connector, 1024, 768);
+ if (count == 0)
+ goto prune;
+
+ drm_mode_connector_list_update(connector);
+
+ if (maxX && maxY)
+ drm_mode_validate_size(dev, &connector->modes, maxX, maxY);
+
+ if (connector->interlace_allowed)
+ mode_flags |= DRM_MODE_FLAG_INTERLACE;
+ if (connector->doublescan_allowed)
+ mode_flags |= DRM_MODE_FLAG_DBLSCAN;
+ if (connector->stereo_allowed)
+ mode_flags |= DRM_MODE_FLAG_3D_MASK;
+ drm_mode_validate_flag(connector, mode_flags);
+
+ list_for_each_entry(mode, &connector->modes, head) {
+ if (mode->status == MODE_OK)
+ mode->status = connector_funcs->mode_valid(connector,
+ mode);
+ }
+
+prune:
+ drm_mode_prune_invalid(dev, &connector->modes, verbose_prune);
+
+ if (list_empty(&connector->modes))
+ return 0;
+
+ list_for_each_entry(mode, &connector->modes, head)
+ mode->vrefresh = drm_mode_vrefresh(mode);
+
+ drm_mode_sort(&connector->modes);
+
+ DRM_DEBUG_KMS("[CONNECTOR:%d:%s] probed modes :\n", connector->base.id,
+ drm_get_connector_name(connector));
+ list_for_each_entry(mode, &connector->modes, head) {
+ drm_mode_set_crtcinfo(mode, CRTC_INTERLACE_HALVE_V);
+ drm_mode_debug_printmodeline(mode);
+ }
+
+ return count;
+}
+EXPORT_SYMBOL(drm_helper_probe_single_connector_modes);
+
+/**
+ * drm_kms_helper_hotplug_event - fire off KMS hotplug events
+ * @dev: drm_device whose connector state changed
+ *
+ * This function fires off the uevent for userspace and also calls the
+ * output_poll_changed function, which is most commonly used to inform the fbdev
+ * emulation code and allow it to update the fbcon output configuration.
+ *
+ * Drivers should call this from their hotplug handling code when a change is
+ * detected. Note that this function does not do any output detection of its
+ * own, like drm_helper_hpd_irq_event() does - this is assumed to be done by the
+ * driver already.
+ *
+ * This function must be called from process context with no mode
+ * setting locks held.
+ */
+void drm_kms_helper_hotplug_event(struct drm_device *dev)
+{
+ /* send a uevent + call fbdev */
+ drm_sysfs_hotplug_event(dev);
+ if (dev->mode_config.funcs->output_poll_changed)
+ dev->mode_config.funcs->output_poll_changed(dev);
+}
+EXPORT_SYMBOL(drm_kms_helper_hotplug_event);
+
+#define DRM_OUTPUT_POLL_PERIOD (10*HZ)
+static void output_poll_execute(struct work_struct *work)
+{
+ struct delayed_work *delayed_work = to_delayed_work(work);
+ struct drm_device *dev = container_of(delayed_work, struct drm_device, mode_config.output_poll_work);
+ struct drm_connector *connector;
+ enum drm_connector_status old_status;
+ bool repoll = false, changed = false;
+
+ if (!drm_kms_helper_poll)
+ return;
+
+ mutex_lock(&dev->mode_config.mutex);
+ list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+
+ /* Ignore forced connectors. */
+ if (connector->force)
+ continue;
+
+ /* Ignore HPD capable connectors and connectors where we don't
+ * want any hotplug detection at all for polling. */
+ if (!connector->polled || connector->polled == DRM_CONNECTOR_POLL_HPD)
+ continue;
+
+ repoll = true;
+
+ old_status = connector->status;
+ /* if we are connected and don't want to poll for disconnect
+ skip it */
+ if (old_status == connector_status_connected &&
+ !(connector->polled & DRM_CONNECTOR_POLL_DISCONNECT))
+ continue;
+
+ connector->status = connector->funcs->detect(connector, false);
+ if (old_status != connector->status) {
+ const char *old, *new;
+
+ old = drm_get_connector_status_name(old_status);
+ new = drm_get_connector_status_name(connector->status);
+
+ DRM_DEBUG_KMS("[CONNECTOR:%d:%s] "
+ "status updated from %s to %s\n",
+ connector->base.id,
+ drm_get_connector_name(connector),
+ old, new);
+
+ changed = true;
+ }
+ }
+
+ mutex_unlock(&dev->mode_config.mutex);
+
+ if (changed)
+ drm_kms_helper_hotplug_event(dev);
+
+ if (repoll)
+ schedule_delayed_work(delayed_work, DRM_OUTPUT_POLL_PERIOD);
+}
+
+/**
+ * drm_kms_helper_poll_disable - disable output polling
+ * @dev: drm_device
+ *
+ * This function disables the output polling work.
+ *
+ * Drivers can call this helper from their device suspend implementation. It is
+ * not an error to call this even when output polling isn't enabled or arlready
+ * disabled.
+ */
+void drm_kms_helper_poll_disable(struct drm_device *dev)
+{
+ if (!dev->mode_config.poll_enabled)
+ return;
+ cancel_delayed_work_sync(&dev->mode_config.output_poll_work);
+}
+EXPORT_SYMBOL(drm_kms_helper_poll_disable);
+
+/**
+ * drm_kms_helper_poll_enable - re-enable output polling.
+ * @dev: drm_device
+ *
+ * This function re-enables the output polling work.
+ *
+ * Drivers can call this helper from their device resume implementation. It is
+ * an error to call this when the output polling support has not yet been set
+ * up.
+ */
+void drm_kms_helper_poll_enable(struct drm_device *dev)
+{
+ bool poll = false;
+ struct drm_connector *connector;
+
+ if (!dev->mode_config.poll_enabled || !drm_kms_helper_poll)
+ return;
+
+ list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+ if (connector->polled & (DRM_CONNECTOR_POLL_CONNECT |
+ DRM_CONNECTOR_POLL_DISCONNECT))
+ poll = true;
+ }
+
+ if (poll)
+ schedule_delayed_work(&dev->mode_config.output_poll_work, DRM_OUTPUT_POLL_PERIOD);
+}
+EXPORT_SYMBOL(drm_kms_helper_poll_enable);
+
+/**
+ * drm_kms_helper_poll_init - initialize and enable output polling
+ * @dev: drm_device
+ *
+ * This function intializes and then also enables output polling support for
+ * @dev. Drivers which do not have reliable hotplug support in hardware can use
+ * this helper infrastructure to regularly poll such connectors for changes in
+ * their connection state.
+ *
+ * Drivers can control which connectors are polled by setting the
+ * DRM_CONNECTOR_POLL_CONNECT and DRM_CONNECTOR_POLL_DISCONNECT flags. On
+ * connectors where probing live outputs can result in visual distortion drivers
+ * should not set the DRM_CONNECTOR_POLL_DISCONNECT flag to avoid this.
+ * Connectors which have no flag or only DRM_CONNECTOR_POLL_HPD set are
+ * completely ignored by the polling logic.
+ *
+ * Note that a connector can be both polled and probed from the hotplug handler,
+ * in case the hotplug interrupt is known to be unreliable.
+ */
+void drm_kms_helper_poll_init(struct drm_device *dev)
+{
+ INIT_DELAYED_WORK(&dev->mode_config.output_poll_work, output_poll_execute);
+ dev->mode_config.poll_enabled = true;
+
+ drm_kms_helper_poll_enable(dev);
+}
+EXPORT_SYMBOL(drm_kms_helper_poll_init);
+
+/**
+ * drm_kms_helper_poll_fini - disable output polling and clean it up
+ * @dev: drm_device
+ */
+void drm_kms_helper_poll_fini(struct drm_device *dev)
+{
+ drm_kms_helper_poll_disable(dev);
+}
+EXPORT_SYMBOL(drm_kms_helper_poll_fini);
+
+/**
+ * drm_helper_hpd_irq_event - hotplug processing
+ * @dev: drm_device
+ *
+ * Drivers can use this helper function to run a detect cycle on all connectors
+ * which have the DRM_CONNECTOR_POLL_HPD flag set in their &polled member. All
+ * other connectors are ignored, which is useful to avoid reprobing fixed
+ * panels.
+ *
+ * This helper function is useful for drivers which can't or don't track hotplug
+ * interrupts for each connector.
+ *
+ * Drivers which support hotplug interrupts for each connector individually and
+ * which have a more fine-grained detect logic should bypass this code and
+ * directly call drm_kms_helper_hotplug_event() in case the connector state
+ * changed.
+ *
+ * This function must be called from process context with no mode
+ * setting locks held.
+ *
+ * Note that a connector can be both polled and probed from the hotplug handler,
+ * in case the hotplug interrupt is known to be unreliable.
+ */
+bool drm_helper_hpd_irq_event(struct drm_device *dev)
+{
+ struct drm_connector *connector;
+ enum drm_connector_status old_status;
+ bool changed = false;
+
+ if (!dev->mode_config.poll_enabled)
+ return false;
+
+ mutex_lock(&dev->mode_config.mutex);
+ list_for_each_entry(connector, &dev->mode_config.connector_list, head) {
+
+ /* Only handle HPD capable connectors. */
+ if (!(connector->polled & DRM_CONNECTOR_POLL_HPD))
+ continue;
+
+ old_status = connector->status;
+
+ connector->status = connector->funcs->detect(connector, false);
+ DRM_DEBUG_KMS("[CONNECTOR:%d:%s] status updated from %s to %s\n",
+ connector->base.id,
+ drm_get_connector_name(connector),
+ drm_get_connector_status_name(old_status),
+ drm_get_connector_status_name(connector->status));
+ if (old_status != connector->status)
+ changed = true;
+ }
+
+ mutex_unlock(&dev->mode_config.mutex);
+
+ if (changed)
+ drm_kms_helper_hotplug_event(dev);
+
+ return changed;
+}
+EXPORT_SYMBOL(drm_helper_hpd_irq_event);
diff --git a/drivers/gpu/drm/i915/i915_drv.h b/drivers/gpu/drm/i915/i915_drv.h
index 0905cd9..ec82f6b 100644
--- a/drivers/gpu/drm/i915/i915_drv.h
+++ b/drivers/gpu/drm/i915/i915_drv.h
@@ -1308,6 +1308,7 @@ struct intel_vbt_data {
struct {
u16 pwm_freq_hz;
+ bool present;
bool active_low_pwm;
} backlight;
@@ -2431,20 +2432,18 @@ int i915_gem_context_open(struct drm_device *dev, struct drm_file *file);
int i915_gem_context_enable(struct drm_i915_private *dev_priv);
void i915_gem_context_close(struct drm_device *dev, struct drm_file *file);
int i915_switch_context(struct intel_ring_buffer *ring,
- struct drm_file *file, struct i915_hw_context *to);
+ struct i915_hw_context *to);
struct i915_hw_context *
i915_gem_context_get(struct drm_i915_file_private *file_priv, u32 id);
void i915_gem_context_free(struct kref *ctx_ref);
static inline void i915_gem_context_reference(struct i915_hw_context *ctx)
{
- if (ctx->obj && HAS_HW_CONTEXTS(ctx->obj->base.dev))
- kref_get(&ctx->ref);
+ kref_get(&ctx->ref);
}
static inline void i915_gem_context_unreference(struct i915_hw_context *ctx)
{
- if (ctx->obj && HAS_HW_CONTEXTS(ctx->obj->base.dev))
- kref_put(&ctx->ref, i915_gem_context_free);
+ kref_put(&ctx->ref, i915_gem_context_free);
}
static inline bool i915_gem_context_is_default(const struct i915_hw_context *c)
diff --git a/drivers/gpu/drm/i915/i915_gem.c b/drivers/gpu/drm/i915/i915_gem.c
index 6370a76..2871ce7 100644
--- a/drivers/gpu/drm/i915/i915_gem.c
+++ b/drivers/gpu/drm/i915/i915_gem.c
@@ -2790,7 +2790,7 @@ int i915_gpu_idle(struct drm_device *dev)
/* Flush everything onto the inactive list. */
for_each_ring(ring, dev_priv, i) {
- ret = i915_switch_context(ring, NULL, ring->default_context);
+ ret = i915_switch_context(ring, ring->default_context);
if (ret)
return ret;
diff --git a/drivers/gpu/drm/i915/i915_gem_context.c b/drivers/gpu/drm/i915/i915_gem_context.c
index 6043062..d72db15 100644
--- a/drivers/gpu/drm/i915/i915_gem_context.c
+++ b/drivers/gpu/drm/i915/i915_gem_context.c
@@ -96,9 +96,6 @@
#define GEN6_CONTEXT_ALIGN (64<<10)
#define GEN7_CONTEXT_ALIGN 4096
-static int do_switch(struct intel_ring_buffer *ring,
- struct i915_hw_context *to);
-
static void do_ppgtt_cleanup(struct i915_hw_ppgtt *ppgtt)
{
struct drm_device *dev = ppgtt->base.dev;
@@ -185,13 +182,15 @@ void i915_gem_context_free(struct kref *ctx_ref)
typeof(*ctx), ref);
struct i915_hw_ppgtt *ppgtt = NULL;
- /* We refcount even the aliasing PPGTT to keep the code symmetric */
- if (USES_PPGTT(ctx->obj->base.dev))
- ppgtt = ctx_to_ppgtt(ctx);
+ if (ctx->obj) {
+ /* We refcount even the aliasing PPGTT to keep the code symmetric */
+ if (USES_PPGTT(ctx->obj->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);
+ /* 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);
@@ -232,32 +231,32 @@ __create_hw_context(struct drm_device *dev,
return ERR_PTR(-ENOMEM);
kref_init(&ctx->ref);
- ctx->obj = i915_gem_alloc_object(dev, dev_priv->hw_context_size);
- INIT_LIST_HEAD(&ctx->link);
- if (ctx->obj == NULL) {
- kfree(ctx);
- DRM_DEBUG_DRIVER("Context object allocated failed\n");
- return ERR_PTR(-ENOMEM);
- }
+ list_add_tail(&ctx->link, &dev_priv->context_list);
- if (INTEL_INFO(dev)->gen >= 7) {
- ret = i915_gem_object_set_cache_level(ctx->obj,
- I915_CACHE_L3_LLC);
- /* Failure shouldn't ever happen this early */
- if (WARN_ON(ret))
+ if (dev_priv->hw_context_size) {
+ ctx->obj = i915_gem_alloc_object(dev, dev_priv->hw_context_size);
+ if (ctx->obj == NULL) {
+ ret = -ENOMEM;
goto err_out;
- }
+ }
- list_add_tail(&ctx->link, &dev_priv->context_list);
+ if (INTEL_INFO(dev)->gen >= 7) {
+ 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;
+ }
+ }
/* Default context will never have a file_priv */
- if (file_priv == NULL)
- return ctx;
-
- ret = idr_alloc(&file_priv->context_idr, ctx, DEFAULT_CONTEXT_ID, 0,
- GFP_KERNEL);
- if (ret < 0)
- goto err_out;
+ if (file_priv != NULL) {
+ ret = idr_alloc(&file_priv->context_idr, ctx,
+ DEFAULT_CONTEXT_ID, 0, GFP_KERNEL);
+ if (ret < 0)
+ goto err_out;
+ } else
+ ret = DEFAULT_CONTEXT_ID;
ctx->file_priv = file_priv;
ctx->id = ret;
@@ -294,7 +293,7 @@ i915_gem_create_context(struct drm_device *dev,
if (IS_ERR(ctx))
return ctx;
- if (is_global_default_ctx) {
+ if (is_global_default_ctx && ctx->obj) {
/* 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
@@ -342,7 +341,7 @@ i915_gem_create_context(struct drm_device *dev,
return ctx;
err_unpin:
- if (is_global_default_ctx)
+ if (is_global_default_ctx && ctx->obj)
i915_gem_object_ggtt_unpin(ctx->obj);
err_destroy:
i915_gem_context_unreference(ctx);
@@ -352,32 +351,22 @@ err_destroy:
void i915_gem_context_reset(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_ring_buffer *ring;
int i;
- if (!HAS_HW_CONTEXTS(dev))
- return;
-
/* Prevent the hardware from restoring the last context (which hung) on
* the next switch */
for (i = 0; i < I915_NUM_RINGS; i++) {
- struct i915_hw_context *dctx;
- if (!(INTEL_INFO(dev)->ring_mask & (1<<i)))
- continue;
+ struct intel_ring_buffer *ring = &dev_priv->ring[i];
+ struct i915_hw_context *dctx = ring->default_context;
/* Do a fake switch to the default context */
- ring = &dev_priv->ring[i];
- dctx = ring->default_context;
- if (WARN_ON(!dctx))
+ if (ring->last_context == dctx)
continue;
if (!ring->last_context)
continue;
- if (ring->last_context == dctx)
- continue;
-
- if (i == RCS) {
+ if (dctx->obj && i == RCS) {
WARN_ON(i915_gem_obj_ggtt_pin(dctx->obj,
get_context_alignment(dev), 0));
/* Fake a finish/inactive */
@@ -394,44 +383,35 @@ void i915_gem_context_reset(struct drm_device *dev)
int i915_gem_context_init(struct drm_device *dev)
{
struct drm_i915_private *dev_priv = dev->dev_private;
- struct intel_ring_buffer *ring;
+ struct i915_hw_context *ctx;
int i;
- if (!HAS_HW_CONTEXTS(dev))
- return 0;
-
/* Init should only be called once per module load. Eventually the
* restriction on the context_disabled check can be loosened. */
if (WARN_ON(dev_priv->ring[RCS].default_context))
return 0;
- dev_priv->hw_context_size = round_up(get_context_size(dev), 4096);
-
- if (dev_priv->hw_context_size > (1<<20)) {
- DRM_DEBUG_DRIVER("Disabling HW Contexts; invalid size\n");
- return -E2BIG;
+ if (HAS_HW_CONTEXTS(dev)) {
+ dev_priv->hw_context_size = round_up(get_context_size(dev), 4096);
+ if (dev_priv->hw_context_size > (1<<20)) {
+ DRM_DEBUG_DRIVER("Disabling HW Contexts; invalid size %d\n",
+ dev_priv->hw_context_size);
+ dev_priv->hw_context_size = 0;
+ }
}
- dev_priv->ring[RCS].default_context =
- i915_gem_create_context(dev, NULL, USES_PPGTT(dev));
-
- if (IS_ERR_OR_NULL(dev_priv->ring[RCS].default_context)) {
- DRM_DEBUG_DRIVER("Disabling HW Contexts; create failed %ld\n",
- PTR_ERR(dev_priv->ring[RCS].default_context));
- return PTR_ERR(dev_priv->ring[RCS].default_context);
+ ctx = i915_gem_create_context(dev, NULL, USES_PPGTT(dev));
+ if (IS_ERR(ctx)) {
+ DRM_ERROR("Failed to create default global context (error %ld)\n",
+ PTR_ERR(ctx));
+ return PTR_ERR(ctx);
}
- for (i = RCS + 1; i < I915_NUM_RINGS; i++) {
- if (!(INTEL_INFO(dev)->ring_mask & (1<<i)))
- continue;
-
- ring = &dev_priv->ring[i];
+ /* NB: RCS will hold a ref for all rings */
+ for (i = 0; i < I915_NUM_RINGS; i++)
+ dev_priv->ring[i].default_context = ctx;
- /* NB: RCS will hold a ref for all rings */
- ring->default_context = dev_priv->ring[RCS].default_context;
- }
-
- DRM_DEBUG_DRIVER("HW context support initialized\n");
+ DRM_DEBUG_DRIVER("%s context support initialized\n", dev_priv->hw_context_size ? "HW" : "fake");
return 0;
}
@@ -441,33 +421,30 @@ void i915_gem_context_fini(struct drm_device *dev)
struct i915_hw_context *dctx = dev_priv->ring[RCS].default_context;
int i;
- if (!HAS_HW_CONTEXTS(dev))
- return;
-
- /* 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. */
- intel_gpu_reset(dev);
-
- /* When default context is created and switched to, base object refcount
- * will be 2 (+1 from object creation and +1 from do_switch()).
- * i915_gem_context_fini() will be called after gpu_idle() has switched
- * to default context. So we need to unreference the base object once
- * to offset the do_switch part, so that i915_gem_context_unreference()
- * can then free the base object correctly. */
- 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);
- i915_gem_context_unreference(dctx);
- dev_priv->ring[RCS].last_context = NULL;
+ if (dctx->obj) {
+ /* 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. */
+ intel_gpu_reset(dev);
+
+ /* When default context is created and switched to, base object refcount
+ * will be 2 (+1 from object creation and +1 from do_switch()).
+ * i915_gem_context_fini() will be called after gpu_idle() has switched
+ * to default context. So we need to unreference the base object once
+ * to offset the do_switch part, so that i915_gem_context_unreference()
+ * can then free the base object correctly. */
+ 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);
+ i915_gem_context_unreference(dctx);
+ dev_priv->ring[RCS].last_context = NULL;
+ }
}
for (i = 0; i < I915_NUM_RINGS; i++) {
struct intel_ring_buffer *ring = &dev_priv->ring[i];
- if (!(INTEL_INFO(dev)->ring_mask & (1<<i)))
- continue;
if (ring->last_context)
i915_gem_context_unreference(ring->last_context);
@@ -478,7 +455,6 @@ void i915_gem_context_fini(struct drm_device *dev)
i915_gem_object_ggtt_unpin(dctx->obj);
i915_gem_context_unreference(dctx);
- dev_priv->mm.aliasing_ppgtt = NULL;
}
int i915_gem_context_enable(struct drm_i915_private *dev_priv)
@@ -486,9 +462,6 @@ int i915_gem_context_enable(struct drm_i915_private *dev_priv)
struct intel_ring_buffer *ring;
int ret, i;
- if (!HAS_HW_CONTEXTS(dev_priv->dev))
- return 0;
-
/* This is the only place the aliasing PPGTT gets enabled, which means
* it has to happen before we bail on reset */
if (dev_priv->mm.aliasing_ppgtt) {
@@ -503,7 +476,7 @@ int i915_gem_context_enable(struct drm_i915_private *dev_priv)
BUG_ON(!dev_priv->ring[RCS].default_context);
for_each_ring(ring, dev_priv, i) {
- ret = do_switch(ring, ring->default_context);
+ ret = i915_switch_context(ring, ring->default_context);
if (ret)
return ret;
}
@@ -526,19 +499,6 @@ static int context_idr_cleanup(int id, void *p, void *data)
int i915_gem_context_open(struct drm_device *dev, struct drm_file *file)
{
struct drm_i915_file_private *file_priv = file->driver_priv;
- struct drm_i915_private *dev_priv = dev->dev_private;
-
- if (!HAS_HW_CONTEXTS(dev)) {
- /* Cheat for hang stats */
- file_priv->private_default_ctx =
- kzalloc(sizeof(struct i915_hw_context), GFP_KERNEL);
-
- if (file_priv->private_default_ctx == NULL)
- return -ENOMEM;
-
- file_priv->private_default_ctx->vm = &dev_priv->gtt.base;
- return 0;
- }
idr_init(&file_priv->context_idr);
@@ -559,14 +519,10 @@ void i915_gem_context_close(struct drm_device *dev, struct drm_file *file)
{
struct drm_i915_file_private *file_priv = file->driver_priv;
- if (!HAS_HW_CONTEXTS(dev)) {
- kfree(file_priv->private_default_ctx);
- return;
- }
-
idr_for_each(&file_priv->context_idr, context_idr_cleanup, NULL);
- i915_gem_context_unreference(file_priv->private_default_ctx);
idr_destroy(&file_priv->context_idr);
+
+ i915_gem_context_unreference(file_priv->private_default_ctx);
}
struct i915_hw_context *
@@ -574,9 +530,6 @@ i915_gem_context_get(struct drm_i915_file_private *file_priv, u32 id)
{
struct i915_hw_context *ctx;
- if (!HAS_HW_CONTEXTS(file_priv->dev_priv->dev))
- return file_priv->private_default_ctx;
-
ctx = (struct i915_hw_context *)idr_find(&file_priv->context_idr, id);
if (!ctx)
return ERR_PTR(-ENOENT);
@@ -758,7 +711,6 @@ unpin_out:
/**
* i915_switch_context() - perform a GPU context switch.
* @ring: ring for which we'll execute the context switch
- * @file_priv: file_priv associated with the context, may be NULL
* @to: the context to switch to
*
* The context life cycle is simple. The context refcount is incremented and
@@ -767,24 +719,30 @@ unpin_out:
* object while letting the normal object tracking destroy the backing BO.
*/
int i915_switch_context(struct intel_ring_buffer *ring,
- struct drm_file *file,
struct i915_hw_context *to)
{
struct drm_i915_private *dev_priv = ring->dev->dev_private;
WARN_ON(!mutex_is_locked(&dev_priv->dev->struct_mutex));
- BUG_ON(file && to == NULL);
-
- /* We have the fake context */
- if (!HAS_HW_CONTEXTS(ring->dev)) {
- ring->last_context = to;
+ if (to->obj == NULL) { /* We have the fake context */
+ if (to != ring->last_context) {
+ i915_gem_context_reference(to);
+ if (ring->last_context)
+ i915_gem_context_unreference(ring->last_context);
+ ring->last_context = to;
+ }
return 0;
}
return do_switch(ring, to);
}
+static bool hw_context_enabled(struct drm_device *dev)
+{
+ return to_i915(dev)->hw_context_size;
+}
+
int i915_gem_context_create_ioctl(struct drm_device *dev, void *data,
struct drm_file *file)
{
@@ -793,7 +751,7 @@ int i915_gem_context_create_ioctl(struct drm_device *dev, void *data,
struct i915_hw_context *ctx;
int ret;
- if (!HAS_HW_CONTEXTS(dev))
+ if (!hw_context_enabled(dev))
return -ENODEV;
ret = i915_mutex_lock_interruptible(dev);
diff --git a/drivers/gpu/drm/i915/i915_gem_execbuffer.c b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
index 7447160..2c9d9cb 100644
--- a/drivers/gpu/drm/i915/i915_gem_execbuffer.c
+++ b/drivers/gpu/drm/i915/i915_gem_execbuffer.c
@@ -1221,7 +1221,7 @@ i915_gem_do_execbuffer(struct drm_device *dev, void *data,
if (ret)
goto err;
- ret = i915_switch_context(ring, file, ctx);
+ ret = i915_switch_context(ring, ctx);
if (ret)
goto err;
diff --git a/drivers/gpu/drm/i915/intel_bios.c b/drivers/gpu/drm/i915/intel_bios.c
index 4867f4c..fa486c5 100644
--- a/drivers/gpu/drm/i915/intel_bios.c
+++ b/drivers/gpu/drm/i915/intel_bios.c
@@ -287,6 +287,9 @@ parse_lfp_backlight(struct drm_i915_private *dev_priv, struct bdb_header *bdb)
const struct bdb_lfp_backlight_data *backlight_data;
const struct bdb_lfp_backlight_data_entry *entry;
+ /* Err to enabling backlight if no backlight block. */
+ dev_priv->vbt.backlight.present = true;
+
backlight_data = find_section(bdb, BDB_LVDS_BACKLIGHT);
if (!backlight_data)
return;
@@ -299,6 +302,13 @@ parse_lfp_backlight(struct drm_i915_private *dev_priv, struct bdb_header *bdb)
entry = &backlight_data->data[panel_type];
+ dev_priv->vbt.backlight.present = entry->type == BDB_BACKLIGHT_TYPE_PWM;
+ if (!dev_priv->vbt.backlight.present) {
+ DRM_DEBUG_KMS("PWM backlight not present in VBT (type %u)\n",
+ entry->type);
+ return;
+ }
+
dev_priv->vbt.backlight.pwm_freq_hz = entry->pwm_freq_hz;
dev_priv->vbt.backlight.active_low_pwm = entry->active_low_pwm;
DRM_DEBUG_KMS("VBT backlight PWM modulation frequency %u Hz, "
diff --git a/drivers/gpu/drm/i915/intel_bios.h b/drivers/gpu/drm/i915/intel_bios.h
index 83b7629..f27f7b2 100644
--- a/drivers/gpu/drm/i915/intel_bios.h
+++ b/drivers/gpu/drm/i915/intel_bios.h
@@ -374,6 +374,9 @@ struct bdb_lvds_lfp_data {
struct bdb_lvds_lfp_data_entry data[16];
} __packed;
+#define BDB_BACKLIGHT_TYPE_NONE 0
+#define BDB_BACKLIGHT_TYPE_PWM 2
+
struct bdb_lfp_backlight_data_entry {
u8 type:2;
u8 active_low_pwm:1;
diff --git a/drivers/gpu/drm/i915/intel_dp.c b/drivers/gpu/drm/i915/intel_dp.c
index a0dad1a..d2a5588 100644
--- a/drivers/gpu/drm/i915/intel_dp.c
+++ b/drivers/gpu/drm/i915/intel_dp.c
@@ -575,7 +575,8 @@ out:
return ret;
}
-#define HEADER_SIZE 4
+#define BARE_ADDRESS_SIZE 3
+#define HEADER_SIZE (BARE_ADDRESS_SIZE + 1)
static ssize_t
intel_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
{
@@ -592,7 +593,7 @@ intel_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
switch (msg->request & ~DP_AUX_I2C_MOT) {
case DP_AUX_NATIVE_WRITE:
case DP_AUX_I2C_WRITE:
- txsize = HEADER_SIZE + msg->size;
+ txsize = msg->size ? HEADER_SIZE + msg->size : BARE_ADDRESS_SIZE;
rxsize = 1;
if (WARN_ON(txsize > 20))
@@ -611,7 +612,7 @@ intel_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
case DP_AUX_NATIVE_READ:
case DP_AUX_I2C_READ:
- txsize = HEADER_SIZE;
+ txsize = msg->size ? HEADER_SIZE : BARE_ADDRESS_SIZE;
rxsize = msg->size + 1;
if (WARN_ON(rxsize > 20))
diff --git a/drivers/gpu/drm/i915/intel_panel.c b/drivers/gpu/drm/i915/intel_panel.c
index cb05840..0eead16 100644
--- a/drivers/gpu/drm/i915/intel_panel.c
+++ b/drivers/gpu/drm/i915/intel_panel.c
@@ -1065,6 +1065,11 @@ int intel_panel_setup_backlight(struct drm_connector *connector)
unsigned long flags;
int ret;
+ if (!dev_priv->vbt.backlight.present) {
+ DRM_DEBUG_KMS("native backlight control not available per VBT\n");
+ return 0;
+ }
+
/* set level and max in panel struct */
spin_lock_irqsave(&dev_priv->backlight_lock, flags);
ret = dev_priv->display.setup_backlight(intel_connector);
diff --git a/drivers/gpu/drm/i915/intel_pm.c b/drivers/gpu/drm/i915/intel_pm.c
index 5874716..19e94c3 100644
--- a/drivers/gpu/drm/i915/intel_pm.c
+++ b/drivers/gpu/drm/i915/intel_pm.c
@@ -1545,6 +1545,16 @@ 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;
+
+ fb = to_intel_framebuffer(enabled->primary->fb);
+
+ /* self-refresh seems busted with untiled */
+ if (fb->obj->tiling_mode == I915_TILING_NONE)
+ enabled = NULL;
+ }
+
/*
* Overlay gets an aggressive default since video jitter is bad.
*/
diff --git a/drivers/gpu/drm/nouveau/core/subdev/bios/base.c b/drivers/gpu/drm/nouveau/core/subdev/bios/base.c
index e9df94f..fb0b6b2 100644
--- a/drivers/gpu/drm/nouveau/core/subdev/bios/base.c
+++ b/drivers/gpu/drm/nouveau/core/subdev/bios/base.c
@@ -109,7 +109,7 @@ nouveau_bios_shadow_pramin(struct nouveau_bios *bios)
return;
}
- addr = (u64)(addr >> 8) << 8;
+ addr = (addr & 0xffffff00) << 8;
if (!addr) {
addr = (u64)nv_rd32(bios, 0x001700) << 16;
addr += 0xf0000;
diff --git a/drivers/gpu/drm/omapdrm/omap_crtc.c b/drivers/gpu/drm/omapdrm/omap_crtc.c
index 355157e..e3c47a8 100644
--- a/drivers/gpu/drm/omapdrm/omap_crtc.c
+++ b/drivers/gpu/drm/omapdrm/omap_crtc.c
@@ -33,6 +33,7 @@ struct omap_crtc {
int pipe;
enum omap_channel channel;
struct omap_overlay_manager_info info;
+ struct drm_encoder *current_encoder;
/*
* Temporary: eventually this will go away, but it is needed
@@ -120,13 +121,25 @@ static void omap_crtc_start_update(struct omap_overlay_manager *mgr)
{
}
+static void set_enabled(struct drm_crtc *crtc, bool enable);
+
static int omap_crtc_enable(struct omap_overlay_manager *mgr)
{
+ struct omap_crtc *omap_crtc = omap_crtcs[mgr->id];
+
+ dispc_mgr_setup(omap_crtc->channel, &omap_crtc->info);
+ dispc_mgr_set_timings(omap_crtc->channel,
+ &omap_crtc->timings);
+ set_enabled(&omap_crtc->base, true);
+
return 0;
}
static void omap_crtc_disable(struct omap_overlay_manager *mgr)
{
+ struct omap_crtc *omap_crtc = omap_crtcs[mgr->id];
+
+ set_enabled(&omap_crtc->base, false);
}
static void omap_crtc_set_timings(struct omap_overlay_manager *mgr,
@@ -184,7 +197,6 @@ static void omap_crtc_destroy(struct drm_crtc *crtc)
WARN_ON(omap_crtc->apply_irq.registered);
omap_irq_unregister(crtc->dev, &omap_crtc->error_irq);
- omap_crtc->plane->funcs->destroy(omap_crtc->plane);
drm_crtc_cleanup(crtc);
kfree(omap_crtc);
@@ -338,17 +350,23 @@ static int omap_crtc_page_flip_locked(struct drm_crtc *crtc,
struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
struct drm_plane *primary = crtc->primary;
struct drm_gem_object *bo;
+ unsigned long flags;
DBG("%d -> %d (event=%p)", primary->fb ? primary->fb->base.id : -1,
fb->base.id, event);
+ spin_lock_irqsave(&dev->event_lock, flags);
+
if (omap_crtc->old_fb) {
+ spin_unlock_irqrestore(&dev->event_lock, flags);
dev_err(dev->dev, "already a pending flip\n");
return -EINVAL;
}
omap_crtc->event = event;
- primary->fb = fb;
+ omap_crtc->old_fb = primary->fb = fb;
+
+ spin_unlock_irqrestore(&dev->event_lock, flags);
/*
* Hold a reference temporarily until the crtc is updated
@@ -528,38 +546,46 @@ static void set_enabled(struct drm_crtc *crtc, bool enable)
struct drm_device *dev = crtc->dev;
struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
enum omap_channel channel = omap_crtc->channel;
- struct omap_irq_wait *wait = NULL;
+ struct omap_irq_wait *wait;
+ u32 framedone_irq, vsync_irq;
+ int ret;
if (dispc_mgr_is_enabled(channel) == enable)
return;
- /* ignore sync-lost irqs during enable/disable */
+ /*
+ * Digit output produces some sync lost interrupts during the first
+ * frame when enabling, so we need to ignore those.
+ */
omap_irq_unregister(crtc->dev, &omap_crtc->error_irq);
- if (dispc_mgr_get_framedone_irq(channel)) {
- if (!enable) {
- wait = omap_irq_wait_init(dev,
- dispc_mgr_get_framedone_irq(channel), 1);
- }
+ framedone_irq = dispc_mgr_get_framedone_irq(channel);
+ vsync_irq = dispc_mgr_get_vsync_irq(channel);
+
+ if (enable) {
+ wait = omap_irq_wait_init(dev, vsync_irq, 1);
} else {
/*
- * When we disable digit output, we need to wait until fields
- * are done. Otherwise the DSS is still working, and turning
- * off the clocks prevents DSS from going to OFF mode. And when
- * enabling, we need to wait for the extra sync losts
+ * When we disable the digit output, we need to wait for
+ * FRAMEDONE to know that DISPC has finished with the output.
+ *
+ * OMAP2/3 does not have FRAMEDONE irq for digit output, and in
+ * that case we need to use vsync interrupt, and wait for both
+ * even and odd frames.
*/
- wait = omap_irq_wait_init(dev,
- dispc_mgr_get_vsync_irq(channel), 2);
+
+ if (framedone_irq)
+ wait = omap_irq_wait_init(dev, framedone_irq, 1);
+ else
+ wait = omap_irq_wait_init(dev, vsync_irq, 2);
}
dispc_mgr_enable(channel, enable);
- if (wait) {
- int ret = omap_irq_wait(dev, wait, msecs_to_jiffies(100));
- if (ret) {
- dev_err(dev->dev, "%s: timeout waiting for %s\n",
- omap_crtc->name, enable ? "enable" : "disable");
- }
+ ret = omap_irq_wait(dev, wait, msecs_to_jiffies(100));
+ if (ret) {
+ dev_err(dev->dev, "%s: timeout waiting for %s\n",
+ omap_crtc->name, enable ? "enable" : "disable");
}
omap_irq_register(crtc->dev, &omap_crtc->error_irq);
@@ -586,8 +612,12 @@ static void omap_crtc_pre_apply(struct omap_drm_apply *apply)
}
}
+ if (omap_crtc->current_encoder && encoder != omap_crtc->current_encoder)
+ omap_encoder_set_enabled(omap_crtc->current_encoder, false);
+
+ omap_crtc->current_encoder = encoder;
+
if (!omap_crtc->enabled) {
- set_enabled(&omap_crtc->base, false);
if (encoder)
omap_encoder_set_enabled(encoder, false);
} else {
@@ -596,13 +626,7 @@ static void omap_crtc_pre_apply(struct omap_drm_apply *apply)
omap_encoder_update(encoder, omap_crtc->mgr,
&omap_crtc->timings);
omap_encoder_set_enabled(encoder, true);
- omap_crtc->full_update = false;
}
-
- dispc_mgr_setup(omap_crtc->channel, &omap_crtc->info);
- dispc_mgr_set_timings(omap_crtc->channel,
- &omap_crtc->timings);
- set_enabled(&omap_crtc->base, true);
}
omap_crtc->full_update = false;
@@ -613,10 +637,30 @@ static void omap_crtc_post_apply(struct omap_drm_apply *apply)
/* nothing needed for post-apply */
}
+void omap_crtc_flush(struct drm_crtc *crtc)
+{
+ struct omap_crtc *omap_crtc = to_omap_crtc(crtc);
+ int loops = 0;
+
+ while (!list_empty(&omap_crtc->pending_applies) ||
+ !list_empty(&omap_crtc->queued_applies) ||
+ omap_crtc->event || omap_crtc->old_fb) {
+
+ if (++loops > 10) {
+ dev_err(crtc->dev->dev,
+ "omap_crtc_flush() timeout\n");
+ break;
+ }
+
+ schedule_timeout_uninterruptible(msecs_to_jiffies(20));
+ }
+}
+
static const char *channel_names[] = {
[OMAP_DSS_CHANNEL_LCD] = "lcd",
[OMAP_DSS_CHANNEL_DIGIT] = "tv",
[OMAP_DSS_CHANNEL_LCD2] = "lcd2",
+ [OMAP_DSS_CHANNEL_LCD3] = "lcd3",
};
void omap_crtc_pre_init(void)
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.c b/drivers/gpu/drm/omapdrm/omap_drv.c
index bf39fcc..c8270e4 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.c
+++ b/drivers/gpu/drm/omapdrm/omap_drv.c
@@ -513,12 +513,18 @@ static int dev_load(struct drm_device *dev, unsigned long flags)
static int dev_unload(struct drm_device *dev)
{
struct omap_drm_private *priv = dev->dev_private;
+ int i;
DBG("unload: dev=%p", dev);
drm_kms_helper_poll_fini(dev);
omap_fbdev_free(dev);
+
+ /* flush crtcs so the fbs get released */
+ for (i = 0; i < priv->num_crtcs; i++)
+ omap_crtc_flush(priv->crtcs[i]);
+
omap_modeset_free(dev);
omap_gem_deinit(dev);
@@ -696,10 +702,11 @@ static int pdev_remove(struct platform_device *device)
{
DBG("");
+ drm_put_dev(platform_get_drvdata(device));
+
omap_disconnect_dssdevs();
omap_crtc_pre_uninit();
- drm_put_dev(platform_get_drvdata(device));
return 0;
}
@@ -726,18 +733,33 @@ static struct platform_driver pdev = {
static int __init omap_drm_init(void)
{
+ int r;
+
DBG("init");
- if (platform_driver_register(&omap_dmm_driver)) {
- /* we can continue on without DMM.. so not fatal */
- dev_err(NULL, "DMM registration failed\n");
+
+ r = platform_driver_register(&omap_dmm_driver);
+ if (r) {
+ pr_err("DMM driver registration failed\n");
+ return r;
+ }
+
+ r = platform_driver_register(&pdev);
+ if (r) {
+ pr_err("omapdrm driver registration failed\n");
+ platform_driver_unregister(&omap_dmm_driver);
+ return r;
}
- return platform_driver_register(&pdev);
+
+ return 0;
}
static void __exit omap_drm_fini(void)
{
DBG("fini");
+
platform_driver_unregister(&pdev);
+
+ platform_driver_unregister(&omap_dmm_driver);
}
/* need late_initcall() so we load after dss_driver's are loaded */
diff --git a/drivers/gpu/drm/omapdrm/omap_drv.h b/drivers/gpu/drm/omapdrm/omap_drv.h
index 428b2981..284b80f 100644
--- a/drivers/gpu/drm/omapdrm/omap_drv.h
+++ b/drivers/gpu/drm/omapdrm/omap_drv.h
@@ -163,6 +163,7 @@ void omap_crtc_pre_init(void);
void omap_crtc_pre_uninit(void);
struct drm_crtc *omap_crtc_init(struct drm_device *dev,
struct drm_plane *plane, enum omap_channel channel, int id);
+void omap_crtc_flush(struct drm_crtc *crtc);
struct drm_plane *omap_plane_init(struct drm_device *dev,
int plane_id, bool private_plane);
diff --git a/drivers/gpu/drm/omapdrm/omap_fb.c b/drivers/gpu/drm/omapdrm/omap_fb.c
index d2b8c49..8b01960 100644
--- a/drivers/gpu/drm/omapdrm/omap_fb.c
+++ b/drivers/gpu/drm/omapdrm/omap_fb.c
@@ -218,6 +218,20 @@ void omap_framebuffer_update_scanout(struct drm_framebuffer *fb,
info->rotation_type = OMAP_DSS_ROT_TILER;
info->screen_width = omap_gem_tiled_stride(plane->bo, orient);
} else {
+ switch (win->rotation & 0xf) {
+ case 0:
+ case BIT(DRM_ROTATE_0):
+ /* OK */
+ break;
+
+ default:
+ dev_warn(fb->dev->dev,
+ "rotation '%d' ignored for non-tiled fb\n",
+ win->rotation);
+ win->rotation = 0;
+ break;
+ }
+
info->paddr = get_linear_addr(plane, format, 0, x, y);
info->rotation_type = OMAP_DSS_ROT_DMA;
info->screen_width = plane->pitch;
diff --git a/drivers/gpu/drm/omapdrm/omap_fbdev.c b/drivers/gpu/drm/omapdrm/omap_fbdev.c
index 002988d..1388ca7 100644
--- a/drivers/gpu/drm/omapdrm/omap_fbdev.c
+++ b/drivers/gpu/drm/omapdrm/omap_fbdev.c
@@ -371,6 +371,9 @@ void omap_fbdev_free(struct drm_device *dev)
fbdev = to_omap_fbdev(priv->fbdev);
+ /* release the ref taken in omap_fbdev_create() */
+ omap_gem_put_paddr(fbdev->bo);
+
/* this will free the backing object */
if (fbdev->fb) {
drm_framebuffer_unregister_private(fbdev->fb);
diff --git a/drivers/gpu/drm/omapdrm/omap_gem.c b/drivers/gpu/drm/omapdrm/omap_gem.c
index c8d9727..95dbce2 100644
--- a/drivers/gpu/drm/omapdrm/omap_gem.c
+++ b/drivers/gpu/drm/omapdrm/omap_gem.c
@@ -980,12 +980,9 @@ int omap_gem_resume(struct device *dev)
#ifdef CONFIG_DEBUG_FS
void omap_gem_describe(struct drm_gem_object *obj, struct seq_file *m)
{
- struct drm_device *dev = obj->dev;
struct omap_gem_object *omap_obj = to_omap_bo(obj);
uint64_t off;
- WARN_ON(!mutex_is_locked(&dev->struct_mutex));
-
off = drm_vma_node_start(&obj->vma_node);
seq_printf(m, "%08x: %2d (%2d) %08llx %08Zx (%2d) %p %4d",
@@ -1050,10 +1047,10 @@ static inline bool is_waiting(struct omap_gem_sync_waiter *waiter)
{
struct omap_gem_object *omap_obj = waiter->omap_obj;
if ((waiter->op & OMAP_GEM_READ) &&
- (omap_obj->sync->read_complete < waiter->read_target))
+ (omap_obj->sync->write_complete < waiter->write_target))
return true;
if ((waiter->op & OMAP_GEM_WRITE) &&
- (omap_obj->sync->write_complete < waiter->write_target))
+ (omap_obj->sync->read_complete < waiter->read_target))
return true;
return false;
}
@@ -1229,6 +1226,8 @@ int omap_gem_op_async(struct drm_gem_object *obj, enum omap_gem_op op,
}
spin_unlock(&sync_lock);
+
+ kfree(waiter);
}
/* no waiting.. */
diff --git a/drivers/gpu/drm/omapdrm/omap_plane.c b/drivers/gpu/drm/omapdrm/omap_plane.c
index 046d5e6..3cf31ee 100644
--- a/drivers/gpu/drm/omapdrm/omap_plane.c
+++ b/drivers/gpu/drm/omapdrm/omap_plane.c
@@ -225,6 +225,11 @@ int omap_plane_mode_set(struct drm_plane *plane,
omap_plane->apply_done_cb.arg = arg;
}
+ if (plane->fb)
+ drm_framebuffer_unreference(plane->fb);
+
+ drm_framebuffer_reference(fb);
+
plane->fb = fb;
plane->crtc = crtc;
@@ -241,10 +246,13 @@ static int omap_plane_update(struct drm_plane *plane,
struct omap_plane *omap_plane = to_omap_plane(plane);
omap_plane->enabled = true;
- if (plane->fb)
- drm_framebuffer_unreference(plane->fb);
-
- drm_framebuffer_reference(fb);
+ /* omap_plane_mode_set() takes adjusted src */
+ switch (omap_plane->win.rotation & 0xf) {
+ case BIT(DRM_ROTATE_90):
+ case BIT(DRM_ROTATE_270):
+ swap(src_w, src_h);
+ break;
+ }
return omap_plane_mode_set(plane, crtc, fb,
crtc_x, crtc_y, crtc_w, crtc_h,
diff --git a/drivers/gpu/drm/radeon/atombios_dp.c b/drivers/gpu/drm/radeon/atombios_dp.c
index 8b0ab17..1593652 100644
--- a/drivers/gpu/drm/radeon/atombios_dp.c
+++ b/drivers/gpu/drm/radeon/atombios_dp.c
@@ -142,7 +142,8 @@ static int radeon_process_aux_ch(struct radeon_i2c_chan *chan,
return recv_bytes;
}
-#define HEADER_SIZE 4
+#define BARE_ADDRESS_SIZE 3
+#define HEADER_SIZE (BARE_ADDRESS_SIZE + 1)
static ssize_t
radeon_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
@@ -160,13 +161,19 @@ radeon_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
tx_buf[0] = msg->address & 0xff;
tx_buf[1] = msg->address >> 8;
tx_buf[2] = msg->request << 4;
- tx_buf[3] = msg->size - 1;
+ tx_buf[3] = msg->size ? (msg->size - 1) : 0;
switch (msg->request & ~DP_AUX_I2C_MOT) {
case DP_AUX_NATIVE_WRITE:
case DP_AUX_I2C_WRITE:
+ /* tx_size needs to be 4 even for bare address packets since the atom
+ * table needs the info in tx_buf[3].
+ */
tx_size = HEADER_SIZE + msg->size;
- tx_buf[3] |= tx_size << 4;
+ if (msg->size == 0)
+ tx_buf[3] |= BARE_ADDRESS_SIZE << 4;
+ else
+ tx_buf[3] |= tx_size << 4;
memcpy(tx_buf + HEADER_SIZE, msg->buffer, msg->size);
ret = radeon_process_aux_ch(chan,
tx_buf, tx_size, NULL, 0, delay, &ack);
@@ -176,8 +183,14 @@ radeon_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
break;
case DP_AUX_NATIVE_READ:
case DP_AUX_I2C_READ:
+ /* tx_size needs to be 4 even for bare address packets since the atom
+ * table needs the info in tx_buf[3].
+ */
tx_size = HEADER_SIZE;
- tx_buf[3] |= tx_size << 4;
+ if (msg->size == 0)
+ tx_buf[3] |= BARE_ADDRESS_SIZE << 4;
+ else
+ tx_buf[3] |= tx_size << 4;
ret = radeon_process_aux_ch(chan,
tx_buf, tx_size, msg->buffer, msg->size, delay, &ack);
break;
@@ -186,7 +199,7 @@ radeon_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
break;
}
- if (ret > 0)
+ if (ret >= 0)
msg->reply = ack >> 4;
return ret;
@@ -194,98 +207,15 @@ radeon_dp_aux_transfer(struct drm_dp_aux *aux, struct drm_dp_aux_msg *msg)
void radeon_dp_aux_init(struct radeon_connector *radeon_connector)
{
- struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
-
- dig_connector->dp_i2c_bus->aux.dev = radeon_connector->base.kdev;
- dig_connector->dp_i2c_bus->aux.transfer = radeon_dp_aux_transfer;
-}
-
-int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
- u8 write_byte, u8 *read_byte)
-{
- struct i2c_algo_dp_aux_data *algo_data = adapter->algo_data;
- struct radeon_i2c_chan *auxch = i2c_get_adapdata(adapter);
- u16 address = algo_data->address;
- u8 msg[5];
- u8 reply[2];
- unsigned retry;
- int msg_bytes;
- int reply_bytes = 1;
int ret;
- u8 ack;
-
- /* Set up the address */
- msg[0] = address;
- msg[1] = address >> 8;
-
- /* Set up the command byte */
- if (mode & MODE_I2C_READ) {
- msg[2] = DP_AUX_I2C_READ << 4;
- msg_bytes = 4;
- msg[3] = msg_bytes << 4;
- } else {
- msg[2] = DP_AUX_I2C_WRITE << 4;
- msg_bytes = 5;
- msg[3] = msg_bytes << 4;
- msg[4] = write_byte;
- }
-
- /* special handling for start/stop */
- if (mode & (MODE_I2C_START | MODE_I2C_STOP))
- msg[3] = 3 << 4;
-
- /* Set MOT bit for all but stop */
- if ((mode & MODE_I2C_STOP) == 0)
- msg[2] |= DP_AUX_I2C_MOT << 4;
-
- for (retry = 0; retry < 7; retry++) {
- ret = radeon_process_aux_ch(auxch,
- msg, msg_bytes, reply, reply_bytes, 0, &ack);
- if (ret == -EBUSY)
- continue;
- else if (ret < 0) {
- DRM_DEBUG_KMS("aux_ch failed %d\n", ret);
- return ret;
- }
-
- switch ((ack >> 4) & DP_AUX_NATIVE_REPLY_MASK) {
- case DP_AUX_NATIVE_REPLY_ACK:
- /* I2C-over-AUX Reply field is only valid
- * when paired with AUX ACK.
- */
- break;
- case DP_AUX_NATIVE_REPLY_NACK:
- DRM_DEBUG_KMS("aux_ch native nack\n");
- return -EREMOTEIO;
- case DP_AUX_NATIVE_REPLY_DEFER:
- DRM_DEBUG_KMS("aux_ch native defer\n");
- usleep_range(500, 600);
- continue;
- default:
- DRM_ERROR("aux_ch invalid native reply 0x%02x\n", ack);
- return -EREMOTEIO;
- }
- switch ((ack >> 4) & DP_AUX_I2C_REPLY_MASK) {
- case DP_AUX_I2C_REPLY_ACK:
- if (mode == MODE_I2C_READ)
- *read_byte = reply[0];
- return ret;
- case DP_AUX_I2C_REPLY_NACK:
- DRM_DEBUG_KMS("aux_i2c nack\n");
- return -EREMOTEIO;
- case DP_AUX_I2C_REPLY_DEFER:
- DRM_DEBUG_KMS("aux_i2c defer\n");
- usleep_range(400, 500);
- break;
- default:
- DRM_ERROR("aux_i2c invalid reply 0x%02x\n", ack);
- return -EREMOTEIO;
- }
- }
+ radeon_connector->ddc_bus->aux.dev = radeon_connector->base.kdev;
+ radeon_connector->ddc_bus->aux.transfer = radeon_dp_aux_transfer;
+ ret = drm_dp_aux_register_i2c_bus(&radeon_connector->ddc_bus->aux);
+ if (!ret)
+ radeon_connector->ddc_bus->has_aux = true;
- DRM_DEBUG_KMS("aux i2c too many retries, giving up\n");
- return -EREMOTEIO;
+ WARN(ret, "drm_dp_aux_register_i2c_bus() failed with error %d\n", ret);
}
/***** general DP utility functions *****/
@@ -420,12 +350,11 @@ static u8 radeon_dp_encoder_service(struct radeon_device *rdev,
u8 radeon_dp_getsinktype(struct radeon_connector *radeon_connector)
{
- struct radeon_connector_atom_dig *dig_connector = radeon_connector->con_priv;
struct drm_device *dev = radeon_connector->base.dev;
struct radeon_device *rdev = dev->dev_private;
return radeon_dp_encoder_service(rdev, ATOM_DP_ACTION_GET_SINK_TYPE, 0,
- dig_connector->dp_i2c_bus->rec.i2c_id, 0);
+ radeon_connector->ddc_bus->rec.i2c_id, 0);
}
static void radeon_dp_probe_oui(struct radeon_connector *radeon_connector)
@@ -436,11 +365,11 @@ static void radeon_dp_probe_oui(struct radeon_connector *radeon_connector)
if (!(dig_connector->dpcd[DP_DOWN_STREAM_PORT_COUNT] & DP_OUI_SUPPORT))
return;
- if (drm_dp_dpcd_read(&dig_connector->dp_i2c_bus->aux, DP_SINK_OUI, buf, 3))
+ if (drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_SINK_OUI, buf, 3))
DRM_DEBUG_KMS("Sink OUI: %02hx%02hx%02hx\n",
buf[0], buf[1], buf[2]);
- if (drm_dp_dpcd_read(&dig_connector->dp_i2c_bus->aux, DP_BRANCH_OUI, buf, 3))
+ if (drm_dp_dpcd_read(&radeon_connector->ddc_bus->aux, DP_BRANCH_OUI, buf, 3))
DRM_DEBUG_KMS("Branch OUI: %02hx%02hx%02hx\n",
buf[0], buf[1], buf[2]);
}
@@ -451,7 +380,7 @@ bool radeon_dp_getdpcd(struct radeon_connector *radeon_connector)
u8 msg[DP_DPCD_SIZE];
int ret, i;
- ret = drm_dp_dpcd_read(&dig_connector->dp_i2c_bus->aux, DP_DPCD_REV, msg,
+ 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);
@@ -489,7 +418,7 @@ int radeon_dp_get_panel_mode(struct drm_encoder *encoder,
if (dp_bridge != ENCODER_OBJECT_ID_NONE) {
/* DP bridge chips */
- drm_dp_dpcd_readb(&dig_connector->dp_i2c_bus->aux,
+ drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux,
DP_EDP_CONFIGURATION_CAP, &tmp);
if (tmp & 1)
panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE;
@@ -500,7 +429,7 @@ int radeon_dp_get_panel_mode(struct drm_encoder *encoder,
panel_mode = DP_PANEL_MODE_EXTERNAL_DP_MODE;
} else if (connector->connector_type == DRM_MODE_CONNECTOR_eDP) {
/* eDP */
- drm_dp_dpcd_readb(&dig_connector->dp_i2c_bus->aux,
+ drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux,
DP_EDP_CONFIGURATION_CAP, &tmp);
if (tmp & 1)
panel_mode = DP_PANEL_MODE_INTERNAL_DP2_MODE;
@@ -554,7 +483,8 @@ bool radeon_dp_needs_link_train(struct radeon_connector *radeon_connector)
u8 link_status[DP_LINK_STATUS_SIZE];
struct radeon_connector_atom_dig *dig = radeon_connector->con_priv;
- if (drm_dp_dpcd_read_link_status(&dig->dp_i2c_bus->aux, link_status) <= 0)
+ if (drm_dp_dpcd_read_link_status(&radeon_connector->ddc_bus->aux, link_status)
+ <= 0)
return false;
if (drm_dp_channel_eq_ok(link_status, dig->dp_lane_count))
return false;
@@ -574,7 +504,7 @@ void radeon_dp_set_rx_power_state(struct drm_connector *connector,
/* power up/down the sink */
if (dig_connector->dpcd[0] >= 0x11) {
- drm_dp_dpcd_writeb(&dig_connector->dp_i2c_bus->aux,
+ drm_dp_dpcd_writeb(&radeon_connector->ddc_bus->aux,
DP_SET_POWER, power_state);
usleep_range(1000, 2000);
}
@@ -878,7 +808,7 @@ void radeon_dp_link_train(struct drm_encoder *encoder,
else
dp_info.enc_id |= ATOM_DP_CONFIG_LINK_A;
- drm_dp_dpcd_readb(&dig_connector->dp_i2c_bus->aux, DP_MAX_LANE_COUNT, &tmp);
+ drm_dp_dpcd_readb(&radeon_connector->ddc_bus->aux, DP_MAX_LANE_COUNT, &tmp);
if (ASIC_IS_DCE5(rdev) && (tmp & DP_TPS3_SUPPORTED))
dp_info.tp3_supported = true;
else
@@ -890,7 +820,7 @@ void radeon_dp_link_train(struct drm_encoder *encoder,
dp_info.connector = connector;
dp_info.dp_lane_count = dig_connector->dp_lane_count;
dp_info.dp_clock = dig_connector->dp_clock;
- dp_info.aux = &dig_connector->dp_i2c_bus->aux;
+ dp_info.aux = &radeon_connector->ddc_bus->aux;
if (radeon_dp_link_train_init(&dp_info))
goto done;
diff --git a/drivers/gpu/drm/radeon/ci_dpm.c b/drivers/gpu/drm/radeon/ci_dpm.c
index cad89a9..10dae41 100644
--- a/drivers/gpu/drm/radeon/ci_dpm.c
+++ b/drivers/gpu/drm/radeon/ci_dpm.c
@@ -21,8 +21,10 @@
*
*/
+#include <linux/firmware.h>
#include "drmP.h"
#include "radeon.h"
+#include "radeon_ucode.h"
#include "cikd.h"
#include "r600_dpm.h"
#include "ci_dpm.h"
@@ -202,24 +204,29 @@ static void ci_initialize_powertune_defaults(struct radeon_device *rdev)
struct ci_power_info *pi = ci_get_pi(rdev);
switch (rdev->pdev->device) {
+ case 0x6649:
case 0x6650:
+ case 0x6651:
case 0x6658:
case 0x665C:
+ case 0x665D:
default:
pi->powertune_defaults = &defaults_bonaire_xt;
break;
- case 0x6651:
- case 0x665D:
- pi->powertune_defaults = &defaults_bonaire_pro;
- break;
case 0x6640:
- pi->powertune_defaults = &defaults_saturn_xt;
- break;
case 0x6641:
- pi->powertune_defaults = &defaults_saturn_pro;
+ case 0x6646:
+ case 0x6647:
+ pi->powertune_defaults = &defaults_saturn_xt;
break;
case 0x67B8:
case 0x67B0:
+ pi->powertune_defaults = &defaults_hawaii_xt;
+ break;
+ case 0x67BA:
+ case 0x67B1:
+ pi->powertune_defaults = &defaults_hawaii_pro;
+ break;
case 0x67A0:
case 0x67A1:
case 0x67A2:
@@ -228,11 +235,7 @@ static void ci_initialize_powertune_defaults(struct radeon_device *rdev)
case 0x67AA:
case 0x67B9:
case 0x67BE:
- pi->powertune_defaults = &defaults_hawaii_xt;
- break;
- case 0x67BA:
- case 0x67B1:
- pi->powertune_defaults = &defaults_hawaii_pro;
+ pi->powertune_defaults = &defaults_bonaire_xt;
break;
}
@@ -5146,6 +5149,12 @@ int ci_dpm_init(struct radeon_device *rdev)
pi->mclk_dpm_key_disabled = 0;
pi->pcie_dpm_key_disabled = 0;
+ /* mclk dpm is unstable on some R7 260X cards with the old mc ucode */
+ if ((rdev->pdev->device == 0x6658) &&
+ (rdev->mc_fw->size == (BONAIRE_MC_UCODE_SIZE * 4))) {
+ pi->mclk_dpm_key_disabled = 1;
+ }
+
pi->caps_sclk_ds = true;
pi->mclk_strobe_mode_threshold = 40000;
diff --git a/drivers/gpu/drm/radeon/cik.c b/drivers/gpu/drm/radeon/cik.c
index 745143c..199eb19 100644
--- a/drivers/gpu/drm/radeon/cik.c
+++ b/drivers/gpu/drm/radeon/cik.c
@@ -38,6 +38,7 @@ 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_mc2.bin");
MODULE_FIRMWARE("radeon/BONAIRE_rlc.bin");
MODULE_FIRMWARE("radeon/BONAIRE_sdma.bin");
MODULE_FIRMWARE("radeon/BONAIRE_smc.bin");
@@ -46,6 +47,7 @@ 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_mc2.bin");
MODULE_FIRMWARE("radeon/HAWAII_rlc.bin");
MODULE_FIRMWARE("radeon/HAWAII_sdma.bin");
MODULE_FIRMWARE("radeon/HAWAII_smc.bin");
@@ -1703,20 +1705,20 @@ int ci_mc_load_microcode(struct radeon_device *rdev)
const __be32 *fw_data;
u32 running, blackout = 0;
u32 *io_mc_regs;
- int i, ucode_size, regs_size;
+ int i, regs_size, ucode_size;
if (!rdev->mc_fw)
return -EINVAL;
+ ucode_size = rdev->mc_fw->size / 4;
+
switch (rdev->family) {
case CHIP_BONAIRE:
io_mc_regs = (u32 *)&bonaire_io_mc_regs;
- ucode_size = CIK_MC_UCODE_SIZE;
regs_size = BONAIRE_IO_MC_REGS_SIZE;
break;
case CHIP_HAWAII:
io_mc_regs = (u32 *)&hawaii_io_mc_regs;
- ucode_size = HAWAII_MC_UCODE_SIZE;
regs_size = HAWAII_IO_MC_REGS_SIZE;
break;
default:
@@ -1783,7 +1785,7 @@ static int cik_init_microcode(struct radeon_device *rdev)
const char *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;
+ sdma_req_size, smc_req_size = 0, mc2_req_size = 0;
char fw_name[30];
int err;
@@ -1797,7 +1799,8 @@ static int cik_init_microcode(struct radeon_device *rdev)
ce_req_size = CIK_CE_UCODE_SIZE * 4;
mec_req_size = CIK_MEC_UCODE_SIZE * 4;
rlc_req_size = BONAIRE_RLC_UCODE_SIZE * 4;
- mc_req_size = CIK_MC_UCODE_SIZE * 4;
+ mc_req_size = BONAIRE_MC_UCODE_SIZE * 4;
+ 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);
break;
@@ -1809,6 +1812,7 @@ static int cik_init_microcode(struct radeon_device *rdev)
mec_req_size = CIK_MEC_UCODE_SIZE * 4;
rlc_req_size = BONAIRE_RLC_UCODE_SIZE * 4;
mc_req_size = HAWAII_MC_UCODE_SIZE * 4;
+ 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);
break;
@@ -1904,16 +1908,22 @@ static int cik_init_microcode(struct radeon_device *rdev)
/* No SMC, MC ucode on APUs */
if (!(rdev->flags & RADEON_IS_IGP)) {
- 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)
- goto out;
- if (rdev->mc_fw->size != mc_req_size) {
+ 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);
snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", chip_name);
err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev);
diff --git a/drivers/gpu/drm/radeon/dce6_afmt.c b/drivers/gpu/drm/radeon/dce6_afmt.c
index 94e8587..0a65dc7 100644
--- a/drivers/gpu/drm/radeon/dce6_afmt.c
+++ b/drivers/gpu/drm/radeon/dce6_afmt.c
@@ -309,11 +309,17 @@ int dce6_audio_init(struct radeon_device *rdev)
rdev->audio.enabled = true;
- if (ASIC_IS_DCE8(rdev))
+ if (ASIC_IS_DCE81(rdev)) /* KV: 4 streams, 7 endpoints */
+ rdev->audio.num_pins = 7;
+ else if (ASIC_IS_DCE83(rdev)) /* KB: 2 streams, 3 endpoints */
+ rdev->audio.num_pins = 3;
+ else if (ASIC_IS_DCE8(rdev)) /* BN/HW: 6 streams, 7 endpoints */
+ rdev->audio.num_pins = 7;
+ else if (ASIC_IS_DCE61(rdev)) /* TN: 4 streams, 6 endpoints */
rdev->audio.num_pins = 6;
- else if (ASIC_IS_DCE61(rdev))
- rdev->audio.num_pins = 4;
- else
+ else if (ASIC_IS_DCE64(rdev)) /* OL: 2 streams, 2 endpoints */
+ rdev->audio.num_pins = 2;
+ else /* SI: 6 streams, 6 endpoints */
rdev->audio.num_pins = 6;
for (i = 0; i < rdev->audio.num_pins; i++) {
diff --git a/drivers/gpu/drm/radeon/radeon.h b/drivers/gpu/drm/radeon/radeon.h
index f21db7a..b58e1af 100644
--- a/drivers/gpu/drm/radeon/radeon.h
+++ b/drivers/gpu/drm/radeon/radeon.h
@@ -739,7 +739,7 @@ union radeon_irq_stat_regs {
struct cik_irq_stat_regs cik;
};
-#define RADEON_MAX_HPD_PINS 6
+#define RADEON_MAX_HPD_PINS 7
#define RADEON_MAX_CRTCS 6
#define RADEON_MAX_AFMT_BLOCKS 7
@@ -2321,6 +2321,7 @@ struct radeon_device {
bool have_disp_power_ref;
};
+bool radeon_is_px(struct drm_device *dev);
int radeon_device_init(struct radeon_device *rdev,
struct drm_device *ddev,
struct pci_dev *pdev,
@@ -2631,6 +2632,9 @@ void r100_pll_errata_after_index(struct radeon_device *rdev);
#define ASIC_IS_DCE64(rdev) ((rdev->family == CHIP_OLAND))
#define ASIC_IS_NODCE(rdev) ((rdev->family == CHIP_HAINAN))
#define ASIC_IS_DCE8(rdev) ((rdev->family >= CHIP_BONAIRE))
+#define ASIC_IS_DCE81(rdev) ((rdev->family == CHIP_KAVERI))
+#define ASIC_IS_DCE82(rdev) ((rdev->family == CHIP_BONAIRE))
+#define ASIC_IS_DCE83(rdev) ((rdev->family == CHIP_KABINI))
#define ASIC_IS_LOMBOK(rdev) ((rdev->ddev->pdev->device == 0x6849) || \
(rdev->ddev->pdev->device == 0x6850) || \
diff --git a/drivers/gpu/drm/radeon/radeon_atpx_handler.c b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
index fa9a9c0..dedea72 100644
--- a/drivers/gpu/drm/radeon/radeon_atpx_handler.c
+++ b/drivers/gpu/drm/radeon/radeon_atpx_handler.c
@@ -59,7 +59,7 @@ struct atpx_mux {
u16 mux;
} __packed;
-bool radeon_is_px(void) {
+bool radeon_has_atpx(void) {
return radeon_atpx_priv.atpx_detected;
}
diff --git a/drivers/gpu/drm/radeon/radeon_connectors.c b/drivers/gpu/drm/radeon/radeon_connectors.c
index c566b48..ea50e0a 100644
--- a/drivers/gpu/drm/radeon/radeon_connectors.c
+++ b/drivers/gpu/drm/radeon/radeon_connectors.c
@@ -1261,21 +1261,6 @@ static const struct drm_connector_funcs radeon_dvi_connector_funcs = {
.force = radeon_dvi_force,
};
-static void radeon_dp_connector_destroy(struct drm_connector *connector)
-{
- struct radeon_connector *radeon_connector = to_radeon_connector(connector);
- struct radeon_connector_atom_dig *radeon_dig_connector = radeon_connector->con_priv;
-
- if (radeon_connector->edid)
- kfree(radeon_connector->edid);
- if (radeon_dig_connector->dp_i2c_bus)
- radeon_i2c_destroy(radeon_dig_connector->dp_i2c_bus);
- kfree(radeon_connector->con_priv);
- drm_sysfs_connector_remove(connector);
- drm_connector_cleanup(connector);
- kfree(connector);
-}
-
static int radeon_dp_get_modes(struct drm_connector *connector)
{
struct radeon_connector *radeon_connector = to_radeon_connector(connector);
@@ -1553,7 +1538,7 @@ static const struct drm_connector_funcs radeon_dp_connector_funcs = {
.detect = radeon_dp_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.set_property = radeon_connector_set_property,
- .destroy = radeon_dp_connector_destroy,
+ .destroy = radeon_connector_destroy,
.force = radeon_dvi_force,
};
@@ -1562,7 +1547,7 @@ static const struct drm_connector_funcs radeon_edp_connector_funcs = {
.detect = radeon_dp_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.set_property = radeon_lvds_set_property,
- .destroy = radeon_dp_connector_destroy,
+ .destroy = radeon_connector_destroy,
.force = radeon_dvi_force,
};
@@ -1571,7 +1556,7 @@ static const struct drm_connector_funcs radeon_lvds_bridge_connector_funcs = {
.detect = radeon_dp_detect,
.fill_modes = drm_helper_probe_single_connector_modes,
.set_property = radeon_lvds_set_property,
- .destroy = radeon_dp_connector_destroy,
+ .destroy = radeon_connector_destroy,
.force = radeon_dvi_force,
};
@@ -1668,17 +1653,10 @@ radeon_add_atom_connector(struct drm_device *dev,
radeon_dig_connector->igp_lane_info = igp_lane_info;
radeon_connector->con_priv = radeon_dig_connector;
if (i2c_bus->valid) {
- /* add DP i2c bus */
- if (connector_type == DRM_MODE_CONNECTOR_eDP)
- radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, i2c_bus, "eDP-auxch");
- else
- radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, i2c_bus, "DP-auxch");
- if (radeon_dig_connector->dp_i2c_bus)
+ radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus);
+ if (radeon_connector->ddc_bus)
has_aux = true;
else
- DRM_ERROR("DP: Failed to assign dp ddc bus! Check dmesg for i2c errors.\n");
- radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus);
- if (!radeon_connector->ddc_bus)
DRM_ERROR("DP: Failed to assign ddc bus! Check dmesg for i2c errors.\n");
}
switch (connector_type) {
@@ -1893,10 +1871,6 @@ radeon_add_atom_connector(struct drm_device *dev,
drm_connector_init(dev, &radeon_connector->base, &radeon_dp_connector_funcs, connector_type);
drm_connector_helper_add(&radeon_connector->base, &radeon_dp_connector_helper_funcs);
if (i2c_bus->valid) {
- /* add DP i2c bus */
- radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, i2c_bus, "DP-auxch");
- if (!radeon_dig_connector->dp_i2c_bus)
- DRM_ERROR("DP: Failed to assign dp ddc bus! Check dmesg for i2c errors.\n");
radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus);
if (radeon_connector->ddc_bus)
has_aux = true;
@@ -1942,14 +1916,10 @@ radeon_add_atom_connector(struct drm_device *dev,
drm_connector_init(dev, &radeon_connector->base, &radeon_edp_connector_funcs, connector_type);
drm_connector_helper_add(&radeon_connector->base, &radeon_dp_connector_helper_funcs);
if (i2c_bus->valid) {
- /* add DP i2c bus */
- radeon_dig_connector->dp_i2c_bus = radeon_i2c_create_dp(dev, i2c_bus, "eDP-auxch");
- if (radeon_dig_connector->dp_i2c_bus)
+ radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus);
+ if (radeon_connector->ddc_bus)
has_aux = true;
else
- DRM_ERROR("DP: Failed to assign dp ddc bus! Check dmesg for i2c errors.\n");
- radeon_connector->ddc_bus = radeon_i2c_lookup(rdev, i2c_bus);
- if (!radeon_connector->ddc_bus)
DRM_ERROR("DP: Failed to assign ddc bus! Check dmesg for i2c errors.\n");
}
drm_object_attach_property(&radeon_connector->base.base,
diff --git a/drivers/gpu/drm/radeon/radeon_device.c b/drivers/gpu/drm/radeon/radeon_device.c
index 835516d..511fe26 100644
--- a/drivers/gpu/drm/radeon/radeon_device.c
+++ b/drivers/gpu/drm/radeon/radeon_device.c
@@ -102,11 +102,14 @@ static const char radeon_family_name[][16] = {
"LAST",
};
-#if defined(CONFIG_VGA_SWITCHEROO)
-bool radeon_is_px(void);
-#else
-static inline bool radeon_is_px(void) { return false; }
-#endif
+bool radeon_is_px(struct drm_device *dev)
+{
+ struct radeon_device *rdev = dev->dev_private;
+
+ if (rdev->flags & RADEON_IS_PX)
+ return true;
+ return false;
+}
/**
* radeon_program_register_sequence - program an array of registers.
@@ -1082,7 +1085,7 @@ static void radeon_switcheroo_set_state(struct pci_dev *pdev, enum vga_switchero
{
struct drm_device *dev = pci_get_drvdata(pdev);
- if (radeon_is_px() && state == VGA_SWITCHEROO_OFF)
+ if (radeon_is_px(dev) && state == VGA_SWITCHEROO_OFF)
return;
if (state == VGA_SWITCHEROO_ON) {
@@ -1301,9 +1304,7 @@ int radeon_device_init(struct radeon_device *rdev,
* ignore it */
vga_client_register(rdev->pdev, rdev, NULL, radeon_vga_set_decode);
- if (radeon_runtime_pm == 1)
- runtime = true;
- if ((radeon_runtime_pm == -1) && radeon_is_px())
+ if (rdev->flags & RADEON_IS_PX)
runtime = true;
vga_switcheroo_register_client(rdev->pdev, &radeon_switcheroo_ops, runtime);
if (runtime)
diff --git a/drivers/gpu/drm/radeon/radeon_display.c b/drivers/gpu/drm/radeon/radeon_display.c
index 386cfa4..2f7cbb9 100644
--- a/drivers/gpu/drm/radeon/radeon_display.c
+++ b/drivers/gpu/drm/radeon/radeon_display.c
@@ -759,19 +759,18 @@ int radeon_ddc_get_modes(struct radeon_connector *radeon_connector)
if (radeon_connector_encoder_get_dp_bridge_encoder_id(&radeon_connector->base) !=
ENCODER_OBJECT_ID_NONE) {
- struct radeon_connector_atom_dig *dig = radeon_connector->con_priv;
-
- if (dig->dp_i2c_bus)
+ if (radeon_connector->ddc_bus->has_aux)
radeon_connector->edid = drm_get_edid(&radeon_connector->base,
- &dig->dp_i2c_bus->adapter);
+ &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) && dig->dp_i2c_bus)
+ dig->dp_sink_type == CONNECTOR_OBJECT_ID_eDP) &&
+ radeon_connector->ddc_bus->has_aux)
radeon_connector->edid = drm_get_edid(&radeon_connector->base,
- &dig->dp_i2c_bus->adapter);
+ &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);
@@ -865,7 +864,7 @@ void radeon_compute_pll_avivo(struct radeon_pll *pll,
unsigned post_div_min, post_div_max, post_div;
unsigned ref_div_min, ref_div_max, ref_div;
unsigned post_div_best, diff_best;
- unsigned nom, den, tmp;
+ unsigned nom, den;
/* determine allowed feedback divider range */
fb_div_min = pll->min_feedback_div;
@@ -937,23 +936,27 @@ void radeon_compute_pll_avivo(struct radeon_pll *pll,
}
post_div = post_div_best;
+ /* limit reference * post divider to a maximum */
+ ref_div_max = min(210 / post_div, ref_div_max);
+
/* get matching reference and feedback divider */
- ref_div = max(den / post_div, 1u);
- fb_div = nom;
+ ref_div = max(DIV_ROUND_CLOSEST(den, post_div), 1u);
+ fb_div = DIV_ROUND_CLOSEST(nom * ref_div * post_div, den);
/* we're almost done, but reference and feedback
divider might be to large now */
- tmp = ref_div;
+ nom = fb_div;
+ den = ref_div;
if (fb_div > fb_div_max) {
- ref_div = ref_div * fb_div_max / fb_div;
+ ref_div = DIV_ROUND_CLOSEST(den * fb_div_max, nom);
fb_div = fb_div_max;
}
if (ref_div > ref_div_max) {
ref_div = ref_div_max;
- fb_div = nom * ref_div_max / tmp;
+ fb_div = DIV_ROUND_CLOSEST(nom * ref_div_max, den);
}
/* reduce the numbers to a simpler ratio once more */
diff --git a/drivers/gpu/drm/radeon/radeon_drv.c b/drivers/gpu/drm/radeon/radeon_drv.c
index d0eba48..c00a2f5 100644
--- a/drivers/gpu/drm/radeon/radeon_drv.c
+++ b/drivers/gpu/drm/radeon/radeon_drv.c
@@ -115,6 +115,7 @@ extern int radeon_get_crtc_scanoutpos(struct drm_device *dev, int crtc,
unsigned int flags,
int *vpos, int *hpos, ktime_t *stime,
ktime_t *etime);
+extern bool radeon_is_px(struct drm_device *dev);
extern const struct drm_ioctl_desc radeon_ioctls_kms[];
extern int radeon_max_kms_ioctl;
int radeon_mmap(struct file *filp, struct vm_area_struct *vma);
@@ -144,11 +145,9 @@ void radeon_debugfs_cleanup(struct drm_minor *minor);
#if defined(CONFIG_VGA_SWITCHEROO)
void radeon_register_atpx_handler(void);
void radeon_unregister_atpx_handler(void);
-bool radeon_is_px(void);
#else
static inline void radeon_register_atpx_handler(void) {}
static inline void radeon_unregister_atpx_handler(void) {}
-static inline bool radeon_is_px(void) { return false; }
#endif
int radeon_no_wb;
@@ -186,7 +185,7 @@ module_param_named(dynclks, radeon_dynclks, int, 0444);
MODULE_PARM_DESC(r4xx_atom, "Enable ATOMBIOS modesetting for R4xx");
module_param_named(r4xx_atom, radeon_r4xx_atom, int, 0444);
-MODULE_PARM_DESC(vramlimit, "Restrict VRAM for testing");
+MODULE_PARM_DESC(vramlimit, "Restrict VRAM for testing, in megabytes");
module_param_named(vramlimit, radeon_vram_limit, int, 0600);
MODULE_PARM_DESC(agpmode, "AGP Mode (-1 == PCI)");
@@ -405,12 +404,7 @@ static int radeon_pmops_runtime_suspend(struct device *dev)
struct drm_device *drm_dev = pci_get_drvdata(pdev);
int ret;
- if (radeon_runtime_pm == 0) {
- pm_runtime_forbid(dev);
- return -EBUSY;
- }
-
- if (radeon_runtime_pm == -1 && !radeon_is_px()) {
+ if (!radeon_is_px(drm_dev)) {
pm_runtime_forbid(dev);
return -EBUSY;
}
@@ -434,10 +428,7 @@ static int radeon_pmops_runtime_resume(struct device *dev)
struct drm_device *drm_dev = pci_get_drvdata(pdev);
int ret;
- if (radeon_runtime_pm == 0)
- return -EINVAL;
-
- if (radeon_runtime_pm == -1 && !radeon_is_px())
+ if (!radeon_is_px(drm_dev))
return -EINVAL;
drm_dev->switch_power_state = DRM_SWITCH_POWER_CHANGING;
@@ -462,14 +453,7 @@ static int radeon_pmops_runtime_idle(struct device *dev)
struct drm_device *drm_dev = pci_get_drvdata(pdev);
struct drm_crtc *crtc;
- if (radeon_runtime_pm == 0) {
- pm_runtime_forbid(dev);
- return -EBUSY;
- }
-
- /* are we PX enabled? */
- if (radeon_runtime_pm == -1 && !radeon_is_px()) {
- DRM_DEBUG_DRIVER("failing to power off - not px\n");
+ if (!radeon_is_px(drm_dev)) {
pm_runtime_forbid(dev);
return -EBUSY;
}
diff --git a/drivers/gpu/drm/radeon/radeon_family.h b/drivers/gpu/drm/radeon/radeon_family.h
index 614ad54..9da5da4 100644
--- a/drivers/gpu/drm/radeon/radeon_family.h
+++ b/drivers/gpu/drm/radeon/radeon_family.h
@@ -115,6 +115,7 @@ enum radeon_chip_flags {
RADEON_NEW_MEMMAP = 0x00400000UL,
RADEON_IS_PCI = 0x00800000UL,
RADEON_IS_IGPGART = 0x01000000UL,
+ RADEON_IS_PX = 0x02000000UL,
};
#endif
diff --git a/drivers/gpu/drm/radeon/radeon_i2c.c b/drivers/gpu/drm/radeon/radeon_i2c.c
index e24ca6a..7b94414 100644
--- a/drivers/gpu/drm/radeon/radeon_i2c.c
+++ b/drivers/gpu/drm/radeon/radeon_i2c.c
@@ -64,8 +64,7 @@ bool radeon_ddc_probe(struct radeon_connector *radeon_connector, bool use_aux)
radeon_router_select_ddc_port(radeon_connector);
if (use_aux) {
- struct radeon_connector_atom_dig *dig = radeon_connector->con_priv;
- ret = i2c_transfer(&dig->dp_i2c_bus->adapter, msgs, 2);
+ ret = i2c_transfer(&radeon_connector->ddc_bus->aux.ddc, msgs, 2);
} else {
ret = i2c_transfer(&radeon_connector->ddc_bus->adapter, msgs, 2);
}
@@ -950,16 +949,16 @@ struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev,
/* set the radeon bit adapter */
snprintf(i2c->adapter.name, sizeof(i2c->adapter.name),
"Radeon i2c bit bus %s", name);
- i2c->adapter.algo_data = &i2c->algo.bit;
- i2c->algo.bit.pre_xfer = pre_xfer;
- i2c->algo.bit.post_xfer = post_xfer;
- i2c->algo.bit.setsda = set_data;
- i2c->algo.bit.setscl = set_clock;
- i2c->algo.bit.getsda = get_data;
- i2c->algo.bit.getscl = get_clock;
- i2c->algo.bit.udelay = 10;
- i2c->algo.bit.timeout = usecs_to_jiffies(2200); /* from VESA */
- i2c->algo.bit.data = i2c;
+ i2c->adapter.algo_data = &i2c->bit;
+ i2c->bit.pre_xfer = pre_xfer;
+ i2c->bit.post_xfer = post_xfer;
+ i2c->bit.setsda = set_data;
+ i2c->bit.setscl = set_clock;
+ i2c->bit.getsda = get_data;
+ i2c->bit.getscl = get_clock;
+ i2c->bit.udelay = 10;
+ i2c->bit.timeout = usecs_to_jiffies(2200); /* from VESA */
+ i2c->bit.data = i2c;
ret = i2c_bit_add_bus(&i2c->adapter);
if (ret) {
DRM_ERROR("Failed to register bit i2c %s\n", name);
@@ -974,46 +973,13 @@ out_free:
}
-struct radeon_i2c_chan *radeon_i2c_create_dp(struct drm_device *dev,
- struct radeon_i2c_bus_rec *rec,
- const char *name)
-{
- struct radeon_i2c_chan *i2c;
- int ret;
-
- i2c = kzalloc(sizeof(struct radeon_i2c_chan), GFP_KERNEL);
- if (i2c == NULL)
- return NULL;
-
- i2c->rec = *rec;
- i2c->adapter.owner = THIS_MODULE;
- i2c->adapter.class = I2C_CLASS_DDC;
- i2c->adapter.dev.parent = &dev->pdev->dev;
- i2c->dev = dev;
- snprintf(i2c->adapter.name, sizeof(i2c->adapter.name),
- "Radeon aux bus %s", name);
- i2c_set_adapdata(&i2c->adapter, i2c);
- i2c->adapter.algo_data = &i2c->algo.dp;
- i2c->algo.dp.aux_ch = radeon_dp_i2c_aux_ch;
- i2c->algo.dp.address = 0;
- ret = i2c_dp_aux_add_bus(&i2c->adapter);
- if (ret) {
- DRM_INFO("Failed to register i2c %s\n", name);
- goto out_free;
- }
-
- return i2c;
-out_free:
- kfree(i2c);
- return NULL;
-
-}
-
void radeon_i2c_destroy(struct radeon_i2c_chan *i2c)
{
if (!i2c)
return;
i2c_del_adapter(&i2c->adapter);
+ if (i2c->has_aux)
+ drm_dp_aux_unregister_i2c_bus(&i2c->aux);
kfree(i2c);
}
diff --git a/drivers/gpu/drm/radeon/radeon_kms.c b/drivers/gpu/drm/radeon/radeon_kms.c
index 3e49342..fb3d13f 100644
--- a/drivers/gpu/drm/radeon/radeon_kms.c
+++ b/drivers/gpu/drm/radeon/radeon_kms.c
@@ -35,9 +35,9 @@
#include <linux/pm_runtime.h>
#if defined(CONFIG_VGA_SWITCHEROO)
-bool radeon_is_px(void);
+bool radeon_has_atpx(void);
#else
-static inline bool radeon_is_px(void) { return false; }
+static inline bool radeon_has_atpx(void) { return false; }
#endif
/**
@@ -107,6 +107,13 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags)
flags |= RADEON_IS_PCI;
}
+ if (radeon_runtime_pm == 1)
+ flags |= RADEON_IS_PX;
+ else if ((radeon_runtime_pm == -1) &&
+ radeon_has_atpx() &&
+ ((flags & RADEON_IS_IGP) == 0))
+ flags |= RADEON_IS_PX;
+
/* radeon_device_init should report only fatal error
* like memory allocation failure or iomapping failure,
* or memory manager initialization failure, it must
@@ -137,8 +144,7 @@ int radeon_driver_load_kms(struct drm_device *dev, unsigned long flags)
"Error during ACPI methods call\n");
}
- if ((radeon_runtime_pm == 1) ||
- ((radeon_runtime_pm == -1) && radeon_is_px())) {
+ if (radeon_is_px(dev)) {
pm_runtime_use_autosuspend(dev->dev);
pm_runtime_set_autosuspend_delay(dev->dev, 5000);
pm_runtime_set_active(dev->dev);
@@ -568,12 +574,17 @@ int radeon_driver_open_kms(struct drm_device *dev, struct drm_file *file_priv)
}
r = radeon_vm_init(rdev, &fpriv->vm);
- if (r)
+ if (r) {
+ kfree(fpriv);
return r;
+ }
r = radeon_bo_reserve(rdev->ring_tmp_bo.bo, false);
- if (r)
+ if (r) {
+ radeon_vm_fini(rdev, &fpriv->vm);
+ kfree(fpriv);
return r;
+ }
/* map the ib pool buffer read only into
* virtual address space */
diff --git a/drivers/gpu/drm/radeon/radeon_mode.h b/drivers/gpu/drm/radeon/radeon_mode.h
index 832d9fa..6ddf31a 100644
--- a/drivers/gpu/drm/radeon/radeon_mode.h
+++ b/drivers/gpu/drm/radeon/radeon_mode.h
@@ -187,12 +187,10 @@ struct radeon_pll {
struct radeon_i2c_chan {
struct i2c_adapter adapter;
struct drm_device *dev;
- union {
- struct i2c_algo_bit_data bit;
- struct i2c_algo_dp_aux_data dp;
- } algo;
+ struct i2c_algo_bit_data bit;
struct radeon_i2c_bus_rec rec;
struct drm_dp_aux aux;
+ bool has_aux;
};
/* mostly for macs, but really any system without connector tables */
@@ -440,7 +438,6 @@ struct radeon_encoder {
struct radeon_connector_atom_dig {
uint32_t igp_lane_info;
/* displayport */
- struct radeon_i2c_chan *dp_i2c_bus;
u8 dpcd[DP_RECEIVER_CAP_SIZE];
u8 dp_sink_type;
int dp_clock;
@@ -702,8 +699,6 @@ extern void atombios_dig_transmitter_setup(struct drm_encoder *encoder,
uint8_t lane_set);
extern void radeon_atom_ext_encoder_setup_ddc(struct drm_encoder *encoder);
extern struct drm_encoder *radeon_get_external_encoder(struct drm_encoder *encoder);
-extern int radeon_dp_i2c_aux_ch(struct i2c_adapter *adapter, int mode,
- u8 write_byte, u8 *read_byte);
void radeon_atom_copy_swap(u8 *dst, u8 *src, u8 num_bytes, bool to_le);
extern void radeon_i2c_init(struct radeon_device *rdev);
@@ -715,9 +710,6 @@ extern void radeon_i2c_add(struct radeon_device *rdev,
const char *name);
extern struct radeon_i2c_chan *radeon_i2c_lookup(struct radeon_device *rdev,
struct radeon_i2c_bus_rec *i2c_bus);
-extern struct radeon_i2c_chan *radeon_i2c_create_dp(struct drm_device *dev,
- struct radeon_i2c_bus_rec *rec,
- const char *name);
extern struct radeon_i2c_chan *radeon_i2c_create(struct drm_device *dev,
struct radeon_i2c_bus_rec *rec,
const char *name);
diff --git a/drivers/gpu/drm/radeon/radeon_ucode.h b/drivers/gpu/drm/radeon/radeon_ucode.h
index a77cd27..58d1293 100644
--- a/drivers/gpu/drm/radeon/radeon_ucode.h
+++ b/drivers/gpu/drm/radeon/radeon_ucode.h
@@ -57,9 +57,14 @@
#define BTC_MC_UCODE_SIZE 6024
#define CAYMAN_MC_UCODE_SIZE 6037
#define SI_MC_UCODE_SIZE 7769
+#define TAHITI_MC_UCODE_SIZE 7808
+#define PITCAIRN_MC_UCODE_SIZE 7775
+#define VERDE_MC_UCODE_SIZE 7875
#define OLAND_MC_UCODE_SIZE 7863
-#define CIK_MC_UCODE_SIZE 7866
+#define BONAIRE_MC_UCODE_SIZE 7866
+#define BONAIRE_MC2_UCODE_SIZE 7948
#define HAWAII_MC_UCODE_SIZE 7933
+#define HAWAII_MC2_UCODE_SIZE 8091
/* SDMA */
#define CIK_SDMA_UCODE_SIZE 1050
diff --git a/drivers/gpu/drm/radeon/radeon_vce.c b/drivers/gpu/drm/radeon/radeon_vce.c
index 76e9904..ced53dd 100644
--- a/drivers/gpu/drm/radeon/radeon_vce.c
+++ b/drivers/gpu/drm/radeon/radeon_vce.c
@@ -613,7 +613,7 @@ void radeon_vce_fence_emit(struct radeon_device *rdev,
struct radeon_fence *fence)
{
struct radeon_ring *ring = &rdev->ring[fence->ring];
- uint32_t addr = rdev->fence_drv[fence->ring].gpu_addr;
+ uint64_t addr = rdev->fence_drv[fence->ring].gpu_addr;
radeon_ring_write(ring, VCE_CMD_FENCE);
radeon_ring_write(ring, addr);
diff --git a/drivers/gpu/drm/radeon/si.c b/drivers/gpu/drm/radeon/si.c
index d589475..ac708e0 100644
--- a/drivers/gpu/drm/radeon/si.c
+++ b/drivers/gpu/drm/radeon/si.c
@@ -39,30 +39,35 @@ 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_mc2.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");
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/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_mc2.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");
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/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_mc2.bin");
MODULE_FIRMWARE("radeon/HAINAN_rlc.bin");
MODULE_FIRMWARE("radeon/HAINAN_smc.bin");
@@ -1467,36 +1472,33 @@ int si_mc_load_microcode(struct radeon_device *rdev)
const __be32 *fw_data;
u32 running, blackout = 0;
u32 *io_mc_regs;
- int i, ucode_size, regs_size;
+ int i, regs_size, ucode_size;
if (!rdev->mc_fw)
return -EINVAL;
+ ucode_size = rdev->mc_fw->size / 4;
+
switch (rdev->family) {
case CHIP_TAHITI:
io_mc_regs = (u32 *)&tahiti_io_mc_regs;
- ucode_size = SI_MC_UCODE_SIZE;
regs_size = TAHITI_IO_MC_REGS_SIZE;
break;
case CHIP_PITCAIRN:
io_mc_regs = (u32 *)&pitcairn_io_mc_regs;
- ucode_size = SI_MC_UCODE_SIZE;
regs_size = TAHITI_IO_MC_REGS_SIZE;
break;
case CHIP_VERDE:
default:
io_mc_regs = (u32 *)&verde_io_mc_regs;
- ucode_size = SI_MC_UCODE_SIZE;
regs_size = TAHITI_IO_MC_REGS_SIZE;
break;
case CHIP_OLAND:
io_mc_regs = (u32 *)&oland_io_mc_regs;
- ucode_size = OLAND_MC_UCODE_SIZE;
regs_size = TAHITI_IO_MC_REGS_SIZE;
break;
case CHIP_HAINAN:
io_mc_regs = (u32 *)&hainan_io_mc_regs;
- ucode_size = OLAND_MC_UCODE_SIZE;
regs_size = TAHITI_IO_MC_REGS_SIZE;
break;
}
@@ -1552,7 +1554,7 @@ static int si_init_microcode(struct radeon_device *rdev)
const char *chip_name;
const char *rlc_chip_name;
size_t pfp_req_size, me_req_size, ce_req_size, rlc_req_size, mc_req_size;
- size_t smc_req_size;
+ size_t smc_req_size, mc2_req_size;
char fw_name[30];
int err;
@@ -1567,6 +1569,7 @@ static int si_init_microcode(struct radeon_device *rdev)
ce_req_size = SI_CE_UCODE_SIZE * 4;
rlc_req_size = SI_RLC_UCODE_SIZE * 4;
mc_req_size = SI_MC_UCODE_SIZE * 4;
+ mc2_req_size = TAHITI_MC_UCODE_SIZE * 4;
smc_req_size = ALIGN(TAHITI_SMC_UCODE_SIZE, 4);
break;
case CHIP_PITCAIRN:
@@ -1577,6 +1580,7 @@ static int si_init_microcode(struct radeon_device *rdev)
ce_req_size = SI_CE_UCODE_SIZE * 4;
rlc_req_size = SI_RLC_UCODE_SIZE * 4;
mc_req_size = SI_MC_UCODE_SIZE * 4;
+ mc2_req_size = PITCAIRN_MC_UCODE_SIZE * 4;
smc_req_size = ALIGN(PITCAIRN_SMC_UCODE_SIZE, 4);
break;
case CHIP_VERDE:
@@ -1587,6 +1591,7 @@ static int si_init_microcode(struct radeon_device *rdev)
ce_req_size = SI_CE_UCODE_SIZE * 4;
rlc_req_size = SI_RLC_UCODE_SIZE * 4;
mc_req_size = SI_MC_UCODE_SIZE * 4;
+ mc2_req_size = VERDE_MC_UCODE_SIZE * 4;
smc_req_size = ALIGN(VERDE_SMC_UCODE_SIZE, 4);
break;
case CHIP_OLAND:
@@ -1596,7 +1601,7 @@ static int si_init_microcode(struct radeon_device *rdev)
me_req_size = SI_PM4_UCODE_SIZE * 4;
ce_req_size = SI_CE_UCODE_SIZE * 4;
rlc_req_size = SI_RLC_UCODE_SIZE * 4;
- mc_req_size = OLAND_MC_UCODE_SIZE * 4;
+ mc_req_size = mc2_req_size = OLAND_MC_UCODE_SIZE * 4;
smc_req_size = ALIGN(OLAND_SMC_UCODE_SIZE, 4);
break;
case CHIP_HAINAN:
@@ -1606,7 +1611,7 @@ static int si_init_microcode(struct radeon_device *rdev)
me_req_size = SI_PM4_UCODE_SIZE * 4;
ce_req_size = SI_CE_UCODE_SIZE * 4;
rlc_req_size = SI_RLC_UCODE_SIZE * 4;
- mc_req_size = OLAND_MC_UCODE_SIZE * 4;
+ mc_req_size = mc2_req_size = OLAND_MC_UCODE_SIZE * 4;
smc_req_size = ALIGN(HAINAN_SMC_UCODE_SIZE, 4);
break;
default: BUG();
@@ -1659,16 +1664,22 @@ static int si_init_microcode(struct radeon_device *rdev)
err = -EINVAL;
}
- 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)
- goto out;
- if (rdev->mc_fw->size != mc_req_size) {
+ 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);
snprintf(fw_name, sizeof(fw_name), "radeon/%s_smc.bin", chip_name);
err = request_firmware(&rdev->smc_fw, fw_name, rdev->dev);
diff --git a/drivers/gpu/drm/tegra/dpaux.c b/drivers/gpu/drm/tegra/dpaux.c
index d536ed3..005c19b 100644
--- a/drivers/gpu/drm/tegra/dpaux.c
+++ b/drivers/gpu/drm/tegra/dpaux.c
@@ -99,55 +99,73 @@ static void tegra_dpaux_read_fifo(struct tegra_dpaux *dpaux, u8 *buffer,
static ssize_t tegra_dpaux_transfer(struct drm_dp_aux *aux,
struct drm_dp_aux_msg *msg)
{
- unsigned long value = DPAUX_DP_AUXCTL_TRANSACTREQ;
unsigned long timeout = msecs_to_jiffies(250);
struct tegra_dpaux *dpaux = to_dpaux(aux);
unsigned long status;
ssize_t ret = 0;
+ u32 value;
- if (msg->size < 1 || msg->size > 16)
+ /* Tegra has 4x4 byte DP AUX transmit and receive FIFOs. */
+ if (msg->size > 16)
return -EINVAL;
- tegra_dpaux_writel(dpaux, msg->address, DPAUX_DP_AUXADDR);
+ /*
+ * Allow zero-sized messages only for I2C, in which case they specify
+ * address-only transactions.
+ */
+ if (msg->size < 1) {
+ switch (msg->request & ~DP_AUX_I2C_MOT) {
+ case DP_AUX_I2C_WRITE:
+ case DP_AUX_I2C_READ:
+ value = DPAUX_DP_AUXCTL_CMD_ADDRESS_ONLY;
+ break;
+
+ default:
+ return -EINVAL;
+ }
+ } else {
+ /* For non-zero-sized messages, set the CMDLEN field. */
+ value = DPAUX_DP_AUXCTL_CMDLEN(msg->size - 1);
+ }
switch (msg->request & ~DP_AUX_I2C_MOT) {
case DP_AUX_I2C_WRITE:
if (msg->request & DP_AUX_I2C_MOT)
- value = DPAUX_DP_AUXCTL_CMD_MOT_WR;
+ value |= DPAUX_DP_AUXCTL_CMD_MOT_WR;
else
- value = DPAUX_DP_AUXCTL_CMD_I2C_WR;
+ value |= DPAUX_DP_AUXCTL_CMD_I2C_WR;
break;
case DP_AUX_I2C_READ:
if (msg->request & DP_AUX_I2C_MOT)
- value = DPAUX_DP_AUXCTL_CMD_MOT_RD;
+ value |= DPAUX_DP_AUXCTL_CMD_MOT_RD;
else
- value = DPAUX_DP_AUXCTL_CMD_I2C_RD;
+ value |= DPAUX_DP_AUXCTL_CMD_I2C_RD;
break;
case DP_AUX_I2C_STATUS:
if (msg->request & DP_AUX_I2C_MOT)
- value = DPAUX_DP_AUXCTL_CMD_MOT_RQ;
+ value |= DPAUX_DP_AUXCTL_CMD_MOT_RQ;
else
- value = DPAUX_DP_AUXCTL_CMD_I2C_RQ;
+ value |= DPAUX_DP_AUXCTL_CMD_I2C_RQ;
break;
case DP_AUX_NATIVE_WRITE:
- value = DPAUX_DP_AUXCTL_CMD_AUX_WR;
+ value |= DPAUX_DP_AUXCTL_CMD_AUX_WR;
break;
case DP_AUX_NATIVE_READ:
- value = DPAUX_DP_AUXCTL_CMD_AUX_RD;
+ value |= DPAUX_DP_AUXCTL_CMD_AUX_RD;
break;
default:
return -EINVAL;
}
- value |= DPAUX_DP_AUXCTL_CMDLEN(msg->size - 1);
+ tegra_dpaux_writel(dpaux, msg->address, DPAUX_DP_AUXADDR);
tegra_dpaux_writel(dpaux, value, DPAUX_DP_AUXCTL);
if ((msg->request & DP_AUX_I2C_READ) == 0) {
@@ -198,7 +216,7 @@ static ssize_t tegra_dpaux_transfer(struct drm_dp_aux *aux,
break;
}
- if (msg->reply == DP_AUX_NATIVE_REPLY_ACK) {
+ if ((msg->size > 0) && (msg->reply == DP_AUX_NATIVE_REPLY_ACK)) {
if (msg->request & DP_AUX_I2C_READ) {
size_t count = value & DPAUX_DP_AUXSTAT_REPLY_MASK;
diff --git a/drivers/gpu/drm/tegra/dpaux.h b/drivers/gpu/drm/tegra/dpaux.h
index 4f5bf10..806e245 100644
--- a/drivers/gpu/drm/tegra/dpaux.h
+++ b/drivers/gpu/drm/tegra/dpaux.h
@@ -32,6 +32,7 @@
#define DPAUX_DP_AUXCTL_CMD_I2C_RQ (2 << 12)
#define DPAUX_DP_AUXCTL_CMD_I2C_RD (1 << 12)
#define DPAUX_DP_AUXCTL_CMD_I2C_WR (0 << 12)
+#define DPAUX_DP_AUXCTL_CMD_ADDRESS_ONLY (1 << 8)
#define DPAUX_DP_AUXCTL_CMDLEN(x) ((x) & 0xff)
#define DPAUX_DP_AUXSTAT 0x31
diff --git a/drivers/gpu/host1x/hw/intr_hw.c b/drivers/gpu/host1x/hw/intr_hw.c
index db9017a..498b37e 100644
--- a/drivers/gpu/host1x/hw/intr_hw.c
+++ b/drivers/gpu/host1x/hw/intr_hw.c
@@ -47,7 +47,7 @@ static irqreturn_t syncpt_thresh_isr(int irq, void *dev_id)
unsigned long reg;
int i, id;
- for (i = 0; i <= BIT_WORD(host->info->nb_pts); i++) {
+ for (i = 0; i < DIV_ROUND_UP(host->info->nb_pts, 32); i++) {
reg = host1x_sync_readl(host,
HOST1X_SYNC_SYNCPT_THRESH_CPU0_INT_STATUS(i));
for_each_set_bit(id, &reg, BITS_PER_LONG) {
@@ -64,7 +64,7 @@ static void _host1x_intr_disable_all_syncpt_intrs(struct host1x *host)
{
u32 i;
- for (i = 0; i <= BIT_WORD(host->info->nb_pts); ++i) {
+ for (i = 0; i < DIV_ROUND_UP(host->info->nb_pts, 32); ++i) {
host1x_sync_writel(host, 0xffffffffu,
HOST1X_SYNC_SYNCPT_THRESH_INT_DISABLE(i));
host1x_sync_writel(host, 0xffffffffu,
diff --git a/drivers/hid/hid-core.c b/drivers/hid/hid-core.c
index 9e806420..10a2c08 100644
--- a/drivers/hid/hid-core.c
+++ b/drivers/hid/hid-core.c
@@ -718,6 +718,9 @@ static int hid_scan_main(struct hid_parser *parser, struct hid_item *item)
case HID_MAIN_ITEM_TAG_END_COLLECTION:
break;
case HID_MAIN_ITEM_TAG_INPUT:
+ /* ignore constant inputs, they will be ignored by hid-input */
+ if (data & HID_MAIN_ITEM_CONSTANT)
+ break;
for (i = 0; i < parser->local.usage_index; i++)
hid_scan_input_usage(parser, parser->local.usage[i]);
break;
@@ -1821,8 +1824,6 @@ static const struct hid_device_id hid_have_special_driver[] = {
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_USB) },
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K) },
{ 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_TYPE_COVER_2) },
- { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TOUCH_COVER_2) },
{ 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_NTRIG, USB_DEVICE_ID_NTRIG_TOUCH_SCREEN) },
diff --git a/drivers/hid/hid-ids.h b/drivers/hid/hid-ids.h
index bd22126..c8af720 100644
--- a/drivers/hid/hid-ids.h
+++ b/drivers/hid/hid-ids.h
@@ -455,7 +455,8 @@
#define USB_VENDOR_ID_INTEL_0 0x8086
#define USB_VENDOR_ID_INTEL_1 0x8087
-#define USB_DEVICE_ID_INTEL_HID_SENSOR 0x09fa
+#define USB_DEVICE_ID_INTEL_HID_SENSOR_0 0x09fa
+#define USB_DEVICE_ID_INTEL_HID_SENSOR_1 0x0a04
#define USB_VENDOR_ID_STM_0 0x0483
#define USB_DEVICE_ID_STM_HID_SENSOR 0x91d1
@@ -629,8 +630,6 @@
#define USB_DEVICE_ID_MS_PRESENTER_8K_USB 0x0713
#define USB_DEVICE_ID_MS_DIGITAL_MEDIA_3K 0x0730
#define USB_DEVICE_ID_MS_COMFORT_MOUSE_4500 0x076c
-#define USB_DEVICE_ID_MS_TOUCH_COVER_2 0x07a7
-#define USB_DEVICE_ID_MS_TYPE_COVER_2 0x07a9
#define USB_VENDOR_ID_MOJO 0x8282
#define USB_DEVICE_ID_RETRO_ADAPTER 0x3201
diff --git a/drivers/hid/hid-microsoft.c b/drivers/hid/hid-microsoft.c
index 6fd5817..8ba17a9 100644
--- a/drivers/hid/hid-microsoft.c
+++ b/drivers/hid/hid-microsoft.c
@@ -274,10 +274,6 @@ static const struct hid_device_id ms_devices[] = {
.driver_data = MS_NOGET },
{ HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_COMFORT_MOUSE_4500),
.driver_data = MS_DUPLICATE_USAGES },
- { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TYPE_COVER_2),
- .driver_data = 0 },
- { HID_USB_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_TOUCH_COVER_2),
- .driver_data = 0 },
{ HID_BLUETOOTH_DEVICE(USB_VENDOR_ID_MICROSOFT, USB_DEVICE_ID_MS_PRESENTER_8K_BT),
.driver_data = MS_PRESENTER },
diff --git a/drivers/hid/hid-sensor-hub.c b/drivers/hid/hid-sensor-hub.c
index 5182031..af8244b 100644
--- a/drivers/hid/hid-sensor-hub.c
+++ b/drivers/hid/hid-sensor-hub.c
@@ -697,10 +697,13 @@ static void sensor_hub_remove(struct hid_device *hdev)
static const struct hid_device_id sensor_hub_devices[] = {
{ HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_INTEL_0,
- USB_DEVICE_ID_INTEL_HID_SENSOR),
+ USB_DEVICE_ID_INTEL_HID_SENSOR_0),
.driver_data = HID_SENSOR_HUB_ENUM_QUIRK},
{ HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_INTEL_1,
- USB_DEVICE_ID_INTEL_HID_SENSOR),
+ USB_DEVICE_ID_INTEL_HID_SENSOR_0),
+ .driver_data = HID_SENSOR_HUB_ENUM_QUIRK},
+ { HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_INTEL_1,
+ USB_DEVICE_ID_INTEL_HID_SENSOR_1),
.driver_data = HID_SENSOR_HUB_ENUM_QUIRK},
{ HID_DEVICE(HID_BUS_ANY, HID_GROUP_SENSOR_HUB, USB_VENDOR_ID_STM_0,
USB_DEVICE_ID_STM_HID_SENSOR),
diff --git a/drivers/hid/hid-sony.c b/drivers/hid/hid-sony.c
index 69204af..908de27 100644
--- a/drivers/hid/hid-sony.c
+++ b/drivers/hid/hid-sony.c
@@ -1721,8 +1721,6 @@ static void sony_remove(struct hid_device *hdev)
if (sc->quirks & SONY_LED_SUPPORT)
sony_leds_remove(hdev);
- if (sc->worker_initialized)
- cancel_work_sync(&sc->state_worker);
if (sc->quirks & SONY_BATTERY_SUPPORT) {
hid_hw_close(hdev);
sony_battery_remove(sc);
diff --git a/drivers/hv/connection.c b/drivers/hv/connection.c
index f2d7bf9..2e7801a 100644
--- a/drivers/hv/connection.c
+++ b/drivers/hv/connection.c
@@ -55,6 +55,9 @@ static __u32 vmbus_get_next_version(__u32 current_version)
case (VERSION_WIN8):
return VERSION_WIN7;
+ case (VERSION_WIN8_1):
+ return VERSION_WIN8;
+
case (VERSION_WS2008):
default:
return VERSION_INVAL;
@@ -77,7 +80,7 @@ static int vmbus_negotiate_version(struct vmbus_channel_msginfo *msginfo,
msg->interrupt_page = virt_to_phys(vmbus_connection.int_page);
msg->monitor_page1 = virt_to_phys(vmbus_connection.monitor_pages[0]);
msg->monitor_page2 = virt_to_phys(vmbus_connection.monitor_pages[1]);
- if (version == VERSION_WIN8)
+ if (version == VERSION_WIN8_1)
msg->target_vcpu = hv_context.vp_index[smp_processor_id()];
/*
diff --git a/drivers/infiniband/hw/cxgb4/cm.c b/drivers/infiniband/hw/cxgb4/cm.c
index 02436d5..185452a 100644
--- a/drivers/infiniband/hw/cxgb4/cm.c
+++ b/drivers/infiniband/hw/cxgb4/cm.c
@@ -173,12 +173,15 @@ static void start_ep_timer(struct c4iw_ep *ep)
add_timer(&ep->timer);
}
-static void stop_ep_timer(struct c4iw_ep *ep)
+static int stop_ep_timer(struct c4iw_ep *ep)
{
PDBG("%s ep %p stopping\n", __func__, ep);
del_timer_sync(&ep->timer);
- if (!test_and_set_bit(TIMEOUT, &ep->com.flags))
+ if (!test_and_set_bit(TIMEOUT, &ep->com.flags)) {
c4iw_put_ep(&ep->com);
+ return 0;
+ }
+ return 1;
}
static int c4iw_l2t_send(struct c4iw_rdev *rdev, struct sk_buff *skb,
@@ -1165,12 +1168,11 @@ static void process_mpa_reply(struct c4iw_ep *ep, struct sk_buff *skb)
PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
/*
- * Stop mpa timer. If it expired, then the state has
- * changed and we bail since ep_timeout already aborted
- * the connection.
+ * Stop mpa timer. If it expired, then
+ * we ignore the MPA reply. process_timeout()
+ * will abort the connection.
*/
- stop_ep_timer(ep);
- if (ep->com.state != MPA_REQ_SENT)
+ if (stop_ep_timer(ep))
return;
/*
@@ -1375,15 +1377,12 @@ static void process_mpa_request(struct c4iw_ep *ep, struct sk_buff *skb)
PDBG("%s ep %p tid %u\n", __func__, ep, ep->hwtid);
- if (ep->com.state != MPA_REQ_WAIT)
- return;
-
/*
* If we get more than the supported amount of private data
* then we must fail this connection.
*/
if (ep->mpa_pkt_len + skb->len > sizeof(ep->mpa_pkt)) {
- stop_ep_timer(ep);
+ (void)stop_ep_timer(ep);
abort_connection(ep, skb, GFP_KERNEL);
return;
}
@@ -1413,13 +1412,13 @@ static void process_mpa_request(struct c4iw_ep *ep, struct sk_buff *skb)
if (mpa->revision > mpa_rev) {
printk(KERN_ERR MOD "%s MPA version mismatch. Local = %d,"
" Received = %d\n", __func__, mpa_rev, mpa->revision);
- stop_ep_timer(ep);
+ (void)stop_ep_timer(ep);
abort_connection(ep, skb, GFP_KERNEL);
return;
}
if (memcmp(mpa->key, MPA_KEY_REQ, sizeof(mpa->key))) {
- stop_ep_timer(ep);
+ (void)stop_ep_timer(ep);
abort_connection(ep, skb, GFP_KERNEL);
return;
}
@@ -1430,7 +1429,7 @@ static void process_mpa_request(struct c4iw_ep *ep, struct sk_buff *skb)
* Fail if there's too much private data.
*/
if (plen > MPA_MAX_PRIVATE_DATA) {
- stop_ep_timer(ep);
+ (void)stop_ep_timer(ep);
abort_connection(ep, skb, GFP_KERNEL);
return;
}
@@ -1439,7 +1438,7 @@ static void process_mpa_request(struct c4iw_ep *ep, struct sk_buff *skb)
* If plen does not account for pkt size
*/
if (ep->mpa_pkt_len > (sizeof(*mpa) + plen)) {
- stop_ep_timer(ep);
+ (void)stop_ep_timer(ep);
abort_connection(ep, skb, GFP_KERNEL);
return;
}
@@ -1496,18 +1495,24 @@ static void process_mpa_request(struct c4iw_ep *ep, struct sk_buff *skb)
ep->mpa_attr.xmit_marker_enabled, ep->mpa_attr.version,
ep->mpa_attr.p2p_type);
- __state_set(&ep->com, MPA_REQ_RCVD);
- stop_ep_timer(ep);
-
- /* drive upcall */
- mutex_lock(&ep->parent_ep->com.mutex);
- if (ep->parent_ep->com.state != DEAD) {
- if (connect_request_upcall(ep))
+ /*
+ * If the endpoint timer already expired, then we ignore
+ * the start request. process_timeout() will abort
+ * the connection.
+ */
+ if (!stop_ep_timer(ep)) {
+ __state_set(&ep->com, MPA_REQ_RCVD);
+
+ /* drive upcall */
+ mutex_lock(&ep->parent_ep->com.mutex);
+ if (ep->parent_ep->com.state != DEAD) {
+ if (connect_request_upcall(ep))
+ abort_connection(ep, skb, GFP_KERNEL);
+ } else {
abort_connection(ep, skb, GFP_KERNEL);
- } else {
- abort_connection(ep, skb, GFP_KERNEL);
+ }
+ mutex_unlock(&ep->parent_ep->com.mutex);
}
- mutex_unlock(&ep->parent_ep->com.mutex);
return;
}
@@ -2265,7 +2270,7 @@ static int peer_close(struct c4iw_dev *dev, struct sk_buff *skb)
disconnect = 0;
break;
case MORIBUND:
- stop_ep_timer(ep);
+ (void)stop_ep_timer(ep);
if (ep->com.cm_id && ep->com.qp) {
attrs.next_state = C4IW_QP_STATE_IDLE;
c4iw_modify_qp(ep->com.qp->rhp, ep->com.qp,
@@ -2325,10 +2330,10 @@ static int peer_abort(struct c4iw_dev *dev, struct sk_buff *skb)
case CONNECTING:
break;
case MPA_REQ_WAIT:
- stop_ep_timer(ep);
+ (void)stop_ep_timer(ep);
break;
case MPA_REQ_SENT:
- stop_ep_timer(ep);
+ (void)stop_ep_timer(ep);
if (mpa_rev == 1 || (mpa_rev == 2 && ep->tried_with_mpa_v1))
connect_reply_upcall(ep, -ECONNRESET);
else {
@@ -2433,7 +2438,7 @@ static int close_con_rpl(struct c4iw_dev *dev, struct sk_buff *skb)
__state_set(&ep->com, MORIBUND);
break;
case MORIBUND:
- stop_ep_timer(ep);
+ (void)stop_ep_timer(ep);
if ((ep->com.cm_id) && (ep->com.qp)) {
attrs.next_state = C4IW_QP_STATE_IDLE;
c4iw_modify_qp(ep->com.qp->rhp,
@@ -3028,7 +3033,7 @@ int c4iw_ep_disconnect(struct c4iw_ep *ep, int abrupt, gfp_t gfp)
if (!test_and_set_bit(CLOSE_SENT, &ep->com.flags)) {
close = 1;
if (abrupt) {
- stop_ep_timer(ep);
+ (void)stop_ep_timer(ep);
ep->com.state = ABORTING;
} else
ep->com.state = MORIBUND;
@@ -3462,6 +3467,16 @@ static void process_timeout(struct c4iw_ep *ep)
__state_set(&ep->com, ABORTING);
close_complete_upcall(ep, -ETIMEDOUT);
break;
+ case ABORTING:
+ case DEAD:
+
+ /*
+ * These states are expected if the ep timed out at the same
+ * time as another thread was calling stop_ep_timer().
+ * So we silently do nothing for these states.
+ */
+ abort = 0;
+ break;
default:
WARN(1, "%s unexpected state ep %p tid %u state %u\n",
__func__, ep, ep->hwtid, ep->com.state);
@@ -3483,6 +3498,8 @@ static void process_timedout_eps(void)
tmp = timeout_list.next;
list_del(tmp);
+ tmp->next = NULL;
+ tmp->prev = NULL;
spin_unlock_irq(&timeout_lock);
ep = list_entry(tmp, struct c4iw_ep, entry);
process_timeout(ep);
@@ -3499,6 +3516,7 @@ static void process_work(struct work_struct *work)
unsigned int opcode;
int ret;
+ process_timedout_eps();
while ((skb = skb_dequeue(&rxq))) {
rpl = cplhdr(skb);
dev = *((struct c4iw_dev **) (skb->cb + sizeof(void *)));
@@ -3508,8 +3526,8 @@ static void process_work(struct work_struct *work)
ret = work_handlers[opcode](dev, skb);
if (!ret)
kfree_skb(skb);
+ process_timedout_eps();
}
- process_timedout_eps();
}
static DECLARE_WORK(skb_work, process_work);
@@ -3521,8 +3539,13 @@ static void ep_timeout(unsigned long arg)
spin_lock(&timeout_lock);
if (!test_and_set_bit(TIMEOUT, &ep->com.flags)) {
- list_add_tail(&ep->entry, &timeout_list);
- kickit = 1;
+ /*
+ * Only insert if it is not already on the list.
+ */
+ if (!ep->entry.next) {
+ list_add_tail(&ep->entry, &timeout_list);
+ kickit = 1;
+ }
}
spin_unlock(&timeout_lock);
if (kickit)
diff --git a/drivers/infiniband/hw/cxgb4/cq.c b/drivers/infiniband/hw/cxgb4/cq.c
index ce468e5..cfaa56a 100644
--- a/drivers/infiniband/hw/cxgb4/cq.c
+++ b/drivers/infiniband/hw/cxgb4/cq.c
@@ -235,27 +235,21 @@ int c4iw_flush_sq(struct c4iw_qp *qhp)
struct t4_cq *cq = &chp->cq;
int idx;
struct t4_swsqe *swsqe;
- int error = (qhp->attr.state != C4IW_QP_STATE_CLOSING &&
- qhp->attr.state != C4IW_QP_STATE_IDLE);
if (wq->sq.flush_cidx == -1)
wq->sq.flush_cidx = wq->sq.cidx;
idx = wq->sq.flush_cidx;
BUG_ON(idx >= wq->sq.size);
while (idx != wq->sq.pidx) {
- if (error) {
- swsqe = &wq->sq.sw_sq[idx];
- BUG_ON(swsqe->flushed);
- swsqe->flushed = 1;
- insert_sq_cqe(wq, cq, swsqe);
- if (wq->sq.oldest_read == swsqe) {
- BUG_ON(swsqe->opcode != FW_RI_READ_REQ);
- advance_oldest_read(wq);
- }
- flushed++;
- } else {
- t4_sq_consume(wq);
+ swsqe = &wq->sq.sw_sq[idx];
+ BUG_ON(swsqe->flushed);
+ swsqe->flushed = 1;
+ insert_sq_cqe(wq, cq, swsqe);
+ if (wq->sq.oldest_read == swsqe) {
+ BUG_ON(swsqe->opcode != FW_RI_READ_REQ);
+ advance_oldest_read(wq);
}
+ flushed++;
if (++idx == wq->sq.size)
idx = 0;
}
@@ -678,7 +672,7 @@ skip_cqe:
static int c4iw_poll_cq_one(struct c4iw_cq *chp, struct ib_wc *wc)
{
struct c4iw_qp *qhp = NULL;
- struct t4_cqe cqe = {0, 0}, *rd_cqe;
+ struct t4_cqe uninitialized_var(cqe), *rd_cqe;
struct t4_wq *wq;
u32 credit = 0;
u8 cqe_flushed;
diff --git a/drivers/infiniband/hw/cxgb4/device.c b/drivers/infiniband/hw/cxgb4/device.c
index 9489a38..f4fa50a 100644
--- a/drivers/infiniband/hw/cxgb4/device.c
+++ b/drivers/infiniband/hw/cxgb4/device.c
@@ -682,7 +682,10 @@ static void c4iw_dealloc(struct uld_ctx *ctx)
idr_destroy(&ctx->dev->hwtid_idr);
idr_destroy(&ctx->dev->stid_idr);
idr_destroy(&ctx->dev->atid_idr);
- iounmap(ctx->dev->rdev.oc_mw_kva);
+ if (ctx->dev->rdev.bar2_kva)
+ iounmap(ctx->dev->rdev.bar2_kva);
+ if (ctx->dev->rdev.oc_mw_kva)
+ iounmap(ctx->dev->rdev.oc_mw_kva);
ib_dealloc_device(&ctx->dev->ibdev);
ctx->dev = NULL;
}
@@ -722,11 +725,31 @@ static struct c4iw_dev *c4iw_alloc(const struct cxgb4_lld_info *infop)
}
devp->rdev.lldi = *infop;
- devp->rdev.oc_mw_pa = pci_resource_start(devp->rdev.lldi.pdev, 2) +
- (pci_resource_len(devp->rdev.lldi.pdev, 2) -
- roundup_pow_of_two(devp->rdev.lldi.vr->ocq.size));
- devp->rdev.oc_mw_kva = ioremap_wc(devp->rdev.oc_mw_pa,
- devp->rdev.lldi.vr->ocq.size);
+ /*
+ * For T5 devices, we map all of BAR2 with WC.
+ * For T4 devices with onchip qp mem, we map only that part
+ * of BAR2 with WC.
+ */
+ devp->rdev.bar2_pa = pci_resource_start(devp->rdev.lldi.pdev, 2);
+ if (is_t5(devp->rdev.lldi.adapter_type)) {
+ devp->rdev.bar2_kva = ioremap_wc(devp->rdev.bar2_pa,
+ pci_resource_len(devp->rdev.lldi.pdev, 2));
+ if (!devp->rdev.bar2_kva) {
+ pr_err(MOD "Unable to ioremap BAR2\n");
+ return ERR_PTR(-EINVAL);
+ }
+ } else if (ocqp_supported(infop)) {
+ devp->rdev.oc_mw_pa =
+ pci_resource_start(devp->rdev.lldi.pdev, 2) +
+ pci_resource_len(devp->rdev.lldi.pdev, 2) -
+ roundup_pow_of_two(devp->rdev.lldi.vr->ocq.size);
+ devp->rdev.oc_mw_kva = ioremap_wc(devp->rdev.oc_mw_pa,
+ devp->rdev.lldi.vr->ocq.size);
+ if (!devp->rdev.oc_mw_kva) {
+ pr_err(MOD "Unable to ioremap onchip mem\n");
+ return ERR_PTR(-EINVAL);
+ }
+ }
PDBG(KERN_INFO MOD "ocq memory: "
"hw_start 0x%x size %u mw_pa 0x%lx mw_kva %p\n",
@@ -1003,9 +1026,11 @@ static int enable_qp_db(int id, void *p, void *data)
static void resume_rc_qp(struct c4iw_qp *qp)
{
spin_lock(&qp->lock);
- t4_ring_sq_db(&qp->wq, qp->wq.sq.wq_pidx_inc);
+ t4_ring_sq_db(&qp->wq, qp->wq.sq.wq_pidx_inc,
+ is_t5(qp->rhp->rdev.lldi.adapter_type), NULL);
qp->wq.sq.wq_pidx_inc = 0;
- t4_ring_rq_db(&qp->wq, qp->wq.rq.wq_pidx_inc);
+ t4_ring_rq_db(&qp->wq, qp->wq.rq.wq_pidx_inc,
+ is_t5(qp->rhp->rdev.lldi.adapter_type), NULL);
qp->wq.rq.wq_pidx_inc = 0;
spin_unlock(&qp->lock);
}
diff --git a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
index e872203..7b8c580 100644
--- a/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
+++ b/drivers/infiniband/hw/cxgb4/iw_cxgb4.h
@@ -149,6 +149,8 @@ struct c4iw_rdev {
struct gen_pool *ocqp_pool;
u32 flags;
struct cxgb4_lld_info lldi;
+ unsigned long bar2_pa;
+ void __iomem *bar2_kva;
unsigned long oc_mw_pa;
void __iomem *oc_mw_kva;
struct c4iw_stats stats;
diff --git a/drivers/infiniband/hw/cxgb4/mem.c b/drivers/infiniband/hw/cxgb4/mem.c
index f9ca072..ec7a298 100644
--- a/drivers/infiniband/hw/cxgb4/mem.c
+++ b/drivers/infiniband/hw/cxgb4/mem.c
@@ -259,8 +259,12 @@ static int write_tpt_entry(struct c4iw_rdev *rdev, u32 reset_tpt_entry,
if ((!reset_tpt_entry) && (*stag == T4_STAG_UNSET)) {
stag_idx = c4iw_get_resource(&rdev->resource.tpt_table);
- if (!stag_idx)
+ if (!stag_idx) {
+ mutex_lock(&rdev->stats.lock);
+ rdev->stats.stag.fail++;
+ mutex_unlock(&rdev->stats.lock);
return -ENOMEM;
+ }
mutex_lock(&rdev->stats.lock);
rdev->stats.stag.cur += 32;
if (rdev->stats.stag.cur > rdev->stats.stag.max)
diff --git a/drivers/infiniband/hw/cxgb4/provider.c b/drivers/infiniband/hw/cxgb4/provider.c
index 7942925..a94a3e1 100644
--- a/drivers/infiniband/hw/cxgb4/provider.c
+++ b/drivers/infiniband/hw/cxgb4/provider.c
@@ -328,7 +328,7 @@ static int c4iw_query_device(struct ib_device *ibdev,
props->max_mr = c4iw_num_stags(&dev->rdev);
props->max_pd = T4_MAX_NUM_PD;
props->local_ca_ack_delay = 0;
- props->max_fast_reg_page_list_len = T4_MAX_FR_DEPTH;
+ props->max_fast_reg_page_list_len = t4_max_fr_depth(use_dsgl);
return 0;
}
diff --git a/drivers/infiniband/hw/cxgb4/qp.c b/drivers/infiniband/hw/cxgb4/qp.c
index cb76eb5..7b5114c 100644
--- a/drivers/infiniband/hw/cxgb4/qp.c
+++ b/drivers/infiniband/hw/cxgb4/qp.c
@@ -212,13 +212,23 @@ static int create_qp(struct c4iw_rdev *rdev, struct t4_wq *wq,
wq->db = rdev->lldi.db_reg;
wq->gts = rdev->lldi.gts_reg;
- if (user) {
- wq->sq.udb = (u64)pci_resource_start(rdev->lldi.pdev, 2) +
- (wq->sq.qid << rdev->qpshift);
- wq->sq.udb &= PAGE_MASK;
- wq->rq.udb = (u64)pci_resource_start(rdev->lldi.pdev, 2) +
- (wq->rq.qid << rdev->qpshift);
- wq->rq.udb &= PAGE_MASK;
+ if (user || is_t5(rdev->lldi.adapter_type)) {
+ u32 off;
+
+ off = (wq->sq.qid << rdev->qpshift) & PAGE_MASK;
+ if (user) {
+ wq->sq.udb = (u64 __iomem *)(rdev->bar2_pa + off);
+ } else {
+ off += 128 * (wq->sq.qid & rdev->qpmask) + 8;
+ wq->sq.udb = (u64 __iomem *)(rdev->bar2_kva + off);
+ }
+ off = (wq->rq.qid << rdev->qpshift) & PAGE_MASK;
+ if (user) {
+ wq->rq.udb = (u64 __iomem *)(rdev->bar2_pa + off);
+ } else {
+ off += 128 * (wq->rq.qid & rdev->qpmask) + 8;
+ wq->rq.udb = (u64 __iomem *)(rdev->bar2_kva + off);
+ }
}
wq->rdev = rdev;
wq->rq.msn = 1;
@@ -299,9 +309,10 @@ static int create_qp(struct c4iw_rdev *rdev, struct t4_wq *wq,
if (ret)
goto free_dma;
- PDBG("%s sqid 0x%x rqid 0x%x kdb 0x%p squdb 0x%llx rqudb 0x%llx\n",
+ PDBG("%s sqid 0x%x rqid 0x%x kdb 0x%p squdb 0x%lx rqudb 0x%lx\n",
__func__, wq->sq.qid, wq->rq.qid, wq->db,
- (unsigned long long)wq->sq.udb, (unsigned long long)wq->rq.udb);
+ (__force unsigned long) wq->sq.udb,
+ (__force unsigned long) wq->rq.udb);
return 0;
free_dma:
@@ -425,6 +436,8 @@ static int build_rdma_send(struct t4_sq *sq, union t4_wr *wqe,
default:
return -EINVAL;
}
+ wqe->send.r3 = 0;
+ wqe->send.r4 = 0;
plen = 0;
if (wr->num_sge) {
@@ -555,7 +568,8 @@ static int build_fastreg(struct t4_sq *sq, union t4_wr *wqe,
int pbllen = roundup(wr->wr.fast_reg.page_list_len * sizeof(u64), 32);
int rem;
- if (wr->wr.fast_reg.page_list_len > T4_MAX_FR_DEPTH)
+ if (wr->wr.fast_reg.page_list_len >
+ t4_max_fr_depth(use_dsgl))
return -EINVAL;
wqe->fr.qpbinde_to_dcacpu = 0;
@@ -650,9 +664,10 @@ static int ring_kernel_sq_db(struct c4iw_qp *qhp, u16 inc)
spin_lock_irqsave(&qhp->rhp->lock, flags);
spin_lock(&qhp->lock);
- if (qhp->rhp->db_state == NORMAL) {
- t4_ring_sq_db(&qhp->wq, inc);
- } else {
+ if (qhp->rhp->db_state == NORMAL)
+ t4_ring_sq_db(&qhp->wq, inc,
+ is_t5(qhp->rhp->rdev.lldi.adapter_type), NULL);
+ else {
add_to_fc_list(&qhp->rhp->db_fc_list, &qhp->db_fc_entry);
qhp->wq.sq.wq_pidx_inc += inc;
}
@@ -667,9 +682,10 @@ static int ring_kernel_rq_db(struct c4iw_qp *qhp, u16 inc)
spin_lock_irqsave(&qhp->rhp->lock, flags);
spin_lock(&qhp->lock);
- if (qhp->rhp->db_state == NORMAL) {
- t4_ring_rq_db(&qhp->wq, inc);
- } else {
+ if (qhp->rhp->db_state == NORMAL)
+ t4_ring_rq_db(&qhp->wq, inc,
+ is_t5(qhp->rhp->rdev.lldi.adapter_type), NULL);
+ else {
add_to_fc_list(&qhp->rhp->db_fc_list, &qhp->db_fc_entry);
qhp->wq.rq.wq_pidx_inc += inc;
}
@@ -686,7 +702,7 @@ int c4iw_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
enum fw_wr_opcodes fw_opcode = 0;
enum fw_ri_wr_flags fw_flags;
struct c4iw_qp *qhp;
- union t4_wr *wqe;
+ union t4_wr *wqe = NULL;
u32 num_wrs;
struct t4_swsqe *swsqe;
unsigned long flag;
@@ -792,7 +808,8 @@ int c4iw_post_send(struct ib_qp *ibqp, struct ib_send_wr *wr,
idx += DIV_ROUND_UP(len16*16, T4_EQ_ENTRY_SIZE);
}
if (!qhp->rhp->rdev.status_page->db_off) {
- t4_ring_sq_db(&qhp->wq, idx);
+ t4_ring_sq_db(&qhp->wq, idx,
+ is_t5(qhp->rhp->rdev.lldi.adapter_type), wqe);
spin_unlock_irqrestore(&qhp->lock, flag);
} else {
spin_unlock_irqrestore(&qhp->lock, flag);
@@ -806,7 +823,7 @@ int c4iw_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr,
{
int err = 0;
struct c4iw_qp *qhp;
- union t4_recv_wr *wqe;
+ union t4_recv_wr *wqe = NULL;
u32 num_wrs;
u8 len16 = 0;
unsigned long flag;
@@ -858,7 +875,8 @@ int c4iw_post_receive(struct ib_qp *ibqp, struct ib_recv_wr *wr,
num_wrs--;
}
if (!qhp->rhp->rdev.status_page->db_off) {
- t4_ring_rq_db(&qhp->wq, idx);
+ t4_ring_rq_db(&qhp->wq, idx,
+ is_t5(qhp->rhp->rdev.lldi.adapter_type), wqe);
spin_unlock_irqrestore(&qhp->lock, flag);
} else {
spin_unlock_irqrestore(&qhp->lock, flag);
@@ -1352,6 +1370,7 @@ int c4iw_modify_qp(struct c4iw_dev *rhp, struct c4iw_qp *qhp,
switch (attrs->next_state) {
case C4IW_QP_STATE_CLOSING:
BUG_ON(atomic_read(&qhp->ep->com.kref.refcount) < 2);
+ t4_set_wq_in_error(&qhp->wq);
set_state(qhp, C4IW_QP_STATE_CLOSING);
ep = qhp->ep;
if (!internal) {
@@ -1359,18 +1378,18 @@ int c4iw_modify_qp(struct c4iw_dev *rhp, struct c4iw_qp *qhp,
disconnect = 1;
c4iw_get_ep(&qhp->ep->com);
}
- t4_set_wq_in_error(&qhp->wq);
ret = rdma_fini(rhp, qhp, ep);
if (ret)
goto err;
break;
case C4IW_QP_STATE_TERMINATE:
+ t4_set_wq_in_error(&qhp->wq);
set_state(qhp, C4IW_QP_STATE_TERMINATE);
qhp->attr.layer_etype = attrs->layer_etype;
qhp->attr.ecode = attrs->ecode;
- t4_set_wq_in_error(&qhp->wq);
ep = qhp->ep;
disconnect = 1;
+ c4iw_get_ep(&qhp->ep->com);
if (!internal)
terminate = 1;
else {
@@ -1378,11 +1397,10 @@ int c4iw_modify_qp(struct c4iw_dev *rhp, struct c4iw_qp *qhp,
if (ret)
goto err;
}
- c4iw_get_ep(&qhp->ep->com);
break;
case C4IW_QP_STATE_ERROR:
- set_state(qhp, C4IW_QP_STATE_ERROR);
t4_set_wq_in_error(&qhp->wq);
+ set_state(qhp, C4IW_QP_STATE_ERROR);
if (!internal) {
abort = 1;
disconnect = 1;
@@ -1677,11 +1695,11 @@ struct ib_qp *c4iw_create_qp(struct ib_pd *pd, struct ib_qp_init_attr *attrs,
mm2->len = PAGE_ALIGN(qhp->wq.rq.memsize);
insert_mmap(ucontext, mm2);
mm3->key = uresp.sq_db_gts_key;
- mm3->addr = qhp->wq.sq.udb;
+ mm3->addr = (__force unsigned long) qhp->wq.sq.udb;
mm3->len = PAGE_SIZE;
insert_mmap(ucontext, mm3);
mm4->key = uresp.rq_db_gts_key;
- mm4->addr = qhp->wq.rq.udb;
+ mm4->addr = (__force unsigned long) qhp->wq.rq.udb;
mm4->len = PAGE_SIZE;
insert_mmap(ucontext, mm4);
if (mm5) {
diff --git a/drivers/infiniband/hw/cxgb4/resource.c b/drivers/infiniband/hw/cxgb4/resource.c
index cdef4d7..67df71a 100644
--- a/drivers/infiniband/hw/cxgb4/resource.c
+++ b/drivers/infiniband/hw/cxgb4/resource.c
@@ -179,8 +179,12 @@ u32 c4iw_get_qpid(struct c4iw_rdev *rdev, struct c4iw_dev_ucontext *uctx)
kfree(entry);
} else {
qid = c4iw_get_resource(&rdev->resource.qid_table);
- if (!qid)
+ if (!qid) {
+ mutex_lock(&rdev->stats.lock);
+ rdev->stats.qid.fail++;
+ mutex_unlock(&rdev->stats.lock);
goto out;
+ }
mutex_lock(&rdev->stats.lock);
rdev->stats.qid.cur += rdev->qpmask + 1;
mutex_unlock(&rdev->stats.lock);
@@ -322,8 +326,8 @@ u32 c4iw_rqtpool_alloc(struct c4iw_rdev *rdev, int size)
unsigned long addr = gen_pool_alloc(rdev->rqt_pool, size << 6);
PDBG("%s addr 0x%x size %d\n", __func__, (u32)addr, size << 6);
if (!addr)
- printk_ratelimited(KERN_WARNING MOD "%s: Out of RQT memory\n",
- pci_name(rdev->lldi.pdev));
+ pr_warn_ratelimited(MOD "%s: Out of RQT memory\n",
+ pci_name(rdev->lldi.pdev));
mutex_lock(&rdev->stats.lock);
if (addr) {
rdev->stats.rqt.cur += roundup(size << 6, 1 << MIN_RQT_SHIFT);
diff --git a/drivers/infiniband/hw/cxgb4/t4.h b/drivers/infiniband/hw/cxgb4/t4.h
index eeca8b1..2178f31 100644
--- a/drivers/infiniband/hw/cxgb4/t4.h
+++ b/drivers/infiniband/hw/cxgb4/t4.h
@@ -84,7 +84,14 @@ struct t4_status_page {
sizeof(struct fw_ri_isgl)) / sizeof(struct fw_ri_sge))
#define T4_MAX_FR_IMMD ((T4_SQ_NUM_BYTES - sizeof(struct fw_ri_fr_nsmr_wr) - \
sizeof(struct fw_ri_immd)) & ~31UL)
-#define T4_MAX_FR_DEPTH (1024 / sizeof(u64))
+#define T4_MAX_FR_IMMD_DEPTH (T4_MAX_FR_IMMD / sizeof(u64))
+#define T4_MAX_FR_DSGL 1024
+#define T4_MAX_FR_DSGL_DEPTH (T4_MAX_FR_DSGL / sizeof(u64))
+
+static inline int t4_max_fr_depth(int use_dsgl)
+{
+ return use_dsgl ? T4_MAX_FR_DSGL_DEPTH : T4_MAX_FR_IMMD_DEPTH;
+}
#define T4_RQ_NUM_SLOTS 2
#define T4_RQ_NUM_BYTES (T4_EQ_ENTRY_SIZE * T4_RQ_NUM_SLOTS)
@@ -292,7 +299,7 @@ struct t4_sq {
unsigned long phys_addr;
struct t4_swsqe *sw_sq;
struct t4_swsqe *oldest_read;
- u64 udb;
+ u64 __iomem *udb;
size_t memsize;
u32 qid;
u16 in_use;
@@ -314,7 +321,7 @@ struct t4_rq {
dma_addr_t dma_addr;
DEFINE_DMA_UNMAP_ADDR(mapping);
struct t4_swrqe *sw_rq;
- u64 udb;
+ u64 __iomem *udb;
size_t memsize;
u32 qid;
u32 msn;
@@ -435,15 +442,67 @@ static inline u16 t4_sq_wq_size(struct t4_wq *wq)
return wq->sq.size * T4_SQ_NUM_SLOTS;
}
-static inline void t4_ring_sq_db(struct t4_wq *wq, u16 inc)
+/* This function copies 64 byte coalesced work request to memory
+ * mapped BAR2 space. For coalesced WRs, the SGE fetches data
+ * from the FIFO instead of from Host.
+ */
+static inline void pio_copy(u64 __iomem *dst, u64 *src)
+{
+ int count = 8;
+
+ while (count) {
+ writeq(*src, dst);
+ src++;
+ dst++;
+ count--;
+ }
+}
+
+static inline void t4_ring_sq_db(struct t4_wq *wq, u16 inc, u8 t5,
+ union t4_wr *wqe)
{
+
+ /* Flush host queue memory writes. */
wmb();
+ if (t5) {
+ if (inc == 1 && wqe) {
+ PDBG("%s: WC wq->sq.pidx = %d\n",
+ __func__, wq->sq.pidx);
+ pio_copy(wq->sq.udb + 7, (void *)wqe);
+ } else {
+ PDBG("%s: DB wq->sq.pidx = %d\n",
+ __func__, wq->sq.pidx);
+ writel(PIDX_T5(inc), wq->sq.udb);
+ }
+
+ /* Flush user doorbell area writes. */
+ wmb();
+ return;
+ }
writel(QID(wq->sq.qid) | PIDX(inc), wq->db);
}
-static inline void t4_ring_rq_db(struct t4_wq *wq, u16 inc)
+static inline void t4_ring_rq_db(struct t4_wq *wq, u16 inc, u8 t5,
+ union t4_recv_wr *wqe)
{
+
+ /* Flush host queue memory writes. */
wmb();
+ if (t5) {
+ if (inc == 1 && wqe) {
+ PDBG("%s: WC wq->rq.pidx = %d\n",
+ __func__, wq->rq.pidx);
+ pio_copy(wq->rq.udb + 7, (void *)wqe);
+ } else {
+ PDBG("%s: DB wq->rq.pidx = %d\n",
+ __func__, wq->rq.pidx);
+ writel(PIDX_T5(inc), wq->rq.udb);
+ }
+
+ /* Flush user doorbell area writes. */
+ wmb();
+ return;
+ }
writel(QID(wq->rq.qid) | PIDX(inc), wq->db);
}
@@ -568,6 +627,9 @@ static inline int t4_next_hw_cqe(struct t4_cq *cq, struct t4_cqe **cqe)
printk(KERN_ERR MOD "cq overflow cqid %u\n", cq->cqid);
BUG_ON(1);
} else if (t4_valid_cqe(cq, &cq->queue[cq->cidx])) {
+
+ /* Ensure CQE is flushed to memory */
+ rmb();
*cqe = &cq->queue[cq->cidx];
ret = 0;
} else
diff --git a/drivers/infiniband/hw/mlx5/main.c b/drivers/infiniband/hw/mlx5/main.c
index fa6dc87..364d4b6 100644
--- a/drivers/infiniband/hw/mlx5/main.c
+++ b/drivers/infiniband/hw/mlx5/main.c
@@ -282,6 +282,8 @@ static int mlx5_ib_query_device(struct ib_device *ibdev,
props->sig_guard_cap = IB_GUARD_T10DIF_CRC |
IB_GUARD_T10DIF_CSUM;
}
+ if (flags & MLX5_DEV_CAP_FLAG_BLOCK_MCAST)
+ props->device_cap_flags |= IB_DEVICE_BLOCK_MULTICAST_LOOPBACK;
props->vendor_id = be32_to_cpup((__be32 *)(out_mad->data + 36)) &
0xffffff;
diff --git a/drivers/infiniband/hw/mlx5/qp.c b/drivers/infiniband/hw/mlx5/qp.c
index ae788d27..dc930ed 100644
--- a/drivers/infiniband/hw/mlx5/qp.c
+++ b/drivers/infiniband/hw/mlx5/qp.c
@@ -807,6 +807,15 @@ static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd,
spin_lock_init(&qp->sq.lock);
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)) {
+ mlx5_ib_dbg(dev, "block multicast loopback isn't supported\n");
+ return -EINVAL;
+ } else {
+ qp->flags |= MLX5_IB_QP_BLOCK_MULTICAST_LOOPBACK;
+ }
+ }
+
if (init_attr->sq_sig_type == IB_SIGNAL_ALL_WR)
qp->sq_signal_bits = MLX5_WQE_CTRL_CQ_UPDATE;
@@ -878,6 +887,9 @@ static int create_qp_common(struct mlx5_ib_dev *dev, struct ib_pd *pd,
if (qp->wq_sig)
in->ctx.flags_pd |= cpu_to_be32(MLX5_QP_ENABLE_SIG);
+ if (qp->flags & MLX5_IB_QP_BLOCK_MULTICAST_LOOPBACK)
+ in->ctx.flags_pd |= cpu_to_be32(MLX5_QP_BLOCK_MCAST);
+
if (qp->scat_cqe && is_connected(init_attr->qp_type)) {
int rcqe_sz;
int scqe_sz;
diff --git a/drivers/infiniband/hw/mthca/mthca_main.c b/drivers/infiniband/hw/mthca/mthca_main.c
index 87897b9..ded76c1 100644
--- a/drivers/infiniband/hw/mthca/mthca_main.c
+++ b/drivers/infiniband/hw/mthca/mthca_main.c
@@ -858,13 +858,9 @@ static int mthca_enable_msi_x(struct mthca_dev *mdev)
entries[1].entry = 1;
entries[2].entry = 2;
- err = pci_enable_msix(mdev->pdev, entries, ARRAY_SIZE(entries));
- if (err) {
- if (err > 0)
- mthca_info(mdev, "Only %d MSI-X vectors available, "
- "not using MSI-X\n", err);
+ err = pci_enable_msix_exact(mdev->pdev, entries, ARRAY_SIZE(entries));
+ if (err)
return err;
- }
mdev->eq_table.eq[MTHCA_EQ_COMP ].msi_x_vector = entries[0].vector;
mdev->eq_table.eq[MTHCA_EQ_ASYNC].msi_x_vector = entries[1].vector;
diff --git a/drivers/infiniband/hw/qib/qib_pcie.c b/drivers/infiniband/hw/qib/qib_pcie.c
index c8d9c4a..61a0046 100644
--- a/drivers/infiniband/hw/qib/qib_pcie.c
+++ b/drivers/infiniband/hw/qib/qib_pcie.c
@@ -197,46 +197,47 @@ static void qib_msix_setup(struct qib_devdata *dd, int pos, u32 *msixcnt,
struct qib_msix_entry *qib_msix_entry)
{
int ret;
- u32 tabsize = 0;
- u16 msix_flags;
+ int nvec = *msixcnt;
struct msix_entry *msix_entry;
int i;
+ ret = pci_msix_vec_count(dd->pcidev);
+ if (ret < 0)
+ goto do_intx;
+
+ nvec = min(nvec, ret);
+
/* We can't pass qib_msix_entry array to qib_msix_setup
* so use a dummy msix_entry array and copy the allocated
* irq back to the qib_msix_entry array. */
- msix_entry = kmalloc(*msixcnt * sizeof(*msix_entry), GFP_KERNEL);
- if (!msix_entry) {
- ret = -ENOMEM;
+ msix_entry = kmalloc(nvec * sizeof(*msix_entry), GFP_KERNEL);
+ if (!msix_entry)
goto do_intx;
- }
- for (i = 0; i < *msixcnt; i++)
+
+ for (i = 0; i < nvec; i++)
msix_entry[i] = qib_msix_entry[i].msix;
- pci_read_config_word(dd->pcidev, pos + PCI_MSIX_FLAGS, &msix_flags);
- tabsize = 1 + (msix_flags & PCI_MSIX_FLAGS_QSIZE);
- if (tabsize > *msixcnt)
- tabsize = *msixcnt;
- ret = pci_enable_msix(dd->pcidev, msix_entry, tabsize);
- if (ret > 0) {
- tabsize = ret;
- ret = pci_enable_msix(dd->pcidev, msix_entry, tabsize);
- }
-do_intx:
- if (ret) {
- qib_dev_err(dd,
- "pci_enable_msix %d vectors failed: %d, falling back to INTx\n",
- tabsize, ret);
- tabsize = 0;
- }
- for (i = 0; i < tabsize; i++)
+ ret = pci_enable_msix_range(dd->pcidev, msix_entry, 1, nvec);
+ if (ret < 0)
+ goto free_msix_entry;
+ else
+ nvec = ret;
+
+ for (i = 0; i < nvec; i++)
qib_msix_entry[i].msix = msix_entry[i];
+
kfree(msix_entry);
- *msixcnt = tabsize;
+ *msixcnt = nvec;
+ return;
- if (ret)
- qib_enable_intx(dd->pcidev);
+free_msix_entry:
+ kfree(msix_entry);
+do_intx:
+ qib_dev_err(dd, "pci_enable_msix_range %d vectors failed: %d, "
+ "falling back to INTx\n", nvec, ret);
+ *msixcnt = 0;
+ qib_enable_intx(dd->pcidev);
}
/**
diff --git a/drivers/irqchip/irq-vic.c b/drivers/irqchip/irq-vic.c
index 37dab0b..7d35287 100644
--- a/drivers/irqchip/irq-vic.c
+++ b/drivers/irqchip/irq-vic.c
@@ -24,6 +24,7 @@
#include <linux/list.h>
#include <linux/io.h>
#include <linux/irq.h>
+#include <linux/irqchip/chained_irq.h>
#include <linux/irqdomain.h>
#include <linux/of.h>
#include <linux/of_address.h>
@@ -228,12 +229,17 @@ static int handle_one_vic(struct vic_device *vic, struct pt_regs *regs)
static void vic_handle_irq_cascaded(unsigned int irq, struct irq_desc *desc)
{
u32 stat, hwirq;
+ struct irq_chip *host_chip = irq_desc_get_chip(desc);
struct vic_device *vic = irq_desc_get_handler_data(desc);
+ chained_irq_enter(host_chip, desc);
+
while ((stat = readl_relaxed(vic->base + VIC_IRQ_STATUS))) {
hwirq = ffs(stat) - 1;
generic_handle_irq(irq_find_mapping(vic->domain, hwirq));
}
+
+ chained_irq_exit(host_chip, desc);
}
/*
diff --git a/drivers/irqchip/spear-shirq.c b/drivers/irqchip/spear-shirq.c
index 8527743..3fdda3a 100644
--- a/drivers/irqchip/spear-shirq.c
+++ b/drivers/irqchip/spear-shirq.c
@@ -5,7 +5,7 @@
* Viresh Kumar <viresh.linux@gmail.com>
*
* Copyright (C) 2012 ST Microelectronics
- * Shiraz Hashim <shiraz.hashim@st.com>
+ * Shiraz Hashim <shiraz.linux.kernel@gmail.com>
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
diff --git a/drivers/isdn/hisax/icc.c b/drivers/isdn/hisax/icc.c
index 51dae91..96d1df0 100644
--- a/drivers/isdn/hisax/icc.c
+++ b/drivers/isdn/hisax/icc.c
@@ -425,7 +425,7 @@ afterXPR:
if (cs->debug & L1_DEB_MONITOR)
debugl1(cs, "ICC %02x -> MOX1", cs->dc.icc.mon_tx[cs->dc.icc.mon_txp - 1]);
}
- AfterMOX1:
+ AfterMOX1: ;
#endif
}
}
diff --git a/drivers/mcb/mcb-parse.c b/drivers/mcb/mcb-parse.c
index d1278b5..0049269 100644
--- a/drivers/mcb/mcb-parse.c
+++ b/drivers/mcb/mcb-parse.c
@@ -141,6 +141,7 @@ int chameleon_parse_cells(struct mcb_bus *bus, phys_addr_t mapbase,
default:
pr_err("Invalid chameleon descriptor type 0x%x\n",
dtype);
+ kfree(header);
return -EINVAL;
}
num_cells++;
diff --git a/drivers/md/raid5.c b/drivers/md/raid5.c
index 25247a8..ad1b9be 100644
--- a/drivers/md/raid5.c
+++ b/drivers/md/raid5.c
@@ -4370,8 +4370,7 @@ static struct stripe_head *__get_priority_stripe(struct r5conf *conf, int group)
sh->group = NULL;
}
list_del_init(&sh->lru);
- atomic_inc(&sh->count);
- BUG_ON(atomic_read(&sh->count) != 1);
+ BUG_ON(atomic_inc_return(&sh->count) != 1);
return sh;
}
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 1cb7408..8baff0e 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -300,8 +300,8 @@ config SGI_GRU_DEBUG
depends on SGI_GRU
default n
---help---
- This option enables addition debugging code for the SGI GRU driver. If
- you are unsure, say N.
+ This option enables additional debugging code for the SGI GRU driver.
+ If you are unsure, say N.
config APDS9802ALS
tristate "Medfield Avago APDS9802 ALS Sensor module"
diff --git a/drivers/misc/genwqe/card_base.h b/drivers/misc/genwqe/card_base.h
index 5e4dbd2..0e608a2 100644
--- a/drivers/misc/genwqe/card_base.h
+++ b/drivers/misc/genwqe/card_base.h
@@ -337,6 +337,44 @@ enum genwqe_requ_state {
};
/**
+ * struct genwqe_sgl - Scatter gather list describing user-space memory
+ * @sgl: scatter gather list needs to be 128 byte aligned
+ * @sgl_dma_addr: dma address of sgl
+ * @sgl_size: size of area used for sgl
+ * @user_addr: user-space address of memory area
+ * @user_size: size of user-space memory area
+ * @page: buffer for partial pages if needed
+ * @page_dma_addr: dma address partial pages
+ */
+struct genwqe_sgl {
+ dma_addr_t sgl_dma_addr;
+ struct sg_entry *sgl;
+ size_t sgl_size; /* size of sgl */
+
+ void __user *user_addr; /* user-space base-address */
+ size_t user_size; /* size of memory area */
+
+ unsigned long nr_pages;
+ unsigned long fpage_offs;
+ size_t fpage_size;
+ size_t lpage_size;
+
+ void *fpage;
+ dma_addr_t fpage_dma_addr;
+
+ void *lpage;
+ dma_addr_t lpage_dma_addr;
+};
+
+int genwqe_alloc_sync_sgl(struct genwqe_dev *cd, struct genwqe_sgl *sgl,
+ void __user *user_addr, size_t user_size);
+
+int genwqe_setup_sgl(struct genwqe_dev *cd, struct genwqe_sgl *sgl,
+ dma_addr_t *dma_list);
+
+int genwqe_free_sync_sgl(struct genwqe_dev *cd, struct genwqe_sgl *sgl);
+
+/**
* struct ddcb_requ - Kernel internal representation of the DDCB request
* @cmd: User space representation of the DDCB execution request
*/
@@ -347,9 +385,7 @@ struct ddcb_requ {
struct ddcb_queue *queue; /* associated queue */
struct dma_mapping dma_mappings[DDCB_FIXUPS];
- struct sg_entry *sgl[DDCB_FIXUPS];
- dma_addr_t sgl_dma_addr[DDCB_FIXUPS];
- size_t sgl_size[DDCB_FIXUPS];
+ struct genwqe_sgl sgls[DDCB_FIXUPS];
/* kernel/user shared content */
struct genwqe_ddcb_cmd cmd; /* ddcb_no for this request */
@@ -453,22 +489,6 @@ int genwqe_user_vmap(struct genwqe_dev *cd, struct dma_mapping *m,
int genwqe_user_vunmap(struct genwqe_dev *cd, struct dma_mapping *m,
struct ddcb_requ *req);
-struct sg_entry *genwqe_alloc_sgl(struct genwqe_dev *cd, int num_pages,
- dma_addr_t *dma_addr, size_t *sgl_size);
-
-void genwqe_free_sgl(struct genwqe_dev *cd, struct sg_entry *sg_list,
- dma_addr_t dma_addr, size_t size);
-
-int genwqe_setup_sgl(struct genwqe_dev *cd,
- unsigned long offs,
- unsigned long size,
- struct sg_entry *sgl, /* genwqe sgl */
- dma_addr_t dma_addr, size_t sgl_size,
- dma_addr_t *dma_list, int page_offs, int num_pages);
-
-int genwqe_check_sgl(struct genwqe_dev *cd, struct sg_entry *sg_list,
- int size);
-
static inline bool dma_mapping_used(struct dma_mapping *m)
{
if (!m)
diff --git a/drivers/misc/genwqe/card_ddcb.c b/drivers/misc/genwqe/card_ddcb.c
index 6f1acc0..c8046db 100644
--- a/drivers/misc/genwqe/card_ddcb.c
+++ b/drivers/misc/genwqe/card_ddcb.c
@@ -305,6 +305,8 @@ static int enqueue_ddcb(struct genwqe_dev *cd, struct ddcb_queue *queue,
break;
new = (old | DDCB_NEXT_BE32);
+
+ wmb();
icrc_hsi_shi = cmpxchg(&prev_ddcb->icrc_hsi_shi_32, old, new);
if (icrc_hsi_shi == old)
@@ -314,6 +316,8 @@ static int enqueue_ddcb(struct genwqe_dev *cd, struct ddcb_queue *queue,
/* Queue must be re-started by updating QUEUE_OFFSET */
ddcb_mark_tapped(pddcb);
num = (u64)ddcb_no << 8;
+
+ wmb();
__genwqe_writeq(cd, queue->IO_QUEUE_OFFSET, num); /* start queue */
return RET_DDCB_TAPPED;
@@ -1306,7 +1310,7 @@ static int queue_wake_up_all(struct genwqe_dev *cd)
*/
int genwqe_finish_queue(struct genwqe_dev *cd)
{
- int i, rc, in_flight;
+ int i, rc = 0, in_flight;
int waitmax = genwqe_ddcb_software_timeout;
struct pci_dev *pci_dev = cd->pci_dev;
struct ddcb_queue *queue = &cd->queue;
diff --git a/drivers/misc/genwqe/card_dev.c b/drivers/misc/genwqe/card_dev.c
index 2c2c9cc..1d2f163 100644
--- a/drivers/misc/genwqe/card_dev.c
+++ b/drivers/misc/genwqe/card_dev.c
@@ -531,7 +531,9 @@ static int do_flash_update(struct genwqe_file *cfile,
case '1':
cmdopts = 0x1C;
break; /* download/erase_first/part_1 */
- case 'v': /* cmdopts = 0x0c (VPD) */
+ case 'v':
+ cmdopts = 0x0C;
+ break; /* download/erase_first/vpd */
default:
return -EINVAL;
}
@@ -665,6 +667,8 @@ static int do_flash_read(struct genwqe_file *cfile,
cmdopts = 0x1A;
break; /* upload/part_1 */
case 'v':
+ cmdopts = 0x0A;
+ break; /* upload/vpd */
default:
return -EINVAL;
}
@@ -836,15 +840,8 @@ static int ddcb_cmd_cleanup(struct genwqe_file *cfile, struct ddcb_requ *req)
__genwqe_del_mapping(cfile, dma_map);
genwqe_user_vunmap(cd, dma_map, req);
}
- if (req->sgl[i] != NULL) {
- genwqe_free_sgl(cd, req->sgl[i],
- req->sgl_dma_addr[i],
- req->sgl_size[i]);
- req->sgl[i] = NULL;
- req->sgl_dma_addr[i] = 0x0;
- req->sgl_size[i] = 0;
- }
-
+ if (req->sgls[i].sgl != NULL)
+ genwqe_free_sync_sgl(cd, &req->sgls[i]);
}
return 0;
}
@@ -913,7 +910,7 @@ static int ddcb_cmd_fixups(struct genwqe_file *cfile, struct ddcb_requ *req)
case ATS_TYPE_SGL_RDWR:
case ATS_TYPE_SGL_RD: {
- int page_offs, nr_pages, offs;
+ int page_offs;
u_addr = be64_to_cpu(*((__be64 *)
&cmd->asiv[asiv_offs]));
@@ -951,27 +948,18 @@ static int ddcb_cmd_fixups(struct genwqe_file *cfile, struct ddcb_requ *req)
page_offs = 0;
}
- offs = offset_in_page(u_addr);
- nr_pages = DIV_ROUND_UP(offs + u_size, PAGE_SIZE);
-
/* create genwqe style scatter gather list */
- req->sgl[i] = genwqe_alloc_sgl(cd, m->nr_pages,
- &req->sgl_dma_addr[i],
- &req->sgl_size[i]);
- if (req->sgl[i] == NULL) {
- rc = -ENOMEM;
+ rc = genwqe_alloc_sync_sgl(cd, &req->sgls[i],
+ (void __user *)u_addr,
+ u_size);
+ if (rc != 0)
goto err_out;
- }
- genwqe_setup_sgl(cd, offs, u_size,
- req->sgl[i],
- req->sgl_dma_addr[i],
- req->sgl_size[i],
- m->dma_list,
- page_offs,
- nr_pages);
+
+ genwqe_setup_sgl(cd, &req->sgls[i],
+ &m->dma_list[page_offs]);
*((__be64 *)&cmd->asiv[asiv_offs]) =
- cpu_to_be64(req->sgl_dma_addr[i]);
+ cpu_to_be64(req->sgls[i].sgl_dma_addr);
break;
}
diff --git a/drivers/misc/genwqe/card_utils.c b/drivers/misc/genwqe/card_utils.c
index 6b1a6ef..d049d27 100644
--- a/drivers/misc/genwqe/card_utils.c
+++ b/drivers/misc/genwqe/card_utils.c
@@ -275,67 +275,107 @@ static int genwqe_sgl_size(int num_pages)
return roundup(len, PAGE_SIZE);
}
-struct sg_entry *genwqe_alloc_sgl(struct genwqe_dev *cd, int num_pages,
- dma_addr_t *dma_addr, size_t *sgl_size)
+/**
+ * genwqe_alloc_sync_sgl() - Allocate memory for sgl and overlapping pages
+ *
+ * Allocates memory for sgl and overlapping pages. Pages which might
+ * overlap other user-space memory blocks are being cached for DMAs,
+ * such that we do not run into syncronization issues. Data is copied
+ * from user-space into the cached pages.
+ */
+int genwqe_alloc_sync_sgl(struct genwqe_dev *cd, struct genwqe_sgl *sgl,
+ void __user *user_addr, size_t user_size)
{
+ int rc;
struct pci_dev *pci_dev = cd->pci_dev;
- struct sg_entry *sgl;
- *sgl_size = genwqe_sgl_size(num_pages);
- if (get_order(*sgl_size) > MAX_ORDER) {
+ sgl->fpage_offs = offset_in_page((unsigned long)user_addr);
+ sgl->fpage_size = min_t(size_t, PAGE_SIZE-sgl->fpage_offs, user_size);
+ sgl->nr_pages = DIV_ROUND_UP(sgl->fpage_offs + user_size, PAGE_SIZE);
+ sgl->lpage_size = (user_size - sgl->fpage_size) % PAGE_SIZE;
+
+ dev_dbg(&pci_dev->dev, "[%s] uaddr=%p usize=%8ld nr_pages=%ld "
+ "fpage_offs=%lx fpage_size=%ld lpage_size=%ld\n",
+ __func__, user_addr, user_size, sgl->nr_pages,
+ sgl->fpage_offs, sgl->fpage_size, sgl->lpage_size);
+
+ sgl->user_addr = user_addr;
+ sgl->user_size = user_size;
+ sgl->sgl_size = genwqe_sgl_size(sgl->nr_pages);
+
+ if (get_order(sgl->sgl_size) > MAX_ORDER) {
dev_err(&pci_dev->dev,
"[%s] err: too much memory requested!\n", __func__);
- return NULL;
+ return -ENOMEM;
}
- sgl = __genwqe_alloc_consistent(cd, *sgl_size, dma_addr);
- if (sgl == NULL) {
+ sgl->sgl = __genwqe_alloc_consistent(cd, sgl->sgl_size,
+ &sgl->sgl_dma_addr);
+ if (sgl->sgl == NULL) {
dev_err(&pci_dev->dev,
"[%s] err: no memory available!\n", __func__);
- return NULL;
+ return -ENOMEM;
}
- return sgl;
+ /* Only use buffering on incomplete pages */
+ if ((sgl->fpage_size != 0) && (sgl->fpage_size != PAGE_SIZE)) {
+ sgl->fpage = __genwqe_alloc_consistent(cd, PAGE_SIZE,
+ &sgl->fpage_dma_addr);
+ if (sgl->fpage == NULL)
+ goto err_out;
+
+ /* Sync with user memory */
+ if (copy_from_user(sgl->fpage + sgl->fpage_offs,
+ user_addr, sgl->fpage_size)) {
+ rc = -EFAULT;
+ goto err_out;
+ }
+ }
+ if (sgl->lpage_size != 0) {
+ sgl->lpage = __genwqe_alloc_consistent(cd, PAGE_SIZE,
+ &sgl->lpage_dma_addr);
+ if (sgl->lpage == NULL)
+ goto err_out1;
+
+ /* Sync with user memory */
+ if (copy_from_user(sgl->lpage, user_addr + user_size -
+ sgl->lpage_size, sgl->lpage_size)) {
+ rc = -EFAULT;
+ goto err_out1;
+ }
+ }
+ return 0;
+
+ err_out1:
+ __genwqe_free_consistent(cd, PAGE_SIZE, sgl->fpage,
+ sgl->fpage_dma_addr);
+ err_out:
+ __genwqe_free_consistent(cd, sgl->sgl_size, sgl->sgl,
+ sgl->sgl_dma_addr);
+ return -ENOMEM;
}
-int genwqe_setup_sgl(struct genwqe_dev *cd,
- unsigned long offs,
- unsigned long size,
- struct sg_entry *sgl,
- dma_addr_t dma_addr, size_t sgl_size,
- dma_addr_t *dma_list, int page_offs, int num_pages)
+int genwqe_setup_sgl(struct genwqe_dev *cd, struct genwqe_sgl *sgl,
+ dma_addr_t *dma_list)
{
int i = 0, j = 0, p;
unsigned long dma_offs, map_offs;
- struct pci_dev *pci_dev = cd->pci_dev;
dma_addr_t prev_daddr = 0;
struct sg_entry *s, *last_s = NULL;
-
- /* sanity checks */
- if (offs > PAGE_SIZE) {
- dev_err(&pci_dev->dev,
- "[%s] too large start offs %08lx\n", __func__, offs);
- return -EFAULT;
- }
- if (sgl_size < genwqe_sgl_size(num_pages)) {
- dev_err(&pci_dev->dev,
- "[%s] sgl_size too small %08lx for %d pages\n",
- __func__, sgl_size, num_pages);
- return -EFAULT;
- }
+ size_t size = sgl->user_size;
dma_offs = 128; /* next block if needed/dma_offset */
- map_offs = offs; /* offset in first page */
+ map_offs = sgl->fpage_offs; /* offset in first page */
- s = &sgl[0]; /* first set of 8 entries */
+ s = &sgl->sgl[0]; /* first set of 8 entries */
p = 0; /* page */
- while (p < num_pages) {
+ while (p < sgl->nr_pages) {
dma_addr_t daddr;
unsigned int size_to_map;
/* always write the chaining entry, cleanup is done later */
j = 0;
- s[j].target_addr = cpu_to_be64(dma_addr + dma_offs);
+ s[j].target_addr = cpu_to_be64(sgl->sgl_dma_addr + dma_offs);
s[j].len = cpu_to_be32(128);
s[j].flags = cpu_to_be32(SG_CHAINED);
j++;
@@ -343,7 +383,17 @@ int genwqe_setup_sgl(struct genwqe_dev *cd,
while (j < 8) {
/* DMA mapping for requested page, offs, size */
size_to_map = min(size, PAGE_SIZE - map_offs);
- daddr = dma_list[page_offs + p] + map_offs;
+
+ if ((p == 0) && (sgl->fpage != NULL)) {
+ daddr = sgl->fpage_dma_addr + map_offs;
+
+ } else if ((p == sgl->nr_pages - 1) &&
+ (sgl->lpage != NULL)) {
+ daddr = sgl->lpage_dma_addr;
+ } else {
+ daddr = dma_list[p] + map_offs;
+ }
+
size -= size_to_map;
map_offs = 0;
@@ -358,7 +408,7 @@ int genwqe_setup_sgl(struct genwqe_dev *cd,
size_to_map);
p++; /* process next page */
- if (p == num_pages)
+ if (p == sgl->nr_pages)
goto fixup; /* nothing to do */
prev_daddr = daddr + size_to_map;
@@ -374,7 +424,7 @@ int genwqe_setup_sgl(struct genwqe_dev *cd,
j++;
p++; /* process next page */
- if (p == num_pages)
+ if (p == sgl->nr_pages)
goto fixup; /* nothing to do */
}
dma_offs += 128;
@@ -395,10 +445,50 @@ int genwqe_setup_sgl(struct genwqe_dev *cd,
return 0;
}
-void genwqe_free_sgl(struct genwqe_dev *cd, struct sg_entry *sg_list,
- dma_addr_t dma_addr, size_t size)
+/**
+ * genwqe_free_sync_sgl() - Free memory for sgl and overlapping pages
+ *
+ * After the DMA transfer has been completed we free the memory for
+ * the sgl and the cached pages. Data is being transfered from cached
+ * pages into user-space buffers.
+ */
+int genwqe_free_sync_sgl(struct genwqe_dev *cd, struct genwqe_sgl *sgl)
{
- __genwqe_free_consistent(cd, size, sg_list, dma_addr);
+ int rc;
+ struct pci_dev *pci_dev = cd->pci_dev;
+
+ if (sgl->fpage) {
+ if (copy_to_user(sgl->user_addr, sgl->fpage + sgl->fpage_offs,
+ sgl->fpage_size)) {
+ dev_err(&pci_dev->dev, "[%s] err: copying fpage!\n",
+ __func__);
+ rc = -EFAULT;
+ }
+ __genwqe_free_consistent(cd, PAGE_SIZE, sgl->fpage,
+ sgl->fpage_dma_addr);
+ sgl->fpage = NULL;
+ sgl->fpage_dma_addr = 0;
+ }
+ if (sgl->lpage) {
+ if (copy_to_user(sgl->user_addr + sgl->user_size -
+ sgl->lpage_size, sgl->lpage,
+ sgl->lpage_size)) {
+ dev_err(&pci_dev->dev, "[%s] err: copying lpage!\n",
+ __func__);
+ rc = -EFAULT;
+ }
+ __genwqe_free_consistent(cd, PAGE_SIZE, sgl->lpage,
+ sgl->lpage_dma_addr);
+ sgl->lpage = NULL;
+ sgl->lpage_dma_addr = 0;
+ }
+ __genwqe_free_consistent(cd, sgl->sgl_size, sgl->sgl,
+ sgl->sgl_dma_addr);
+
+ sgl->sgl = NULL;
+ sgl->sgl_dma_addr = 0x0;
+ sgl->sgl_size = 0;
+ return rc;
}
/**
diff --git a/drivers/misc/genwqe/genwqe_driver.h b/drivers/misc/genwqe/genwqe_driver.h
index 46e916b..cd52631 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.0"
+#define DRV_VERS_STRING "2.0.15"
/*
* Static minor number assignement, until we decide/implement
diff --git a/drivers/misc/mei/hw-me-regs.h b/drivers/misc/mei/hw-me-regs.h
index 66f411a..cabc043 100644
--- a/drivers/misc/mei/hw-me-regs.h
+++ b/drivers/misc/mei/hw-me-regs.h
@@ -115,6 +115,11 @@
#define MEI_DEV_ID_LPT_HR 0x8CBA /* Lynx Point H Refresh */
#define MEI_DEV_ID_WPT_LP 0x9CBA /* Wildcat Point LP */
+
+/* Host Firmware Status Registers in PCI Config Space */
+#define PCI_CFG_HFS_1 0x40
+#define PCI_CFG_HFS_2 0x48
+
/*
* MEI HW Section
*/
diff --git a/drivers/misc/mei/interrupt.c b/drivers/misc/mei/interrupt.c
index 29b5af8..4e3cba6d 100644
--- a/drivers/misc/mei/interrupt.c
+++ b/drivers/misc/mei/interrupt.c
@@ -455,8 +455,7 @@ int mei_irq_write_handler(struct mei_device *dev, struct mei_cl_cb *cmpl_list)
cl->status = 0;
list_del(&cb->list);
- if (MEI_WRITING == cl->writing_state &&
- cb->fop_type == MEI_FOP_WRITE &&
+ if (cb->fop_type == MEI_FOP_WRITE &&
cl != &dev->iamthif_cl) {
cl_dbg(dev, cl, "MEI WRITE COMPLETE\n");
cl->writing_state = MEI_WRITE_COMPLETE;
diff --git a/drivers/misc/mei/main.c b/drivers/misc/mei/main.c
index b35594d..1474131 100644
--- a/drivers/misc/mei/main.c
+++ b/drivers/misc/mei/main.c
@@ -644,8 +644,7 @@ static unsigned int mei_poll(struct file *file, poll_table *wait)
goto out;
}
- if (MEI_WRITE_COMPLETE == cl->writing_state)
- mask |= (POLLIN | POLLRDNORM);
+ mask |= (POLLIN | POLLRDNORM);
out:
mutex_unlock(&dev->device_lock);
diff --git a/drivers/misc/mei/pci-me.c b/drivers/misc/mei/pci-me.c
index 1c8fd3a..95889e2 100644
--- a/drivers/misc/mei/pci-me.c
+++ b/drivers/misc/mei/pci-me.c
@@ -97,15 +97,31 @@ static bool mei_me_quirk_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
u32 reg;
- if (ent->device == MEI_DEV_ID_PBG_1) {
- pci_read_config_dword(pdev, 0x48, &reg);
- /* make sure that bit 9 is up and bit 10 is down */
- if ((reg & 0x600) == 0x200) {
- dev_info(&pdev->dev, "Device doesn't have valid ME Interface\n");
- return false;
- }
+ /* Cougar Point || Patsburg */
+ if (ent->device == MEI_DEV_ID_CPT_1 ||
+ ent->device == MEI_DEV_ID_PBG_1) {
+ pci_read_config_dword(pdev, PCI_CFG_HFS_2, &reg);
+ /* make sure that bit 9 (NM) is up and bit 10 (DM) is down */
+ if ((reg & 0x600) == 0x200)
+ goto no_mei;
}
+
+ /* Lynx Point */
+ if (ent->device == MEI_DEV_ID_LPT_H ||
+ ent->device == MEI_DEV_ID_LPT_W ||
+ ent->device == MEI_DEV_ID_LPT_HR) {
+ /* Read ME FW Status check for SPS Firmware */
+ pci_read_config_dword(pdev, PCI_CFG_HFS_1, &reg);
+ /* if bits [19:16] = 15, running SPS Firmware */
+ if ((reg & 0xf0000) == 0xf0000)
+ goto no_mei;
+ }
+
return true;
+
+no_mei:
+ dev_info(&pdev->dev, "Device doesn't have valid ME Interface\n");
+ return false;
}
/**
* mei_probe - Device Initialization Routine
diff --git a/drivers/mtd/devices/spear_smi.c b/drivers/mtd/devices/spear_smi.c
index 363da96..c4176b0 100644
--- a/drivers/mtd/devices/spear_smi.c
+++ b/drivers/mtd/devices/spear_smi.c
@@ -6,7 +6,7 @@
*
* Copyright © 2010 STMicroelectronics.
* Ashish Priyadarshi
- * Shiraz Hashim <shiraz.hashim@st.com>
+ * Shiraz Hashim <shiraz.linux.kernel@gmail.com>
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
@@ -1089,5 +1089,5 @@ static struct platform_driver spear_smi_driver = {
module_platform_driver(spear_smi_driver);
MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Ashish Priyadarshi, Shiraz Hashim <shiraz.hashim@st.com>");
+MODULE_AUTHOR("Ashish Priyadarshi, Shiraz Hashim <shiraz.linux.kernel@gmail.com>");
MODULE_DESCRIPTION("MTD SMI driver for serial nor flash chips");
diff --git a/drivers/net/bonding/bond_3ad.c b/drivers/net/bonding/bond_3ad.c
index b667a51..9a0d61e 100644
--- a/drivers/net/bonding/bond_3ad.c
+++ b/drivers/net/bonding/bond_3ad.c
@@ -2440,7 +2440,7 @@ int bond_3ad_xmit_xor(struct sk_buff *skb, struct net_device *dev)
goto err_free;
}
- slave_agg_no = bond_xmit_hash(bond, skb, slaves_in_agg);
+ slave_agg_no = bond_xmit_hash(bond, skb) % slaves_in_agg;
first_ok_slave = NULL;
bond_for_each_slave_rcu(bond, slave, iter) {
diff --git a/drivers/net/bonding/bond_alb.c b/drivers/net/bonding/bond_alb.c
index 9f69e81..70de039 100644
--- a/drivers/net/bonding/bond_alb.c
+++ b/drivers/net/bonding/bond_alb.c
@@ -1347,6 +1347,77 @@ void bond_alb_deinitialize(struct bonding *bond)
rlb_deinitialize(bond);
}
+static int bond_do_alb_xmit(struct sk_buff *skb, struct bonding *bond,
+ struct slave *tx_slave)
+{
+ struct alb_bond_info *bond_info = &(BOND_ALB_INFO(bond));
+ struct ethhdr *eth_data = eth_hdr(skb);
+
+ if (!tx_slave) {
+ /* unbalanced or unassigned, send through primary */
+ tx_slave = rcu_dereference(bond->curr_active_slave);
+ if (bond->params.tlb_dynamic_lb)
+ bond_info->unbalanced_load += skb->len;
+ }
+
+ if (tx_slave && SLAVE_IS_OK(tx_slave)) {
+ if (tx_slave != rcu_dereference(bond->curr_active_slave)) {
+ ether_addr_copy(eth_data->h_source,
+ tx_slave->dev->dev_addr);
+ }
+
+ bond_dev_queue_xmit(bond, skb, tx_slave->dev);
+ goto out;
+ }
+
+ if (tx_slave && bond->params.tlb_dynamic_lb) {
+ _lock_tx_hashtbl(bond);
+ __tlb_clear_slave(bond, tx_slave, 0);
+ _unlock_tx_hashtbl(bond);
+ }
+
+ /* no suitable interface, frame not sent */
+ dev_kfree_skb_any(skb);
+out:
+ return NETDEV_TX_OK;
+}
+
+int bond_tlb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
+{
+ struct bonding *bond = netdev_priv(bond_dev);
+ struct ethhdr *eth_data;
+ struct slave *tx_slave = NULL;
+ u32 hash_index;
+
+ skb_reset_mac_header(skb);
+ eth_data = eth_hdr(skb);
+
+ /* Do not TX balance any multicast or broadcast */
+ if (!is_multicast_ether_addr(eth_data->h_dest)) {
+ switch (skb->protocol) {
+ case htons(ETH_P_IP):
+ case htons(ETH_P_IPX):
+ /* In case of IPX, it will falback to L2 hash */
+ case htons(ETH_P_IPV6):
+ hash_index = bond_xmit_hash(bond, skb);
+ if (bond->params.tlb_dynamic_lb) {
+ tx_slave = tlb_choose_channel(bond,
+ hash_index & 0xFF,
+ skb->len);
+ } else {
+ struct list_head *iter;
+ int idx = hash_index % bond->slave_cnt;
+
+ bond_for_each_slave_rcu(bond, tx_slave, iter)
+ if (--idx < 0)
+ break;
+ }
+ break;
+ }
+ }
+ return bond_do_alb_xmit(skb, bond, tx_slave);
+}
+
int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
{
struct bonding *bond = netdev_priv(bond_dev);
@@ -1355,7 +1426,7 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
struct slave *tx_slave = NULL;
static const __be32 ip_bcast = htonl(0xffffffff);
int hash_size = 0;
- int do_tx_balance = 1;
+ bool do_tx_balance = true;
u32 hash_index = 0;
const u8 *hash_start = NULL;
struct ipv6hdr *ip6hdr;
@@ -1370,7 +1441,7 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
if (ether_addr_equal_64bits(eth_data->h_dest, mac_bcast) ||
(iph->daddr == ip_bcast) ||
(iph->protocol == IPPROTO_IGMP)) {
- do_tx_balance = 0;
+ do_tx_balance = false;
break;
}
hash_start = (char *)&(iph->daddr);
@@ -1382,7 +1453,7 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
* that here just in case.
*/
if (ether_addr_equal_64bits(eth_data->h_dest, mac_bcast)) {
- do_tx_balance = 0;
+ do_tx_balance = false;
break;
}
@@ -1390,7 +1461,7 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
* broadcasts in IPv4.
*/
if (ether_addr_equal_64bits(eth_data->h_dest, mac_v6_allmcast)) {
- do_tx_balance = 0;
+ do_tx_balance = false;
break;
}
@@ -1400,7 +1471,7 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
*/
ip6hdr = ipv6_hdr(skb);
if (ipv6_addr_any(&ip6hdr->saddr)) {
- do_tx_balance = 0;
+ do_tx_balance = false;
break;
}
@@ -1410,7 +1481,7 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
case ETH_P_IPX:
if (ipx_hdr(skb)->ipx_checksum != IPX_NO_CHECKSUM) {
/* something is wrong with this packet */
- do_tx_balance = 0;
+ do_tx_balance = false;
break;
}
@@ -1419,7 +1490,7 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
* this family since it has an "ARP" like
* mechanism
*/
- do_tx_balance = 0;
+ do_tx_balance = false;
break;
}
@@ -1427,12 +1498,12 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
hash_size = ETH_ALEN;
break;
case ETH_P_ARP:
- do_tx_balance = 0;
+ do_tx_balance = false;
if (bond_info->rlb_enabled)
tx_slave = rlb_arp_xmit(skb, bond);
break;
default:
- do_tx_balance = 0;
+ do_tx_balance = false;
break;
}
@@ -1441,32 +1512,7 @@ int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev)
tx_slave = tlb_choose_channel(bond, hash_index, skb->len);
}
- if (!tx_slave) {
- /* unbalanced or unassigned, send through primary */
- tx_slave = rcu_dereference(bond->curr_active_slave);
- bond_info->unbalanced_load += skb->len;
- }
-
- if (tx_slave && SLAVE_IS_OK(tx_slave)) {
- if (tx_slave != rcu_dereference(bond->curr_active_slave)) {
- ether_addr_copy(eth_data->h_source,
- tx_slave->dev->dev_addr);
- }
-
- bond_dev_queue_xmit(bond, skb, tx_slave->dev);
- goto out;
- }
-
- if (tx_slave) {
- _lock_tx_hashtbl(bond);
- __tlb_clear_slave(bond, tx_slave, 0);
- _unlock_tx_hashtbl(bond);
- }
-
- /* no suitable interface, frame not sent */
- dev_kfree_skb_any(skb);
-out:
- return NETDEV_TX_OK;
+ return bond_do_alb_xmit(skb, bond, tx_slave);
}
void bond_alb_monitor(struct work_struct *work)
diff --git a/drivers/net/bonding/bond_alb.h b/drivers/net/bonding/bond_alb.h
index e09dd4bf..5fc76c0 100644
--- a/drivers/net/bonding/bond_alb.h
+++ b/drivers/net/bonding/bond_alb.h
@@ -175,6 +175,7 @@ void bond_alb_deinit_slave(struct bonding *bond, struct slave *slave);
void bond_alb_handle_link_change(struct bonding *bond, struct slave *slave, char link);
void bond_alb_handle_active_change(struct bonding *bond, struct slave *new_slave);
int bond_alb_xmit(struct sk_buff *skb, struct net_device *bond_dev);
+int bond_tlb_xmit(struct sk_buff *skb, struct net_device *bond_dev);
void bond_alb_monitor(struct work_struct *);
int bond_alb_set_mac_address(struct net_device *bond_dev, void *addr);
void bond_alb_clear_vlan(struct bonding *bond, unsigned short vlan_id);
diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
index 69aff72..9d08e00 100644
--- a/drivers/net/bonding/bond_main.c
+++ b/drivers/net/bonding/bond_main.c
@@ -3015,20 +3015,18 @@ static bool bond_flow_dissect(struct bonding *bond, struct sk_buff *skb,
* bond_xmit_hash - generate a hash value based on the xmit policy
* @bond: bonding device
* @skb: buffer to use for headers
- * @count: modulo value
*
* This function will extract the necessary headers from the skb buffer and use
* them to generate a hash based on the xmit_policy set in the bonding device
- * which will be reduced modulo count before returning.
*/
-int bond_xmit_hash(struct bonding *bond, struct sk_buff *skb, int count)
+u32 bond_xmit_hash(struct bonding *bond, struct sk_buff *skb)
{
struct flow_keys flow;
u32 hash;
if (bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER2 ||
!bond_flow_dissect(bond, skb, &flow))
- return bond_eth_hash(skb) % count;
+ return bond_eth_hash(skb);
if (bond->params.xmit_policy == BOND_XMIT_POLICY_LAYER23 ||
bond->params.xmit_policy == BOND_XMIT_POLICY_ENCAP23)
@@ -3039,7 +3037,7 @@ int bond_xmit_hash(struct bonding *bond, struct sk_buff *skb, int count)
hash ^= (hash >> 16);
hash ^= (hash >> 8);
- return hash % count;
+ return hash;
}
/*-------------------------- Device entry points ----------------------------*/
@@ -3098,7 +3096,8 @@ static int bond_open(struct net_device *bond_dev)
*/
if (bond_alb_initialize(bond, (bond->params.mode == BOND_MODE_ALB)))
return -ENOMEM;
- queue_delayed_work(bond->wq, &bond->alb_work, 0);
+ if (bond->params.tlb_dynamic_lb)
+ queue_delayed_work(bond->wq, &bond->alb_work, 0);
}
if (bond->params.miimon) /* link check interval, in milliseconds. */
@@ -3666,7 +3665,7 @@ static int bond_xmit_xor(struct sk_buff *skb, struct net_device *bond_dev)
{
struct bonding *bond = netdev_priv(bond_dev);
- bond_xmit_slave_id(bond, skb, bond_xmit_hash(bond, skb, bond->slave_cnt));
+ bond_xmit_slave_id(bond, skb, bond_xmit_hash(bond, skb) % bond->slave_cnt);
return NETDEV_TX_OK;
}
@@ -3776,8 +3775,9 @@ static netdev_tx_t __bond_start_xmit(struct sk_buff *skb, struct net_device *dev
case BOND_MODE_8023AD:
return bond_3ad_xmit_xor(skb, dev);
case BOND_MODE_ALB:
- case BOND_MODE_TLB:
return bond_alb_xmit(skb, dev);
+ case BOND_MODE_TLB:
+ return bond_tlb_xmit(skb, dev);
default:
/* Should never happen, mode already checked */
pr_err("%s: Error: Unknown bonding mode %d\n",
@@ -3998,7 +3998,8 @@ static int bond_check_params(struct bond_params *params)
if (xmit_hash_policy) {
if ((bond_mode != BOND_MODE_XOR) &&
- (bond_mode != BOND_MODE_8023AD)) {
+ (bond_mode != BOND_MODE_8023AD) &&
+ (bond_mode != BOND_MODE_TLB)) {
pr_info("xmit_hash_policy param is irrelevant in mode %s\n",
bond_mode_name(bond_mode));
} else {
@@ -4304,6 +4305,7 @@ static int bond_check_params(struct bond_params *params)
params->min_links = min_links;
params->lp_interval = lp_interval;
params->packets_per_slave = packets_per_slave;
+ params->tlb_dynamic_lb = 1; /* Default value */
if (packets_per_slave > 0) {
params->reciprocal_packets_per_slave =
reciprocal_value(packets_per_slave);
diff --git a/drivers/net/bonding/bond_options.c b/drivers/net/bonding/bond_options.c
index 724e30f..9fba7a1 100644
--- a/drivers/net/bonding/bond_options.c
+++ b/drivers/net/bonding/bond_options.c
@@ -70,6 +70,8 @@ static int bond_option_mode_set(struct bonding *bond,
const struct bond_opt_value *newval);
static int bond_option_slaves_set(struct bonding *bond,
const struct bond_opt_value *newval);
+static int bond_option_tlb_dynamic_lb_set(struct bonding *bond,
+ const struct bond_opt_value *newval);
static const struct bond_opt_value bond_mode_tbl[] = {
@@ -179,6 +181,12 @@ static const struct bond_opt_value bond_lp_interval_tbl[] = {
{ NULL, -1, 0},
};
+static const struct bond_opt_value bond_tlb_dynamic_lb_tbl[] = {
+ { "off", 0, 0},
+ { "on", 1, BOND_VALFLAG_DEFAULT},
+ { NULL, -1, 0}
+};
+
static const struct bond_option bond_opts[] = {
[BOND_OPT_MODE] = {
.id = BOND_OPT_MODE,
@@ -199,7 +207,7 @@ static const struct bond_option bond_opts[] = {
[BOND_OPT_XMIT_HASH] = {
.id = BOND_OPT_XMIT_HASH,
.name = "xmit_hash_policy",
- .desc = "balance-xor and 802.3ad hashing method",
+ .desc = "balance-xor, 802.3ad, and tlb hashing method",
.values = bond_xmit_hashtype_tbl,
.set = bond_option_xmit_hash_policy_set
},
@@ -364,6 +372,15 @@ static const struct bond_option bond_opts[] = {
.flags = BOND_OPTFLAG_RAWVAL,
.set = bond_option_slaves_set
},
+ [BOND_OPT_TLB_DYNAMIC_LB] = {
+ .id = BOND_OPT_TLB_DYNAMIC_LB,
+ .name = "dynamic_lb",
+ .desc = "Enable dynamic flow shuffling",
+ .unsuppmodes = BOND_MODE_ALL_EX(BIT(BOND_MODE_TLB)),
+ .values = bond_tlb_dynamic_lb_tbl,
+ .flags = BOND_OPTFLAG_IFDOWN,
+ .set = bond_option_tlb_dynamic_lb_set,
+ },
{ }
};
@@ -1337,3 +1354,13 @@ err_no_cmd:
ret = -EPERM;
goto out;
}
+
+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);
+ bond->params.tlb_dynamic_lb = newval->value;
+
+ return 0;
+}
diff --git a/drivers/net/bonding/bond_options.h b/drivers/net/bonding/bond_options.h
index 12be9e1..c1860f0 100644
--- a/drivers/net/bonding/bond_options.h
+++ b/drivers/net/bonding/bond_options.h
@@ -62,6 +62,7 @@ enum {
BOND_OPT_RESEND_IGMP,
BOND_OPT_LP_INTERVAL,
BOND_OPT_SLAVES,
+ BOND_OPT_TLB_DYNAMIC_LB,
BOND_OPT_LAST
};
diff --git a/drivers/net/bonding/bond_sysfs.c b/drivers/net/bonding/bond_sysfs.c
index 0e8b268..431892f 100644
--- a/drivers/net/bonding/bond_sysfs.c
+++ b/drivers/net/bonding/bond_sysfs.c
@@ -1039,6 +1039,34 @@ static ssize_t bonding_store_lp_interval(struct device *d,
static DEVICE_ATTR(lp_interval, S_IRUGO | S_IWUSR,
bonding_show_lp_interval, bonding_store_lp_interval);
+static ssize_t bonding_show_tlb_dynamic_lb(struct device *d,
+ struct device_attribute *attr,
+ char *buf)
+{
+ struct bonding *bond = to_bond(d);
+ return sprintf(buf, "%d\n", bond->params.tlb_dynamic_lb);
+}
+
+static ssize_t bonding_store_tlb_dynamic_lb(struct device *d,
+ struct device_attribute *attr,
+ const char *buf,
+ size_t count)
+{
+ struct bonding *bond = to_bond(d);
+ int ret;
+
+ ret = bond_opt_tryset_rtnl(bond, BOND_OPT_TLB_DYNAMIC_LB,
+ (char *)buf);
+ if (!ret)
+ ret = count;
+
+ return ret;
+}
+
+static DEVICE_ATTR(tlb_dynamic_lb, S_IRUGO | S_IWUSR,
+ bonding_show_tlb_dynamic_lb,
+ bonding_store_tlb_dynamic_lb);
+
static ssize_t bonding_show_packets_per_slave(struct device *d,
struct device_attribute *attr,
char *buf)
@@ -1099,6 +1127,7 @@ static struct attribute *per_bond_attrs[] = {
&dev_attr_min_links.attr,
&dev_attr_lp_interval.attr,
&dev_attr_packets_per_slave.attr,
+ &dev_attr_tlb_dynamic_lb.attr,
NULL,
};
diff --git a/drivers/net/bonding/bonding.h b/drivers/net/bonding/bonding.h
index b8bdd0a..c1c7c2f 100644
--- a/drivers/net/bonding/bonding.h
+++ b/drivers/net/bonding/bonding.h
@@ -174,6 +174,7 @@ struct bond_params {
int resend_igmp;
int lp_interval;
int packets_per_slave;
+ int tlb_dynamic_lb;
struct reciprocal_value reciprocal_packets_per_slave;
};
@@ -499,7 +500,7 @@ int bond_sysfs_slave_add(struct slave *slave);
void bond_sysfs_slave_del(struct slave *slave);
int bond_enslave(struct net_device *bond_dev, struct net_device *slave_dev);
int bond_release(struct net_device *bond_dev, struct net_device *slave_dev);
-int bond_xmit_hash(struct bonding *bond, struct sk_buff *skb, int count);
+u32 bond_xmit_hash(struct bonding *bond, struct sk_buff *skb);
void bond_select_active_slave(struct bonding *bond);
void bond_change_active_slave(struct bonding *bond, struct slave *new_active);
void bond_create_debugfs(void);
diff --git a/drivers/net/can/Kconfig b/drivers/net/can/Kconfig
index 9e7d95d..4aacaa9 100644
--- a/drivers/net/can/Kconfig
+++ b/drivers/net/can/Kconfig
@@ -77,12 +77,6 @@ config CAN_TI_HECC
Driver for TI HECC (High End CAN Controller) module found on many
TI devices. The device specifications are available from www.ti.com
-config CAN_MCP251X
- tristate "Microchip MCP251x SPI CAN controllers"
- depends on SPI && HAS_DMA
- ---help---
- Driver for the Microchip MCP251x SPI CAN controllers.
-
config CAN_BFIN
depends on BF534 || BF536 || BF537 || BF538 || BF539 || BF54x
tristate "Analog Devices Blackfin on-chip CAN"
@@ -133,6 +127,8 @@ source "drivers/net/can/c_can/Kconfig"
source "drivers/net/can/cc770/Kconfig"
+source "drivers/net/can/spi/Kconfig"
+
source "drivers/net/can/usb/Kconfig"
source "drivers/net/can/softing/Kconfig"
diff --git a/drivers/net/can/Makefile b/drivers/net/can/Makefile
index c744039..c420588 100644
--- a/drivers/net/can/Makefile
+++ b/drivers/net/can/Makefile
@@ -10,6 +10,7 @@ can-dev-y := dev.o
can-dev-$(CONFIG_CAN_LEDS) += led.o
+obj-y += spi/
obj-y += usb/
obj-y += softing/
@@ -19,7 +20,6 @@ obj-$(CONFIG_CAN_C_CAN) += c_can/
obj-$(CONFIG_CAN_CC770) += cc770/
obj-$(CONFIG_CAN_AT91) += at91_can.o
obj-$(CONFIG_CAN_TI_HECC) += ti_hecc.o
-obj-$(CONFIG_CAN_MCP251X) += mcp251x.o
obj-$(CONFIG_CAN_BFIN) += bfin_can.o
obj-$(CONFIG_CAN_JANZ_ICAN3) += janz-ican3.o
obj-$(CONFIG_CAN_FLEXCAN) += flexcan.o
diff --git a/drivers/net/can/c_can/c_can_pci.c b/drivers/net/can/c_can/c_can_pci.c
index bce0be5..7ab384f 100644
--- a/drivers/net/can/c_can/c_can_pci.c
+++ b/drivers/net/can/c_can/c_can_pci.c
@@ -19,9 +19,13 @@
#include "c_can.h"
+#define PCI_DEVICE_ID_PCH_CAN 0x8818
+#define PCH_PCI_SOFT_RESET 0x01fc
+
enum c_can_pci_reg_align {
C_CAN_REG_ALIGN_16,
C_CAN_REG_ALIGN_32,
+ C_CAN_REG_32,
};
struct c_can_pci_data {
@@ -31,6 +35,10 @@ struct c_can_pci_data {
enum c_can_pci_reg_align reg_align;
/* Set the frequency */
unsigned int freq;
+ /* PCI bar number */
+ int bar;
+ /* Callback for reset */
+ void (*init)(const struct c_can_priv *priv, bool enable);
};
/*
@@ -63,6 +71,29 @@ static void c_can_pci_write_reg_aligned_to_32bit(struct c_can_priv *priv,
writew(val, priv->base + 2 * priv->regs[index]);
}
+static u16 c_can_pci_read_reg_32bit(struct c_can_priv *priv,
+ enum reg index)
+{
+ return (u16)ioread32(priv->base + 2 * priv->regs[index]);
+}
+
+static void c_can_pci_write_reg_32bit(struct c_can_priv *priv,
+ enum reg index, u16 val)
+{
+ iowrite32((u32)val, priv->base + 2 * priv->regs[index]);
+}
+
+static void c_can_pci_reset_pch(const struct c_can_priv *priv, bool enable)
+{
+ if (enable) {
+ u32 __iomem *addr = priv->base + PCH_PCI_SOFT_RESET;
+
+ /* write to sw reset register */
+ iowrite32(1, addr);
+ iowrite32(0, addr);
+ }
+}
+
static int c_can_pci_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
@@ -87,7 +118,8 @@ static int c_can_pci_probe(struct pci_dev *pdev,
pci_set_master(pdev);
pci_enable_msi(pdev);
- addr = pci_iomap(pdev, 0, pci_resource_len(pdev, 0));
+ addr = pci_iomap(pdev, c_can_pci_data->bar,
+ pci_resource_len(pdev, c_can_pci_data->bar));
if (!addr) {
dev_err(&pdev->dev,
"device has no PCI memory resources, "
@@ -142,11 +174,17 @@ static int c_can_pci_probe(struct pci_dev *pdev,
priv->read_reg = c_can_pci_read_reg_aligned_to_16bit;
priv->write_reg = c_can_pci_write_reg_aligned_to_16bit;
break;
+ case C_CAN_REG_32:
+ priv->read_reg = c_can_pci_read_reg_32bit;
+ priv->write_reg = c_can_pci_write_reg_32bit;
+ break;
default:
ret = -EINVAL;
goto out_free_c_can;
}
+ priv->raminit = c_can_pci_data->init;
+
ret = register_c_can_dev(dev);
if (ret) {
dev_err(&pdev->dev, "registering %s failed (err=%d)\n",
@@ -193,6 +231,15 @@ static struct c_can_pci_data c_can_sta2x11= {
.type = BOSCH_C_CAN,
.reg_align = C_CAN_REG_ALIGN_32,
.freq = 52000000, /* 52 Mhz */
+ .bar = 0,
+};
+
+static struct c_can_pci_data c_can_pch = {
+ .type = BOSCH_C_CAN,
+ .reg_align = C_CAN_REG_32,
+ .freq = 50000000, /* 50 MHz */
+ .init = c_can_pci_reset_pch,
+ .bar = 1,
};
#define C_CAN_ID(_vend, _dev, _driverdata) { \
@@ -202,6 +249,8 @@ static struct c_can_pci_data c_can_sta2x11= {
static DEFINE_PCI_DEVICE_TABLE(c_can_pci_tbl) = {
C_CAN_ID(PCI_VENDOR_ID_STMICRO, PCI_DEVICE_ID_STMICRO_CAN,
c_can_sta2x11),
+ C_CAN_ID(PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_PCH_CAN,
+ c_can_pch),
{},
};
static struct pci_driver c_can_pci_driver = {
diff --git a/drivers/net/can/softing/softing_main.c b/drivers/net/can/softing/softing_main.c
index 7d8c8f3..bacd236 100644
--- a/drivers/net/can/softing/softing_main.c
+++ b/drivers/net/can/softing/softing_main.c
@@ -556,15 +556,6 @@ failed:
/*
* netdev sysfs
*/
-static ssize_t show_channel(struct device *dev, struct device_attribute *attr,
- char *buf)
-{
- struct net_device *ndev = to_net_dev(dev);
- struct softing_priv *priv = netdev2softing(ndev);
-
- return sprintf(buf, "%i\n", priv->index);
-}
-
static ssize_t show_chip(struct device *dev, struct device_attribute *attr,
char *buf)
{
@@ -609,12 +600,10 @@ static ssize_t store_output(struct device *dev, struct device_attribute *attr,
return count;
}
-static const DEVICE_ATTR(channel, S_IRUGO, show_channel, NULL);
static const DEVICE_ATTR(chip, S_IRUGO, show_chip, NULL);
static const DEVICE_ATTR(output, S_IRUGO | S_IWUSR, show_output, store_output);
static const struct attribute *const netdev_sysfs_attrs[] = {
- &dev_attr_channel.attr,
&dev_attr_chip.attr,
&dev_attr_output.attr,
NULL,
@@ -679,17 +668,20 @@ static int softing_netdev_register(struct net_device *netdev)
{
int ret;
- netdev->sysfs_groups[0] = &netdev_sysfs_group;
ret = register_candev(netdev);
if (ret) {
dev_alert(&netdev->dev, "register failed\n");
return ret;
}
+ if (sysfs_create_group(&netdev->dev.kobj, &netdev_sysfs_group) < 0)
+ netdev_alert(netdev, "sysfs group failed\n");
+
return 0;
}
static void softing_netdev_cleanup(struct net_device *netdev)
{
+ sysfs_remove_group(&netdev->dev.kobj, &netdev_sysfs_group);
unregister_candev(netdev);
free_candev(netdev);
}
@@ -721,8 +713,6 @@ DEV_ATTR_RO(firmware_version, id.fw_version);
DEV_ATTR_RO_STR(hardware, pdat->name);
DEV_ATTR_RO(hardware_version, id.hw_version);
DEV_ATTR_RO(license, id.license);
-DEV_ATTR_RO(frequency, id.freq);
-DEV_ATTR_RO(txpending, tx.pending);
static struct attribute *softing_pdev_attrs[] = {
&dev_attr_serial.attr,
@@ -731,8 +721,6 @@ static struct attribute *softing_pdev_attrs[] = {
&dev_attr_hardware.attr,
&dev_attr_hardware_version.attr,
&dev_attr_license.attr,
- &dev_attr_frequency.attr,
- &dev_attr_txpending.attr,
NULL,
};
diff --git a/drivers/net/can/spi/Kconfig b/drivers/net/can/spi/Kconfig
new file mode 100644
index 0000000..148cae5
--- /dev/null
+++ b/drivers/net/can/spi/Kconfig
@@ -0,0 +1,10 @@
+menu "CAN SPI interfaces"
+ depends on SPI
+
+config CAN_MCP251X
+ tristate "Microchip MCP251x SPI CAN controllers"
+ depends on HAS_DMA
+ ---help---
+ Driver for the Microchip MCP251x SPI CAN controllers.
+
+endmenu
diff --git a/drivers/net/can/spi/Makefile b/drivers/net/can/spi/Makefile
new file mode 100644
index 0000000..90bcacf
--- /dev/null
+++ b/drivers/net/can/spi/Makefile
@@ -0,0 +1,8 @@
+#
+# Makefile for the Linux Controller Area Network SPI drivers.
+#
+
+
+obj-$(CONFIG_CAN_MCP251X) += mcp251x.o
+
+ccflags-$(CONFIG_CAN_DEBUG_DEVICES) := -DDEBUG
diff --git a/drivers/net/can/mcp251x.c b/drivers/net/can/spi/mcp251x.c
index 28c11f8..bc235f9 100644
--- a/drivers/net/can/mcp251x.c
+++ b/drivers/net/can/spi/mcp251x.c
@@ -214,6 +214,8 @@
#define TX_ECHO_SKB_MAX 1
+#define MCP251X_OST_DELAY_MS (5)
+
#define DEVICE_NAME "mcp251x"
static int mcp251x_enable_dma; /* Enable SPI DMA. Default: 0 (Off) */
@@ -624,50 +626,45 @@ static int mcp251x_setup(struct net_device *net, struct mcp251x_priv *priv,
static int mcp251x_hw_reset(struct spi_device *spi)
{
struct mcp251x_priv *priv = spi_get_drvdata(spi);
+ u8 reg;
int ret;
- unsigned long timeout;
+
+ /* Wait for oscillator startup timer after power up */
+ mdelay(MCP251X_OST_DELAY_MS);
priv->spi_tx_buf[0] = INSTRUCTION_RESET;
- ret = spi_write(spi, priv->spi_tx_buf, 1);
- if (ret) {
- dev_err(&spi->dev, "reset failed: ret = %d\n", ret);
- return -EIO;
- }
+ ret = mcp251x_spi_trans(spi, 1);
+ if (ret)
+ return ret;
+
+ /* Wait for oscillator startup timer after reset */
+ mdelay(MCP251X_OST_DELAY_MS);
+
+ reg = mcp251x_read_reg(spi, CANSTAT);
+ if ((reg & CANCTRL_REQOP_MASK) != CANCTRL_REQOP_CONF)
+ return -ENODEV;
- /* Wait for reset to finish */
- timeout = jiffies + HZ;
- mdelay(10);
- while ((mcp251x_read_reg(spi, CANSTAT) & CANCTRL_REQOP_MASK)
- != CANCTRL_REQOP_CONF) {
- schedule();
- if (time_after(jiffies, timeout)) {
- dev_err(&spi->dev, "MCP251x didn't"
- " enter in conf mode after reset\n");
- return -EBUSY;
- }
- }
return 0;
}
static int mcp251x_hw_probe(struct spi_device *spi)
{
- int st1, st2;
+ u8 ctrl;
+ int ret;
- mcp251x_hw_reset(spi);
+ ret = mcp251x_hw_reset(spi);
+ if (ret)
+ return ret;
- /*
- * Please note that these are "magic values" based on after
- * reset defaults taken from data sheet which allows us to see
- * if we really have a chip on the bus (we avoid common all
- * zeroes or all ones situations)
- */
- st1 = mcp251x_read_reg(spi, CANSTAT) & 0xEE;
- st2 = mcp251x_read_reg(spi, CANCTRL) & 0x17;
+ ctrl = mcp251x_read_reg(spi, CANCTRL);
+
+ dev_dbg(&spi->dev, "CANCTRL 0x%02x\n", ctrl);
- dev_dbg(&spi->dev, "CANSTAT 0x%02x CANCTRL 0x%02x\n", st1, st2);
+ /* Check for power up default value */
+ if ((ctrl & 0x17) != 0x07)
+ return -ENODEV;
- /* Check for power up default values */
- return (st1 == 0x80 && st2 == 0x07) ? 1 : 0;
+ return 0;
}
static int mcp251x_power_enable(struct regulator *reg, int enable)
@@ -776,7 +773,6 @@ static void mcp251x_restart_work_handler(struct work_struct *ws)
mutex_lock(&priv->mcp_lock);
if (priv->after_suspend) {
- mdelay(10);
mcp251x_hw_reset(spi);
mcp251x_setup(net, priv, spi);
if (priv->after_suspend & AFTER_SUSPEND_RESTART) {
@@ -1032,8 +1028,8 @@ static int mcp251x_can_probe(struct spi_device *spi)
struct mcp251x_platform_data *pdata = dev_get_platdata(&spi->dev);
struct net_device *net;
struct mcp251x_priv *priv;
- int freq, ret = -ENODEV;
struct clk *clk;
+ int freq, ret;
clk = devm_clk_get(&spi->dev, NULL);
if (IS_ERR(clk)) {
@@ -1076,6 +1072,18 @@ static int mcp251x_can_probe(struct spi_device *spi)
priv->net = net;
priv->clk = clk;
+ spi_set_drvdata(spi, priv);
+
+ /* Configure the SPI bus */
+ spi->bits_per_word = 8;
+ if (mcp251x_is_2510(spi))
+ spi->max_speed_hz = spi->max_speed_hz ? : 5 * 1000 * 1000;
+ else
+ spi->max_speed_hz = spi->max_speed_hz ? : 10 * 1000 * 1000;
+ ret = spi_setup(spi);
+ if (ret)
+ goto out_clk;
+
priv->power = devm_regulator_get(&spi->dev, "vdd");
priv->transceiver = devm_regulator_get(&spi->dev, "xceiver");
if ((PTR_ERR(priv->power) == -EPROBE_DEFER) ||
@@ -1088,8 +1096,6 @@ static int mcp251x_can_probe(struct spi_device *spi)
if (ret)
goto out_clk;
- spi_set_drvdata(spi, priv);
-
priv->spi = spi;
mutex_init(&priv->mcp_lock);
@@ -1134,20 +1140,11 @@ static int mcp251x_can_probe(struct spi_device *spi)
SET_NETDEV_DEV(net, &spi->dev);
- /* Configure the SPI bus */
- spi->mode = spi->mode ? : SPI_MODE_0;
- if (mcp251x_is_2510(spi))
- spi->max_speed_hz = spi->max_speed_hz ? : 5 * 1000 * 1000;
- else
- spi->max_speed_hz = spi->max_speed_hz ? : 10 * 1000 * 1000;
- spi->bits_per_word = 8;
- spi_setup(spi);
-
/* Here is OK to not lock the MCP, no one knows about it yet */
- if (!mcp251x_hw_probe(spi)) {
- ret = -ENODEV;
+ ret = mcp251x_hw_probe(spi);
+ if (ret)
goto error_probe;
- }
+
mcp251x_hw_sleep(spi);
ret = register_candev(net);
@@ -1156,7 +1153,7 @@ static int mcp251x_can_probe(struct spi_device *spi)
devm_can_led_init(net);
- return ret;
+ return 0;
error_probe:
if (mcp251x_enable_dma)
diff --git a/drivers/net/can/usb/Kconfig b/drivers/net/can/usb/Kconfig
index fc96a3d..0b918eb 100644
--- a/drivers/net/can/usb/Kconfig
+++ b/drivers/net/can/usb/Kconfig
@@ -19,7 +19,7 @@ config CAN_KVASER_USB
This driver adds support for Kvaser CAN/USB devices like Kvaser
Leaf Light.
- The driver gives support for the following devices:
+ The driver provides support for the following devices:
- Kvaser Leaf Light
- Kvaser Leaf Professional HS
- Kvaser Leaf SemiPro HS
@@ -36,6 +36,8 @@ config CAN_KVASER_USB
- Kvaser Leaf Light "China"
- Kvaser BlackBird SemiPro
- Kvaser USBcan R
+ - Kvaser Leaf Light v2
+ - Kvaser Mini PCI Express HS
If unsure, say N.
diff --git a/drivers/net/can/usb/kvaser_usb.c b/drivers/net/can/usb/kvaser_usb.c
index 4ca46ed..541fb7a 100644
--- a/drivers/net/can/usb/kvaser_usb.c
+++ b/drivers/net/can/usb/kvaser_usb.c
@@ -53,6 +53,8 @@
#define USB_OEM_MERCURY_PRODUCT_ID 34
#define USB_OEM_LEAF_PRODUCT_ID 35
#define USB_CAN_R_PRODUCT_ID 39
+#define USB_LEAF_LITE_V2_PRODUCT_ID 288
+#define USB_MINI_PCIE_HS_PRODUCT_ID 289
/* USB devices features */
#define KVASER_HAS_SILENT_MODE BIT(0)
@@ -356,6 +358,8 @@ static const struct usb_device_id kvaser_usb_table[] = {
.driver_info = KVASER_HAS_TXRX_ERRORS },
{ USB_DEVICE(KVASER_VENDOR_ID, USB_CAN_R_PRODUCT_ID),
.driver_info = KVASER_HAS_TXRX_ERRORS },
+ { USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_V2_PRODUCT_ID) },
+ { USB_DEVICE(KVASER_VENDOR_ID, USB_MINI_PCIE_HS_PRODUCT_ID) },
{ }
};
MODULE_DEVICE_TABLE(usb, kvaser_usb_table);
@@ -379,38 +383,43 @@ static int kvaser_usb_wait_msg(const struct kvaser_usb *dev, u8 id,
void *buf;
int actual_len;
int err;
- int pos = 0;
+ int pos;
+ unsigned long to = jiffies + msecs_to_jiffies(USB_RECV_TIMEOUT);
buf = kzalloc(RX_BUFFER_SIZE, GFP_KERNEL);
if (!buf)
return -ENOMEM;
- err = usb_bulk_msg(dev->udev,
- usb_rcvbulkpipe(dev->udev,
- dev->bulk_in->bEndpointAddress),
- buf, RX_BUFFER_SIZE, &actual_len,
- USB_RECV_TIMEOUT);
- if (err < 0)
- goto end;
+ do {
+ err = usb_bulk_msg(dev->udev,
+ usb_rcvbulkpipe(dev->udev,
+ dev->bulk_in->bEndpointAddress),
+ buf, RX_BUFFER_SIZE, &actual_len,
+ USB_RECV_TIMEOUT);
+ if (err < 0)
+ goto end;
- while (pos <= actual_len - MSG_HEADER_LEN) {
- tmp = buf + pos;
+ pos = 0;
+ while (pos <= actual_len - MSG_HEADER_LEN) {
+ tmp = buf + pos;
- if (!tmp->len)
- break;
+ if (!tmp->len)
+ break;
- if (pos + tmp->len > actual_len) {
- dev_err(dev->udev->dev.parent, "Format error\n");
- break;
- }
+ if (pos + tmp->len > actual_len) {
+ dev_err(dev->udev->dev.parent,
+ "Format error\n");
+ break;
+ }
- if (tmp->id == id) {
- memcpy(msg, tmp, tmp->len);
- goto end;
- }
+ if (tmp->id == id) {
+ memcpy(msg, tmp, tmp->len);
+ goto end;
+ }
- pos += tmp->len;
- }
+ pos += tmp->len;
+ }
+ } while (time_before(jiffies, to));
err = -EINVAL;
diff --git a/drivers/net/dsa/mv88e6123_61_65.c b/drivers/net/dsa/mv88e6123_61_65.c
index 41ee5b6..69c4251 100644
--- a/drivers/net/dsa/mv88e6123_61_65.c
+++ b/drivers/net/dsa/mv88e6123_61_65.c
@@ -289,7 +289,7 @@ static int mv88e6123_61_65_setup_port(struct dsa_switch *ds, int p)
static int mv88e6123_61_65_setup(struct dsa_switch *ds)
{
- struct mv88e6xxx_priv_state *ps = (void *)(ds + 1);
+ struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
int i;
int ret;
diff --git a/drivers/net/dsa/mv88e6131.c b/drivers/net/dsa/mv88e6131.c
index dadfafb..953bc6a 100644
--- a/drivers/net/dsa/mv88e6131.c
+++ b/drivers/net/dsa/mv88e6131.c
@@ -155,7 +155,7 @@ static int mv88e6131_setup_global(struct dsa_switch *ds)
static int mv88e6131_setup_port(struct dsa_switch *ds, int p)
{
- struct mv88e6xxx_priv_state *ps = (void *)(ds + 1);
+ struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
int addr = REG_PORT(p);
u16 val;
@@ -274,7 +274,7 @@ static int mv88e6131_setup_port(struct dsa_switch *ds, int p)
static int mv88e6131_setup(struct dsa_switch *ds)
{
- struct mv88e6xxx_priv_state *ps = (void *)(ds + 1);
+ struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
int i;
int ret;
diff --git a/drivers/net/dsa/mv88e6xxx.c b/drivers/net/dsa/mv88e6xxx.c
index 17314ed..9ce2146 100644
--- a/drivers/net/dsa/mv88e6xxx.c
+++ b/drivers/net/dsa/mv88e6xxx.c
@@ -74,7 +74,7 @@ int __mv88e6xxx_reg_read(struct mii_bus *bus, int sw_addr, int addr, int reg)
int mv88e6xxx_reg_read(struct dsa_switch *ds, int addr, int reg)
{
- struct mv88e6xxx_priv_state *ps = (void *)(ds + 1);
+ struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
int ret;
mutex_lock(&ps->smi_mutex);
@@ -118,7 +118,7 @@ int __mv88e6xxx_reg_write(struct mii_bus *bus, int sw_addr, int addr,
int mv88e6xxx_reg_write(struct dsa_switch *ds, int addr, int reg, u16 val)
{
- struct mv88e6xxx_priv_state *ps = (void *)(ds + 1);
+ struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
int ret;
mutex_lock(&ps->smi_mutex);
@@ -256,7 +256,7 @@ static void mv88e6xxx_ppu_reenable_timer(unsigned long _ps)
static int mv88e6xxx_ppu_access_get(struct dsa_switch *ds)
{
- struct mv88e6xxx_priv_state *ps = (void *)(ds + 1);
+ struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
int ret;
mutex_lock(&ps->ppu_mutex);
@@ -283,7 +283,7 @@ static int mv88e6xxx_ppu_access_get(struct dsa_switch *ds)
static void mv88e6xxx_ppu_access_put(struct dsa_switch *ds)
{
- struct mv88e6xxx_priv_state *ps = (void *)(ds + 1);
+ struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
/* Schedule a timer to re-enable the PHY polling unit. */
mod_timer(&ps->ppu_timer, jiffies + msecs_to_jiffies(10));
@@ -292,7 +292,7 @@ static void mv88e6xxx_ppu_access_put(struct dsa_switch *ds)
void mv88e6xxx_ppu_state_init(struct dsa_switch *ds)
{
- struct mv88e6xxx_priv_state *ps = (void *)(ds + 1);
+ struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
mutex_init(&ps->ppu_mutex);
INIT_WORK(&ps->ppu_work, mv88e6xxx_ppu_reenable_work);
@@ -463,7 +463,7 @@ void mv88e6xxx_get_ethtool_stats(struct dsa_switch *ds,
int nr_stats, struct mv88e6xxx_hw_stat *stats,
int port, uint64_t *data)
{
- struct mv88e6xxx_priv_state *ps = (void *)(ds + 1);
+ struct mv88e6xxx_priv_state *ps = ds_to_priv(ds);
int ret;
int i;
diff --git a/drivers/net/ethernet/altera/altera_msgdma.c b/drivers/net/ethernet/altera/altera_msgdma.c
index 3df1866..0e38a03 100644
--- a/drivers/net/ethernet/altera/altera_msgdma.c
+++ b/drivers/net/ethernet/altera/altera_msgdma.c
@@ -32,10 +32,8 @@ void msgdma_uninitialize(struct altera_tse_private *priv)
void msgdma_reset(struct altera_tse_private *priv)
{
int counter;
- struct msgdma_csr *txcsr =
- (struct msgdma_csr *)priv->tx_dma_csr;
- struct msgdma_csr *rxcsr =
- (struct msgdma_csr *)priv->rx_dma_csr;
+ struct msgdma_csr *txcsr = priv->tx_dma_csr;
+ struct msgdma_csr *rxcsr = priv->rx_dma_csr;
/* Reset Rx mSGDMA */
iowrite32(MSGDMA_CSR_STAT_MASK, &rxcsr->status);
@@ -133,8 +131,7 @@ u32 msgdma_tx_completions(struct altera_tse_private *priv)
u32 ready = 0;
u32 inuse;
u32 status;
- struct msgdma_csr *txcsr =
- (struct msgdma_csr *)priv->tx_dma_csr;
+ struct msgdma_csr *txcsr = priv->tx_dma_csr;
/* Get number of sent descriptors */
inuse = ioread32(&txcsr->rw_fill_level) & 0xffff;
@@ -186,10 +183,8 @@ u32 msgdma_rx_status(struct altera_tse_private *priv)
u32 rxstatus = 0;
u32 pktlength;
u32 pktstatus;
- struct msgdma_csr *rxcsr =
- (struct msgdma_csr *)priv->rx_dma_csr;
- struct msgdma_response *rxresp =
- (struct msgdma_response *)priv->rx_dma_resp;
+ struct msgdma_csr *rxcsr = priv->rx_dma_csr;
+ struct msgdma_response *rxresp = priv->rx_dma_resp;
if (ioread32(&rxcsr->resp_fill_level) & 0xffff) {
pktlength = ioread32(&rxresp->bytes_transferred);
diff --git a/drivers/net/ethernet/altera/altera_sgdma.c b/drivers/net/ethernet/altera/altera_sgdma.c
index 0ee9663..519f0f0 100644
--- a/drivers/net/ethernet/altera/altera_sgdma.c
+++ b/drivers/net/ethernet/altera/altera_sgdma.c
@@ -112,12 +112,12 @@ void sgdma_uninitialize(struct altera_tse_private *priv)
*/
void sgdma_reset(struct altera_tse_private *priv)
{
- u32 *ptxdescripmem = (u32 *)priv->tx_dma_desc;
+ u32 *ptxdescripmem = priv->tx_dma_desc;
u32 txdescriplen = priv->txdescmem;
- u32 *prxdescripmem = (u32 *)priv->rx_dma_desc;
+ u32 *prxdescripmem = priv->rx_dma_desc;
u32 rxdescriplen = priv->rxdescmem;
- struct sgdma_csr *ptxsgdma = (struct sgdma_csr *)priv->tx_dma_csr;
- struct sgdma_csr *prxsgdma = (struct sgdma_csr *)priv->rx_dma_csr;
+ struct sgdma_csr *ptxsgdma = priv->tx_dma_csr;
+ struct sgdma_csr *prxsgdma = priv->rx_dma_csr;
/* Initialize descriptor memory to 0 */
memset(ptxdescripmem, 0, txdescriplen);
@@ -132,14 +132,14 @@ void sgdma_reset(struct altera_tse_private *priv)
void sgdma_enable_rxirq(struct altera_tse_private *priv)
{
- struct sgdma_csr *csr = (struct sgdma_csr *)priv->rx_dma_csr;
+ struct sgdma_csr *csr = priv->rx_dma_csr;
priv->rxctrlreg |= SGDMA_CTRLREG_INTEN;
tse_set_bit(&csr->control, SGDMA_CTRLREG_INTEN);
}
void sgdma_enable_txirq(struct altera_tse_private *priv)
{
- struct sgdma_csr *csr = (struct sgdma_csr *)priv->tx_dma_csr;
+ struct sgdma_csr *csr = priv->tx_dma_csr;
priv->txctrlreg |= SGDMA_CTRLREG_INTEN;
tse_set_bit(&csr->control, SGDMA_CTRLREG_INTEN);
}
@@ -156,13 +156,13 @@ void sgdma_disable_txirq(struct altera_tse_private *priv)
void sgdma_clear_rxirq(struct altera_tse_private *priv)
{
- struct sgdma_csr *csr = (struct sgdma_csr *)priv->rx_dma_csr;
+ struct sgdma_csr *csr = priv->rx_dma_csr;
tse_set_bit(&csr->control, SGDMA_CTRLREG_CLRINT);
}
void sgdma_clear_txirq(struct altera_tse_private *priv)
{
- struct sgdma_csr *csr = (struct sgdma_csr *)priv->tx_dma_csr;
+ struct sgdma_csr *csr = priv->tx_dma_csr;
tse_set_bit(&csr->control, SGDMA_CTRLREG_CLRINT);
}
@@ -174,8 +174,7 @@ void sgdma_clear_txirq(struct altera_tse_private *priv)
int sgdma_tx_buffer(struct altera_tse_private *priv, struct tse_buffer *buffer)
{
int pktstx = 0;
- struct sgdma_descrip *descbase =
- (struct sgdma_descrip *)priv->tx_dma_desc;
+ struct sgdma_descrip *descbase = priv->tx_dma_desc;
struct sgdma_descrip *cdesc = &descbase[0];
struct sgdma_descrip *ndesc = &descbase[1];
@@ -208,7 +207,7 @@ int sgdma_tx_buffer(struct altera_tse_private *priv, struct tse_buffer *buffer)
u32 sgdma_tx_completions(struct altera_tse_private *priv)
{
u32 ready = 0;
- struct sgdma_descrip *desc = (struct sgdma_descrip *)priv->tx_dma_desc;
+ struct sgdma_descrip *desc = priv->tx_dma_desc;
if (!sgdma_txbusy(priv) &&
((desc->control & SGDMA_CONTROL_HW_OWNED) == 0) &&
@@ -231,8 +230,8 @@ int sgdma_add_rx_desc(struct altera_tse_private *priv,
*/
u32 sgdma_rx_status(struct altera_tse_private *priv)
{
- struct sgdma_csr *csr = (struct sgdma_csr *)priv->rx_dma_csr;
- struct sgdma_descrip *base = (struct sgdma_descrip *)priv->rx_dma_desc;
+ struct sgdma_csr *csr = priv->rx_dma_csr;
+ struct sgdma_descrip *base = priv->rx_dma_desc;
struct sgdma_descrip *desc = NULL;
int pktsrx;
unsigned int rxstatus = 0;
@@ -312,10 +311,8 @@ static void sgdma_descrip(struct sgdma_descrip *desc,
*/
static int sgdma_async_read(struct altera_tse_private *priv)
{
- struct sgdma_csr *csr = (struct sgdma_csr *)priv->rx_dma_csr;
- struct sgdma_descrip *descbase =
- (struct sgdma_descrip *)priv->rx_dma_desc;
-
+ struct sgdma_csr *csr = priv->rx_dma_csr;
+ struct sgdma_descrip *descbase = priv->rx_dma_desc;
struct sgdma_descrip *cdesc = &descbase[0];
struct sgdma_descrip *ndesc = &descbase[1];
@@ -364,7 +361,7 @@ static int sgdma_async_read(struct altera_tse_private *priv)
static int sgdma_async_write(struct altera_tse_private *priv,
struct sgdma_descrip *desc)
{
- struct sgdma_csr *csr = (struct sgdma_csr *)priv->tx_dma_csr;
+ struct sgdma_csr *csr = priv->tx_dma_csr;
if (sgdma_txbusy(priv))
return 0;
@@ -485,7 +482,7 @@ queue_rx_peekhead(struct altera_tse_private *priv)
*/
static int sgdma_rxbusy(struct altera_tse_private *priv)
{
- struct sgdma_csr *csr = (struct sgdma_csr *)priv->rx_dma_csr;
+ struct sgdma_csr *csr = priv->rx_dma_csr;
return ioread32(&csr->status) & SGDMA_STSREG_BUSY;
}
@@ -495,7 +492,7 @@ static int sgdma_rxbusy(struct altera_tse_private *priv)
static int sgdma_txbusy(struct altera_tse_private *priv)
{
int delay = 0;
- struct sgdma_csr *csr = (struct sgdma_csr *)priv->tx_dma_csr;
+ struct sgdma_csr *csr = priv->tx_dma_csr;
/* if DMA is busy, wait for current transactino to finish */
while ((ioread32(&csr->status) & SGDMA_STSREG_BUSY) && (delay++ < 100))
diff --git a/drivers/net/ethernet/arc/emac_main.c b/drivers/net/ethernet/arc/emac_main.c
index eeecc29..9f45782 100644
--- a/drivers/net/ethernet/arc/emac_main.c
+++ b/drivers/net/ethernet/arc/emac_main.c
@@ -574,6 +574,18 @@ static int arc_emac_tx(struct sk_buff *skb, struct net_device *ndev)
return NETDEV_TX_OK;
}
+static void arc_emac_set_address_internal(struct net_device *ndev)
+{
+ struct arc_emac_priv *priv = netdev_priv(ndev);
+ unsigned int addr_low, addr_hi;
+
+ addr_low = le32_to_cpu(*(__le32 *) &ndev->dev_addr[0]);
+ addr_hi = le16_to_cpu(*(__le16 *) &ndev->dev_addr[4]);
+
+ arc_reg_set(priv, R_ADDRL, addr_low);
+ arc_reg_set(priv, R_ADDRH, addr_hi);
+}
+
/**
* arc_emac_set_address - Set the MAC address for this device.
* @ndev: Pointer to net_device structure.
@@ -587,9 +599,7 @@ static int arc_emac_tx(struct sk_buff *skb, struct net_device *ndev)
*/
static int arc_emac_set_address(struct net_device *ndev, void *p)
{
- struct arc_emac_priv *priv = netdev_priv(ndev);
struct sockaddr *addr = p;
- unsigned int addr_low, addr_hi;
if (netif_running(ndev))
return -EBUSY;
@@ -599,11 +609,7 @@ static int arc_emac_set_address(struct net_device *ndev, void *p)
memcpy(ndev->dev_addr, addr->sa_data, ndev->addr_len);
- addr_low = le32_to_cpu(*(__le32 *) &ndev->dev_addr[0]);
- addr_hi = le16_to_cpu(*(__le16 *) &ndev->dev_addr[4]);
-
- arc_reg_set(priv, R_ADDRL, addr_low);
- arc_reg_set(priv, R_ADDRH, addr_hi);
+ arc_emac_set_address_internal(ndev);
return 0;
}
@@ -713,6 +719,7 @@ static int arc_emac_probe(struct platform_device *pdev)
else
eth_hw_addr_random(ndev);
+ arc_emac_set_address_internal(ndev);
dev_info(&pdev->dev, "MAC address is now %pM\n", ndev->dev_addr);
/* Do 1 allocation instead of 2 separate ones for Rx and Tx BD rings */
diff --git a/drivers/net/ethernet/broadcom/Kconfig b/drivers/net/ethernet/broadcom/Kconfig
index 85dbddd..3e48809 100644
--- a/drivers/net/ethernet/broadcom/Kconfig
+++ b/drivers/net/ethernet/broadcom/Kconfig
@@ -150,4 +150,15 @@ config BGMAC
In case of using this driver on BCM4706 it's also requires to enable
BCMA_DRIVER_GMAC_CMN to make it work.
+config SYSTEMPORT
+ tristate "Broadcom SYSTEMPORT internal MAC support"
+ depends on OF
+ select MII
+ select PHYLIB
+ select FIXED_PHY if SYSTEMPORT=y
+ help
+ This driver supports the built-in Ethernet MACs found in the
+ Broadcom BCM7xxx Set Top Box family chipset using an internal
+ Ethernet switch.
+
endif # NET_VENDOR_BROADCOM
diff --git a/drivers/net/ethernet/broadcom/Makefile b/drivers/net/ethernet/broadcom/Makefile
index fd639a0..e2a958a 100644
--- a/drivers/net/ethernet/broadcom/Makefile
+++ b/drivers/net/ethernet/broadcom/Makefile
@@ -11,3 +11,4 @@ obj-$(CONFIG_BNX2X) += bnx2x/
obj-$(CONFIG_SB1250_MAC) += sb1250-mac.o
obj-$(CONFIG_TIGON3) += tg3.o
obj-$(CONFIG_BGMAC) += bgmac.o
+obj-$(CONFIG_SYSTEMPORT) += bcmsysport.o
diff --git a/drivers/net/ethernet/broadcom/bcm63xx_enet.c b/drivers/net/ethernet/broadcom/bcm63xx_enet.c
index a7d11f5..8db34d3 100644
--- a/drivers/net/ethernet/broadcom/bcm63xx_enet.c
+++ b/drivers/net/ethernet/broadcom/bcm63xx_enet.c
@@ -1315,8 +1315,7 @@ static const struct bcm_enet_stats bcm_enet_gstrings_stats[] = {
};
-#define BCM_ENET_STATS_LEN \
- (sizeof(bcm_enet_gstrings_stats) / sizeof(struct bcm_enet_stats))
+#define BCM_ENET_STATS_LEN ARRAY_SIZE(bcm_enet_gstrings_stats)
static const u32 unused_mib_regs[] = {
ETH_MIB_TX_ALL_OCTETS,
diff --git a/drivers/net/ethernet/broadcom/bcmsysport.c b/drivers/net/ethernet/broadcom/bcmsysport.c
new file mode 100644
index 0000000..4dc8d1e
--- /dev/null
+++ b/drivers/net/ethernet/broadcom/bcmsysport.c
@@ -0,0 +1,1614 @@
+/*
+ * Broadcom BCM7xxx System Port Ethernet MAC driver
+ *
+ * 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) KBUILD_MODNAME ": " fmt
+
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/netdevice.h>
+#include <linux/etherdevice.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_net.h>
+#include <linux/of_mdio.h>
+#include <linux/phy.h>
+#include <linux/phy_fixed.h>
+#include <net/ip.h>
+#include <net/ipv6.h>
+
+#include "bcmsysport.h"
+
+/* I/O accessors register helpers */
+#define BCM_SYSPORT_IO_MACRO(name, offset) \
+static inline u32 name##_readl(struct bcm_sysport_priv *priv, u32 off) \
+{ \
+ u32 reg = __raw_readl(priv->base + offset + off); \
+ return reg; \
+} \
+static inline void name##_writel(struct bcm_sysport_priv *priv, \
+ u32 val, u32 off) \
+{ \
+ __raw_writel(val, priv->base + offset + off); \
+} \
+
+BCM_SYSPORT_IO_MACRO(intrl2_0, SYS_PORT_INTRL2_0_OFFSET);
+BCM_SYSPORT_IO_MACRO(intrl2_1, SYS_PORT_INTRL2_1_OFFSET);
+BCM_SYSPORT_IO_MACRO(umac, SYS_PORT_UMAC_OFFSET);
+BCM_SYSPORT_IO_MACRO(tdma, SYS_PORT_TDMA_OFFSET);
+BCM_SYSPORT_IO_MACRO(rdma, SYS_PORT_RDMA_OFFSET);
+BCM_SYSPORT_IO_MACRO(rxchk, SYS_PORT_RXCHK_OFFSET);
+BCM_SYSPORT_IO_MACRO(txchk, SYS_PORT_TXCHK_OFFSET);
+BCM_SYSPORT_IO_MACRO(rbuf, SYS_PORT_RBUF_OFFSET);
+BCM_SYSPORT_IO_MACRO(tbuf, SYS_PORT_TBUF_OFFSET);
+BCM_SYSPORT_IO_MACRO(topctrl, SYS_PORT_TOPCTRL_OFFSET);
+
+/* L2-interrupt masking/unmasking helpers, does automatic saving of the applied
+ * mask in a software copy to avoid CPU_MASK_STATUS reads in hot-paths.
+ */
+#define BCM_SYSPORT_INTR_L2(which) \
+static inline void intrl2_##which##_mask_clear(struct bcm_sysport_priv *priv, \
+ u32 mask) \
+{ \
+ intrl2_##which##_writel(priv, mask, INTRL2_CPU_MASK_CLEAR); \
+ priv->irq##which##_mask &= ~(mask); \
+} \
+static inline void intrl2_##which##_mask_set(struct bcm_sysport_priv *priv, \
+ u32 mask) \
+{ \
+ intrl2_## which##_writel(priv, mask, INTRL2_CPU_MASK_SET); \
+ priv->irq##which##_mask |= (mask); \
+} \
+
+BCM_SYSPORT_INTR_L2(0)
+BCM_SYSPORT_INTR_L2(1)
+
+/* Register accesses to GISB/RBUS registers are expensive (few hundred
+ * nanoseconds), so keep the check for 64-bits explicit here to save
+ * one register write per-packet on 32-bits platforms.
+ */
+static inline void dma_desc_set_addr(struct bcm_sysport_priv *priv,
+ void __iomem *d,
+ dma_addr_t addr)
+{
+#ifdef CONFIG_PHYS_ADDR_T_64BIT
+ __raw_writel(upper_32_bits(addr) & DESC_ADDR_HI_MASK,
+ 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)
+{
+ /* Ports are latched, so write upper address first */
+ tdma_writel(priv, desc->addr_status_len, TDMA_WRITE_PORT_HI(port));
+ tdma_writel(priv, desc->addr_lo, TDMA_WRITE_PORT_LO(port));
+}
+
+/* Ethtool operations */
+static int bcm_sysport_set_settings(struct net_device *dev,
+ struct ethtool_cmd *cmd)
+{
+ struct bcm_sysport_priv *priv = netdev_priv(dev);
+
+ if (!netif_running(dev))
+ return -EINVAL;
+
+ return phy_ethtool_sset(priv->phydev, cmd);
+}
+
+static int bcm_sysport_get_settings(struct net_device *dev,
+ struct ethtool_cmd *cmd)
+{
+ struct bcm_sysport_priv *priv = netdev_priv(dev);
+
+ if (!netif_running(dev))
+ return -EINVAL;
+
+ return phy_ethtool_gset(priv->phydev, cmd);
+}
+
+static int bcm_sysport_set_rx_csum(struct net_device *dev,
+ netdev_features_t wanted)
+{
+ struct bcm_sysport_priv *priv = netdev_priv(dev);
+ u32 reg;
+
+ priv->rx_csum_en = !!(wanted & NETIF_F_RXCSUM);
+ reg = rxchk_readl(priv, RXCHK_CONTROL);
+ if (priv->rx_csum_en)
+ reg |= RXCHK_EN;
+ else
+ reg &= ~RXCHK_EN;
+
+ /* 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)
+ reg |= RXCHK_SKIP_FCS;
+ else
+ reg &= ~RXCHK_SKIP_FCS;
+
+ rxchk_writel(priv, reg, RXCHK_CONTROL);
+
+ return 0;
+}
+
+static int bcm_sysport_set_tx_csum(struct net_device *dev,
+ netdev_features_t wanted)
+{
+ struct bcm_sysport_priv *priv = netdev_priv(dev);
+ u32 reg;
+
+ /* Hardware transmit checksum requires us to enable the Transmit status
+ * block prepended to the packet contents
+ */
+ priv->tsb_en = !!(wanted & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM));
+ reg = tdma_readl(priv, TDMA_CONTROL);
+ if (priv->tsb_en)
+ reg |= TSB_EN;
+ else
+ reg &= ~TSB_EN;
+ tdma_writel(priv, reg, TDMA_CONTROL);
+
+ return 0;
+}
+
+static int bcm_sysport_set_features(struct net_device *dev,
+ netdev_features_t features)
+{
+ netdev_features_t changed = features ^ dev->features;
+ netdev_features_t wanted = dev->wanted_features;
+ int ret = 0;
+
+ if (changed & NETIF_F_RXCSUM)
+ ret = bcm_sysport_set_rx_csum(dev, wanted);
+ if (changed & (NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM))
+ ret = bcm_sysport_set_tx_csum(dev, wanted);
+
+ return ret;
+}
+
+/* Hardware counters must be kept in sync because the order/offset
+ * is important here (order in structure declaration = order in hardware)
+ */
+static const struct bcm_sysport_stats bcm_sysport_gstrings_stats[] = {
+ /* general stats */
+ STAT_NETDEV(rx_packets),
+ STAT_NETDEV(tx_packets),
+ STAT_NETDEV(rx_bytes),
+ STAT_NETDEV(tx_bytes),
+ STAT_NETDEV(rx_errors),
+ STAT_NETDEV(tx_errors),
+ STAT_NETDEV(rx_dropped),
+ STAT_NETDEV(tx_dropped),
+ STAT_NETDEV(multicast),
+ /* UniMAC RSV counters */
+ STAT_MIB_RX("rx_64_octets", mib.rx.pkt_cnt.cnt_64),
+ STAT_MIB_RX("rx_65_127_oct", mib.rx.pkt_cnt.cnt_127),
+ STAT_MIB_RX("rx_128_255_oct", mib.rx.pkt_cnt.cnt_255),
+ STAT_MIB_RX("rx_256_511_oct", mib.rx.pkt_cnt.cnt_511),
+ STAT_MIB_RX("rx_512_1023_oct", mib.rx.pkt_cnt.cnt_1023),
+ STAT_MIB_RX("rx_1024_1518_oct", mib.rx.pkt_cnt.cnt_1518),
+ STAT_MIB_RX("rx_vlan_1519_1522_oct", mib.rx.pkt_cnt.cnt_mgv),
+ STAT_MIB_RX("rx_1522_2047_oct", mib.rx.pkt_cnt.cnt_2047),
+ STAT_MIB_RX("rx_2048_4095_oct", mib.rx.pkt_cnt.cnt_4095),
+ STAT_MIB_RX("rx_4096_9216_oct", mib.rx.pkt_cnt.cnt_9216),
+ STAT_MIB_RX("rx_pkts", mib.rx.pkt),
+ STAT_MIB_RX("rx_bytes", mib.rx.bytes),
+ STAT_MIB_RX("rx_multicast", mib.rx.mca),
+ STAT_MIB_RX("rx_broadcast", mib.rx.bca),
+ STAT_MIB_RX("rx_fcs", mib.rx.fcs),
+ STAT_MIB_RX("rx_control", mib.rx.cf),
+ STAT_MIB_RX("rx_pause", mib.rx.pf),
+ STAT_MIB_RX("rx_unknown", mib.rx.uo),
+ STAT_MIB_RX("rx_align", mib.rx.aln),
+ STAT_MIB_RX("rx_outrange", mib.rx.flr),
+ STAT_MIB_RX("rx_code", mib.rx.cde),
+ STAT_MIB_RX("rx_carrier", mib.rx.fcr),
+ STAT_MIB_RX("rx_oversize", mib.rx.ovr),
+ STAT_MIB_RX("rx_jabber", mib.rx.jbr),
+ STAT_MIB_RX("rx_mtu_err", mib.rx.mtue),
+ STAT_MIB_RX("rx_good_pkts", mib.rx.pok),
+ STAT_MIB_RX("rx_unicast", mib.rx.uc),
+ STAT_MIB_RX("rx_ppp", mib.rx.ppp),
+ STAT_MIB_RX("rx_crc", mib.rx.rcrc),
+ /* UniMAC TSV counters */
+ STAT_MIB_TX("tx_64_octets", mib.tx.pkt_cnt.cnt_64),
+ STAT_MIB_TX("tx_65_127_oct", mib.tx.pkt_cnt.cnt_127),
+ STAT_MIB_TX("tx_128_255_oct", mib.tx.pkt_cnt.cnt_255),
+ STAT_MIB_TX("tx_256_511_oct", mib.tx.pkt_cnt.cnt_511),
+ STAT_MIB_TX("tx_512_1023_oct", mib.tx.pkt_cnt.cnt_1023),
+ STAT_MIB_TX("tx_1024_1518_oct", mib.tx.pkt_cnt.cnt_1518),
+ STAT_MIB_TX("tx_vlan_1519_1522_oct", mib.tx.pkt_cnt.cnt_mgv),
+ STAT_MIB_TX("tx_1522_2047_oct", mib.tx.pkt_cnt.cnt_2047),
+ STAT_MIB_TX("tx_2048_4095_oct", mib.tx.pkt_cnt.cnt_4095),
+ STAT_MIB_TX("tx_4096_9216_oct", mib.tx.pkt_cnt.cnt_9216),
+ STAT_MIB_TX("tx_pkts", mib.tx.pkts),
+ STAT_MIB_TX("tx_multicast", mib.tx.mca),
+ STAT_MIB_TX("tx_broadcast", mib.tx.bca),
+ STAT_MIB_TX("tx_pause", mib.tx.pf),
+ STAT_MIB_TX("tx_control", mib.tx.cf),
+ STAT_MIB_TX("tx_fcs_err", mib.tx.fcs),
+ STAT_MIB_TX("tx_oversize", mib.tx.ovr),
+ STAT_MIB_TX("tx_defer", mib.tx.drf),
+ STAT_MIB_TX("tx_excess_defer", mib.tx.edf),
+ STAT_MIB_TX("tx_single_col", mib.tx.scl),
+ STAT_MIB_TX("tx_multi_col", mib.tx.mcl),
+ STAT_MIB_TX("tx_late_col", mib.tx.lcl),
+ STAT_MIB_TX("tx_excess_col", mib.tx.ecl),
+ STAT_MIB_TX("tx_frags", mib.tx.frg),
+ STAT_MIB_TX("tx_total_col", mib.tx.ncl),
+ STAT_MIB_TX("tx_jabber", mib.tx.jbr),
+ STAT_MIB_TX("tx_bytes", mib.tx.bytes),
+ STAT_MIB_TX("tx_good_pkts", mib.tx.pok),
+ STAT_MIB_TX("tx_unicast", mib.tx.uc),
+ /* UniMAC RUNT counters */
+ STAT_RUNT("rx_runt_pkts", mib.rx_runt_cnt),
+ STAT_RUNT("rx_runt_valid_fcs", mib.rx_runt_fcs),
+ STAT_RUNT("rx_runt_inval_fcs_align", mib.rx_runt_fcs_align),
+ STAT_RUNT("rx_runt_bytes", mib.rx_runt_bytes),
+ /* 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),
+ /* 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),
+};
+
+#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)
+{
+ strlcpy(info->driver, KBUILD_MODNAME, sizeof(info->driver));
+ strlcpy(info->version, "0.1", sizeof(info->version));
+ strlcpy(info->bus_info, "platform", sizeof(info->bus_info));
+ info->n_stats = BCM_SYSPORT_STATS_LEN;
+}
+
+static u32 bcm_sysport_get_msglvl(struct net_device *dev)
+{
+ struct bcm_sysport_priv *priv = netdev_priv(dev);
+
+ return priv->msg_enable;
+}
+
+static void bcm_sysport_set_msglvl(struct net_device *dev, u32 enable)
+{
+ struct bcm_sysport_priv *priv = netdev_priv(dev);
+
+ priv->msg_enable = enable;
+}
+
+static int bcm_sysport_get_sset_count(struct net_device *dev, int string_set)
+{
+ switch (string_set) {
+ case ETH_SS_STATS:
+ return BCM_SYSPORT_STATS_LEN;
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+static void bcm_sysport_get_strings(struct net_device *dev,
+ u32 stringset, u8 *data)
+{
+ int i;
+
+ switch (stringset) {
+ 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);
+ }
+ break;
+ default:
+ break;
+ }
+}
+
+static void bcm_sysport_update_mib_counters(struct bcm_sysport_priv *priv)
+{
+ int i, j = 0;
+
+ for (i = 0; i < BCM_SYSPORT_STATS_LEN; i++) {
+ const struct bcm_sysport_stats *s;
+ u8 offset = 0;
+ u32 val = 0;
+ char *p;
+
+ s = &bcm_sysport_gstrings_stats[i];
+ switch (s->type) {
+ case BCM_SYSPORT_STAT_NETDEV:
+ continue;
+ case BCM_SYSPORT_STAT_MIB_RX:
+ case BCM_SYSPORT_STAT_MIB_TX:
+ case BCM_SYSPORT_STAT_RUNT:
+ if (s->type != BCM_SYSPORT_STAT_MIB_RX)
+ offset = UMAC_MIB_STAT_OFFSET;
+ val = umac_readl(priv, UMAC_MIB_START + j + offset);
+ break;
+ case BCM_SYSPORT_STAT_RXCHK:
+ val = rxchk_readl(priv, s->reg_offset);
+ if (val == ~0)
+ rxchk_writel(priv, 0, s->reg_offset);
+ break;
+ case BCM_SYSPORT_STAT_RBUF:
+ val = rbuf_readl(priv, s->reg_offset);
+ if (val == ~0)
+ rbuf_writel(priv, 0, s->reg_offset);
+ break;
+ }
+
+ j += s->stat_sizeof;
+ p = (char *)priv + s->stat_offset;
+ *(u32 *)p = val;
+ }
+
+ netif_dbg(priv, hw, priv->netdev, "updated MIB counters\n");
+}
+
+static void bcm_sysport_get_stats(struct net_device *dev,
+ struct ethtool_stats *stats, u64 *data)
+{
+ struct bcm_sysport_priv *priv = netdev_priv(dev);
+ int i;
+
+ if (netif_running(dev))
+ bcm_sysport_update_mib_counters(priv);
+
+ for (i = 0; i < BCM_SYSPORT_STATS_LEN; i++) {
+ const struct bcm_sysport_stats *s;
+ char *p;
+
+ s = &bcm_sysport_gstrings_stats[i];
+ if (s->type == BCM_SYSPORT_STAT_NETDEV)
+ p = (char *)&dev->stats;
+ else
+ p = (char *)priv;
+ p += s->stat_offset;
+ data[i] = *(u32 *)p;
+ }
+}
+
+static void bcm_sysport_free_cb(struct bcm_sysport_cb *cb)
+{
+ dev_kfree_skb_any(cb->skb);
+ cb->skb = NULL;
+ dma_unmap_addr_set(cb, dma_addr, 0);
+}
+
+static int bcm_sysport_rx_refill(struct bcm_sysport_priv *priv,
+ struct bcm_sysport_cb *cb)
+{
+ struct device *kdev = &priv->pdev->dev;
+ struct net_device *ndev = priv->netdev;
+ dma_addr_t mapping;
+ int ret;
+
+ cb->skb = netdev_alloc_skb(priv->netdev, RX_BUF_LENGTH);
+ if (!cb->skb) {
+ netif_err(priv, rx_err, ndev, "SKB alloc failed\n");
+ return -ENOMEM;
+ }
+
+ mapping = dma_map_single(kdev, cb->skb->data,
+ RX_BUF_LENGTH, DMA_FROM_DEVICE);
+ ret = dma_mapping_error(kdev, mapping);
+ if (ret) {
+ bcm_sysport_free_cb(cb);
+ netif_err(priv, rx_err, ndev, "DMA mapping failure\n");
+ return ret;
+ }
+
+ dma_unmap_addr_set(cb, dma_addr, mapping);
+ dma_desc_set_addr(priv, priv->rx_bd_assign_ptr, mapping);
+
+ priv->rx_bd_assign_index++;
+ priv->rx_bd_assign_index &= (priv->num_rx_bds - 1);
+ priv->rx_bd_assign_ptr = priv->rx_bds +
+ (priv->rx_bd_assign_index * DESC_SIZE);
+
+ netif_dbg(priv, rx_status, ndev, "RX refill\n");
+
+ return 0;
+}
+
+static int bcm_sysport_alloc_rx_bufs(struct bcm_sysport_priv *priv)
+{
+ struct bcm_sysport_cb *cb;
+ int ret = 0;
+ unsigned int i;
+
+ for (i = 0; i < priv->num_rx_bds; i++) {
+ cb = &priv->rx_cbs[priv->rx_bd_assign_index];
+ if (cb->skb)
+ continue;
+
+ ret = bcm_sysport_rx_refill(priv, cb);
+ if (ret)
+ break;
+ }
+
+ return ret;
+}
+
+/* Poll the hardware for up to budget packets to process */
+static unsigned int bcm_sysport_desc_rx(struct bcm_sysport_priv *priv,
+ unsigned int budget)
+{
+ struct device *kdev = &priv->pdev->dev;
+ struct net_device *ndev = priv->netdev;
+ unsigned int processed = 0, to_process;
+ struct bcm_sysport_cb *cb;
+ struct sk_buff *skb;
+ unsigned int p_index;
+ u16 len, status;
+ struct rsb *rsb;
+
+ /* Determine how much we should process since last call */
+ p_index = rdma_readl(priv, RDMA_PROD_INDEX);
+ p_index &= RDMA_PROD_INDEX_MASK;
+
+ if (p_index < priv->rx_c_index)
+ to_process = (RDMA_CONS_INDEX_MASK + 1) -
+ priv->rx_c_index + p_index;
+ else
+ 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)) {
+
+ cb = &priv->rx_cbs[priv->rx_read_ptr];
+ skb = cb->skb;
+ dma_unmap_single(kdev, dma_unmap_addr(cb, dma_addr),
+ dma_unmap_len(cb, dma_len), DMA_FROM_DEVICE);
+
+ /* Extract the Receive Status Block prepended */
+ rsb = (struct 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;
+
+ processed++;
+ priv->rx_read_ptr++;
+ if (priv->rx_read_ptr == priv->num_rx_bds)
+ 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);
+
+ if (unlikely(!skb)) {
+ netif_err(priv, rx_err, ndev, "out of memory!\n");
+ ndev->stats.rx_dropped++;
+ ndev->stats.rx_errors++;
+ goto refill;
+ }
+
+ if (unlikely(!(status & DESC_EOP) || !(status & DESC_SOP))) {
+ netif_err(priv, rx_status, ndev, "fragmented packet!\n");
+ ndev->stats.rx_dropped++;
+ ndev->stats.rx_errors++;
+ bcm_sysport_free_cb(cb);
+ goto refill;
+ }
+
+ if (unlikely(status & (RX_STATUS_ERR | RX_STATUS_OVFLOW))) {
+ netif_err(priv, rx_err, ndev, "error packet\n");
+ if (RX_STATUS_OVFLOW)
+ ndev->stats.rx_over_errors++;
+ ndev->stats.rx_dropped++;
+ ndev->stats.rx_errors++;
+ bcm_sysport_free_cb(cb);
+ goto refill;
+ }
+
+ skb_put(skb, len);
+
+ /* Hardware validated our checksum */
+ if (likely(status & DESC_L4_CSUM))
+ skb->ip_summed = CHECKSUM_UNNECESSARY;
+
+ /* Hardware pre-pends packets with 2bytes between Ethernet
+ * and IP header plus we have the Receive Status Block, strip
+ * off all of this from the SKB.
+ */
+ skb_pull(skb, sizeof(*rsb) + 2);
+ len -= (sizeof(*rsb) + 2);
+
+ /* UniMAC may forward CRC */
+ if (priv->crc_fwd) {
+ skb_trim(skb, len - ETH_FCS_LEN);
+ len -= ETH_FCS_LEN;
+ }
+
+ skb->protocol = eth_type_trans(skb, ndev);
+ ndev->stats.rx_packets++;
+ ndev->stats.rx_bytes += len;
+
+ napi_gro_receive(&priv->napi, skb);
+refill:
+ bcm_sysport_rx_refill(priv, cb);
+ }
+
+ return processed;
+}
+
+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 device *kdev = &priv->pdev->dev;
+ struct net_device *ndev = priv->netdev;
+
+ if (cb->skb) {
+ 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);
+ ndev->stats.tx_packets++;
+ (*pkts_compl)++;
+ bcm_sysport_free_cb(cb);
+ /* SKB fragment */
+ } 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_addr_set(cb, dma_addr, 0);
+ }
+}
+
+/* Reclaim queued SKBs for transmission completion, lockless version */
+static unsigned int __bcm_sysport_tx_reclaim(struct bcm_sysport_priv *priv,
+ struct bcm_sysport_tx_ring *ring)
+{
+ struct net_device *ndev = priv->netdev;
+ unsigned int c_index, last_c_index, last_tx_cn, num_tx_cbs;
+ unsigned int pkts_compl = 0, bytes_compl = 0;
+ struct bcm_sysport_cb *cb;
+ struct netdev_queue *txq;
+ u32 hw_ind;
+
+ txq = netdev_get_tx_queue(ndev, ring->index);
+
+ /* Compute how many descriptors have been processed since last call */
+ hw_ind = tdma_readl(priv, TDMA_DESC_RING_PROD_CONS_INDEX(ring->index));
+ c_index = (hw_ind >> RING_CONS_INDEX_SHIFT) & RING_CONS_INDEX_MASK;
+ ring->p_index = (hw_ind & RING_PROD_INDEX_MASK);
+
+ last_c_index = ring->c_index;
+ num_tx_cbs = ring->size;
+
+ c_index &= (num_tx_cbs - 1);
+
+ if (c_index >= last_c_index)
+ last_tx_cn = c_index - last_c_index;
+ else
+ 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);
+
+ while (last_tx_cn-- > 0) {
+ cb = ring->cbs + last_c_index;
+ bcm_sysport_tx_reclaim_one(priv, cb, &bytes_compl, &pkts_compl);
+
+ ring->desc_count++;
+ last_c_index++;
+ last_c_index &= (num_tx_cbs - 1);
+ }
+
+ ring->c_index = c_index;
+
+ if (netif_tx_queue_stopped(txq) && pkts_compl)
+ 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);
+
+ return pkts_compl;
+}
+
+/* Locked version of the per-ring TX reclaim routine */
+static unsigned int bcm_sysport_tx_reclaim(struct bcm_sysport_priv *priv,
+ struct bcm_sysport_tx_ring *ring)
+{
+ unsigned int released;
+
+ spin_lock(&ring->lock);
+ released = __bcm_sysport_tx_reclaim(priv, ring);
+ spin_unlock(&ring->lock);
+
+ return released;
+}
+
+static int bcm_sysport_tx_poll(struct napi_struct *napi, int budget)
+{
+ struct bcm_sysport_tx_ring *ring =
+ container_of(napi, struct bcm_sysport_tx_ring, napi);
+ unsigned int work_done = 0;
+
+ work_done = bcm_sysport_tx_reclaim(ring->priv, ring);
+
+ if (work_done < budget) {
+ napi_complete(napi);
+ /* re-enable TX interrupt */
+ intrl2_1_mask_clear(ring->priv, BIT(ring->index));
+ }
+
+ return work_done;
+}
+
+static void bcm_sysport_tx_reclaim_all(struct bcm_sysport_priv *priv)
+{
+ unsigned int q;
+
+ for (q = 0; q < priv->netdev->num_tx_queues; q++)
+ bcm_sysport_tx_reclaim(priv, &priv->tx_rings[q]);
+}
+
+static int bcm_sysport_poll(struct napi_struct *napi, int budget)
+{
+ struct bcm_sysport_priv *priv =
+ container_of(napi, struct bcm_sysport_priv, napi);
+ unsigned int work_done = 0;
+
+ work_done = bcm_sysport_desc_rx(priv, budget);
+
+ priv->rx_c_index += work_done;
+ priv->rx_c_index &= RDMA_CONS_INDEX_MASK;
+ rdma_writel(priv, priv->rx_c_index, RDMA_CONS_INDEX);
+
+ if (work_done < budget) {
+ napi_complete(napi);
+ /* re-enable RX interrupts */
+ intrl2_0_mask_clear(priv, INTRL2_0_RDMA_MBDONE);
+ }
+
+ return work_done;
+}
+
+
+/* RX and misc interrupt routine */
+static irqreturn_t bcm_sysport_rx_isr(int irq, void *dev_id)
+{
+ struct net_device *dev = dev_id;
+ struct bcm_sysport_priv *priv = netdev_priv(dev);
+
+ priv->irq0_stat = intrl2_0_readl(priv, INTRL2_CPU_STATUS) &
+ ~intrl2_0_readl(priv, INTRL2_CPU_MASK_STATUS);
+ intrl2_0_writel(priv, priv->irq0_stat, INTRL2_CPU_CLEAR);
+
+ if (unlikely(priv->irq0_stat == 0)) {
+ netdev_warn(priv->netdev, "spurious RX interrupt\n");
+ return IRQ_NONE;
+ }
+
+ if (priv->irq0_stat & INTRL2_0_RDMA_MBDONE) {
+ if (likely(napi_schedule_prep(&priv->napi))) {
+ /* disable RX interrupts */
+ intrl2_0_mask_set(priv, INTRL2_0_RDMA_MBDONE);
+ __napi_schedule(&priv->napi);
+ }
+ }
+
+ /* TX ring is full, perform a full reclaim since we do not know
+ * which one would trigger this interrupt
+ */
+ if (priv->irq0_stat & INTRL2_0_TX_RING_FULL)
+ bcm_sysport_tx_reclaim_all(priv);
+
+ return IRQ_HANDLED;
+}
+
+/* TX interrupt service routine */
+static irqreturn_t bcm_sysport_tx_isr(int irq, void *dev_id)
+{
+ struct net_device *dev = dev_id;
+ struct bcm_sysport_priv *priv = netdev_priv(dev);
+ struct bcm_sysport_tx_ring *txr;
+ unsigned int ring;
+
+ priv->irq1_stat = intrl2_1_readl(priv, INTRL2_CPU_STATUS) &
+ ~intrl2_1_readl(priv, INTRL2_CPU_MASK_STATUS);
+ intrl2_1_writel(priv, 0xffffffff, INTRL2_CPU_CLEAR);
+
+ if (unlikely(priv->irq1_stat == 0)) {
+ netdev_warn(priv->netdev, "spurious TX interrupt\n");
+ return IRQ_NONE;
+ }
+
+ for (ring = 0; ring < dev->num_tx_queues; ring++) {
+ if (!(priv->irq1_stat & BIT(ring)))
+ continue;
+
+ txr = &priv->tx_rings[ring];
+
+ if (likely(napi_schedule_prep(&txr->napi))) {
+ intrl2_1_mask_set(priv, BIT(ring));
+ __napi_schedule(&txr->napi);
+ }
+ }
+
+ return IRQ_HANDLED;
+}
+
+static int bcm_sysport_insert_tsb(struct sk_buff *skb, struct net_device *dev)
+{
+ struct sk_buff *nskb;
+ struct tsb *tsb;
+ u32 csum_info;
+ u8 ip_proto;
+ u16 csum_start;
+ u16 ip_ver;
+
+ /* Re-allocate SKB if needed */
+ if (unlikely(skb_headroom(skb) < sizeof(*tsb))) {
+ nskb = skb_realloc_headroom(skb, sizeof(*tsb));
+ dev_kfree_skb(skb);
+ if (!nskb) {
+ dev->stats.tx_errors++;
+ dev->stats.tx_dropped++;
+ return -ENOMEM;
+ }
+ skb = nskb;
+ }
+
+ tsb = (struct tsb *)skb_push(skb, sizeof(*tsb));
+ /* Zero-out TSB by default */
+ memset(tsb, 0, sizeof(*tsb));
+
+ if (skb->ip_summed == CHECKSUM_PARTIAL) {
+ ip_ver = htons(skb->protocol);
+ switch (ip_ver) {
+ case ETH_P_IP:
+ ip_proto = ip_hdr(skb)->protocol;
+ break;
+ case ETH_P_IPV6:
+ ip_proto = ipv6_hdr(skb)->nexthdr;
+ break;
+ default:
+ return 0;
+ }
+
+ /* Get the checksum offset and the L4 (transport) offset */
+ csum_start = skb_checksum_start_offset(skb) - sizeof(*tsb);
+ csum_info = (csum_start + skb->csum_offset) & L4_CSUM_PTR_MASK;
+ csum_info |= (csum_start << L4_PTR_SHIFT);
+
+ if (ip_proto == IPPROTO_TCP || ip_proto == IPPROTO_UDP) {
+ csum_info |= L4_LENGTH_VALID;
+ if (ip_proto == IPPROTO_UDP && ip_ver == ETH_P_IP)
+ csum_info |= L4_UDP;
+ } else
+ csum_info = 0;
+
+ tsb->l4_ptr_dest_map = csum_info;
+ }
+
+ return 0;
+}
+
+static netdev_tx_t bcm_sysport_xmit(struct sk_buff *skb,
+ struct net_device *dev)
+{
+ struct bcm_sysport_priv *priv = netdev_priv(dev);
+ struct device *kdev = &priv->pdev->dev;
+ struct bcm_sysport_tx_ring *ring;
+ struct bcm_sysport_cb *cb;
+ struct netdev_queue *txq;
+ struct dma_desc *desc;
+ dma_addr_t mapping;
+ u32 len_status;
+ u16 queue;
+ int ret;
+
+ queue = skb_get_queue_mapping(skb);
+ txq = netdev_get_tx_queue(dev, queue);
+ ring = &priv->tx_rings[queue];
+
+ /* lock against tx reclaim in BH context */
+ spin_lock(&ring->lock);
+ if (unlikely(ring->desc_count == 0)) {
+ netif_tx_stop_queue(txq);
+ netdev_err(dev, "queue %d awake and ring full!\n", queue);
+ ret = NETDEV_TX_BUSY;
+ goto out;
+ }
+
+ /* Insert TSB and checksum infos */
+ if (priv->tsb_en) {
+ ret = bcm_sysport_insert_tsb(skb, dev);
+ if (ret) {
+ ret = NETDEV_TX_OK;
+ goto out;
+ }
+ }
+
+ 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);
+ ret = NETDEV_TX_OK;
+ goto out;
+ }
+
+ /* Remember the SKB for future freeing */
+ cb = &ring->cbs[ring->curr_desc];
+ cb->skb = skb;
+ dma_unmap_addr_set(cb, dma_addr, mapping);
+ dma_unmap_len_set(cb, dma_len, skb->len);
+
+ /* Fetch a descriptor entry from our pool */
+ desc = ring->desc_cpu;
+
+ desc->addr_lo = lower_32_bits(mapping);
+ 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;
+ if (skb->ip_summed == CHECKSUM_PARTIAL)
+ len_status |= (DESC_L4_CSUM << DESC_STATUS_SHIFT);
+
+ ring->curr_desc++;
+ if (ring->curr_desc == ring->size)
+ ring->curr_desc = 0;
+ ring->desc_count--;
+
+ /* Ensure write completion of the descriptor status/length
+ * in DRAM before the System Port WRITE_PORT register latches
+ * the value
+ */
+ wmb();
+ desc->addr_status_len = len_status;
+ wmb();
+
+ /* Write this descriptor address to the RING write port */
+ tdma_port_write_desc_addr(priv, desc, ring->index);
+
+ /* Check ring space and update SW control flow */
+ if (ring->desc_count == 0)
+ 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);
+
+ ret = NETDEV_TX_OK;
+out:
+ spin_unlock(&ring->lock);
+ return ret;
+}
+
+static void bcm_sysport_tx_timeout(struct net_device *dev)
+{
+ netdev_warn(dev, "transmit timeout!\n");
+
+ dev->trans_start = jiffies;
+ dev->stats.tx_errors++;
+
+ netif_tx_wake_all_queues(dev);
+}
+
+/* phylib adjust link callback */
+static void bcm_sysport_adj_link(struct net_device *dev)
+{
+ struct bcm_sysport_priv *priv = netdev_priv(dev);
+ struct phy_device *phydev = priv->phydev;
+ unsigned int changed = 0;
+ u32 cmd_bits = 0, reg;
+
+ if (priv->old_link != phydev->link) {
+ changed = 1;
+ priv->old_link = phydev->link;
+ }
+
+ if (priv->old_duplex != phydev->duplex) {
+ changed = 1;
+ priv->old_duplex = phydev->duplex;
+ }
+
+ switch (phydev->speed) {
+ case SPEED_2500:
+ cmd_bits = CMD_SPEED_2500;
+ break;
+ case SPEED_1000:
+ cmd_bits = CMD_SPEED_1000;
+ break;
+ case SPEED_100:
+ cmd_bits = CMD_SPEED_100;
+ break;
+ case SPEED_10:
+ cmd_bits = CMD_SPEED_10;
+ break;
+ default:
+ break;
+ }
+ cmd_bits <<= CMD_SPEED_SHIFT;
+
+ if (phydev->duplex == DUPLEX_HALF)
+ cmd_bits |= CMD_HD_EN;
+
+ if (priv->old_pause != phydev->pause) {
+ changed = 1;
+ priv->old_pause = phydev->pause;
+ }
+
+ if (!phydev->pause)
+ cmd_bits |= CMD_RX_PAUSE_IGNORE | CMD_TX_PAUSE_IGNORE;
+
+ reg = 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;
+ umac_writel(priv, reg, UMAC_CMD);
+
+ if (changed)
+ phy_print_status(priv->phydev);
+}
+
+static int bcm_sysport_init_tx_ring(struct bcm_sysport_priv *priv,
+ unsigned int index)
+{
+ struct bcm_sysport_tx_ring *ring = &priv->tx_rings[index];
+ struct device *kdev = &priv->pdev->dev;
+ size_t size;
+ void *p;
+ u32 reg;
+
+ /* Simple descriptors partitioning for now */
+ size = 256;
+
+ /* We just need one DMA descriptor which is DMA-able, since writing to
+ * the port will allocate a new descriptor in its internal linked-list
+ */
+ p = dma_zalloc_coherent(kdev, 1, &ring->desc_dma, GFP_KERNEL);
+ if (!p) {
+ netif_err(priv, hw, priv->netdev, "DMA alloc failed\n");
+ return -ENOMEM;
+ }
+
+ ring->cbs = kzalloc(sizeof(struct bcm_sysport_cb) * size, GFP_KERNEL);
+ if (!ring->cbs) {
+ netif_err(priv, hw, priv->netdev, "CB allocation failed\n");
+ return -ENOMEM;
+ }
+
+ /* Initialize SW view of the ring */
+ spin_lock_init(&ring->lock);
+ ring->priv = priv;
+ netif_napi_add(priv->netdev, &ring->napi, bcm_sysport_tx_poll, 64);
+ ring->index = index;
+ ring->size = size;
+ ring->alloc_size = ring->size;
+ ring->desc_cpu = p;
+ ring->desc_count = ring->size;
+ ring->curr_desc = 0;
+
+ /* Initialize HW ring */
+ tdma_writel(priv, RING_EN, TDMA_DESC_RING_HEAD_TAIL_PTR(index));
+ tdma_writel(priv, 0, TDMA_DESC_RING_COUNT(index));
+ tdma_writel(priv, 1, TDMA_DESC_RING_INTR_CONTROL(index));
+ tdma_writel(priv, 0, TDMA_DESC_RING_PROD_CONS_INDEX(index));
+ tdma_writel(priv, RING_IGNORE_STATUS, TDMA_DESC_RING_MAPPING(index));
+ tdma_writel(priv, 0, TDMA_DESC_RING_PCP_DEI_VID(index));
+
+ /* Program the number of descriptors as MAX_THRESHOLD and half of
+ * its size for the hysteresis trigger
+ */
+ tdma_writel(priv, ring->size |
+ 1 << RING_HYST_THRESH_SHIFT,
+ TDMA_DESC_RING_MAX_HYST(index));
+
+ /* Enable the ring queue in the arbiter */
+ reg = tdma_readl(priv, TDMA_TIER1_ARB_0_QUEUE_EN);
+ reg |= (1 << index);
+ tdma_writel(priv, reg, TDMA_TIER1_ARB_0_QUEUE_EN);
+
+ napi_enable(&ring->napi);
+
+ netif_dbg(priv, hw, priv->netdev,
+ "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)
+{
+ struct bcm_sysport_tx_ring *ring = &priv->tx_rings[index];
+ struct device *kdev = &priv->pdev->dev;
+ u32 reg;
+
+ /* Caller should stop the TDMA engine */
+ reg = tdma_readl(priv, TDMA_STATUS);
+ if (!(reg & TDMA_DISABLED))
+ netdev_warn(priv->netdev, "TDMA not stopped!\n");
+
+ napi_disable(&ring->napi);
+ netif_napi_del(&ring->napi);
+
+ bcm_sysport_tx_reclaim(priv, ring);
+
+ kfree(ring->cbs);
+ ring->cbs = NULL;
+
+ if (ring->desc_dma) {
+ dma_free_coherent(kdev, 1, ring->desc_cpu, ring->desc_dma);
+ ring->desc_dma = 0;
+ }
+ ring->size = 0;
+ ring->alloc_size = 0;
+
+ netif_dbg(priv, hw, priv->netdev, "TDMA fini done\n");
+}
+
+/* RDMA helper */
+static inline int rdma_enable_set(struct bcm_sysport_priv *priv,
+ unsigned int enable)
+{
+ unsigned int timeout = 1000;
+ u32 reg;
+
+ reg = rdma_readl(priv, RDMA_CONTROL);
+ if (enable)
+ reg |= RDMA_EN;
+ else
+ reg &= ~RDMA_EN;
+ rdma_writel(priv, reg, RDMA_CONTROL);
+
+ /* Poll for RMDA disabling completion */
+ do {
+ reg = rdma_readl(priv, RDMA_STATUS);
+ if (!!(reg & RDMA_DISABLED) == !enable)
+ return 0;
+ usleep_range(1000, 2000);
+ } while (timeout-- > 0);
+
+ netdev_err(priv->netdev, "timeout waiting for RDMA to finish\n");
+
+ return -ETIMEDOUT;
+}
+
+/* TDMA helper */
+static inline int tdma_enable_set(struct bcm_sysport_priv *priv,
+ unsigned int enable)
+{
+ unsigned int timeout = 1000;
+ u32 reg;
+
+ reg = tdma_readl(priv, TDMA_CONTROL);
+ if (enable)
+ reg |= TDMA_EN;
+ else
+ reg &= ~TDMA_EN;
+ tdma_writel(priv, reg, TDMA_CONTROL);
+
+ /* Poll for TMDA disabling completion */
+ do {
+ reg = tdma_readl(priv, TDMA_STATUS);
+ if (!!(reg & TDMA_DISABLED) == !enable)
+ return 0;
+
+ usleep_range(1000, 2000);
+ } while (timeout-- > 0);
+
+ netdev_err(priv->netdev, "timeout waiting for TDMA to finish\n");
+
+ return -ETIMEDOUT;
+}
+
+static int bcm_sysport_init_rx_ring(struct bcm_sysport_priv *priv)
+{
+ u32 reg;
+ int ret;
+
+ /* Initialize SW view of the RX ring */
+ priv->num_rx_bds = NUM_RX_DESC;
+ priv->rx_bds = priv->base + SYS_PORT_RDMA_OFFSET;
+ priv->rx_bd_assign_ptr = priv->rx_bds;
+ 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);
+ if (!priv->rx_cbs) {
+ netif_err(priv, hw, priv->netdev, "CB allocation failed\n");
+ return -ENOMEM;
+ }
+
+ ret = bcm_sysport_alloc_rx_bufs(priv);
+ if (ret) {
+ netif_err(priv, hw, priv->netdev, "SKB allocation failed\n");
+ return ret;
+ }
+
+ /* Initialize HW, ensure RDMA is disabled */
+ reg = rdma_readl(priv, RDMA_STATUS);
+ if (!(reg & RDMA_DISABLED))
+ rdma_enable_set(priv, 0);
+
+ rdma_writel(priv, 0, RDMA_WRITE_PTR_LO);
+ rdma_writel(priv, 0, RDMA_WRITE_PTR_HI);
+ rdma_writel(priv, 0, RDMA_PROD_INDEX);
+ rdma_writel(priv, 0, RDMA_CONS_INDEX);
+ rdma_writel(priv, priv->num_rx_bds << RDMA_RING_SIZE_SHIFT |
+ RX_BUF_LENGTH, RDMA_RING_BUF_SIZE);
+ /* Operate the queue in ring mode */
+ rdma_writel(priv, 0, RDMA_START_ADDR_HI);
+ rdma_writel(priv, 0, RDMA_START_ADDR_LO);
+ rdma_writel(priv, 0, RDMA_END_ADDR_HI);
+ rdma_writel(priv, NUM_HW_RX_DESC_WORDS - 1, RDMA_END_ADDR_LO);
+
+ 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);
+
+ return 0;
+}
+
+static void bcm_sysport_fini_rx_ring(struct bcm_sysport_priv *priv)
+{
+ struct bcm_sysport_cb *cb;
+ unsigned int i;
+ u32 reg;
+
+ /* Caller should ensure RDMA is disabled */
+ reg = rdma_readl(priv, RDMA_STATUS);
+ if (!(reg & RDMA_DISABLED))
+ netdev_warn(priv->netdev, "RDMA not stopped!\n");
+
+ for (i = 0; i < priv->num_rx_bds; i++) {
+ 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);
+ bcm_sysport_free_cb(cb);
+ }
+
+ kfree(priv->rx_cbs);
+ priv->rx_cbs = NULL;
+
+ netif_dbg(priv, hw, priv->netdev, "RDMA fini done\n");
+}
+
+static void bcm_sysport_set_rx_mode(struct net_device *dev)
+{
+ struct bcm_sysport_priv *priv = netdev_priv(dev);
+ u32 reg;
+
+ reg = umac_readl(priv, UMAC_CMD);
+ if (dev->flags & IFF_PROMISC)
+ reg |= CMD_PROMISC;
+ else
+ reg &= ~CMD_PROMISC;
+ umac_writel(priv, reg, UMAC_CMD);
+
+ /* No support for ALLMULTI */
+ if (dev->flags & IFF_ALLMULTI)
+ return;
+}
+
+static inline void umac_enable_set(struct bcm_sysport_priv *priv,
+ unsigned int enable)
+{
+ u32 reg;
+
+ reg = umac_readl(priv, UMAC_CMD);
+ if (enable)
+ reg |= CMD_RX_EN | CMD_TX_EN;
+ else
+ reg &= ~(CMD_RX_EN | CMD_TX_EN);
+ umac_writel(priv, reg, UMAC_CMD);
+}
+
+static inline int 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;
+}
+
+static void umac_set_hw_addr(struct bcm_sysport_priv *priv,
+ unsigned char *addr)
+{
+ umac_writel(priv, (addr[0] << 24) | (addr[1] << 16) |
+ (addr[2] << 8) | addr[3], UMAC_MAC0);
+ umac_writel(priv, (addr[4] << 8) | addr[5], UMAC_MAC1);
+}
+
+static void topctrl_flush(struct bcm_sysport_priv *priv)
+{
+ topctrl_writel(priv, RX_FLUSH, RX_FLUSH_CNTL);
+ topctrl_writel(priv, TX_FLUSH, TX_FLUSH_CNTL);
+ mdelay(1);
+ topctrl_writel(priv, 0, RX_FLUSH_CNTL);
+ topctrl_writel(priv, 0, TX_FLUSH_CNTL);
+}
+
+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;
+ }
+
+ /* Flush TX and RX FIFOs at TOPCTRL level */
+ topctrl_flush(priv);
+
+ /* Disable the UniMAC RX/TX */
+ umac_enable_set(priv, 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);
+
+ /* 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);
+
+ /* Read CRC forward */
+ priv->crc_fwd = !!(umac_readl(priv, UMAC_CMD) & CMD_CRC_FWD);
+
+ priv->phydev = of_phy_connect_fixed_link(dev, bcm_sysport_adj_link,
+ priv->phy_interface);
+ if (!priv->phydev) {
+ netdev_err(dev, "could not attach to PHY\n");
+ return -ENODEV;
+ }
+
+ /* Reset house keeping link status */
+ priv->old_duplex = -1;
+ priv->old_link = -1;
+ priv->old_pause = -1;
+
+ /* mask all interrupts and request them */
+ intrl2_0_writel(priv, 0xffffffff, INTRL2_CPU_MASK_SET);
+ intrl2_0_writel(priv, 0xffffffff, INTRL2_CPU_CLEAR);
+ intrl2_0_writel(priv, 0, INTRL2_CPU_MASK_CLEAR);
+ intrl2_1_writel(priv, 0xffffffff, INTRL2_CPU_MASK_SET);
+ intrl2_1_writel(priv, 0xffffffff, INTRL2_CPU_CLEAR);
+ intrl2_1_writel(priv, 0, INTRL2_CPU_MASK_CLEAR);
+
+ ret = request_irq(priv->irq0, bcm_sysport_rx_isr, 0, dev->name, dev);
+ if (ret) {
+ netdev_err(dev, "failed to request RX interrupt\n");
+ goto out_phy_disconnect;
+ }
+
+ ret = request_irq(priv->irq1, bcm_sysport_tx_isr, 0, dev->name, dev);
+ if (ret) {
+ netdev_err(dev, "failed to request TX interrupt\n");
+ goto out_free_irq0;
+ }
+
+ /* 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_ring;
+ }
+ }
+
+ /* 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;
+ }
+
+ /* Turn on RDMA */
+ ret = rdma_enable_set(priv, 1);
+ if (ret)
+ goto out_free_rx_ring;
+
+ /* Enable RX interrupt and TX ring full interrupt */
+ intrl2_0_mask_clear(priv, INTRL2_0_RDMA_MBDONE | INTRL2_0_TX_RING_FULL);
+
+ /* Turn on TDMA */
+ ret = tdma_enable_set(priv, 1);
+ 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);
+
+ /* 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);
+
+ return 0;
+
+out_clear_rx_int:
+ intrl2_0_mask_set(priv, INTRL2_0_RDMA_MBDONE | INTRL2_0_TX_RING_FULL);
+out_free_rx_ring:
+ bcm_sysport_fini_rx_ring(priv);
+out_free_tx_ring:
+ for (i = 0; i < dev->num_tx_queues; i++)
+ bcm_sysport_fini_tx_ring(priv, i);
+ free_irq(priv->irq1, dev);
+out_free_irq0:
+ free_irq(priv->irq0, dev);
+out_phy_disconnect:
+ phy_disconnect(priv->phydev);
+ return ret;
+}
+
+static int bcm_sysport_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);
+ napi_disable(&priv->napi);
+ phy_stop(priv->phydev);
+
+ /* mask all interrupts */
+ intrl2_0_mask_set(priv, 0xffffffff);
+ intrl2_0_writel(priv, 0xffffffff, INTRL2_CPU_CLEAR);
+ intrl2_1_mask_set(priv, 0xffffffff);
+ intrl2_1_writel(priv, 0xffffffff, INTRL2_CPU_CLEAR);
+
+ /* Disable UniMAC RX */
+ reg = umac_readl(priv, UMAC_CMD);
+ reg &= ~CMD_RX_EN;
+ umac_writel(priv, reg, UMAC_CMD);
+
+ ret = tdma_enable_set(priv, 0);
+ if (ret) {
+ netdev_err(dev, "timeout disabling RDMA\n");
+ return ret;
+ }
+
+ /* Wait for a maximum packet size to be drained */
+ usleep_range(2000, 3000);
+
+ ret = rdma_enable_set(priv, 0);
+ if (ret) {
+ netdev_err(dev, "timeout disabling TDMA\n");
+ return ret;
+ }
+
+ /* Disable UniMAC TX */
+ reg = umac_readl(priv, UMAC_CMD);
+ reg &= ~CMD_TX_EN;
+ umac_writel(priv, reg, UMAC_CMD);
+
+ /* 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);
+
+ free_irq(priv->irq0, dev);
+ free_irq(priv->irq1, dev);
+
+ /* Disconnect from PHY */
+ phy_disconnect(priv->phydev);
+
+ return 0;
+}
+
+static struct ethtool_ops bcm_sysport_ethtool_ops = {
+ .get_settings = bcm_sysport_get_settings,
+ .set_settings = bcm_sysport_set_settings,
+ .get_drvinfo = bcm_sysport_get_drvinfo,
+ .get_msglevel = bcm_sysport_get_msglvl,
+ .set_msglevel = bcm_sysport_set_msglvl,
+ .get_link = ethtool_op_get_link,
+ .get_strings = bcm_sysport_get_strings,
+ .get_ethtool_stats = bcm_sysport_get_stats,
+ .get_sset_count = bcm_sysport_get_sset_count,
+};
+
+static const struct net_device_ops bcm_sysport_netdev_ops = {
+ .ndo_start_xmit = bcm_sysport_xmit,
+ .ndo_tx_timeout = bcm_sysport_tx_timeout,
+ .ndo_open = bcm_sysport_open,
+ .ndo_stop = bcm_sysport_stop,
+ .ndo_set_features = bcm_sysport_set_features,
+ .ndo_set_rx_mode = bcm_sysport_set_rx_mode,
+};
+
+#define REV_FMT "v%2x.%02x"
+
+static int bcm_sysport_probe(struct platform_device *pdev)
+{
+ struct bcm_sysport_priv *priv;
+ struct device_node *dn;
+ struct net_device *dev;
+ const void *macaddr;
+ struct resource *r;
+ u32 txq, rxq;
+ int ret;
+
+ dn = pdev->dev.of_node;
+ r = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+
+ /* Read the Transmit/Receive Queue properties */
+ if (of_property_read_u32(dn, "systemport,num-txq", &txq))
+ txq = TDMA_NUM_RINGS;
+ if (of_property_read_u32(dn, "systemport,num-rxq", &rxq))
+ rxq = 1;
+
+ dev = alloc_etherdev_mqs(sizeof(*priv), txq, rxq);
+ if (!dev)
+ return -ENOMEM;
+
+ /* Initialize private members */
+ priv = netdev_priv(dev);
+
+ priv->irq0 = platform_get_irq(pdev, 0);
+ priv->irq1 = platform_get_irq(pdev, 1);
+ if (priv->irq0 <= 0 || priv->irq1 <= 0) {
+ dev_err(&pdev->dev, "invalid interrupts\n");
+ ret = -EINVAL;
+ goto err;
+ }
+
+ priv->base = devm_request_and_ioremap(&pdev->dev, r);
+ if (!priv->base) {
+ dev_err(&pdev->dev, "register remap failed\n");
+ ret = -ENOMEM;
+ goto err;
+ }
+
+ priv->netdev = dev;
+ priv->pdev = pdev;
+
+ priv->phy_interface = of_get_phy_mode(dn);
+ /* Default to GMII interface mode */
+ if (priv->phy_interface < 0)
+ priv->phy_interface = PHY_INTERFACE_MODE_GMII;
+
+ /* Initialize netdevice members */
+ macaddr = of_get_mac_address(dn);
+ if (!macaddr || !is_valid_ether_addr(macaddr)) {
+ dev_warn(&pdev->dev, "using random Ethernet MAC\n");
+ random_ether_addr(dev->dev_addr);
+ } else {
+ ether_addr_copy(dev->dev_addr, macaddr);
+ }
+
+ SET_NETDEV_DEV(dev, &pdev->dev);
+ dev_set_drvdata(&pdev->dev, dev);
+ SET_ETHTOOL_OPS(dev, &bcm_sysport_ethtool_ops);
+ dev->netdev_ops = &bcm_sysport_netdev_ops;
+ netif_napi_add(dev, &priv->napi, bcm_sysport_poll, 64);
+
+ /* HW supported features, none enabled by default */
+ dev->hw_features |= NETIF_F_RXCSUM | NETIF_F_HIGHDMA |
+ NETIF_F_IP_CSUM | NETIF_F_IPV6_CSUM;
+
+ /* Set the needed headroom once and for all */
+ BUILD_BUG_ON(sizeof(struct tsb) != 8);
+ dev->needed_headroom += sizeof(struct 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;
+
+ ret = register_netdev(dev);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register net_device\n");
+ goto err;
+ }
+
+ 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);
+
+ return 0;
+err:
+ free_netdev(dev);
+ return ret;
+}
+
+static int bcm_sysport_remove(struct platform_device *pdev)
+{
+ struct net_device *dev = dev_get_drvdata(&pdev->dev);
+
+ /* Not much to do, ndo_close has been called
+ * and we use managed allocations
+ */
+ unregister_netdev(dev);
+ free_netdev(dev);
+ dev_set_drvdata(&pdev->dev, NULL);
+
+ return 0;
+}
+
+static const struct of_device_id bcm_sysport_of_match[] = {
+ { .compatible = "brcm,systemport-v1.00" },
+ { .compatible = "brcm,systemport" },
+ { /* sentinel */ }
+};
+
+static struct platform_driver bcm_sysport_driver = {
+ .probe = bcm_sysport_probe,
+ .remove = bcm_sysport_remove,
+ .driver = {
+ .name = "brcm-systemport",
+ .owner = THIS_MODULE,
+ .of_match_table = bcm_sysport_of_match,
+ },
+};
+module_platform_driver(bcm_sysport_driver);
+
+MODULE_AUTHOR("Broadcom Corporation");
+MODULE_DESCRIPTION("Broadcom System Port Ethernet MAC driver");
+MODULE_ALIAS("platform:brcm-systemport");
+MODULE_LICENSE("GPL");
diff --git a/drivers/net/ethernet/broadcom/bcmsysport.h b/drivers/net/ethernet/broadcom/bcmsysport.h
new file mode 100644
index 0000000..a0441e7
--- /dev/null
+++ b/drivers/net/ethernet/broadcom/bcmsysport.h
@@ -0,0 +1,677 @@
+/*
+ * Broadcom BCM7xxx System Port Ethernet MAC driver
+ *
+ * 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.
+ */
+
+#ifndef __BCM_SYSPORT_H
+#define __BCM_SYSPORT_H
+
+#include <linux/if_vlan.h>
+
+/* Receive/transmit descriptor format */
+#define DESC_ADDR_HI_STATUS_LEN 0x00
+#define DESC_ADDR_HI_SHIFT 0
+#define DESC_ADDR_HI_MASK 0xff
+#define DESC_STATUS_SHIFT 8
+#define DESC_STATUS_MASK 0x3ff
+#define DESC_LEN_SHIFT 18
+#define DESC_LEN_MASK 0x7fff
+#define DESC_ADDR_LO 0x04
+
+/* HW supports 40-bit addressing hence the */
+#define DESC_SIZE (WORDS_PER_DESC * sizeof(u32))
+
+/* Default RX buffer allocation size */
+#define RX_BUF_LENGTH 2048
+
+/* Body(1500) + EH_SIZE(14) + VLANTAG(4) + BRCMTAG(6) + FCS(4) = 1528.
+ * 1536 is multiple of 256 bytes
+ */
+#define ENET_BRCM_TAG_LEN 6
+#define ENET_PAD 8
+#define UMAC_MAX_MTU_SIZE (ETH_DATA_LEN + ETH_HLEN + VLAN_HLEN + \
+ ENET_BRCM_TAG_LEN + ETH_FCS_LEN + ENET_PAD)
+
+/* Transmit status block */
+struct tsb {
+ u32 pcp_dei_vid;
+#define PCP_DEI_MASK 0xf
+#define VID_SHIFT 4
+#define VID_MASK 0xfff
+ u32 l4_ptr_dest_map;
+#define L4_CSUM_PTR_MASK 0x1ff
+#define L4_PTR_SHIFT 9
+#define L4_PTR_MASK 0x1ff
+#define L4_UDP (1 << 18)
+#define L4_LENGTH_VALID (1 << 19)
+#define DEST_MAP_SHIFT 20
+#define DEST_MAP_MASK 0x1ff
+};
+
+/* Receive status block uses the same
+ * definitions as the DMA descriptor
+ */
+struct rsb {
+ u32 rx_status_len;
+ u32 brcm_egress_tag;
+};
+
+/* Common Receive/Transmit status bits */
+#define DESC_L4_CSUM (1 << 7)
+#define DESC_SOP (1 << 8)
+#define DESC_EOP (1 << 9)
+
+/* Receive Status bits */
+#define RX_STATUS_UCAST 0
+#define RX_STATUS_BCAST 0x04
+#define RX_STATUS_MCAST 0x08
+#define RX_STATUS_L2_MCAST 0x0c
+#define RX_STATUS_ERR (1 << 4)
+#define RX_STATUS_OVFLOW (1 << 5)
+#define RX_STATUS_PARSE_FAIL (1 << 6)
+
+/* Transmit Status bits */
+#define TX_STATUS_VLAN_NO_ACT 0x00
+#define TX_STATUS_VLAN_PCP_TSB 0x01
+#define TX_STATUS_VLAN_QUEUE 0x02
+#define TX_STATUS_VLAN_VID_TSB 0x03
+#define TX_STATUS_OWR_CRC (1 << 2)
+#define TX_STATUS_APP_CRC (1 << 3)
+#define TX_STATUS_BRCM_TAG_NO_ACT 0
+#define TX_STATUS_BRCM_TAG_ZERO 0x10
+#define TX_STATUS_BRCM_TAG_ONE_QUEUE 0x20
+#define TX_STATUS_BRCM_TAG_ONE_TSB 0x30
+#define TX_STATUS_SKIP_BYTES (1 << 6)
+
+/* Specific register definitions */
+#define SYS_PORT_TOPCTRL_OFFSET 0
+#define REV_CNTL 0x00
+#define REV_MASK 0xffff
+
+#define RX_FLUSH_CNTL 0x04
+#define RX_FLUSH (1 << 0)
+
+#define TX_FLUSH_CNTL 0x08
+#define TX_FLUSH (1 << 0)
+
+#define MISC_CNTL 0x0c
+#define SYS_CLK_SEL (1 << 0)
+#define TDMA_EOP_SEL (1 << 1)
+
+/* Level-2 Interrupt controller offsets and defines */
+#define SYS_PORT_INTRL2_0_OFFSET 0x200
+#define SYS_PORT_INTRL2_1_OFFSET 0x240
+#define INTRL2_CPU_STATUS 0x00
+#define INTRL2_CPU_SET 0x04
+#define INTRL2_CPU_CLEAR 0x08
+#define INTRL2_CPU_MASK_STATUS 0x0c
+#define INTRL2_CPU_MASK_SET 0x10
+#define INTRL2_CPU_MASK_CLEAR 0x14
+
+/* Level-2 instance 0 interrupt bits */
+#define INTRL2_0_GISB_ERR (1 << 0)
+#define INTRL2_0_RBUF_OVFLOW (1 << 1)
+#define INTRL2_0_TBUF_UNDFLOW (1 << 2)
+#define INTRL2_0_MPD (1 << 3)
+#define INTRL2_0_BRCM_MATCH_TAG (1 << 4)
+#define INTRL2_0_RDMA_MBDONE (1 << 5)
+#define INTRL2_0_OVER_MAX_THRESH (1 << 6)
+#define INTRL2_0_BELOW_HYST_THRESH (1 << 7)
+#define INTRL2_0_FREE_LIST_EMPTY (1 << 8)
+#define INTRL2_0_TX_RING_FULL (1 << 9)
+#define INTRL2_0_DESC_ALLOC_ERR (1 << 10)
+#define INTRL2_0_UNEXP_PKTSIZE_ACK (1 << 11)
+
+/* RXCHK offset and defines */
+#define SYS_PORT_RXCHK_OFFSET 0x300
+
+#define RXCHK_CONTROL 0x00
+#define RXCHK_EN (1 << 0)
+#define RXCHK_SKIP_FCS (1 << 1)
+#define RXCHK_BAD_CSUM_DIS (1 << 2)
+#define RXCHK_BRCM_TAG_EN (1 << 3)
+#define RXCHK_BRCM_TAG_MATCH_SHIFT 4
+#define RXCHK_BRCM_TAG_MATCH_MASK 0xff
+#define RXCHK_PARSE_TNL (1 << 12)
+#define RXCHK_VIOL_EN (1 << 13)
+#define RXCHK_VIOL_DIS (1 << 14)
+#define RXCHK_INCOM_PKT (1 << 15)
+#define RXCHK_V6_DUPEXT_EN (1 << 16)
+#define RXCHK_V6_DUPEXT_DIS (1 << 17)
+#define RXCHK_ETHERTYPE_DIS (1 << 18)
+#define RXCHK_L2_HDR_DIS (1 << 19)
+#define RXCHK_L3_HDR_DIS (1 << 20)
+#define RXCHK_MAC_RX_ERR_DIS (1 << 21)
+#define RXCHK_PARSE_AUTH (1 << 22)
+
+#define RXCHK_BRCM_TAG0 0x04
+#define RXCHK_BRCM_TAG(i) ((i) * RXCHK_BRCM_TAG0)
+#define RXCHK_BRCM_TAG0_MASK 0x24
+#define RXCHK_BRCM_TAG_MASK(i) ((i) * RXCHK_BRCM_TAG0_MASK)
+#define RXCHK_BRCM_TAG_MATCH_STATUS 0x44
+#define RXCHK_ETHERTYPE 0x48
+#define RXCHK_BAD_CSUM_CNTR 0x4C
+#define RXCHK_OTHER_DISC_CNTR 0x50
+
+/* TXCHCK offsets and defines */
+#define SYS_PORT_TXCHK_OFFSET 0x380
+#define TXCHK_PKT_RDY_THRESH 0x00
+
+/* Receive buffer offset and defines */
+#define SYS_PORT_RBUF_OFFSET 0x400
+
+#define RBUF_CONTROL 0x00
+#define RBUF_RSB_EN (1 << 0)
+#define RBUF_4B_ALGN (1 << 1)
+#define RBUF_BRCM_TAG_STRIP (1 << 2)
+#define RBUF_BAD_PKT_DISC (1 << 3)
+#define RBUF_RESUME_THRESH_SHIFT 4
+#define RBUF_RESUME_THRESH_MASK 0xff
+#define RBUF_OK_TO_SEND_SHIFT 12
+#define RBUF_OK_TO_SEND_MASK 0xff
+#define RBUF_CRC_REPLACE (1 << 20)
+#define RBUF_OK_TO_SEND_MODE (1 << 21)
+#define RBUF_RSB_SWAP (1 << 22)
+#define RBUF_ACPI_EN (1 << 23)
+
+#define RBUF_PKT_RDY_THRESH 0x04
+
+#define RBUF_STATUS 0x08
+#define RBUF_WOL_MODE (1 << 0)
+#define RBUF_MPD (1 << 1)
+#define RBUF_ACPI (1 << 2)
+
+#define RBUF_OVFL_DISC_CNTR 0x0c
+#define RBUF_ERR_PKT_CNTR 0x10
+
+/* Transmit buffer offset and defines */
+#define SYS_PORT_TBUF_OFFSET 0x600
+
+#define TBUF_CONTROL 0x00
+#define TBUF_BP_EN (1 << 0)
+#define TBUF_MAX_PKT_THRESH_SHIFT 1
+#define TBUF_MAX_PKT_THRESH_MASK 0x1f
+#define TBUF_FULL_THRESH_SHIFT 8
+#define TBUF_FULL_THRESH_MASK 0x1f
+
+/* UniMAC offset and defines */
+#define SYS_PORT_UMAC_OFFSET 0x800
+
+#define UMAC_CMD 0x008
+#define CMD_TX_EN (1 << 0)
+#define CMD_RX_EN (1 << 1)
+#define CMD_SPEED_SHIFT 2
+#define CMD_SPEED_10 0
+#define CMD_SPEED_100 1
+#define CMD_SPEED_1000 2
+#define CMD_SPEED_2500 3
+#define CMD_SPEED_MASK 3
+#define CMD_PROMISC (1 << 4)
+#define CMD_PAD_EN (1 << 5)
+#define CMD_CRC_FWD (1 << 6)
+#define CMD_PAUSE_FWD (1 << 7)
+#define CMD_RX_PAUSE_IGNORE (1 << 8)
+#define CMD_TX_ADDR_INS (1 << 9)
+#define CMD_HD_EN (1 << 10)
+#define CMD_SW_RESET (1 << 13)
+#define CMD_LCL_LOOP_EN (1 << 15)
+#define CMD_AUTO_CONFIG (1 << 22)
+#define CMD_CNTL_FRM_EN (1 << 23)
+#define CMD_NO_LEN_CHK (1 << 24)
+#define CMD_RMT_LOOP_EN (1 << 25)
+#define CMD_PRBL_EN (1 << 27)
+#define CMD_TX_PAUSE_IGNORE (1 << 28)
+#define CMD_TX_RX_EN (1 << 29)
+#define CMD_RUNT_FILTER_DIS (1 << 30)
+
+#define UMAC_MAC0 0x00c
+#define UMAC_MAC1 0x010
+#define UMAC_MAX_FRAME_LEN 0x014
+
+#define UMAC_TX_FLUSH 0x334
+
+#define UMAC_MIB_START 0x400
+
+/* There is a 0xC gap between the end of RX and beginning of TX stats and then
+ * between the end of TX stats and the beginning of the RX RUNT
+ */
+#define UMAC_MIB_STAT_OFFSET 0xc
+
+#define UMAC_MIB_CTRL 0x580
+#define MIB_RX_CNT_RST (1 << 0)
+#define MIB_RUNT_CNT_RST (1 << 1)
+#define MIB_TX_CNT_RST (1 << 2)
+#define UMAC_MDF_CTRL 0x650
+#define UMAC_MDF_ADDR 0x654
+
+/* Receive DMA offset and defines */
+#define SYS_PORT_RDMA_OFFSET 0x2000
+
+#define RDMA_CONTROL 0x1000
+#define RDMA_EN (1 << 0)
+#define RDMA_RING_CFG (1 << 1)
+#define RDMA_DISC_EN (1 << 2)
+#define RDMA_BUF_DATA_OFFSET_SHIFT 4
+#define RDMA_BUF_DATA_OFFSET_MASK 0x3ff
+
+#define RDMA_STATUS 0x1004
+#define RDMA_DISABLED (1 << 0)
+#define RDMA_DESC_RAM_INIT_BUSY (1 << 1)
+#define RDMA_BP_STATUS (1 << 2)
+
+#define RDMA_SCB_BURST_SIZE 0x1008
+
+#define RDMA_RING_BUF_SIZE 0x100c
+#define RDMA_RING_SIZE_SHIFT 16
+
+#define RDMA_WRITE_PTR_HI 0x1010
+#define RDMA_WRITE_PTR_LO 0x1014
+#define RDMA_PROD_INDEX 0x1018
+#define RDMA_PROD_INDEX_MASK 0xffff
+
+#define RDMA_CONS_INDEX 0x101c
+#define RDMA_CONS_INDEX_MASK 0xffff
+
+#define RDMA_START_ADDR_HI 0x1020
+#define RDMA_START_ADDR_LO 0x1024
+#define RDMA_END_ADDR_HI 0x1028
+#define RDMA_END_ADDR_LO 0x102c
+
+#define RDMA_MBDONE_INTR 0x1030
+#define RDMA_INTR_THRESH_MASK 0xff
+#define RDMA_TIMEOUT_SHIFT 16
+#define RDMA_TIMEOUT_MASK 0xffff
+
+#define RDMA_XON_XOFF_THRESH 0x1034
+#define RDMA_XON_XOFF_THRESH_MASK 0xffff
+#define RDMA_XOFF_THRESH_SHIFT 16
+
+#define RDMA_READ_PTR_HI 0x1038
+#define RDMA_READ_PTR_LO 0x103c
+
+#define RDMA_OVERRIDE 0x1040
+#define RDMA_LE_MODE (1 << 0)
+#define RDMA_REG_MODE (1 << 1)
+
+#define RDMA_TEST 0x1044
+#define RDMA_TP_OUT_SEL (1 << 0)
+#define RDMA_MEM_SEL (1 << 1)
+
+#define RDMA_DEBUG 0x1048
+
+/* Transmit DMA offset and defines */
+#define TDMA_NUM_RINGS 32 /* rings = queues */
+#define TDMA_PORT_SIZE DESC_SIZE /* two 32-bits words */
+
+#define SYS_PORT_TDMA_OFFSET 0x4000
+#define TDMA_WRITE_PORT_OFFSET 0x0000
+#define TDMA_WRITE_PORT_HI(i) (TDMA_WRITE_PORT_OFFSET + \
+ (i) * TDMA_PORT_SIZE)
+#define TDMA_WRITE_PORT_LO(i) (TDMA_WRITE_PORT_OFFSET + \
+ sizeof(u32) + (i) * TDMA_PORT_SIZE)
+
+#define TDMA_READ_PORT_OFFSET (TDMA_WRITE_PORT_OFFSET + \
+ (TDMA_NUM_RINGS * TDMA_PORT_SIZE))
+#define TDMA_READ_PORT_HI(i) (TDMA_READ_PORT_OFFSET + \
+ (i) * TDMA_PORT_SIZE)
+#define TDMA_READ_PORT_LO(i) (TDMA_READ_PORT_OFFSET + \
+ sizeof(u32) + (i) * TDMA_PORT_SIZE)
+
+#define TDMA_READ_PORT_CMD_OFFSET (TDMA_READ_PORT_OFFSET + \
+ (TDMA_NUM_RINGS * TDMA_PORT_SIZE))
+#define TDMA_READ_PORT_CMD(i) (TDMA_READ_PORT_CMD_OFFSET + \
+ (i) * sizeof(u32))
+
+#define TDMA_DESC_RING_00_BASE (TDMA_READ_PORT_CMD_OFFSET + \
+ (TDMA_NUM_RINGS * sizeof(u32)))
+
+/* Register offsets and defines relatives to a specific ring number */
+#define RING_HEAD_TAIL_PTR 0x00
+#define RING_HEAD_MASK 0x7ff
+#define RING_TAIL_SHIFT 11
+#define RING_TAIL_MASK 0x7ff
+#define RING_FLUSH (1 << 24)
+#define RING_EN (1 << 25)
+
+#define RING_COUNT 0x04
+#define RING_COUNT_MASK 0x7ff
+#define RING_BUFF_DONE_SHIFT 11
+#define RING_BUFF_DONE_MASK 0x7ff
+
+#define RING_MAX_HYST 0x08
+#define RING_MAX_THRESH_MASK 0x7ff
+#define RING_HYST_THRESH_SHIFT 11
+#define RING_HYST_THRESH_MASK 0x7ff
+
+#define RING_INTR_CONTROL 0x0c
+#define RING_INTR_THRESH_MASK 0x7ff
+#define RING_EMPTY_INTR_EN (1 << 15)
+#define RING_TIMEOUT_SHIFT 16
+#define RING_TIMEOUT_MASK 0xffff
+
+#define RING_PROD_CONS_INDEX 0x10
+#define RING_PROD_INDEX_MASK 0xffff
+#define RING_CONS_INDEX_SHIFT 16
+#define RING_CONS_INDEX_MASK 0xffff
+
+#define RING_MAPPING 0x14
+#define RING_QID_MASK 0x3
+#define RING_PORT_ID_SHIFT 3
+#define RING_PORT_ID_MASK 0x7
+#define RING_IGNORE_STATUS (1 << 6)
+#define RING_FAILOVER_EN (1 << 7)
+#define RING_CREDIT_SHIFT 8
+#define RING_CREDIT_MASK 0xffff
+
+#define RING_PCP_DEI_VID 0x18
+#define RING_VID_MASK 0x7ff
+#define RING_DEI (1 << 12)
+#define RING_PCP_SHIFT 13
+#define RING_PCP_MASK 0x7
+#define RING_PKT_SIZE_ADJ_SHIFT 16
+#define RING_PKT_SIZE_ADJ_MASK 0xf
+
+#define TDMA_DESC_RING_SIZE 28
+
+/* Defininition for a given TX ring base address */
+#define TDMA_DESC_RING_BASE(i) (TDMA_DESC_RING_00_BASE + \
+ ((i) * TDMA_DESC_RING_SIZE))
+
+/* Ring indexed register addreses */
+#define TDMA_DESC_RING_HEAD_TAIL_PTR(i) (TDMA_DESC_RING_BASE(i) + \
+ RING_HEAD_TAIL_PTR)
+#define TDMA_DESC_RING_COUNT(i) (TDMA_DESC_RING_BASE(i) + \
+ RING_COUNT)
+#define TDMA_DESC_RING_MAX_HYST(i) (TDMA_DESC_RING_BASE(i) + \
+ RING_MAX_HYST)
+#define TDMA_DESC_RING_INTR_CONTROL(i) (TDMA_DESC_RING_BASE(i) + \
+ RING_INTR_CONTROL)
+#define TDMA_DESC_RING_PROD_CONS_INDEX(i) \
+ (TDMA_DESC_RING_BASE(i) + \
+ RING_PROD_CONS_INDEX)
+#define TDMA_DESC_RING_MAPPING(i) (TDMA_DESC_RING_BASE(i) + \
+ RING_MAPPING)
+#define TDMA_DESC_RING_PCP_DEI_VID(i) (TDMA_DESC_RING_BASE(i) + \
+ RING_PCP_DEI_VID)
+
+#define TDMA_CONTROL 0x600
+#define TDMA_EN (1 << 0)
+#define TSB_EN (1 << 1)
+#define TSB_SWAP (1 << 2)
+#define ACB_ALGO (1 << 3)
+#define BUF_DATA_OFFSET_SHIFT 4
+#define BUF_DATA_OFFSET_MASK 0x3ff
+#define VLAN_EN (1 << 14)
+#define SW_BRCM_TAG (1 << 15)
+#define WNC_KPT_SIZE_UPDATE (1 << 16)
+#define SYNC_PKT_SIZE (1 << 17)
+#define ACH_TXDONE_DELAY_SHIFT 18
+#define ACH_TXDONE_DELAY_MASK 0xff
+
+#define TDMA_STATUS 0x604
+#define TDMA_DISABLED (1 << 0)
+#define TDMA_LL_RAM_INIT_BUSY (1 << 1)
+
+#define TDMA_SCB_BURST_SIZE 0x608
+#define TDMA_OVER_MAX_THRESH_STATUS 0x60c
+#define TDMA_OVER_HYST_THRESH_STATUS 0x610
+#define TDMA_TPID 0x614
+
+#define TDMA_FREE_LIST_HEAD_TAIL_PTR 0x618
+#define TDMA_FREE_HEAD_MASK 0x7ff
+#define TDMA_FREE_TAIL_SHIFT 11
+#define TDMA_FREE_TAIL_MASK 0x7ff
+
+#define TDMA_FREE_LIST_COUNT 0x61c
+#define TDMA_FREE_LIST_COUNT_MASK 0x7ff
+
+#define TDMA_TIER2_ARB_CTRL 0x620
+#define TDMA_ARB_MODE_RR 0
+#define TDMA_ARB_MODE_WEIGHT_RR 0x1
+#define TDMA_ARB_MODE_STRICT 0x2
+#define TDMA_ARB_MODE_DEFICIT_RR 0x3
+#define TDMA_CREDIT_SHIFT 4
+#define TDMA_CREDIT_MASK 0xffff
+
+#define TDMA_TIER1_ARB_0_CTRL 0x624
+#define TDMA_ARB_EN (1 << 0)
+
+#define TDMA_TIER1_ARB_0_QUEUE_EN 0x628
+#define TDMA_TIER1_ARB_1_CTRL 0x62c
+#define TDMA_TIER1_ARB_1_QUEUE_EN 0x630
+#define TDMA_TIER1_ARB_2_CTRL 0x634
+#define TDMA_TIER1_ARB_2_QUEUE_EN 0x638
+#define TDMA_TIER1_ARB_3_CTRL 0x63c
+#define TDMA_TIER1_ARB_3_QUEUE_EN 0x640
+
+#define TDMA_SCB_ENDIAN_OVERRIDE 0x644
+#define TDMA_LE_MODE (1 << 0)
+#define TDMA_REG_MODE (1 << 1)
+
+#define TDMA_TEST 0x648
+#define TDMA_TP_OUT_SEL (1 << 0)
+#define TDMA_MEM_TM (1 << 1)
+
+#define TDMA_DEBUG 0x64c
+
+/* Transmit/Receive descriptor */
+struct dma_desc {
+ u32 addr_status_len;
+ u32 addr_lo;
+};
+
+/* Number of Receive hardware descriptor words */
+#define NUM_HW_RX_DESC_WORDS 1024
+/* Real number of usable descriptors */
+#define NUM_RX_DESC (NUM_HW_RX_DESC_WORDS / WORDS_PER_DESC)
+
+/* Internal linked-list RAM has up to 1536 entries */
+#define NUM_TX_DESC 1536
+
+#define WORDS_PER_DESC (sizeof(struct dma_desc) / sizeof(u32))
+
+/* Rx/Tx common counter group.*/
+struct bcm_sysport_pkt_counters {
+ u32 cnt_64; /* RO Received/Transmited 64 bytes packet */
+ u32 cnt_127; /* RO Rx/Tx 127 bytes packet */
+ u32 cnt_255; /* RO Rx/Tx 65-255 bytes packet */
+ u32 cnt_511; /* RO Rx/Tx 256-511 bytes packet */
+ u32 cnt_1023; /* RO Rx/Tx 512-1023 bytes packet */
+ u32 cnt_1518; /* RO Rx/Tx 1024-1518 bytes packet */
+ u32 cnt_mgv; /* RO Rx/Tx 1519-1522 good VLAN packet */
+ u32 cnt_2047; /* RO Rx/Tx 1522-2047 bytes packet*/
+ u32 cnt_4095; /* RO Rx/Tx 2048-4095 bytes packet*/
+ u32 cnt_9216; /* RO Rx/Tx 4096-9216 bytes packet*/
+};
+
+/* RSV, Receive Status Vector */
+struct bcm_sysport_rx_counters {
+ struct bcm_sysport_pkt_counters pkt_cnt;
+ u32 pkt; /* RO (0x428) Received pkt count*/
+ u32 bytes; /* RO Received byte count */
+ u32 mca; /* RO # of Received multicast pkt */
+ u32 bca; /* RO # of Receive broadcast pkt */
+ u32 fcs; /* RO # of Received FCS error */
+ u32 cf; /* RO # of Received control frame pkt*/
+ u32 pf; /* RO # of Received pause frame pkt */
+ u32 uo; /* RO # of unknown op code pkt */
+ u32 aln; /* RO # of alignment error count */
+ u32 flr; /* RO # of frame length out of range count */
+ u32 cde; /* RO # of code error pkt */
+ u32 fcr; /* RO # of carrier sense error pkt */
+ u32 ovr; /* RO # of oversize pkt*/
+ u32 jbr; /* RO # of jabber count */
+ u32 mtue; /* RO # of MTU error pkt*/
+ u32 pok; /* RO # of Received good pkt */
+ u32 uc; /* RO # of unicast pkt */
+ u32 ppp; /* RO # of PPP pkt */
+ u32 rcrc; /* RO (0x470),# of CRC match pkt */
+};
+
+/* TSV, Transmit Status Vector */
+struct bcm_sysport_tx_counters {
+ struct bcm_sysport_pkt_counters pkt_cnt;
+ u32 pkts; /* RO (0x4a8) Transmited pkt */
+ u32 mca; /* RO # of xmited multicast pkt */
+ u32 bca; /* RO # of xmited broadcast pkt */
+ u32 pf; /* RO # of xmited pause frame count */
+ u32 cf; /* RO # of xmited control frame count */
+ u32 fcs; /* RO # of xmited FCS error count */
+ u32 ovr; /* RO # of xmited oversize pkt */
+ u32 drf; /* RO # of xmited deferral pkt */
+ u32 edf; /* RO # of xmited Excessive deferral pkt*/
+ u32 scl; /* RO # of xmited single collision pkt */
+ u32 mcl; /* RO # of xmited multiple collision pkt*/
+ u32 lcl; /* RO # of xmited late collision pkt */
+ u32 ecl; /* RO # of xmited excessive collision pkt*/
+ u32 frg; /* RO # of xmited fragments pkt*/
+ u32 ncl; /* RO # of xmited total collision count */
+ u32 jbr; /* RO # of xmited jabber count*/
+ u32 bytes; /* RO # of xmited byte count */
+ u32 pok; /* RO # of xmited good pkt */
+ u32 uc; /* RO (0x0x4f0)# of xmited unitcast pkt */
+};
+
+struct bcm_sysport_mib {
+ struct bcm_sysport_rx_counters rx;
+ struct bcm_sysport_tx_counters tx;
+ u32 rx_runt_cnt;
+ u32 rx_runt_fcs;
+ u32 rx_runt_fcs_align;
+ u32 rx_runt_bytes;
+ u32 rxchk_bad_csum;
+ u32 rxchk_other_pkt_disc;
+ u32 rbuf_ovflow_cnt;
+ u32 rbuf_err_cnt;
+};
+
+/* HW maintains a large list of counters */
+enum bcm_sysport_stat_type {
+ BCM_SYSPORT_STAT_NETDEV = -1,
+ BCM_SYSPORT_STAT_MIB_RX,
+ BCM_SYSPORT_STAT_MIB_TX,
+ BCM_SYSPORT_STAT_RUNT,
+ BCM_SYSPORT_STAT_RXCHK,
+ BCM_SYSPORT_STAT_RBUF,
+};
+
+/* Macros to help define ethtool statistics */
+#define STAT_NETDEV(m) { \
+ .stat_string = __stringify(m), \
+ .stat_sizeof = sizeof(((struct net_device_stats *)0)->m), \
+ .stat_offset = offsetof(struct net_device_stats, m), \
+ .type = BCM_SYSPORT_STAT_NETDEV, \
+}
+
+#define STAT_MIB(str, m, _type) { \
+ .stat_string = str, \
+ .stat_sizeof = sizeof(((struct bcm_sysport_priv *)0)->m), \
+ .stat_offset = offsetof(struct bcm_sysport_priv, m), \
+ .type = _type, \
+}
+
+#define STAT_MIB_RX(str, m) STAT_MIB(str, m, BCM_SYSPORT_STAT_MIB_RX)
+#define STAT_MIB_TX(str, m) STAT_MIB(str, m, BCM_SYSPORT_STAT_MIB_TX)
+#define STAT_RUNT(str, m) STAT_MIB(str, m, BCM_SYSPORT_STAT_RUNT)
+
+#define STAT_RXCHK(str, m, ofs) { \
+ .stat_string = str, \
+ .stat_sizeof = sizeof(((struct bcm_sysport_priv *)0)->m), \
+ .stat_offset = offsetof(struct bcm_sysport_priv, m), \
+ .type = BCM_SYSPORT_STAT_RXCHK, \
+ .reg_offset = ofs, \
+}
+
+#define STAT_RBUF(str, m, ofs) { \
+ .stat_string = str, \
+ .stat_sizeof = sizeof(((struct bcm_sysport_priv *)0)->m), \
+ .stat_offset = offsetof(struct bcm_sysport_priv, m), \
+ .type = BCM_SYSPORT_STAT_RBUF, \
+ .reg_offset = ofs, \
+}
+
+struct bcm_sysport_stats {
+ char stat_string[ETH_GSTRING_LEN];
+ int stat_sizeof;
+ int stat_offset;
+ enum bcm_sysport_stat_type type;
+ /* reg offset from UMAC base for misc counters */
+ u16 reg_offset;
+};
+
+/* Software house keeping helper structure */
+struct bcm_sysport_cb {
+ struct sk_buff *skb; /* SKB for RX packets */
+ void __iomem *bd_addr; /* Buffer descriptor PHYS addr */
+
+ DEFINE_DMA_UNMAP_ADDR(dma_addr);
+ DEFINE_DMA_UNMAP_LEN(dma_len);
+};
+
+/* Software view of the TX ring */
+struct bcm_sysport_tx_ring {
+ spinlock_t lock; /* Ring lock for tx reclaim/xmit */
+ struct napi_struct napi; /* NAPI per tx queue */
+ dma_addr_t desc_dma; /* DMA cookie */
+ unsigned int index; /* Ring index */
+ unsigned int size; /* Ring current size */
+ unsigned int alloc_size; /* Ring one-time allocated size */
+ unsigned int desc_count; /* Number of descriptors */
+ unsigned int curr_desc; /* Current descriptor */
+ unsigned int c_index; /* Last consumer index */
+ unsigned int p_index; /* Current producer index */
+ struct bcm_sysport_cb *cbs; /* Transmit control blocks */
+ struct dma_desc *desc_cpu; /* CPU view of the descriptor */
+ struct bcm_sysport_priv *priv; /* private context backpointer */
+};
+
+/* Driver private structure */
+struct bcm_sysport_priv {
+ void __iomem *base;
+ u32 irq0_stat;
+ u32 irq0_mask;
+ u32 irq1_stat;
+ u32 irq1_mask;
+ struct napi_struct napi ____cacheline_aligned;
+ struct net_device *netdev;
+ struct platform_device *pdev;
+ int irq0;
+ int irq1;
+
+ /* Transmit rings */
+ struct bcm_sysport_tx_ring tx_rings[TDMA_NUM_RINGS];
+
+ /* Receive queue */
+ void __iomem *rx_bds;
+ void __iomem *rx_bd_assign_ptr;
+ unsigned int rx_bd_assign_index;
+ struct bcm_sysport_cb *rx_cbs;
+ unsigned int num_rx_bds;
+ unsigned int rx_read_ptr;
+ unsigned int rx_c_index;
+
+ /* PHY device */
+ struct phy_device *phydev;
+ phy_interface_t phy_interface;
+ int old_pause;
+ int old_link;
+ int old_duplex;
+
+ /* Misc fields */
+ unsigned int rx_csum_en:1;
+ unsigned int tsb_en:1;
+ unsigned int crc_fwd:1;
+ u16 rev;
+
+ /* MIB related fields */
+ struct bcm_sysport_mib mib;
+
+ /* Ethtool */
+ u32 msg_enable;
+};
+#endif /* __BCM_SYSPORT_H */
diff --git a/drivers/net/ethernet/broadcom/tg3.c b/drivers/net/ethernet/broadcom/tg3.c
index b9f7022..e5d95c5 100644
--- a/drivers/net/ethernet/broadcom/tg3.c
+++ b/drivers/net/ethernet/broadcom/tg3.c
@@ -12286,7 +12286,9 @@ static int tg3_set_ringparam(struct net_device *dev, struct ethtool_ringparam *e
if (tg3_flag(tp, MAX_RXPEND_64) &&
tp->rx_pending > 63)
tp->rx_pending = 63;
- tp->rx_jumbo_pending = ering->rx_jumbo_pending;
+
+ if (tg3_flag(tp, JUMBO_RING_ENABLE))
+ tp->rx_jumbo_pending = ering->rx_jumbo_pending;
for (i = 0; i < tp->irq_max; i++)
tp->napi[i].tx_pending = ering->tx_pending;
diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
index 97db5a7..2f67c7c 100644
--- a/drivers/net/ethernet/emulex/benet/be.h
+++ b/drivers/net/ethernet/emulex/benet/be.h
@@ -120,6 +120,9 @@ static inline char *nic_name(struct pci_dev *pdev)
#define MAX_VFS 30 /* Max VFs supported by BE3 FW */
#define FW_VER_LEN 32
+#define RSS_INDIR_TABLE_LEN 128
+#define RSS_HASH_KEY_LEN 40
+
struct be_dma_mem {
void *va;
dma_addr_t dma;
@@ -409,6 +412,13 @@ struct be_resources {
u32 if_cap_flags;
};
+struct rss_info {
+ u64 rss_flags;
+ u8 rsstable[RSS_INDIR_TABLE_LEN];
+ u8 rss_queue[RSS_INDIR_TABLE_LEN];
+ u8 rss_hkey[RSS_HASH_KEY_LEN];
+};
+
struct be_adapter {
struct pci_dev *pdev;
struct net_device *netdev;
@@ -507,7 +517,7 @@ struct be_adapter {
u32 msg_enable;
int be_get_temp_freq;
u8 pf_number;
- u64 rss_flags;
+ struct rss_info rss_info;
};
#define be_physfn(adapter) (!adapter->virtfn)
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.c b/drivers/net/ethernet/emulex/benet/be_cmds.c
index d1ec15a..07e78e8 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.c
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.c
@@ -2020,13 +2020,10 @@ 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)
+ u32 rss_hash_opts, u16 table_size, u8 *rss_hkey)
{
struct be_mcc_wrb *wrb;
struct be_cmd_req_rss_config *req;
- u32 myhash[10] = {0x15d43fa5, 0x2534685a, 0x5f87693a, 0x5668494e,
- 0x33cf6a53, 0x383334c6, 0x76ac4257, 0x59b242b2,
- 0x3ea83c02, 0x4a110304};
int status;
if (!(be_if_cap_flags(adapter) & BE_IF_FLAGS_RSS))
@@ -2049,7 +2046,7 @@ int be_cmd_rss_config(struct be_adapter *adapter, u8 *rsstable,
req->hdr.version = 1;
memcpy(req->cpu_table, rsstable, table_size);
- memcpy(req->hash, myhash, sizeof(myhash));
+ memcpy(req->hash, rss_hkey, RSS_HASH_KEY_LEN);
be_dws_cpu_to_le(req->hash, sizeof(req->hash));
status = be_mbox_notify_wait(adapter);
diff --git a/drivers/net/ethernet/emulex/benet/be_cmds.h b/drivers/net/ethernet/emulex/benet/be_cmds.h
index b60e4d5..4ea79b9 100644
--- a/drivers/net/ethernet/emulex/benet/be_cmds.h
+++ b/drivers/net/ethernet/emulex/benet/be_cmds.h
@@ -2068,7 +2068,7 @@ 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_reset_function(struct be_adapter *adapter);
int be_cmd_rss_config(struct be_adapter *adapter, u8 *rsstable,
- u32 rss_hash_opts, u16 table_size);
+ u32 rss_hash_opts, u16 table_size, u8 *rss_hkey);
int be_process_mcc(struct be_adapter *adapter);
int be_cmd_set_beacon_state(struct be_adapter *adapter, u8 port_num, u8 beacon,
u8 status, u8 state);
diff --git a/drivers/net/ethernet/emulex/benet/be_ethtool.c b/drivers/net/ethernet/emulex/benet/be_ethtool.c
index 15ba96c..6f3494e 100644
--- a/drivers/net/ethernet/emulex/benet/be_ethtool.c
+++ b/drivers/net/ethernet/emulex/benet/be_ethtool.c
@@ -933,27 +933,27 @@ static u64 be_get_rss_hash_opts(struct be_adapter *adapter, u64 flow_type)
switch (flow_type) {
case TCP_V4_FLOW:
- if (adapter->rss_flags & RSS_ENABLE_IPV4)
+ if (adapter->rss_info.rss_flags & RSS_ENABLE_IPV4)
data |= RXH_IP_DST | RXH_IP_SRC;
- if (adapter->rss_flags & RSS_ENABLE_TCP_IPV4)
+ if (adapter->rss_info.rss_flags & RSS_ENABLE_TCP_IPV4)
data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
break;
case UDP_V4_FLOW:
- if (adapter->rss_flags & RSS_ENABLE_IPV4)
+ if (adapter->rss_info.rss_flags & RSS_ENABLE_IPV4)
data |= RXH_IP_DST | RXH_IP_SRC;
- if (adapter->rss_flags & RSS_ENABLE_UDP_IPV4)
+ if (adapter->rss_info.rss_flags & RSS_ENABLE_UDP_IPV4)
data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
break;
case TCP_V6_FLOW:
- if (adapter->rss_flags & RSS_ENABLE_IPV6)
+ if (adapter->rss_info.rss_flags & RSS_ENABLE_IPV6)
data |= RXH_IP_DST | RXH_IP_SRC;
- if (adapter->rss_flags & RSS_ENABLE_TCP_IPV6)
+ if (adapter->rss_info.rss_flags & RSS_ENABLE_TCP_IPV6)
data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
break;
case UDP_V6_FLOW:
- if (adapter->rss_flags & RSS_ENABLE_IPV6)
+ if (adapter->rss_info.rss_flags & RSS_ENABLE_IPV6)
data |= RXH_IP_DST | RXH_IP_SRC;
- if (adapter->rss_flags & RSS_ENABLE_UDP_IPV6)
+ if (adapter->rss_info.rss_flags & RSS_ENABLE_UDP_IPV6)
data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
break;
}
@@ -992,7 +992,7 @@ static int be_set_rss_hash_opts(struct be_adapter *adapter,
struct be_rx_obj *rxo;
int status = 0, i, j;
u8 rsstable[128];
- u32 rss_flags = adapter->rss_flags;
+ u32 rss_flags = adapter->rss_info.rss_flags;
if (cmd->data != L3_RSS_FLAGS &&
cmd->data != (L3_RSS_FLAGS | L4_RSS_FLAGS))
@@ -1039,7 +1039,7 @@ static int be_set_rss_hash_opts(struct be_adapter *adapter,
return -EINVAL;
}
- if (rss_flags == adapter->rss_flags)
+ if (rss_flags == adapter->rss_info.rss_flags)
return status;
if (be_multi_rxq(adapter)) {
@@ -1051,9 +1051,11 @@ static int be_set_rss_hash_opts(struct be_adapter *adapter,
}
}
}
- status = be_cmd_rss_config(adapter, rsstable, rss_flags, 128);
+
+ status = be_cmd_rss_config(adapter, adapter->rss_info.rsstable,
+ rss_flags, 128, adapter->rss_info.rss_hkey);
if (!status)
- adapter->rss_flags = rss_flags;
+ adapter->rss_info.rss_flags = rss_flags;
return status;
}
@@ -1103,6 +1105,68 @@ static int be_set_channels(struct net_device *netdev,
return be_update_queues(adapter);
}
+static u32 be_get_rxfh_indir_size(struct net_device *netdev)
+{
+ return RSS_INDIR_TABLE_LEN;
+}
+
+static u32 be_get_rxfh_key_size(struct net_device *netdev)
+{
+ return RSS_HASH_KEY_LEN;
+}
+
+static int be_get_rxfh(struct net_device *netdev, u32 *indir, u8 *hkey)
+{
+ struct be_adapter *adapter = netdev_priv(netdev);
+ int i;
+ struct rss_info *rss = &adapter->rss_info;
+
+ if (indir) {
+ for (i = 0; i < RSS_INDIR_TABLE_LEN; i++)
+ indir[i] = rss->rss_queue[i];
+ }
+
+ if (hkey)
+ memcpy(hkey, rss->rss_hkey, RSS_HASH_KEY_LEN);
+
+ return 0;
+}
+
+static int be_set_rxfh(struct net_device *netdev, u32 *indir, u8 *hkey)
+{
+ int rc = 0, i, j;
+ struct be_adapter *adapter = netdev_priv(netdev);
+ u8 rsstable[RSS_INDIR_TABLE_LEN];
+
+ if (indir) {
+ struct be_rx_obj *rxo;
+ for (i = 0; i < RSS_INDIR_TABLE_LEN; i++) {
+ j = indir[i];
+ rxo = &adapter->rx_obj[j];
+ rsstable[i] = rxo->rss_id;
+ adapter->rss_info.rss_queue[i] = j;
+ }
+ } else {
+ memcpy(rsstable, adapter->rss_info.rsstable,
+ RSS_INDIR_TABLE_LEN);
+ }
+
+ if (!hkey)
+ hkey = adapter->rss_info.rss_hkey;
+
+ rc = be_cmd_rss_config(adapter, rsstable,
+ adapter->rss_info.rss_flags,
+ RSS_INDIR_TABLE_LEN, hkey);
+ if (rc) {
+ adapter->rss_info.rss_flags = RSS_ENABLE_NONE;
+ return -EIO;
+ }
+ memcpy(adapter->rss_info.rss_hkey, hkey, RSS_HASH_KEY_LEN);
+ memcpy(adapter->rss_info.rsstable, rsstable,
+ RSS_INDIR_TABLE_LEN);
+ return 0;
+}
+
const struct ethtool_ops be_ethtool_ops = {
.get_settings = be_get_settings,
.get_drvinfo = be_get_drvinfo,
@@ -1129,6 +1193,10 @@ const struct ethtool_ops be_ethtool_ops = {
.self_test = be_self_test,
.get_rxnfc = be_get_rxnfc,
.set_rxnfc = be_set_rxnfc,
+ .get_rxfh_indir_size = be_get_rxfh_indir_size,
+ .get_rxfh_key_size = be_get_rxfh_key_size,
+ .get_rxfh = be_get_rxfh,
+ .set_rxfh = be_set_rxfh,
.get_channels = be_get_channels,
.set_channels = be_set_channels
};
diff --git a/drivers/net/ethernet/emulex/benet/be_main.c b/drivers/net/ethernet/emulex/benet/be_main.c
index a186454..a3c6a27 100644
--- a/drivers/net/ethernet/emulex/benet/be_main.c
+++ b/drivers/net/ethernet/emulex/benet/be_main.c
@@ -2774,7 +2774,8 @@ static int be_rx_qs_create(struct be_adapter *adapter)
{
struct be_rx_obj *rxo;
int rc, i, j;
- u8 rsstable[128];
+ u8 rss_hkey[RSS_HASH_KEY_LEN];
+ struct rss_info *rss = &adapter->rss_info;
for_all_rx_queues(adapter, rxo, i) {
rc = be_queue_alloc(adapter, &rxo->q, RX_Q_LEN,
@@ -2799,31 +2800,37 @@ static int be_rx_qs_create(struct be_adapter *adapter)
}
if (be_multi_rxq(adapter)) {
- for (j = 0; j < 128; j += adapter->num_rx_qs - 1) {
+ for (j = 0; j < RSS_INDIR_TABLE_LEN;
+ j += adapter->num_rx_qs - 1) {
for_all_rss_queues(adapter, rxo, i) {
- if ((j + i) >= 128)
+ if ((j + i) >= RSS_INDIR_TABLE_LEN)
break;
- rsstable[j + i] = rxo->rss_id;
+ rss->rsstable[j + i] = rxo->rss_id;
+ rss->rss_queue[j + i] = i;
}
}
- adapter->rss_flags = RSS_ENABLE_TCP_IPV4 | RSS_ENABLE_IPV4 |
- RSS_ENABLE_TCP_IPV6 | RSS_ENABLE_IPV6;
+ rss->rss_flags = RSS_ENABLE_TCP_IPV4 | RSS_ENABLE_IPV4 |
+ RSS_ENABLE_TCP_IPV6 | RSS_ENABLE_IPV6;
if (!BEx_chip(adapter))
- adapter->rss_flags |= RSS_ENABLE_UDP_IPV4 |
- RSS_ENABLE_UDP_IPV6;
+ rss->rss_flags |= RSS_ENABLE_UDP_IPV4 |
+ RSS_ENABLE_UDP_IPV6;
} else {
/* Disable RSS, if only default RX Q is created */
- adapter->rss_flags = RSS_ENABLE_NONE;
+ rss->rss_flags = RSS_ENABLE_NONE;
}
- rc = be_cmd_rss_config(adapter, rsstable, adapter->rss_flags,
- 128);
+ get_random_bytes(rss_hkey, RSS_HASH_KEY_LEN);
+ rc = be_cmd_rss_config(adapter, rss->rsstable,
+ rss->rss_flags,
+ 128, rss_hkey);
if (rc) {
- adapter->rss_flags = RSS_ENABLE_NONE;
+ rss->rss_flags = RSS_ENABLE_NONE;
return rc;
}
+ memcpy(rss->rss_hkey, rss_hkey, RSS_HASH_KEY_LEN);
+
/* First time posting */
for_all_rx_queues(adapter, rxo, i)
be_post_rx_frags(rxo, GFP_KERNEL);
diff --git a/drivers/net/ethernet/ethoc.c b/drivers/net/ethernet/ethoc.c
index 8b70ca7..f3658bd 100644
--- a/drivers/net/ethernet/ethoc.c
+++ b/drivers/net/ethernet/ethoc.c
@@ -769,11 +769,6 @@ static int ethoc_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
return phy_mii_ioctl(phy, ifr, cmd);
}
-static int ethoc_config(struct net_device *dev, struct ifmap *map)
-{
- return -ENOSYS;
-}
-
static void ethoc_do_set_mac_address(struct net_device *dev)
{
struct ethoc *priv = netdev_priv(dev);
@@ -995,7 +990,6 @@ static const struct net_device_ops ethoc_netdev_ops = {
.ndo_open = ethoc_open,
.ndo_stop = ethoc_stop,
.ndo_do_ioctl = ethoc_ioctl,
- .ndo_set_config = ethoc_config,
.ndo_set_mac_address = ethoc_set_mac_address,
.ndo_set_rx_mode = ethoc_set_multicast_list,
.ndo_change_mtu = ethoc_change_mtu,
diff --git a/drivers/net/ethernet/intel/e1000e/e1000.h b/drivers/net/ethernet/intel/e1000e/e1000.h
index 1471c54..e27e609 100644
--- a/drivers/net/ethernet/intel/e1000e/e1000.h
+++ b/drivers/net/ethernet/intel/e1000e/e1000.h
@@ -265,10 +265,10 @@ struct e1000_adapter {
u32 tx_hwtstamp_timeouts;
/* Rx */
- bool (*clean_rx) (struct e1000_ring *ring, int *work_done,
- int work_to_do) ____cacheline_aligned_in_smp;
- void (*alloc_rx_buf) (struct e1000_ring *ring, int cleaned_count,
- gfp_t gfp);
+ bool (*clean_rx)(struct e1000_ring *ring, int *work_done,
+ int work_to_do) ____cacheline_aligned_in_smp;
+ void (*alloc_rx_buf)(struct e1000_ring *ring, int cleaned_count,
+ gfp_t gfp);
struct e1000_ring *rx_ring;
u32 rx_int_delay;
diff --git a/drivers/net/ethernet/intel/e1000e/ethtool.c b/drivers/net/ethernet/intel/e1000e/ethtool.c
index cad250b..4e5ad7e 100644
--- a/drivers/net/ethernet/intel/e1000e/ethtool.c
+++ b/drivers/net/ethernet/intel/e1000e/ethtool.c
@@ -169,6 +169,7 @@ static int e1000_get_settings(struct net_device *netdev,
}
} else if (!pm_runtime_suspended(netdev->dev.parent)) {
u32 status = er32(STATUS);
+
if (status & E1000_STATUS_LU) {
if (status & E1000_STATUS_SPEED_1000)
speed = SPEED_1000;
@@ -783,25 +784,26 @@ static bool reg_pattern_test(struct e1000_adapter *adapter, u64 *data,
reg + (offset << 2), val,
(test[pat] & write & mask));
*data = reg;
- return 1;
+ return true;
}
}
- return 0;
+ return false;
}
static bool reg_set_and_check(struct e1000_adapter *adapter, u64 *data,
int reg, u32 mask, u32 write)
{
u32 val;
+
__ew32(&adapter->hw, reg, write & mask);
val = __er32(&adapter->hw, reg);
if ((write & mask) != (val & mask)) {
e_err("set/check test failed (reg 0x%05X): got 0x%08X expected 0x%08X\n",
reg, (val & mask), (write & mask));
*data = reg;
- return 1;
+ return true;
}
- return 0;
+ return false;
}
#define REG_PATTERN_TEST_ARRAY(reg, offset, mask, write) \
@@ -1717,6 +1719,7 @@ static int e1000_link_test(struct e1000_adapter *adapter, u64 *data)
*data = 0;
if (hw->phy.media_type == e1000_media_type_internal_serdes) {
int i = 0;
+
hw->mac.serdes_has_link = false;
/* On some blade server designs, link establishment
diff --git a/drivers/net/ethernet/intel/e1000e/ich8lan.c b/drivers/net/ethernet/intel/e1000e/ich8lan.c
index 9866f26..a290113 100644
--- a/drivers/net/ethernet/intel/e1000e/ich8lan.c
+++ b/drivers/net/ethernet/intel/e1000e/ich8lan.c
@@ -1320,6 +1320,7 @@ static s32 e1000_check_for_copper_link_ich8lan(struct e1000_hw *hw)
*/
if ((hw->mac.type == e1000_pch2lan) && link) {
u32 reg;
+
reg = er32(STATUS);
if (!(reg & (E1000_STATUS_FD | E1000_STATUS_SPEED_MASK))) {
reg = er32(TIPG);
diff --git a/drivers/net/ethernet/intel/e1000e/netdev.c b/drivers/net/ethernet/intel/e1000e/netdev.c
index d50c91e..e4207ef 100644
--- a/drivers/net/ethernet/intel/e1000e/netdev.c
+++ b/drivers/net/ethernet/intel/e1000e/netdev.c
@@ -599,6 +599,7 @@ static void e1000e_update_rdt_wa(struct e1000_ring *rx_ring, unsigned int i)
if (unlikely(!ret_val && (i != readl(rx_ring->tail)))) {
u32 rctl = er32(RCTL);
+
ew32(RCTL, rctl & ~E1000_RCTL_EN);
e_err("ME firmware caused invalid RDT - resetting\n");
schedule_work(&adapter->reset_task);
@@ -615,6 +616,7 @@ static void e1000e_update_tdt_wa(struct e1000_ring *tx_ring, unsigned int i)
if (unlikely(!ret_val && (i != readl(tx_ring->tail)))) {
u32 tctl = er32(TCTL);
+
ew32(TCTL, tctl & ~E1000_TCTL_EN);
e_err("ME firmware caused invalid TDT - resetting\n");
schedule_work(&adapter->reset_task);
@@ -1165,7 +1167,7 @@ static void e1000e_tx_hwtstamp_work(struct work_struct *work)
dev_kfree_skb_any(adapter->tx_hwtstamp_skb);
adapter->tx_hwtstamp_skb = NULL;
adapter->tx_hwtstamp_timeouts++;
- e_warn("clearing Tx timestamp hang");
+ e_warn("clearing Tx timestamp hang\n");
} else {
/* reschedule to check later */
schedule_work(&adapter->tx_hwtstamp_work);
@@ -1198,6 +1200,7 @@ static bool e1000_clean_tx_irq(struct e1000_ring *tx_ring)
while ((eop_desc->upper.data & cpu_to_le32(E1000_TXD_STAT_DD)) &&
(count < tx_ring->count)) {
bool cleaned = false;
+
rmb(); /* read buffer_info after eop_desc */
for (; !cleaned; count++) {
tx_desc = E1000_TX_DESC(*tx_ring, i);
@@ -1753,6 +1756,7 @@ static irqreturn_t e1000_intr_msi(int __always_unused irq, void *data)
adapter->flags & FLAG_RX_NEEDS_RESTART) {
/* disable receives */
u32 rctl = er32(RCTL);
+
ew32(RCTL, rctl & ~E1000_RCTL_EN);
adapter->flags |= FLAG_RESTART_NOW;
}
@@ -1960,6 +1964,7 @@ static void e1000_configure_msix(struct e1000_adapter *adapter)
/* Workaround issue with spurious interrupts on 82574 in MSI-X mode */
if (hw->mac.type == e1000_82574) {
u32 rfctl = er32(RFCTL);
+
rfctl |= E1000_RFCTL_ACK_DIS;
ew32(RFCTL, rfctl);
}
@@ -2204,6 +2209,7 @@ static void e1000_irq_disable(struct e1000_adapter *adapter)
if (adapter->msix_entries) {
int i;
+
for (i = 0; i < adapter->num_vectors; i++)
synchronize_irq(adapter->msix_entries[i].vector);
} else {
@@ -2921,6 +2927,7 @@ static void e1000_configure_tx(struct e1000_adapter *adapter)
if (adapter->flags2 & FLAG2_DMA_BURST) {
u32 txdctl = er32(TXDCTL(0));
+
txdctl &= ~(E1000_TXDCTL_PTHRESH | E1000_TXDCTL_HTHRESH |
E1000_TXDCTL_WTHRESH);
/* set up some performance related parameters to encourage the
@@ -3239,6 +3246,7 @@ static void e1000_configure_rx(struct e1000_adapter *adapter)
if (adapter->flags & FLAG_IS_ICH) {
u32 rxdctl = er32(RXDCTL(0));
+
ew32(RXDCTL(0), rxdctl | 0x3);
}
@@ -4695,6 +4703,7 @@ static void e1000e_update_stats(struct e1000_adapter *adapter)
/* Correctable ECC Errors */
if (hw->mac.type == e1000_pch_lpt) {
u32 pbeccsts = er32(PBECCSTS);
+
adapter->corr_errors +=
pbeccsts & E1000_PBECCSTS_CORR_ERR_CNT_MASK;
adapter->uncorr_errors +=
@@ -4808,6 +4817,7 @@ static void e1000e_enable_receives(struct e1000_adapter *adapter)
(adapter->flags & FLAG_RESTART_NOW)) {
struct e1000_hw *hw = &adapter->hw;
u32 rctl = er32(RCTL);
+
ew32(RCTL, rctl | E1000_RCTL_EN);
adapter->flags &= ~FLAG_RESTART_NOW;
}
@@ -4930,6 +4940,7 @@ static void e1000_watchdog_task(struct work_struct *work)
if ((adapter->flags & FLAG_TARC_SPEED_MODE_BIT) &&
!txb2b) {
u32 tarc0;
+
tarc0 = er32(TARC(0));
tarc0 &= ~SPEED_MODE_BIT;
ew32(TARC(0), tarc0);
@@ -5170,7 +5181,7 @@ static bool e1000_tx_csum(struct e1000_ring *tx_ring, struct sk_buff *skb)
__be16 protocol;
if (skb->ip_summed != CHECKSUM_PARTIAL)
- return 0;
+ return false;
if (skb->protocol == cpu_to_be16(ETH_P_8021Q))
protocol = vlan_eth_hdr(skb)->h_vlan_encapsulated_proto;
@@ -5215,7 +5226,7 @@ static bool e1000_tx_csum(struct e1000_ring *tx_ring, struct sk_buff *skb)
i = 0;
tx_ring->next_to_use = i;
- return 1;
+ return true;
}
static int e1000_tx_map(struct e1000_ring *tx_ring, struct sk_buff *skb,
@@ -5687,7 +5698,7 @@ struct rtnl_link_stats64 *e1000e_get_stats64(struct net_device *netdev,
static int e1000_change_mtu(struct net_device *netdev, int new_mtu)
{
struct e1000_adapter *adapter = netdev_priv(netdev);
- int max_frame = new_mtu + ETH_HLEN + ETH_FCS_LEN;
+ int max_frame = new_mtu + VLAN_HLEN + ETH_HLEN + ETH_FCS_LEN;
/* Jumbo frame support */
if ((max_frame > ETH_FRAME_LEN + ETH_FCS_LEN) &&
@@ -6209,6 +6220,7 @@ static int __e1000_resume(struct pci_dev *pdev)
e1e_wphy(&adapter->hw, BM_WUS, ~0);
} else {
u32 wus = er32(WUS);
+
if (wus) {
e_info("MAC Wakeup cause - %s\n",
wus & E1000_WUS_EX ? "Unicast Packet" :
@@ -6235,6 +6247,7 @@ static int __e1000_resume(struct pci_dev *pdev)
return 0;
}
+#ifdef CONFIG_PM_SLEEP
static int e1000e_pm_thaw(struct device *dev)
{
struct net_device *netdev = pci_get_drvdata(to_pci_dev(dev));
@@ -6255,7 +6268,6 @@ static int e1000e_pm_thaw(struct device *dev)
return 0;
}
-#ifdef CONFIG_PM_SLEEP
static int e1000e_pm_suspend(struct device *dev)
{
struct pci_dev *pdev = to_pci_dev(dev);
@@ -7027,7 +7039,7 @@ static const struct pci_error_handlers e1000_err_handler = {
.resume = e1000_io_resume,
};
-static DEFINE_PCI_DEVICE_TABLE(e1000_pci_tbl) = {
+static const struct pci_device_id e1000_pci_tbl[] = {
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_COPPER), board_82571 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_FIBER), board_82571 },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_82571EB_QUAD_COPPER), board_82571 },
@@ -7144,6 +7156,7 @@ static struct pci_driver e1000_driver = {
static int __init e1000_init_module(void)
{
int ret;
+
pr_info("Intel(R) PRO/1000 Network Driver - %s\n",
e1000e_driver_version);
pr_info("Copyright(c) 1999 - 2014 Intel Corporation.\n");
diff --git a/drivers/net/ethernet/intel/e1000e/nvm.c b/drivers/net/ethernet/intel/e1000e/nvm.c
index a9a976f..b1f212b 100644
--- a/drivers/net/ethernet/intel/e1000e/nvm.c
+++ b/drivers/net/ethernet/intel/e1000e/nvm.c
@@ -398,6 +398,7 @@ s32 e1000e_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
/* Loop to allow for up to whole page write of eeprom */
while (widx < words) {
u16 word_out = data[widx];
+
word_out = (word_out >> 8) | (word_out << 8);
e1000_shift_out_eec_bits(hw, word_out, 16);
widx++;
diff --git a/drivers/net/ethernet/intel/e1000e/param.c b/drivers/net/ethernet/intel/e1000e/param.c
index d0ac0f3..aa1923f 100644
--- a/drivers/net/ethernet/intel/e1000e/param.c
+++ b/drivers/net/ethernet/intel/e1000e/param.c
@@ -436,6 +436,7 @@ void e1000e_check_options(struct e1000_adapter *adapter)
if (num_IntMode > bd) {
unsigned int int_mode = IntMode[bd];
+
e1000_validate_option(&int_mode, &opt, adapter);
adapter->int_mode = int_mode;
} else {
@@ -457,6 +458,7 @@ void e1000e_check_options(struct e1000_adapter *adapter)
if (num_SmartPowerDownEnable > bd) {
unsigned int spd = SmartPowerDownEnable[bd];
+
e1000_validate_option(&spd, &opt, adapter);
if ((adapter->flags & FLAG_HAS_SMART_POWER_DOWN) && spd)
adapter->flags |= FLAG_SMART_POWER_DOWN;
@@ -473,6 +475,7 @@ void e1000e_check_options(struct e1000_adapter *adapter)
if (num_CrcStripping > bd) {
unsigned int crc_stripping = CrcStripping[bd];
+
e1000_validate_option(&crc_stripping, &opt, adapter);
if (crc_stripping == OPTION_ENABLED) {
adapter->flags2 |= FLAG2_CRC_STRIPPING;
@@ -495,6 +498,7 @@ void e1000e_check_options(struct e1000_adapter *adapter)
if (num_KumeranLockLoss > bd) {
unsigned int kmrn_lock_loss = KumeranLockLoss[bd];
+
e1000_validate_option(&kmrn_lock_loss, &opt, adapter);
enabled = kmrn_lock_loss;
}
diff --git a/drivers/net/ethernet/intel/e1000e/phy.c b/drivers/net/ethernet/intel/e1000e/phy.c
index 00b3fc9..b2005e1 100644
--- a/drivers/net/ethernet/intel/e1000e/phy.c
+++ b/drivers/net/ethernet/intel/e1000e/phy.c
@@ -2896,6 +2896,7 @@ static s32 __e1000_write_phy_reg_hv(struct e1000_hw *hw, u32 offset, u16 data,
(hw->phy.addr == 2) &&
!(MAX_PHY_REG_ADDRESS & reg) && (data & (1 << 11))) {
u16 data2 = 0x7EFF;
+
ret_val = e1000_access_phy_debug_regs_hv(hw,
(1 << 6) | 0x3,
&data2, false);
diff --git a/drivers/net/ethernet/intel/i40e/i40e.h b/drivers/net/ethernet/intel/i40e/i40e.h
index beb7b43..a46571c 100644
--- a/drivers/net/ethernet/intel/i40e/i40e.h
+++ b/drivers/net/ethernet/intel/i40e/i40e.h
@@ -329,9 +329,7 @@ struct i40e_pf {
struct ptp_clock *ptp_clock;
struct ptp_clock_info ptp_caps;
struct sk_buff *ptp_tx_skb;
- struct work_struct ptp_tx_work;
struct hwtstamp_config tstamp_config;
- unsigned long ptp_tx_start;
unsigned long last_rx_ptp_check;
spinlock_t tmreg_lock; /* Used to protect the device time registers. */
u64 ptp_base_adj;
diff --git a/drivers/net/ethernet/intel/i40e/i40e_adminq.c b/drivers/net/ethernet/intel/i40e/i40e_adminq.c
index ed3902b..34415d3 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_adminq.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_adminq.c
@@ -33,6 +33,16 @@
static void i40e_resume_aq(struct i40e_hw *hw);
/**
+ * i40e_is_nvm_update_op - return true if this is an NVM update operation
+ * @desc: API request descriptor
+ **/
+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);
+}
+
+/**
* i40e_adminq_init_regs - Initialize AdminQ registers
* @hw: pointer to the hardware structure
*
@@ -585,6 +595,7 @@ i40e_status i40e_init_adminq(struct i40e_hw *hw)
/* pre-emptive resource lock release */
i40e_aq_release_resource(hw, I40E_NVM_RESOURCE_ID, 0, NULL);
+ hw->aq.nvm_busy = false;
ret_code = i40e_aq_set_hmc_resource_profile(hw,
I40E_HMC_PROFILE_DEFAULT,
@@ -708,6 +719,12 @@ i40e_status i40e_asq_send_command(struct i40e_hw *hw,
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;
+ goto asq_send_command_exit;
+ }
+
details = I40E_ADMINQ_DETAILS(hw->aq.asq, hw->aq.asq.next_to_use);
if (cmd_details) {
*details = *cmd_details;
@@ -835,6 +852,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;
+
/* update the error if time out occurred */
if ((!cmd_completed) &&
(!details->async && !details->postpone)) {
@@ -929,6 +949,9 @@ i40e_status i40e_clean_arq_element(struct i40e_hw *hw,
e->msg_size);
}
+ if (i40e_is_nvm_update_op(&e->desc))
+ hw->aq.nvm_busy = false;
+
/* 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/i40e/i40e_adminq.h b/drivers/net/ethernet/intel/i40e/i40e_adminq.h
index 993f768..b1552fb 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_adminq.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_adminq.h
@@ -90,6 +90,7 @@ struct i40e_adminq_info {
u16 fw_min_ver; /* firmware minor version */
u16 api_maj_ver; /* api major version */
u16 api_min_ver; /* api minor version */
+ bool nvm_busy;
struct mutex asq_mutex; /* Send queue lock */
struct mutex arq_mutex; /* Receive queue lock */
diff --git a/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h b/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h
index 7b6374a..f2ba4b7 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_adminq_cmd.h
@@ -182,9 +182,6 @@ enum i40e_admin_queue_opc {
i40e_aqc_opc_add_mirror_rule = 0x0260,
i40e_aqc_opc_delete_mirror_rule = 0x0261,
- i40e_aqc_opc_set_storm_control_config = 0x0280,
- i40e_aqc_opc_get_storm_control_config = 0x0281,
-
/* DCB commands */
i40e_aqc_opc_dcb_ignore_pfc = 0x0301,
i40e_aqc_opc_dcb_updated = 0x0302,
@@ -207,6 +204,7 @@ enum i40e_admin_queue_opc {
i40e_aqc_opc_query_switching_comp_bw_config = 0x041A,
i40e_aqc_opc_suspend_port_tx = 0x041B,
i40e_aqc_opc_resume_port_tx = 0x041C,
+ i40e_aqc_opc_configure_partition_bw = 0x041D,
/* hmc */
i40e_aqc_opc_query_hmc_resource_profile = 0x0500,
@@ -1289,27 +1287,6 @@ struct i40e_aqc_add_delete_mirror_rule_completion {
I40E_CHECK_CMD_LENGTH(i40e_aqc_add_delete_mirror_rule_completion);
-/* Set Storm Control Configuration (direct 0x0280)
- * Get Storm Control Configuration (direct 0x0281)
- * the command and response use the same descriptor structure
- */
-struct i40e_aqc_set_get_storm_control_config {
- __le32 broadcast_threshold;
- __le32 multicast_threshold;
- __le32 control_flags;
-#define I40E_AQC_STORM_CONTROL_MDIPW 0x01
-#define I40E_AQC_STORM_CONTROL_MDICW 0x02
-#define I40E_AQC_STORM_CONTROL_BDIPW 0x04
-#define I40E_AQC_STORM_CONTROL_BDICW 0x08
-#define I40E_AQC_STORM_CONTROL_BIDU 0x10
-#define I40E_AQC_STORM_CONTROL_INTERVAL_SHIFT 8
-#define I40E_AQC_STORM_CONTROL_INTERVAL_MASK (0x3FF << \
- I40E_AQC_STORM_CONTROL_INTERVAL_SHIFT)
- u8 reserved[4];
-};
-
-I40E_CHECK_CMD_LENGTH(i40e_aqc_set_get_storm_control_config);
-
/* DCB 0x03xx*/
/* PFC Ignore (direct 0x0301)
@@ -1499,6 +1476,15 @@ struct i40e_aqc_query_switching_comp_bw_config_resp {
* (direct 0x041B and 0x041C) uses the generic SEID struct
*/
+/* Configure partition BW
+ * (indirect 0x041D)
+ */
+struct i40e_aqc_configure_partition_bw_data {
+ __le16 pf_valid_bits;
+ u8 min_bw[16]; /* guaranteed bandwidth */
+ u8 max_bw[16]; /* bandwidth limit */
+};
+
/* Get and set the active HMC resource profile and status.
* (direct 0x0500) and (direct 0x0501)
*/
@@ -1583,11 +1569,8 @@ struct i40e_aq_get_phy_abilities_resp {
#define I40E_AQ_PHY_FLAG_PAUSE_TX 0x01
#define I40E_AQ_PHY_FLAG_PAUSE_RX 0x02
#define I40E_AQ_PHY_FLAG_LOW_POWER 0x04
-#define I40E_AQ_PHY_FLAG_AN_SHIFT 3
-#define I40E_AQ_PHY_FLAG_AN_MASK (0x3 << I40E_AQ_PHY_FLAG_AN_SHIFT)
-#define I40E_AQ_PHY_FLAG_AN_OFF 0x00 /* link forced on */
-#define I40E_AQ_PHY_FLAG_AN_OFF_LINK_DOWN 0x01
-#define I40E_AQ_PHY_FLAG_AN_ON 0x02
+#define I40E_AQ_PHY_LINK_ENABLED 0x08
+#define I40E_AQ_PHY_AN_ENABLED 0x10
#define I40E_AQ_PHY_FLAG_MODULE_QUAL 0x20
__le16 eee_capability;
#define I40E_AQ_EEE_100BASE_TX 0x0002
diff --git a/drivers/net/ethernet/intel/i40e/i40e_common.c b/drivers/net/ethernet/intel/i40e/i40e_common.c
index 922cdcc..22eefda 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_common.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_common.c
@@ -975,6 +975,13 @@ i40e_status i40e_aq_get_link_info(struct i40e_hw *hw,
hw_link_info->an_info = resp->an_info;
hw_link_info->ext_info = resp->ext_info;
hw_link_info->loopback = resp->loopback;
+ hw_link_info->max_frame_size = le16_to_cpu(resp->max_frame_size);
+ hw_link_info->pacing = resp->config & I40E_AQ_CONFIG_PACING_MASK;
+
+ if (resp->config & I40E_AQ_CONFIG_CRC_ENA)
+ hw_link_info->crc_enable = true;
+ else
+ hw_link_info->crc_enable = false;
if (resp->command_flags & cpu_to_le16(I40E_AQ_LSE_ENABLE))
hw_link_info->lse_enable = true;
@@ -1300,6 +1307,7 @@ i40e_status i40e_aq_send_driver_version(struct i40e_hw *hw,
struct i40e_aqc_driver_version *cmd =
(struct i40e_aqc_driver_version *)&desc.params.raw;
i40e_status status;
+ u16 len;
if (dv == NULL)
return I40E_ERR_PARAM;
@@ -1311,7 +1319,14 @@ i40e_status i40e_aq_send_driver_version(struct i40e_hw *hw,
cmd->driver_minor_ver = dv->minor_version;
cmd->driver_build_ver = dv->build_version;
cmd->driver_subbuild_ver = dv->subbuild_version;
- status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
+
+ len = 0;
+ while (len < sizeof(dv->driver_string) &&
+ (dv->driver_string[len] < 0x80) &&
+ dv->driver_string[len])
+ len++;
+ status = i40e_asq_send_command(hw, &desc, dv->driver_string,
+ len, cmd_details);
return status;
}
@@ -2094,8 +2109,8 @@ i40e_status i40e_aq_start_lldp(struct i40e_hw *hw,
* @cmd_details: pointer to command details structure or NULL
**/
i40e_status i40e_aq_add_udp_tunnel(struct i40e_hw *hw,
- u16 udp_port, u8 header_len,
- u8 protocol_index, u8 *filter_index,
+ u16 udp_port, u8 protocol_index,
+ u8 *filter_index,
struct i40e_asq_cmd_details *cmd_details)
{
struct i40e_aq_desc desc;
@@ -2253,6 +2268,35 @@ static i40e_status i40e_aq_tx_sched_cmd(struct i40e_hw *hw, u16 seid,
}
/**
+ * i40e_aq_config_vsi_bw_limit - Configure VSI BW Limit
+ * @hw: pointer to the hw struct
+ * @seid: VSI seid
+ * @credit: BW limit credits (0 = disabled)
+ * @max_credit: Max BW limit credits
+ * @cmd_details: pointer to command details structure or NULL
+ **/
+i40e_status i40e_aq_config_vsi_bw_limit(struct i40e_hw *hw,
+ u16 seid, u16 credit, u8 max_credit,
+ struct i40e_asq_cmd_details *cmd_details)
+{
+ struct i40e_aq_desc desc;
+ struct i40e_aqc_configure_vsi_bw_limit *cmd =
+ (struct i40e_aqc_configure_vsi_bw_limit *)&desc.params.raw;
+ i40e_status status;
+
+ i40e_fill_default_direct_cmd_desc(&desc,
+ i40e_aqc_opc_configure_vsi_bw_limit);
+
+ cmd->vsi_seid = cpu_to_le16(seid);
+ cmd->credit = cpu_to_le16(credit);
+ cmd->max_credit = max_credit;
+
+ status = i40e_asq_send_command(hw, &desc, NULL, 0, cmd_details);
+
+ return status;
+}
+
+/**
* i40e_aq_config_vsi_tc_bw - Config VSI BW Allocation per TC
* @hw: pointer to the hw struct
* @seid: VSI seid
diff --git a/drivers/net/ethernet/intel/i40e/i40e_debugfs.c b/drivers/net/ethernet/intel/i40e/i40e_debugfs.c
index 3c37386..1aaec40 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_debugfs.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_debugfs.c
@@ -1744,10 +1744,6 @@ 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-sb off", 9) == 0) {
- i40e_dbg_cmd_fd_ctrl(pf, I40E_FLAG_FD_SB_ENABLED, false);
- } else if (strncmp(cmd_buf, "fd-sb on", 8) == 0) {
- i40e_dbg_cmd_fd_ctrl(pf, I40E_FLAG_FD_SB_ENABLED, true);
} else if (strncmp(cmd_buf, "lldp", 4) == 0) {
if (strncmp(&cmd_buf[5], "stop", 4) == 0) {
int ret;
@@ -1967,8 +1963,6 @@ 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-sb off\n");
- dev_info(&pf->pdev->dev, " fd-sb on\n");
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 03d99cb..0cf47c9 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_ethtool.c
@@ -649,7 +649,7 @@ static void i40e_get_ethtool_stats(struct net_device *netdev,
sizeof(u64)) ? *(u64 *)p : *(u32 *)p;
}
rcu_read_lock();
- for (j = 0; j < vsi->num_queue_pairs; j++, i += 4) {
+ for (j = 0; j < vsi->num_queue_pairs; j++) {
struct i40e_ring *tx_ring = ACCESS_ONCE(vsi->tx_rings[j]);
struct i40e_ring *rx_ring;
@@ -662,14 +662,16 @@ static void i40e_get_ethtool_stats(struct net_device *netdev,
data[i] = tx_ring->stats.packets;
data[i + 1] = tx_ring->stats.bytes;
} while (u64_stats_fetch_retry_irq(&tx_ring->syncp, start));
+ i += 2;
/* Rx ring is the 2nd half of the queue pair */
rx_ring = &tx_ring[1];
do {
start = u64_stats_fetch_begin_irq(&rx_ring->syncp);
- data[i + 2] = rx_ring->stats.packets;
- data[i + 3] = rx_ring->stats.bytes;
+ data[i] = rx_ring->stats.packets;
+ data[i + 1] = rx_ring->stats.bytes;
} while (u64_stats_fetch_retry_irq(&rx_ring->syncp, start));
+ i += 2;
}
rcu_read_unlock();
if (vsi == pf->vsi[pf->lan_vsi]) {
@@ -1189,6 +1191,12 @@ static int i40e_get_ethtool_fdir_entry(struct i40e_pf *pf,
return -EINVAL;
fsp->flow_type = rule->flow_type;
+ if (fsp->flow_type == IP_USER_FLOW) {
+ fsp->h_u.usr_ip4_spec.ip_ver = ETH_RX_NFC_IP4;
+ fsp->h_u.usr_ip4_spec.proto = 0;
+ fsp->m_u.usr_ip4_spec.proto = 0;
+ }
+
fsp->h_u.tcp_ip4_spec.psrc = rule->src_port;
fsp->h_u.tcp_ip4_spec.pdst = rule->dst_port;
fsp->h_u.tcp_ip4_spec.ip4src = rule->src_ip[0];
diff --git a/drivers/net/ethernet/intel/i40e/i40e_lan_hmc.c b/drivers/net/ethernet/intel/i40e/i40e_lan_hmc.c
index d5d98fe..5c341ae 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_lan_hmc.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_lan_hmc.c
@@ -747,6 +747,7 @@ static struct i40e_context_ele i40e_hmc_rxq_ce_info[] = {
{ I40E_HMC_STORE(i40e_hmc_obj_rxq, tphdata_ena), 1, 195 },
{ I40E_HMC_STORE(i40e_hmc_obj_rxq, tphhead_ena), 1, 196 },
{ I40E_HMC_STORE(i40e_hmc_obj_rxq, lrxqthresh), 3, 198 },
+ { I40E_HMC_STORE(i40e_hmc_obj_rxq, prefena), 1, 201 },
{ 0 }
};
diff --git a/drivers/net/ethernet/intel/i40e/i40e_lan_hmc.h b/drivers/net/ethernet/intel/i40e/i40e_lan_hmc.h
index 341de92..eb65fe2 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_lan_hmc.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_lan_hmc.h
@@ -56,6 +56,7 @@ struct i40e_hmc_obj_rxq {
u8 tphdata_ena;
u8 tphhead_ena;
u8 lrxqthresh;
+ u8 prefena; /* NOTE: normally must be set to 1 at init */
};
/* Tx queue context data */
diff --git a/drivers/net/ethernet/intel/i40e/i40e_main.c b/drivers/net/ethernet/intel/i40e/i40e_main.c
index 861b722..109052a 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 3
-#define DRV_VERSION_BUILD 36
+#define DRV_VERSION_BUILD 46
#define DRV_VERSION __stringify(DRV_VERSION_MAJOR) "." \
__stringify(DRV_VERSION_MINOR) "." \
__stringify(DRV_VERSION_BUILD) DRV_KERN
@@ -2312,6 +2312,8 @@ static int i40e_configure_rx_ring(struct i40e_ring *ring)
rx_ctx.crcstrip = 1;
rx_ctx.l2tsel = 1;
rx_ctx.showiv = 1;
+ /* set the prefena field to 1 because the manual says to */
+ rx_ctx.prefena = 1;
/* clear the context in the HMC */
err = i40e_clear_lan_rx_queue_context(hw, pf_q);
@@ -3163,9 +3165,7 @@ static int i40e_vsi_control_tx(struct i40e_vsi *vsi, bool enable)
usleep_range(1000, 2000);
}
/* Skip if the queue is already in the requested state */
- if (enable && (tx_reg & I40E_QTX_ENA_QENA_STAT_MASK))
- continue;
- if (!enable && !(tx_reg & I40E_QTX_ENA_QENA_STAT_MASK))
+ if (enable == !!(tx_reg & I40E_QTX_ENA_QENA_STAT_MASK))
continue;
/* turn on/off the queue */
@@ -3181,13 +3181,8 @@ static int i40e_vsi_control_tx(struct i40e_vsi *vsi, bool enable)
/* wait for the change to finish */
for (j = 0; j < 10; j++) {
tx_reg = rd32(hw, I40E_QTX_ENA(pf_q));
- if (enable) {
- if ((tx_reg & I40E_QTX_ENA_QENA_STAT_MASK))
- break;
- } else {
- if (!(tx_reg & I40E_QTX_ENA_QENA_STAT_MASK))
- break;
- }
+ if (enable == !!(tx_reg & I40E_QTX_ENA_QENA_STAT_MASK))
+ break;
udelay(10);
}
@@ -3226,15 +3221,9 @@ static int i40e_vsi_control_rx(struct i40e_vsi *vsi, bool enable)
usleep_range(1000, 2000);
}
- if (enable) {
- /* is STAT set ? */
- if ((rx_reg & I40E_QRX_ENA_QENA_STAT_MASK))
- continue;
- } else {
- /* is !STAT set ? */
- if (!(rx_reg & I40E_QRX_ENA_QENA_STAT_MASK))
- continue;
- }
+ /* Skip if the queue is already in the requested state */
+ if (enable == !!(rx_reg & I40E_QRX_ENA_QENA_STAT_MASK))
+ continue;
/* turn on/off the queue */
if (enable)
@@ -3247,13 +3236,8 @@ static int i40e_vsi_control_rx(struct i40e_vsi *vsi, bool enable)
for (j = 0; j < 10; j++) {
rx_reg = rd32(hw, I40E_QRX_ENA(pf_q));
- if (enable) {
- if ((rx_reg & I40E_QRX_ENA_QENA_STAT_MASK))
- break;
- } else {
- if (!(rx_reg & I40E_QRX_ENA_QENA_STAT_MASK))
- break;
- }
+ if (enable == !!(rx_reg & I40E_QRX_ENA_QENA_STAT_MASK))
+ break;
udelay(10);
}
@@ -3516,6 +3500,19 @@ static void i40e_napi_disable_all(struct i40e_vsi *vsi)
}
/**
+ * i40e_vsi_close - Shut down a VSI
+ * @vsi: the vsi to be quelled
+ **/
+static void i40e_vsi_close(struct i40e_vsi *vsi)
+{
+ if (!test_and_set_bit(__I40E_DOWN, &vsi->state))
+ i40e_down(vsi);
+ i40e_vsi_free_irq(vsi);
+ i40e_vsi_free_tx_resources(vsi);
+ i40e_vsi_free_rx_resources(vsi);
+}
+
+/**
* i40e_quiesce_vsi - Pause a given VSI
* @vsi: the VSI being paused
**/
@@ -3528,8 +3525,7 @@ static void i40e_quiesce_vsi(struct i40e_vsi *vsi)
if (vsi->netdev && netif_running(vsi->netdev)) {
vsi->netdev->netdev_ops->ndo_stop(vsi->netdev);
} else {
- set_bit(__I40E_DOWN, &vsi->state);
- i40e_down(vsi);
+ i40e_vsi_close(vsi);
}
}
@@ -3546,7 +3542,7 @@ static void i40e_unquiesce_vsi(struct i40e_vsi *vsi)
if (vsi->netdev && netif_running(vsi->netdev))
vsi->netdev->netdev_ops->ndo_open(vsi->netdev);
else
- i40e_up(vsi); /* this clears the DOWN bit */
+ i40e_vsi_open(vsi); /* this clears the DOWN bit */
}
/**
@@ -4031,6 +4027,8 @@ static void i40e_dcb_reconfigure(struct i40e_pf *pf)
pf->vsi[v]->seid);
/* Will try to configure as many components */
} else {
+ /* Re-configure VSI vectors based on updated TC map */
+ i40e_vsi_map_rings_to_vectors(pf->vsi[v]);
if (pf->vsi[v]->netdev)
i40e_dcbnl_set_all(pf->vsi[v]);
}
@@ -4070,6 +4068,9 @@ static int i40e_init_pf_dcb(struct i40e_pf *pf)
DCB_CAP_DCBX_VER_IEEE;
pf->flags |= I40E_FLAG_DCB_ENABLED;
}
+ } else {
+ dev_info(&pf->pdev->dev, "AQ Querying DCB configuration failed: %d\n",
+ pf->hw.aq.asq_last_status);
}
out:
@@ -4271,6 +4272,14 @@ static int i40e_open(struct net_device *netdev)
if (err)
return err;
+ /* configure global TSO hardware offload settings */
+ wr32(&pf->hw, I40E_GLLAN_TSOMSK_F, be32_to_cpu(TCP_FLAG_PSH |
+ TCP_FLAG_FIN) >> 16);
+ wr32(&pf->hw, I40E_GLLAN_TSOMSK_M, be32_to_cpu(TCP_FLAG_PSH |
+ TCP_FLAG_FIN |
+ TCP_FLAG_CWR) >> 16);
+ wr32(&pf->hw, I40E_GLLAN_TSOMSK_L, be32_to_cpu(TCP_FLAG_CWR) >> 16);
+
#ifdef CONFIG_I40E_VXLAN
vxlan_get_rx_port(netdev);
#endif
@@ -4304,24 +4313,32 @@ int i40e_vsi_open(struct i40e_vsi *vsi)
if (err)
goto err_setup_rx;
- if (!vsi->netdev) {
+ if (vsi->netdev) {
+ snprintf(int_name, sizeof(int_name) - 1, "%s-%s",
+ dev_driver_string(&pf->pdev->dev), vsi->netdev->name);
+ err = i40e_vsi_request_irq(vsi, int_name);
+ if (err)
+ goto err_setup_rx;
+
+ /* Notify the stack of the actual queue counts. */
+ err = netif_set_real_num_tx_queues(vsi->netdev,
+ vsi->num_queue_pairs);
+ if (err)
+ goto err_set_queues;
+
+ err = netif_set_real_num_rx_queues(vsi->netdev,
+ vsi->num_queue_pairs);
+ if (err)
+ goto err_set_queues;
+
+ } else if (vsi->type == I40E_VSI_FDIR) {
+ snprintf(int_name, sizeof(int_name) - 1, "%s-fdir",
+ dev_driver_string(&pf->pdev->dev));
+ err = i40e_vsi_request_irq(vsi, int_name);
+ } else {
err = EINVAL;
goto err_setup_rx;
}
- snprintf(int_name, sizeof(int_name) - 1, "%s-%s",
- dev_driver_string(&pf->pdev->dev), vsi->netdev->name);
- err = i40e_vsi_request_irq(vsi, int_name);
- if (err)
- goto err_setup_rx;
-
- /* Notify the stack of the actual queue counts. */
- err = netif_set_real_num_tx_queues(vsi->netdev, vsi->num_queue_pairs);
- if (err)
- goto err_set_queues;
-
- err = netif_set_real_num_rx_queues(vsi->netdev, vsi->num_queue_pairs);
- if (err)
- goto err_set_queues;
err = i40e_up_complete(vsi);
if (err)
@@ -4378,14 +4395,7 @@ static int i40e_close(struct net_device *netdev)
struct i40e_netdev_priv *np = netdev_priv(netdev);
struct i40e_vsi *vsi = np->vsi;
- if (test_and_set_bit(__I40E_DOWN, &vsi->state))
- return 0;
-
- i40e_down(vsi);
- i40e_vsi_free_irq(vsi);
-
- i40e_vsi_free_tx_resources(vsi);
- i40e_vsi_free_rx_resources(vsi);
+ i40e_vsi_close(vsi);
return 0;
}
@@ -5221,9 +5231,6 @@ static int i40e_get_capabilities(struct i40e_pf *pf)
}
} while (err);
- /* increment MSI-X count because current FW skips one */
- pf->hw.func_caps.num_msix_vectors++;
-
if (((pf->hw.aq.fw_maj_ver == 2) && (pf->hw.aq.fw_min_ver < 22)) ||
(pf->hw.aq.fw_maj_ver < 2)) {
pf->hw.func_caps.num_msix_vectors++;
@@ -5262,8 +5269,7 @@ static int i40e_vsi_clear(struct i40e_vsi *vsi);
static void i40e_fdir_sb_setup(struct i40e_pf *pf)
{
struct i40e_vsi *vsi;
- bool new_vsi = false;
- int err, i;
+ int i;
if (!(pf->flags & I40E_FLAG_FD_SB_ENABLED))
return;
@@ -5283,47 +5289,12 @@ static void i40e_fdir_sb_setup(struct i40e_pf *pf)
pf->vsi[pf->lan_vsi]->seid, 0);
if (!vsi) {
dev_info(&pf->pdev->dev, "Couldn't create FDir VSI\n");
- goto err_vsi;
+ pf->flags &= ~I40E_FLAG_FD_SB_ENABLED;
+ return;
}
- new_vsi = true;
- }
- i40e_vsi_setup_irqhandler(vsi, i40e_fdir_clean_ring);
-
- err = i40e_vsi_setup_tx_resources(vsi);
- if (err)
- goto err_setup_tx;
- err = i40e_vsi_setup_rx_resources(vsi);
- if (err)
- goto err_setup_rx;
-
- if (new_vsi) {
- char int_name[IFNAMSIZ + 9];
- err = i40e_vsi_configure(vsi);
- if (err)
- goto err_setup_rx;
- snprintf(int_name, sizeof(int_name) - 1, "%s-fdir",
- dev_driver_string(&pf->pdev->dev));
- err = i40e_vsi_request_irq(vsi, int_name);
- if (err)
- goto err_setup_rx;
- err = i40e_up_complete(vsi);
- if (err)
- goto err_up_complete;
- clear_bit(__I40E_NEEDS_RESTART, &vsi->state);
}
- return;
-
-err_up_complete:
- i40e_down(vsi);
- i40e_vsi_free_irq(vsi);
-err_setup_rx:
- i40e_vsi_free_rx_resources(vsi);
-err_setup_tx:
- i40e_vsi_free_tx_resources(vsi);
-err_vsi:
- pf->flags &= ~I40E_FLAG_FD_SB_ENABLED;
- i40e_vsi_clear(vsi);
+ i40e_vsi_setup_irqhandler(vsi, i40e_fdir_clean_ring);
}
/**
@@ -5637,7 +5608,6 @@ static void i40e_handle_mdd_event(struct i40e_pf *pf)
**/
static void i40e_sync_vxlan_filters_subtask(struct i40e_pf *pf)
{
- const int vxlan_hdr_qwords = 4;
struct i40e_hw *hw = &pf->hw;
i40e_status ret;
u8 filter_index;
@@ -5655,7 +5625,6 @@ static void i40e_sync_vxlan_filters_subtask(struct i40e_pf *pf)
port = pf->vxlan_ports[i];
ret = port ?
i40e_aq_add_udp_tunnel(hw, ntohs(port),
- vxlan_hdr_qwords,
I40E_AQC_TUNNEL_TYPE_VXLAN,
&filter_index, NULL)
: i40e_aq_del_udp_tunnel(hw, i, NULL);
@@ -6644,6 +6613,96 @@ static void i40e_del_vxlan_port(struct net_device *netdev,
}
#endif
+#ifdef HAVE_FDB_OPS
+#ifdef USE_CONST_DEV_UC_CHAR
+static int i40e_ndo_fdb_add(struct ndmsg *ndm, struct nlattr *tb[],
+ struct net_device *dev,
+ const unsigned char *addr,
+ u16 flags)
+#else
+static int i40e_ndo_fdb_add(struct ndmsg *ndm,
+ struct net_device *dev,
+ unsigned char *addr,
+ u16 flags)
+#endif
+{
+ struct i40e_netdev_priv *np = netdev_priv(dev);
+ struct i40e_pf *pf = np->vsi->back;
+ int err = 0;
+
+ if (!(pf->flags & I40E_FLAG_SRIOV_ENABLED))
+ return -EOPNOTSUPP;
+
+ /* Hardware does not support aging addresses so if a
+ * ndm_state is given only allow permanent addresses
+ */
+ if (ndm->ndm_state && !(ndm->ndm_state & NUD_PERMANENT)) {
+ netdev_info(dev, "FDB only supports static addresses\n");
+ return -EINVAL;
+ }
+
+ if (is_unicast_ether_addr(addr) || is_link_local_ether_addr(addr))
+ err = dev_uc_add_excl(dev, addr);
+ else if (is_multicast_ether_addr(addr))
+ err = dev_mc_add_excl(dev, addr);
+ else
+ err = -EINVAL;
+
+ /* Only return duplicate errors if NLM_F_EXCL is set */
+ if (err == -EEXIST && !(flags & NLM_F_EXCL))
+ err = 0;
+
+ return err;
+}
+
+#ifndef USE_DEFAULT_FDB_DEL_DUMP
+#ifdef USE_CONST_DEV_UC_CHAR
+static int i40e_ndo_fdb_del(struct ndmsg *ndm,
+ struct net_device *dev,
+ const unsigned char *addr)
+#else
+static int i40e_ndo_fdb_del(struct ndmsg *ndm,
+ struct net_device *dev,
+ unsigned char *addr)
+#endif
+{
+ struct i40e_netdev_priv *np = netdev_priv(dev);
+ struct i40e_pf *pf = np->vsi->back;
+ int err = -EOPNOTSUPP;
+
+ if (ndm->ndm_state & NUD_PERMANENT) {
+ netdev_info(dev, "FDB only supports static addresses\n");
+ return -EINVAL;
+ }
+
+ if (pf->flags & I40E_FLAG_SRIOV_ENABLED) {
+ if (is_unicast_ether_addr(addr))
+ err = dev_uc_del(dev, addr);
+ else if (is_multicast_ether_addr(addr))
+ err = dev_mc_del(dev, addr);
+ else
+ err = -EINVAL;
+ }
+
+ return err;
+}
+
+static int i40e_ndo_fdb_dump(struct sk_buff *skb,
+ struct netlink_callback *cb,
+ struct net_device *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);
+
+ return idx;
+}
+
+#endif /* USE_DEFAULT_FDB_DEL_DUMP */
+#endif /* HAVE_FDB_OPS */
static const struct net_device_ops i40e_netdev_ops = {
.ndo_open = i40e_open,
.ndo_stop = i40e_close,
@@ -6671,6 +6730,13 @@ 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
+#ifdef HAVE_FDB_OPS
+ .ndo_fdb_add = i40e_ndo_fdb_add,
+#ifndef USE_DEFAULT_FDB_DEL_DUMP
+ .ndo_fdb_del = i40e_ndo_fdb_del,
+ .ndo_fdb_dump = i40e_ndo_fdb_dump,
+#endif
+#endif
};
/**
@@ -6712,12 +6778,15 @@ static int i40e_config_netdev(struct i40e_vsi *vsi)
NETIF_F_HW_VLAN_CTAG_FILTER |
NETIF_F_IPV6_CSUM |
NETIF_F_TSO |
+ NETIF_F_TSO_ECN |
NETIF_F_TSO6 |
NETIF_F_RXCSUM |
- NETIF_F_NTUPLE |
NETIF_F_RXHASH |
0;
+ if (!(pf->flags & I40E_FLAG_MFP_ENABLED))
+ netdev->features |= NETIF_F_NTUPLE;
+
/* copy netdev features into list of user selectable features */
netdev->hw_features |= netdev->features;
@@ -6976,11 +7045,7 @@ int i40e_vsi_release(struct i40e_vsi *vsi)
unregister_netdev(vsi->netdev);
}
} else {
- if (!test_and_set_bit(__I40E_DOWN, &vsi->state))
- i40e_down(vsi);
- i40e_vsi_free_irq(vsi);
- i40e_vsi_free_tx_resources(vsi);
- i40e_vsi_free_rx_resources(vsi);
+ i40e_vsi_close(vsi);
}
i40e_vsi_disable_irq(vsi);
}
@@ -8084,6 +8149,7 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
u16 link_status;
int err = 0;
u32 len;
+ u32 i;
err = pci_enable_device_mem(pdev);
if (err)
@@ -8237,7 +8303,7 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
if (err) {
dev_info(&pdev->dev, "init_pf_dcb failed: %d\n", err);
pf->flags &= ~I40E_FLAG_DCB_ENABLED;
- goto err_init_dcb;
+ /* Continue without DCB enabled */
}
#endif /* CONFIG_I40E_DCB */
@@ -8273,6 +8339,13 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
dev_info(&pdev->dev, "setup_pf_switch failed: %d\n", err);
goto err_vsis;
}
+ /* if FDIR VSI was set up, start it now */
+ for (i = 0; i < pf->hw.func_caps.num_vsis; i++) {
+ if (pf->vsi[i] && pf->vsi[i]->type == I40E_VSI_FDIR) {
+ i40e_vsi_open(pf->vsi[i]);
+ break;
+ }
+ }
/* The main driver is (mostly) up and happy. We need to set this state
* before setting up the misc vector or we get a race and the vector
@@ -8326,6 +8399,7 @@ static int i40e_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
dv.minor_version = DRV_VERSION_MINOR;
dv.build_version = DRV_VERSION_BUILD;
dv.subbuild_version = 0;
+ strncpy(dv.driver_string, DRV_VERSION, sizeof(dv.driver_string));
i40e_aq_send_driver_version(&pf->hw, &dv, NULL);
/* since everything's happy, start the service_task timer */
@@ -8367,9 +8441,6 @@ err_vsis:
err_switch_setup:
i40e_reset_interrupt_capability(pf);
del_timer_sync(&pf->service_timer);
-#ifdef CONFIG_I40E_DCB
-err_init_dcb:
-#endif /* CONFIG_I40E_DCB */
err_mac_addr:
err_configure_lan_hmc:
(void)i40e_shutdown_lan_hmc(hw);
diff --git a/drivers/net/ethernet/intel/i40e/i40e_nvm.c b/drivers/net/ethernet/intel/i40e/i40e_nvm.c
index 262bdf1..8129918 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_nvm.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_nvm.c
@@ -160,7 +160,7 @@ static i40e_status i40e_poll_sr_srctl_done_bit(struct i40e_hw *hw)
udelay(5);
}
if (ret_code == I40E_ERR_TIMEOUT)
- hw_dbg(hw, "Done bit in GLNVM_SRCTL not set");
+ hw_dbg(hw, "Done bit in GLNVM_SRCTL not set\n");
return ret_code;
}
diff --git a/drivers/net/ethernet/intel/i40e/i40e_prototype.h b/drivers/net/ethernet/intel/i40e/i40e_prototype.h
index 9cd57e6..d351832 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_prototype.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_prototype.h
@@ -157,8 +157,8 @@ i40e_status i40e_aq_stop_lldp(struct i40e_hw *hw, bool shutdown_agent,
i40e_status i40e_aq_start_lldp(struct i40e_hw *hw,
struct i40e_asq_cmd_details *cmd_details);
i40e_status i40e_aq_add_udp_tunnel(struct i40e_hw *hw,
- u16 udp_port, u8 header_len,
- u8 protocol_index, u8 *filter_index,
+ u16 udp_port, u8 protocol_index,
+ u8 *filter_index,
struct i40e_asq_cmd_details *cmd_details);
i40e_status i40e_aq_del_udp_tunnel(struct i40e_hw *hw, u8 index,
struct i40e_asq_cmd_details *cmd_details);
@@ -167,6 +167,9 @@ i40e_status i40e_aq_delete_element(struct i40e_hw *hw, u16 seid,
i40e_status i40e_aq_mac_address_write(struct i40e_hw *hw,
u16 flags, u8 *mac_addr,
struct i40e_asq_cmd_details *cmd_details);
+i40e_status i40e_aq_config_vsi_bw_limit(struct i40e_hw *hw,
+ u16 seid, u16 credit, u8 max_credit,
+ struct i40e_asq_cmd_details *cmd_details);
i40e_status i40e_aq_dcb_updated(struct i40e_hw *hw,
struct i40e_asq_cmd_details *cmd_details);
i40e_status i40e_aq_set_hmc_resource_profile(struct i40e_hw *hw,
diff --git a/drivers/net/ethernet/intel/i40e/i40e_ptp.c b/drivers/net/ethernet/intel/i40e/i40e_ptp.c
index e33ec6c..1fedc7a 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_ptp.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_ptp.c
@@ -217,40 +217,6 @@ static int i40e_ptp_settime(struct ptp_clock_info *ptp,
}
/**
- * i40e_ptp_tx_work
- * @work: pointer to work struct
- *
- * This work function polls the PRTTSYN_STAT_0.TXTIME bit to determine when a
- * Tx timestamp event has occurred, in order to pass the Tx timestamp value up
- * the stack in the skb.
- */
-static void i40e_ptp_tx_work(struct work_struct *work)
-{
- struct i40e_pf *pf = container_of(work, struct i40e_pf,
- ptp_tx_work);
- struct i40e_hw *hw = &pf->hw;
- u32 prttsyn_stat_0;
-
- if (!pf->ptp_tx_skb)
- return;
-
- if (time_is_before_jiffies(pf->ptp_tx_start +
- I40E_PTP_TX_TIMEOUT)) {
- dev_kfree_skb_any(pf->ptp_tx_skb);
- pf->ptp_tx_skb = NULL;
- pf->tx_hwtstamp_timeouts++;
- dev_warn(&pf->pdev->dev, "clearing Tx timestamp hang");
- return;
- }
-
- prttsyn_stat_0 = rd32(hw, I40E_PRTTSYN_STAT_0);
- if (prttsyn_stat_0 & I40E_PRTTSYN_STAT_0_TXTIME_MASK)
- i40e_ptp_tx_hwtstamp(pf);
- else
- schedule_work(&pf->ptp_tx_work);
-}
-
-/**
* i40e_ptp_enable - Enable/disable ancillary features of the PHC subsystem
* @ptp: The PTP clock structure
* @rq: The requested feature to change
@@ -321,7 +287,7 @@ void i40e_ptp_rx_hang(struct i40e_vsi *vsi)
pf->last_rx_ptp_check = jiffies;
pf->rx_hwtstamp_cleared++;
dev_warn(&vsi->back->pdev->dev,
- "%s: clearing Rx timestamp hang",
+ "%s: clearing Rx timestamp hang\n",
__func__);
}
}
@@ -608,7 +574,6 @@ void i40e_ptp_init(struct i40e_pf *pf)
u32 regval;
spin_lock_init(&pf->tmreg_lock);
- INIT_WORK(&pf->ptp_tx_work, i40e_ptp_tx_work);
dev_info(&pf->pdev->dev, "%s: added PHC on %s\n", __func__,
netdev->name);
@@ -647,7 +612,6 @@ void i40e_ptp_stop(struct i40e_pf *pf)
pf->ptp_tx = false;
pf->ptp_rx = false;
- cancel_work_sync(&pf->ptp_tx_work);
if (pf->ptp_tx_skb) {
dev_kfree_skb_any(pf->ptp_tx_skb);
pf->ptp_tx_skb = NULL;
diff --git a/drivers/net/ethernet/intel/i40e/i40e_txrx.c b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
index 0f5d96a..ece7ae9 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_txrx.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_txrx.c
@@ -418,7 +418,7 @@ int i40e_add_del_fdir(struct i40e_vsi *vsi,
}
break;
default:
- dev_info(&pf->pdev->dev, "Could not specify spec type %d",
+ dev_info(&pf->pdev->dev, "Could not specify spec type %d\n",
input->flow_type);
ret = -EINVAL;
}
@@ -478,7 +478,7 @@ static void i40e_fd_handle_status(struct i40e_ring *rx_ring,
pf->flags |= I40E_FLAG_FDIR_REQUIRES_REINIT;
}
} else {
- dev_info(&pdev->dev, "FD filter programming error");
+ dev_info(&pdev->dev, "FD filter programming error\n");
}
} else if (error ==
(0x1 << I40E_RX_PROG_STATUS_DESC_NO_FD_ENTRY_SHIFT)) {
@@ -1713,9 +1713,11 @@ static int i40e_tx_prepare_vlan_flags(struct sk_buff *skb,
I40E_TX_FLAGS_VLAN_PRIO_SHIFT;
if (tx_flags & I40E_TX_FLAGS_SW_VLAN) {
struct vlan_ethhdr *vhdr;
- if (skb_header_cloned(skb) &&
- pskb_expand_head(skb, 0, 0, GFP_ATOMIC))
- return -ENOMEM;
+ int rc;
+
+ rc = skb_cow_head(skb, 0);
+ if (rc < 0)
+ return rc;
vhdr = (struct vlan_ethhdr *)skb->data;
vhdr->h_vlan_TCI = htons(tx_flags >>
I40E_TX_FLAGS_VLAN_SHIFT);
@@ -1743,20 +1745,18 @@ static int i40e_tso(struct i40e_ring *tx_ring, struct sk_buff *skb,
u64 *cd_type_cmd_tso_mss, u32 *cd_tunneling)
{
u32 cd_cmd, cd_tso_len, cd_mss;
+ struct ipv6hdr *ipv6h;
struct tcphdr *tcph;
struct iphdr *iph;
u32 l4len;
int err;
- struct ipv6hdr *ipv6h;
if (!skb_is_gso(skb))
return 0;
- if (skb_header_cloned(skb)) {
- err = pskb_expand_head(skb, 0, 0, GFP_ATOMIC);
- if (err)
- return err;
- }
+ err = skb_cow_head(skb, 0);
+ if (err < 0)
+ return err;
if (protocol == htons(ETH_P_IP)) {
iph = skb->encapsulation ? inner_ip_hdr(skb) : ip_hdr(skb);
@@ -1825,9 +1825,6 @@ static int i40e_tsyn(struct i40e_ring *tx_ring, struct sk_buff *skb,
*cd_type_cmd_tso_mss |= (u64)I40E_TX_CTX_DESC_TSYN <<
I40E_TXD_CTX_QW1_CMD_SHIFT;
- pf->ptp_tx_start = jiffies;
- schedule_work(&pf->ptp_tx_work);
-
return 1;
}
diff --git a/drivers/net/ethernet/intel/i40e/i40e_type.h b/drivers/net/ethernet/intel/i40e/i40e_type.h
index 71a968f..c4df8ba 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_type.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_type.h
@@ -167,6 +167,9 @@ struct i40e_link_status {
u8 loopback;
/* is Link Status Event notification to SW enabled */
bool lse_enable;
+ u16 max_frame_size;
+ bool crc_enable;
+ u8 pacing;
};
struct i40e_phy_info {
@@ -409,6 +412,7 @@ struct i40e_driver_version {
u8 minor_version;
u8 build_version;
u8 subbuild_version;
+ u8 driver_string[32];
};
/* RX Descriptors */
diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
index 02c11a7..82e7abf 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
+++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.c
@@ -29,6 +29,24 @@
/***********************misc routines*****************************/
/**
+ * i40e_vc_disable_vf
+ * @pf: pointer to the pf info
+ * @vf: pointer to the vf info
+ *
+ * Disable the VF through a SW reset
+ **/
+static inline void i40e_vc_disable_vf(struct i40e_pf *pf, struct i40e_vf *vf)
+{
+ struct i40e_hw *hw = &pf->hw;
+ u32 reg;
+
+ reg = rd32(hw, I40E_VPGEN_VFRTRIG(vf->vf_id));
+ reg |= I40E_VPGEN_VFRTRIG_VFSWR_MASK;
+ wr32(hw, I40E_VPGEN_VFRTRIG(vf->vf_id), reg);
+ i40e_flush(hw);
+}
+
+/**
* i40e_vc_isvalid_vsi_id
* @vf: pointer to the vf info
* @vsi_id: vf relative vsi id
@@ -416,6 +434,15 @@ static int i40e_alloc_vsi_res(struct i40e_vf *vf, enum i40e_vsi_type type)
if (ret)
dev_err(&pf->pdev->dev, "Unable to program ucast filters\n");
+ /* Set VF bandwidth if specified */
+ if (vf->tx_rate) {
+ ret = i40e_aq_config_vsi_bw_limit(&pf->hw, vsi->seid,
+ vf->tx_rate / 50, 0, NULL);
+ if (ret)
+ dev_err(&pf->pdev->dev, "Unable to set tx rate, VF %d, error code %d.\n",
+ vf->vf_id, ret);
+ }
+
error_alloc_vsi_res:
return ret;
}
@@ -2022,10 +2049,11 @@ int i40e_ndo_set_vf_mac(struct net_device *netdev, int vf_id, u8 *mac)
}
/* delete the temporary mac address */
- i40e_del_filter(vsi, vf->default_lan_addr.addr, 0, true, false);
+ i40e_del_filter(vsi, vf->default_lan_addr.addr, vf->port_vlan_id,
+ true, false);
/* add the new mac address */
- f = i40e_add_filter(vsi, mac, 0, true, false);
+ f = i40e_add_filter(vsi, mac, vf->port_vlan_id, true, false);
if (!f) {
dev_err(&pf->pdev->dev,
"Unable to add VF ucast filter\n");
@@ -2088,18 +2116,28 @@ int i40e_ndo_set_vf_port_vlan(struct net_device *netdev,
goto error_pvid;
}
- if (vsi->info.pvid == 0 && i40e_is_vsi_in_vlan(vsi))
+ if (vsi->info.pvid == 0 && i40e_is_vsi_in_vlan(vsi)) {
dev_err(&pf->pdev->dev,
"VF %d has already configured VLAN filters and the administrator is requesting a port VLAN override.\nPlease unload and reload the VF driver for this change to take effect.\n",
vf_id);
+ /* Administrator Error - knock the VF offline until he does
+ * the right thing by reconfiguring his network correctly
+ * and then reloading the VF driver.
+ */
+ i40e_vc_disable_vf(pf, vf);
+ }
/* Check for condition where there was already a port VLAN ID
* filter set and now it is being deleted by setting it to zero.
+ * Additionally check for the condition where there was a port
+ * VLAN but now there is a new and different port VLAN being set.
* Before deleting all the old VLAN filters we must add new ones
* with -1 (I40E_VLAN_ANY) or otherwise we're left with all our
* MAC addresses deleted.
*/
- if (!(vlan_id || qos) && vsi->info.pvid)
+ if ((!(vlan_id || qos) ||
+ (vlan_id | qos) != le16_to_cpu(vsi->info.pvid)) &&
+ vsi->info.pvid)
ret = i40e_vsi_add_vlan(vsi, I40E_VLAN_ANY);
if (vsi->info.pvid) {
@@ -2160,7 +2198,61 @@ error_pvid:
**/
int i40e_ndo_set_vf_bw(struct net_device *netdev, int vf_id, int tx_rate)
{
- return -EOPNOTSUPP;
+ struct i40e_netdev_priv *np = netdev_priv(netdev);
+ struct i40e_pf *pf = np->vsi->back;
+ struct i40e_vsi *vsi;
+ struct i40e_vf *vf;
+ int speed = 0;
+ int ret = 0;
+
+ /* validate the request */
+ if (vf_id >= pf->num_alloc_vfs) {
+ dev_err(&pf->pdev->dev, "Invalid VF Identifier %d.\n", vf_id);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ vf = &(pf->vf[vf_id]);
+ vsi = pf->vsi[vf->lan_vsi_index];
+ if (!test_bit(I40E_VF_STAT_INIT, &vf->vf_states)) {
+ dev_err(&pf->pdev->dev, "Uninitialized VF %d.\n", vf_id);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ switch (pf->hw.phy.link_info.link_speed) {
+ case I40E_LINK_SPEED_40GB:
+ speed = 40000;
+ break;
+ case I40E_LINK_SPEED_10GB:
+ speed = 10000;
+ break;
+ case I40E_LINK_SPEED_1GB:
+ speed = 1000;
+ break;
+ default:
+ break;
+ }
+
+ if (tx_rate > speed) {
+ dev_err(&pf->pdev->dev, "Invalid tx rate %d specified for vf %d.",
+ tx_rate, vf->vf_id);
+ ret = -EINVAL;
+ goto error;
+ }
+
+ /* Tx rate credits are in values of 50Mbps, 0 is disabled*/
+ ret = i40e_aq_config_vsi_bw_limit(&pf->hw, vsi->seid, tx_rate / 50, 0,
+ NULL);
+ if (ret) {
+ dev_err(&pf->pdev->dev, "Unable to set tx rate, error code %d.\n",
+ ret);
+ ret = -EIO;
+ goto error;
+ }
+ vf->tx_rate = tx_rate;
+error:
+ return ret;
}
/**
@@ -2200,10 +2292,17 @@ int i40e_ndo_get_vf_config(struct net_device *netdev,
memcpy(&ivi->mac, vf->default_lan_addr.addr, ETH_ALEN);
- ivi->tx_rate = 0;
+ ivi->tx_rate = vf->tx_rate;
ivi->vlan = le16_to_cpu(vsi->info.pvid) & I40E_VLAN_MASK;
ivi->qos = (le16_to_cpu(vsi->info.pvid) & I40E_PRIORITY_MASK) >>
I40E_VLAN_PRIORITY_SHIFT;
+ if (vf->link_forced == false)
+ ivi->linkstate = IFLA_VF_LINK_STATE_AUTO;
+ else if (vf->link_up == true)
+ ivi->linkstate = IFLA_VF_LINK_STATE_ENABLE;
+ else
+ ivi->linkstate = IFLA_VF_LINK_STATE_DISABLE;
+
ret = 0;
error_param:
diff --git a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h
index 389c47f..ba3d1f8 100644
--- a/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h
+++ b/drivers/net/ethernet/intel/i40e/i40e_virtchnl_pf.h
@@ -98,6 +98,7 @@ struct i40e_vf {
unsigned long vf_caps; /* vf's adv. capabilities */
unsigned long vf_states; /* vf's runtime states */
+ unsigned int tx_rate; /* Tx bandwidth limit in Mbps */
bool link_forced;
bool link_up; /* only valid if vf link is forced */
};
diff --git a/drivers/net/ethernet/intel/i40evf/i40e_adminq.c b/drivers/net/ethernet/intel/i40evf/i40e_adminq.c
index 5470ce9..c79df25 100644
--- a/drivers/net/ethernet/intel/i40evf/i40e_adminq.c
+++ b/drivers/net/ethernet/intel/i40evf/i40e_adminq.c
@@ -28,6 +28,16 @@
#include "i40e_prototype.h"
/**
+ * i40e_is_nvm_update_op - return true if this is an NVM update operation
+ * @desc: API request descriptor
+ **/
+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);
+}
+
+/**
* i40e_adminq_init_regs - Initialize AdminQ registers
* @hw: pointer to the hardware structure
*
@@ -659,6 +669,12 @@ i40e_status i40evf_asq_send_command(struct i40e_hw *hw,
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;
+ goto asq_send_command_exit;
+ }
+
details = I40E_ADMINQ_DETAILS(hw->aq.asq, hw->aq.asq.next_to_use);
if (cmd_details) {
*details = *cmd_details;
@@ -786,6 +802,9 @@ i40e_status i40evf_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;
+
/* update the error if time out occurred */
if ((!cmd_completed) &&
(!details->async && !details->postpone)) {
@@ -880,6 +899,9 @@ i40e_status i40evf_clean_arq_element(struct i40e_hw *hw,
e->msg_size);
}
+ if (i40e_is_nvm_update_op(&e->desc))
+ hw->aq.nvm_busy = false;
+
/* 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 8f72c31d..7d24be5 100644
--- a/drivers/net/ethernet/intel/i40evf/i40e_adminq.h
+++ b/drivers/net/ethernet/intel/i40evf/i40e_adminq.h
@@ -87,6 +87,7 @@ struct i40e_adminq_info {
u16 fw_min_ver; /* firmware minor version */
u16 api_maj_ver; /* api major version */
u16 api_min_ver; /* api minor version */
+ bool nvm_busy;
struct mutex asq_mutex; /* Send queue lock */
struct mutex arq_mutex; /* Receive queue lock */
diff --git a/drivers/net/ethernet/intel/i40evf/i40e_adminq_cmd.h b/drivers/net/ethernet/intel/i40evf/i40e_adminq_cmd.h
index 97662b6..6e61766 100644
--- a/drivers/net/ethernet/intel/i40evf/i40e_adminq_cmd.h
+++ b/drivers/net/ethernet/intel/i40evf/i40e_adminq_cmd.h
@@ -180,9 +180,6 @@ enum i40e_admin_queue_opc {
i40e_aqc_opc_add_mirror_rule = 0x0260,
i40e_aqc_opc_delete_mirror_rule = 0x0261,
- i40e_aqc_opc_set_storm_control_config = 0x0280,
- i40e_aqc_opc_get_storm_control_config = 0x0281,
-
/* DCB commands */
i40e_aqc_opc_dcb_ignore_pfc = 0x0301,
i40e_aqc_opc_dcb_updated = 0x0302,
@@ -205,6 +202,7 @@ enum i40e_admin_queue_opc {
i40e_aqc_opc_query_switching_comp_bw_config = 0x041A,
i40e_aqc_opc_suspend_port_tx = 0x041B,
i40e_aqc_opc_resume_port_tx = 0x041C,
+ i40e_aqc_opc_configure_partition_bw = 0x041D,
/* hmc */
i40e_aqc_opc_query_hmc_resource_profile = 0x0500,
@@ -1289,27 +1287,6 @@ struct i40e_aqc_add_delete_mirror_rule_completion {
I40E_CHECK_CMD_LENGTH(i40e_aqc_add_delete_mirror_rule_completion);
-/* Set Storm Control Configuration (direct 0x0280)
- * Get Storm Control Configuration (direct 0x0281)
- * the command and response use the same descriptor structure
- */
-struct i40e_aqc_set_get_storm_control_config {
- __le32 broadcast_threshold;
- __le32 multicast_threshold;
- __le32 control_flags;
-#define I40E_AQC_STORM_CONTROL_MDIPW 0x01
-#define I40E_AQC_STORM_CONTROL_MDICW 0x02
-#define I40E_AQC_STORM_CONTROL_BDIPW 0x04
-#define I40E_AQC_STORM_CONTROL_BDICW 0x08
-#define I40E_AQC_STORM_CONTROL_BIDU 0x10
-#define I40E_AQC_STORM_CONTROL_INTERVAL_SHIFT 8
-#define I40E_AQC_STORM_CONTROL_INTERVAL_MASK (0x3FF << \
- I40E_AQC_STORM_CONTROL_INTERVAL_SHIFT)
- u8 reserved[4];
-};
-
-I40E_CHECK_CMD_LENGTH(i40e_aqc_set_get_storm_control_config);
-
/* DCB 0x03xx*/
/* PFC Ignore (direct 0x0301)
@@ -1499,6 +1476,15 @@ struct i40e_aqc_query_switching_comp_bw_config_resp {
* (direct 0x041B and 0x041C) uses the generic SEID struct
*/
+/* Configure partition BW
+ * (indirect 0x041D)
+ */
+struct i40e_aqc_configure_partition_bw_data {
+ __le16 pf_valid_bits;
+ u8 min_bw[16]; /* guaranteed bandwidth */
+ u8 max_bw[16]; /* bandwidth limit */
+};
+
/* Get and set the active HMC resource profile and status.
* (direct 0x0500) and (direct 0x0501)
*/
@@ -1583,11 +1569,8 @@ struct i40e_aq_get_phy_abilities_resp {
#define I40E_AQ_PHY_FLAG_PAUSE_TX 0x01
#define I40E_AQ_PHY_FLAG_PAUSE_RX 0x02
#define I40E_AQ_PHY_FLAG_LOW_POWER 0x04
-#define I40E_AQ_PHY_FLAG_AN_SHIFT 3
-#define I40E_AQ_PHY_FLAG_AN_MASK (0x3 << I40E_AQ_PHY_FLAG_AN_SHIFT)
-#define I40E_AQ_PHY_FLAG_AN_OFF 0x00 /* link forced on */
-#define I40E_AQ_PHY_FLAG_AN_OFF_LINK_DOWN 0x01
-#define I40E_AQ_PHY_FLAG_AN_ON 0x02
+#define I40E_AQ_PHY_LINK_ENABLED 0x08
+#define I40E_AQ_PHY_AN_ENABLED 0x10
#define I40E_AQ_PHY_FLAG_MODULE_QUAL 0x20
__le16 eee_capability;
#define I40E_AQ_EEE_100BASE_TX 0x0002
diff --git a/drivers/net/ethernet/intel/i40evf/i40e_lan_hmc.h b/drivers/net/ethernet/intel/i40evf/i40e_lan_hmc.h
index 17e42ca..775fcb2 100644
--- a/drivers/net/ethernet/intel/i40evf/i40e_lan_hmc.h
+++ b/drivers/net/ethernet/intel/i40evf/i40e_lan_hmc.h
@@ -53,6 +53,7 @@ struct i40e_hmc_obj_rxq {
u8 tphdata_ena;
u8 tphhead_ena;
u8 lrxqthresh;
+ u8 prefena; /* NOTE: normally must be set to 1 at init */
};
/* Tx queue context data */
diff --git a/drivers/net/ethernet/intel/i40evf/i40e_type.h b/drivers/net/ethernet/intel/i40evf/i40e_type.h
index 4673b33..51a6dee 100644
--- a/drivers/net/ethernet/intel/i40evf/i40e_type.h
+++ b/drivers/net/ethernet/intel/i40evf/i40e_type.h
@@ -173,6 +173,9 @@ struct i40e_link_status {
u8 loopback;
/* is Link Status Event notification to SW enabled */
bool lse_enable;
+ u16 max_frame_size;
+ bool crc_enable;
+ u8 pacing;
};
struct i40e_phy_info {
@@ -415,6 +418,7 @@ struct i40e_driver_version {
u8 minor_version;
u8 build_version;
u8 subbuild_version;
+ u8 driver_string[32];
};
/* RX Descriptors */
diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c b/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c
index 8b0db1c..a46be01 100644
--- a/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c
+++ b/drivers/net/ethernet/intel/i40evf/i40evf_ethtool.c
@@ -365,6 +365,316 @@ static int i40evf_set_coalesce(struct net_device *netdev,
return 0;
}
+/**
+ * i40e_get_rss_hash_opts - Get RSS hash Input Set for each flow type
+ * @adapter: board private structure
+ * @cmd: ethtool rxnfc command
+ *
+ * Returns Success if the flow is supported, else Invalid Input.
+ **/
+static int i40evf_get_rss_hash_opts(struct i40evf_adapter *adapter,
+ struct ethtool_rxnfc *cmd)
+{
+ struct i40e_hw *hw = &adapter->hw;
+ u64 hena = (u64)rd32(hw, I40E_VFQF_HENA(0)) |
+ ((u64)rd32(hw, I40E_VFQF_HENA(1)) << 32);
+
+ /* We always hash on IP src and dest addresses */
+ cmd->data = RXH_IP_SRC | RXH_IP_DST;
+
+ switch (cmd->flow_type) {
+ case TCP_V4_FLOW:
+ if (hena & ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV4_TCP))
+ cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
+ break;
+ case UDP_V4_FLOW:
+ if (hena & ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV4_UDP))
+ cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
+ break;
+
+ case SCTP_V4_FLOW:
+ case AH_ESP_V4_FLOW:
+ case AH_V4_FLOW:
+ case ESP_V4_FLOW:
+ case IPV4_FLOW:
+ break;
+
+ case TCP_V6_FLOW:
+ if (hena & ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_TCP))
+ cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
+ break;
+ case UDP_V6_FLOW:
+ if (hena & ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_UDP))
+ cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
+ break;
+
+ case SCTP_V6_FLOW:
+ case AH_ESP_V6_FLOW:
+ case AH_V6_FLOW:
+ case ESP_V6_FLOW:
+ case IPV6_FLOW:
+ break;
+ default:
+ cmd->data = 0;
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+/**
+ * i40evf_get_rxnfc - command to get RX flow classification rules
+ * @netdev: network interface device structure
+ * @cmd: ethtool rxnfc command
+ *
+ * Returns Success if the command is supported.
+ **/
+static int i40evf_get_rxnfc(struct net_device *netdev,
+ struct ethtool_rxnfc *cmd,
+ u32 *rule_locs)
+{
+ struct i40evf_adapter *adapter = netdev_priv(netdev);
+ int ret = -EOPNOTSUPP;
+
+ switch (cmd->cmd) {
+ case ETHTOOL_GRXRINGS:
+ cmd->data = adapter->vsi_res->num_queue_pairs;
+ ret = 0;
+ break;
+ case ETHTOOL_GRXFH:
+ ret = i40evf_get_rss_hash_opts(adapter, cmd);
+ break;
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+/**
+ * i40evf_set_rss_hash_opt - Enable/Disable flow types for RSS hash
+ * @adapter: board private structure
+ * @cmd: ethtool rxnfc command
+ *
+ * Returns Success if the flow input set is supported.
+ **/
+static int i40evf_set_rss_hash_opt(struct i40evf_adapter *adapter,
+ struct ethtool_rxnfc *nfc)
+{
+ struct i40e_hw *hw = &adapter->hw;
+
+ u64 hena = (u64)rd32(hw, I40E_VFQF_HENA(0)) |
+ ((u64)rd32(hw, I40E_VFQF_HENA(1)) << 32);
+
+ /* RSS does not support anything other than hashing
+ * to queues on src and dst IPs and ports
+ */
+ if (nfc->data & ~(RXH_IP_SRC | RXH_IP_DST |
+ RXH_L4_B_0_1 | RXH_L4_B_2_3))
+ return -EINVAL;
+
+ /* We need at least the IP SRC and DEST fields for hashing */
+ if (!(nfc->data & RXH_IP_SRC) ||
+ !(nfc->data & RXH_IP_DST))
+ return -EINVAL;
+
+ switch (nfc->flow_type) {
+ case TCP_V4_FLOW:
+ switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
+ case 0:
+ hena &= ~((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV4_TCP);
+ break;
+ case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
+ hena |= ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV4_TCP);
+ break;
+ default:
+ return -EINVAL;
+ }
+ break;
+ case TCP_V6_FLOW:
+ switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
+ case 0:
+ hena &= ~((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_TCP);
+ break;
+ case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
+ hena |= ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_TCP);
+ break;
+ default:
+ return -EINVAL;
+ }
+ break;
+ case UDP_V4_FLOW:
+ switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
+ case 0:
+ hena &= ~(((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV4_UDP) |
+ ((u64)1 << I40E_FILTER_PCTYPE_FRAG_IPV4));
+ break;
+ case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
+ hena |= (((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV4_UDP) |
+ ((u64)1 << I40E_FILTER_PCTYPE_FRAG_IPV4));
+ break;
+ default:
+ return -EINVAL;
+ }
+ break;
+ case UDP_V6_FLOW:
+ switch (nfc->data & (RXH_L4_B_0_1 | RXH_L4_B_2_3)) {
+ case 0:
+ hena &= ~(((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_UDP) |
+ ((u64)1 << I40E_FILTER_PCTYPE_FRAG_IPV6));
+ break;
+ case (RXH_L4_B_0_1 | RXH_L4_B_2_3):
+ hena |= (((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_UDP) |
+ ((u64)1 << I40E_FILTER_PCTYPE_FRAG_IPV6));
+ break;
+ default:
+ return -EINVAL;
+ }
+ break;
+ case AH_ESP_V4_FLOW:
+ case AH_V4_FLOW:
+ case ESP_V4_FLOW:
+ case SCTP_V4_FLOW:
+ if ((nfc->data & RXH_L4_B_0_1) ||
+ (nfc->data & RXH_L4_B_2_3))
+ return -EINVAL;
+ hena |= ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV4_OTHER);
+ break;
+ case AH_ESP_V6_FLOW:
+ case AH_V6_FLOW:
+ case ESP_V6_FLOW:
+ case SCTP_V6_FLOW:
+ if ((nfc->data & RXH_L4_B_0_1) ||
+ (nfc->data & RXH_L4_B_2_3))
+ return -EINVAL;
+ hena |= ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_OTHER);
+ break;
+ case IPV4_FLOW:
+ hena |= ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV4_OTHER) |
+ ((u64)1 << I40E_FILTER_PCTYPE_FRAG_IPV4);
+ break;
+ case IPV6_FLOW:
+ hena |= ((u64)1 << I40E_FILTER_PCTYPE_NONF_IPV6_OTHER) |
+ ((u64)1 << I40E_FILTER_PCTYPE_FRAG_IPV6);
+ break;
+ default:
+ return -EINVAL;
+ }
+
+ wr32(hw, I40E_VFQF_HENA(0), (u32)hena);
+ wr32(hw, I40E_VFQF_HENA(1), (u32)(hena >> 32));
+ i40e_flush(hw);
+
+ return 0;
+}
+
+/**
+ * i40evf_set_rxnfc - command to set RX flow classification rules
+ * @netdev: network interface device structure
+ * @cmd: ethtool rxnfc command
+ *
+ * Returns Success if the command is supported.
+ **/
+static int i40evf_set_rxnfc(struct net_device *netdev,
+ struct ethtool_rxnfc *cmd)
+{
+ struct i40evf_adapter *adapter = netdev_priv(netdev);
+ int ret = -EOPNOTSUPP;
+
+ switch (cmd->cmd) {
+ case ETHTOOL_SRXFH:
+ ret = i40evf_set_rss_hash_opt(adapter, cmd);
+ break;
+ default:
+ break;
+ }
+
+ return ret;
+}
+
+/**
+ * i40evf_get_channels: get the number of channels supported by the device
+ * @netdev: network interface device structure
+ * @ch: channel information structure
+ *
+ * For the purposes of our device, we only use combined channels, i.e. a tx/rx
+ * queue pair. Report one extra channel to match our "other" MSI-X vector.
+ **/
+static void i40evf_get_channels(struct net_device *netdev,
+ struct ethtool_channels *ch)
+{
+ struct i40evf_adapter *adapter = netdev_priv(netdev);
+
+ /* Report maximum channels */
+ ch->max_combined = adapter->vsi_res->num_queue_pairs;
+
+ ch->max_other = NONQ_VECS;
+ ch->other_count = NONQ_VECS;
+
+ ch->combined_count = adapter->vsi_res->num_queue_pairs;
+}
+
+/**
+ * i40evf_get_rxfh_indir_size - get the rx flow hash indirection table size
+ * @netdev: network interface device structure
+ *
+ * Returns the table size.
+ **/
+static u32 i40evf_get_rxfh_indir_size(struct net_device *netdev)
+{
+ return (I40E_VFQF_HLUT_MAX_INDEX + 1) * 4;
+}
+
+/**
+ * i40evf_get_rxfh_indir - get the rx flow hash indirection table
+ * @netdev: network interface device structure
+ * @indir: indirection table
+ *
+ * Reads the indirection table directly from the hardware. Always returns 0.
+ **/
+static int i40evf_get_rxfh_indir(struct net_device *netdev, u32 *indir)
+{
+ struct i40evf_adapter *adapter = netdev_priv(netdev);
+ struct i40e_hw *hw = &adapter->hw;
+ u32 hlut_val;
+ int i, j;
+
+ 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;
+ indir[j++] = (hlut_val >> 16) & 0xff;
+ indir[j++] = (hlut_val >> 24) & 0xff;
+ }
+ return 0;
+}
+
+/**
+ * i40evf_set_rxfh_indir - set the rx flow hash indirection table
+ * @netdev: network interface device structure
+ * @indir: indirection table
+ *
+ * Returns -EINVAL if the table specifies an inavlid queue id, otherwise
+ * returns 0 after programming the table.
+ **/
+static int i40evf_set_rxfh_indir(struct net_device *netdev, const u32 *indir)
+{
+ struct i40evf_adapter *adapter = netdev_priv(netdev);
+ struct i40e_hw *hw = &adapter->hw;
+ u32 hlut_val;
+ int i, j;
+
+ for (i = 0, j = 0; i < I40E_VFQF_HLUT_MAX_INDEX + 1; i++) {
+ hlut_val = indir[j++];
+ hlut_val |= indir[j++] << 8;
+ hlut_val |= indir[j++] << 16;
+ hlut_val |= indir[j++] << 24;
+ wr32(hw, I40E_VFQF_HLUT(i), hlut_val);
+ }
+
+ return 0;
+}
+
static struct ethtool_ops i40evf_ethtool_ops = {
.get_settings = i40evf_get_settings,
.get_drvinfo = i40evf_get_drvinfo,
@@ -378,6 +688,12 @@ static struct ethtool_ops i40evf_ethtool_ops = {
.set_msglevel = i40evf_set_msglevel,
.get_coalesce = i40evf_get_coalesce,
.set_coalesce = i40evf_set_coalesce,
+ .get_rxnfc = i40evf_get_rxnfc,
+ .set_rxnfc = i40evf_set_rxnfc,
+ .get_rxfh_indir_size = i40evf_get_rxfh_indir_size,
+ .get_rxfh_indir = i40evf_get_rxfh_indir,
+ .set_rxfh_indir = i40evf_set_rxfh_indir,
+ .get_channels = i40evf_get_channels,
};
/**
diff --git a/drivers/net/ethernet/intel/i40evf/i40evf_main.c b/drivers/net/ethernet/intel/i40evf/i40evf_main.c
index 2797548..6edd581 100644
--- a/drivers/net/ethernet/intel/i40evf/i40evf_main.c
+++ b/drivers/net/ethernet/intel/i40evf/i40evf_main.c
@@ -25,13 +25,15 @@
#include "i40e_prototype.h"
static int i40evf_setup_all_tx_resources(struct i40evf_adapter *adapter);
static int i40evf_setup_all_rx_resources(struct i40evf_adapter *adapter);
+static void i40evf_free_all_tx_resources(struct i40evf_adapter *adapter);
+static void i40evf_free_all_rx_resources(struct i40evf_adapter *adapter);
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";
-#define DRV_VERSION "0.9.16"
+#define DRV_VERSION "0.9.23"
const char i40evf_driver_version[] = DRV_VERSION;
static const char i40evf_copyright[] =
"Copyright (c) 2013 - 2014 Intel Corporation.";
@@ -1309,7 +1311,6 @@ static void i40evf_watchdog_task(struct work_struct *work)
goto restart_watchdog;
if (adapter->flags & I40EVF_FLAG_PF_COMMS_FAILED) {
- dev_info(&adapter->pdev->dev, "Checking for redemption\n");
if ((rd32(hw, I40E_VFGEN_RSTAT) & 0x3) == I40E_VFR_VFACTIVE) {
/* A chance for redemption! */
dev_err(&adapter->pdev->dev, "Hardware came out of reset. Attempting reinit.\n");
@@ -1534,9 +1535,13 @@ static void i40evf_reset_task(struct work_struct *work)
rstat_val);
adapter->flags |= I40EVF_FLAG_PF_COMMS_FAILED;
- if (netif_running(adapter->netdev))
- i40evf_close(adapter->netdev);
-
+ if (netif_running(adapter->netdev)) {
+ set_bit(__I40E_DOWN, &adapter->vsi.state);
+ i40evf_down(adapter);
+ i40evf_free_traffic_irqs(adapter);
+ i40evf_free_all_tx_resources(adapter);
+ i40evf_free_all_rx_resources(adapter);
+ }
i40evf_free_misc_irq(adapter);
i40evf_reset_interrupt_capability(adapter);
i40evf_free_queues(adapter);
diff --git a/drivers/net/ethernet/intel/igb/e1000_82575.c b/drivers/net/ethernet/intel/igb/e1000_82575.c
index fa36fe12..2e36c67 100644
--- a/drivers/net/ethernet/intel/igb/e1000_82575.c
+++ b/drivers/net/ethernet/intel/igb/e1000_82575.c
@@ -1,28 +1,25 @@
-/*******************************************************************************
-
- Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-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
-
-*******************************************************************************/
+/* Intel(R) Gigabit Ethernet Linux driver
+ * Copyright(c) 2007-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
+ */
/* e1000_82575
* e1000_82576
@@ -73,9 +70,8 @@ static s32 igb_validate_nvm_checksum_82580(struct e1000_hw *hw);
static s32 igb_update_nvm_checksum_82580(struct e1000_hw *hw);
static s32 igb_validate_nvm_checksum_i350(struct e1000_hw *hw);
static s32 igb_update_nvm_checksum_i350(struct e1000_hw *hw);
-static const u16 e1000_82580_rxpbs_table[] =
- { 36, 72, 144, 1, 2, 4, 8, 16,
- 35, 70, 140 };
+static const u16 e1000_82580_rxpbs_table[] = {
+ 36, 72, 144, 1, 2, 4, 8, 16, 35, 70, 140 };
/**
* igb_sgmii_uses_mdio_82575 - Determine if I2C pins are for external MDIO
@@ -526,7 +522,7 @@ out:
static s32 igb_get_invariants_82575(struct e1000_hw *hw)
{
struct e1000_mac_info *mac = &hw->mac;
- struct e1000_dev_spec_82575 * dev_spec = &hw->dev_spec._82575;
+ struct e1000_dev_spec_82575 *dev_spec = &hw->dev_spec._82575;
s32 ret_val;
u32 ctrl_ext = 0;
u32 link_mode = 0;
@@ -1180,8 +1176,8 @@ static void igb_release_swfw_sync_82575(struct e1000_hw *hw, u16 mask)
{
u32 swfw_sync;
- while (igb_get_hw_semaphore(hw) != 0);
- /* Empty */
+ while (igb_get_hw_semaphore(hw) != 0)
+ ; /* Empty */
swfw_sync = rd32(E1000_SW_FW_SYNC);
swfw_sync &= ~mask;
@@ -1216,7 +1212,7 @@ static s32 igb_get_cfg_done_82575(struct e1000_hw *hw)
while (timeout) {
if (rd32(E1000_EEMNGCTL) & mask)
break;
- msleep(1);
+ usleep_range(1000, 2000);
timeout--;
}
if (!timeout)
@@ -1269,7 +1265,7 @@ static s32 igb_check_for_link_82575(struct e1000_hw *hw)
if (hw->phy.media_type != e1000_media_type_copper) {
ret_val = igb_get_pcs_speed_and_duplex_82575(hw, &speed,
- &duplex);
+ &duplex);
/* Use this flag to determine if link needs to be checked or
* not. If we have link clear the flag so that we do not
* continue to check for link.
@@ -1316,7 +1312,7 @@ void igb_power_up_serdes_link_82575(struct e1000_hw *hw)
/* flush the write to verify completion */
wrfl();
- msleep(1);
+ usleep_range(1000, 2000);
}
/**
@@ -1411,7 +1407,7 @@ void igb_shutdown_serdes_link_82575(struct e1000_hw *hw)
/* flush the write to verify completion */
wrfl();
- msleep(1);
+ usleep_range(1000, 2000);
}
}
@@ -1436,9 +1432,8 @@ static s32 igb_reset_hw_82575(struct e1000_hw *hw)
/* set the completion timeout for interface */
ret_val = igb_set_pcie_completion_timeout(hw);
- if (ret_val) {
+ if (ret_val)
hw_dbg("PCI-E Set completion timeout has failed.\n");
- }
hw_dbg("Masking off all interrupts\n");
wr32(E1000_IMC, 0xffffffff);
@@ -1447,7 +1442,7 @@ static s32 igb_reset_hw_82575(struct e1000_hw *hw)
wr32(E1000_TCTL, E1000_TCTL_PSP);
wrfl();
- msleep(10);
+ usleep_range(10000, 20000);
ctrl = rd32(E1000_CTRL);
@@ -1676,7 +1671,7 @@ static s32 igb_setup_serdes_link_82575(struct e1000_hw *hw)
hw->mac.type == e1000_82576) {
ret_val = hw->nvm.ops.read(hw, NVM_COMPAT, 1, &data);
if (ret_val) {
- printk(KERN_DEBUG "NVM Read Error\n\n");
+ hw_dbg(KERN_DEBUG "NVM Read Error\n\n");
return ret_val;
}
@@ -1689,7 +1684,7 @@ static s32 igb_setup_serdes_link_82575(struct e1000_hw *hw)
* link either autoneg or be forced to 1000/Full
*/
ctrl_reg |= E1000_CTRL_SPD_1000 | E1000_CTRL_FRCSPD |
- E1000_CTRL_FD | E1000_CTRL_FRCDPX;
+ E1000_CTRL_FD | E1000_CTRL_FRCDPX;
/* set speed of 1000/Full if speed/duplex is forced */
reg |= E1000_PCS_LCTL_FSV_1000 | E1000_PCS_LCTL_FDV_FULL;
@@ -1925,7 +1920,7 @@ void igb_rx_fifo_flush_82575(struct e1000_hw *hw)
}
/* Poll all queues to verify they have shut down */
for (ms_wait = 0; ms_wait < 10; ms_wait++) {
- msleep(1);
+ usleep_range(1000, 2000);
rx_enabled = 0;
for (i = 0; i < 4; i++)
rx_enabled |= rd32(E1000_RXDCTL(i));
@@ -1953,7 +1948,7 @@ void igb_rx_fifo_flush_82575(struct e1000_hw *hw)
wr32(E1000_RCTL, temp_rctl);
wr32(E1000_RCTL, temp_rctl | E1000_RCTL_EN);
wrfl();
- msleep(2);
+ usleep_range(2000, 3000);
/* Enable RX queues that were previously enabled and restore our
* previous state
@@ -2005,14 +2000,14 @@ static s32 igb_set_pcie_completion_timeout(struct e1000_hw *hw)
* 16ms to 55ms
*/
ret_val = igb_read_pcie_cap_reg(hw, PCIE_DEVICE_CONTROL2,
- &pcie_devctl2);
+ &pcie_devctl2);
if (ret_val)
goto out;
pcie_devctl2 |= PCIE_DEVICE_CONTROL2_16ms;
ret_val = igb_write_pcie_cap_reg(hw, PCIE_DEVICE_CONTROL2,
- &pcie_devctl2);
+ &pcie_devctl2);
out:
/* disable completion timeout resend */
gcr &= ~E1000_GCR_CMPL_TMOUT_RESEND;
@@ -2241,7 +2236,7 @@ static s32 igb_reset_hw_82580(struct e1000_hw *hw)
wr32(E1000_TCTL, E1000_TCTL_PSP);
wrfl();
- msleep(10);
+ usleep_range(10000, 11000);
/* Determine whether or not a global dev reset is requested */
if (global_device_reset &&
@@ -2259,7 +2254,7 @@ static s32 igb_reset_hw_82580(struct e1000_hw *hw)
/* Add delay to insure DEV_RST has time to complete */
if (global_device_reset)
- msleep(5);
+ usleep_range(5000, 6000);
ret_val = igb_get_auto_rd_done(hw);
if (ret_val) {
@@ -2436,8 +2431,7 @@ static s32 igb_update_nvm_checksum_82580(struct e1000_hw *hw)
ret_val = hw->nvm.ops.read(hw, NVM_COMPATIBILITY_REG_3, 1, &nvm_data);
if (ret_val) {
- hw_dbg("NVM Read Error while updating checksum"
- " compatibility bit.\n");
+ hw_dbg("NVM Read Error while updating checksum compatibility bit.\n");
goto out;
}
@@ -2447,8 +2441,7 @@ static s32 igb_update_nvm_checksum_82580(struct e1000_hw *hw)
ret_val = hw->nvm.ops.write(hw, NVM_COMPATIBILITY_REG_3, 1,
&nvm_data);
if (ret_val) {
- hw_dbg("NVM Write Error while updating checksum"
- " compatibility bit.\n");
+ hw_dbg("NVM Write Error while updating checksum compatibility bit.\n");
goto out;
}
}
diff --git a/drivers/net/ethernet/intel/igb/e1000_82575.h b/drivers/net/ethernet/intel/igb/e1000_82575.h
index 09d78be..b407c55 100644
--- a/drivers/net/ethernet/intel/igb/e1000_82575.h
+++ b/drivers/net/ethernet/intel/igb/e1000_82575.h
@@ -1,28 +1,25 @@
-/*******************************************************************************
-
- Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-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
-
-*******************************************************************************/
+/* Intel(R) Gigabit Ethernet Linux driver
+ * Copyright(c) 2007-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 _E1000_82575_H_
#define _E1000_82575_H_
@@ -37,9 +34,9 @@ s32 igb_write_i2c_byte(struct e1000_hw *hw, u8 byte_offset, u8 dev_addr,
u8 data);
#define ID_LED_DEFAULT_82575_SERDES ((ID_LED_DEF1_DEF2 << 12) | \
- (ID_LED_DEF1_DEF2 << 8) | \
- (ID_LED_DEF1_DEF2 << 4) | \
- (ID_LED_OFF1_ON2))
+ (ID_LED_DEF1_DEF2 << 8) | \
+ (ID_LED_DEF1_DEF2 << 4) | \
+ (ID_LED_OFF1_ON2))
#define E1000_RAR_ENTRIES_82575 16
#define E1000_RAR_ENTRIES_82576 24
@@ -67,16 +64,16 @@ s32 igb_write_i2c_byte(struct e1000_hw *hw, u8 byte_offset, u8 dev_addr,
#define E1000_MRQC_RSS_FIELD_IPV6_UDP_EX 0x01000000
#define E1000_EICR_TX_QUEUE ( \
- E1000_EICR_TX_QUEUE0 | \
- E1000_EICR_TX_QUEUE1 | \
- E1000_EICR_TX_QUEUE2 | \
- E1000_EICR_TX_QUEUE3)
+ E1000_EICR_TX_QUEUE0 | \
+ E1000_EICR_TX_QUEUE1 | \
+ E1000_EICR_TX_QUEUE2 | \
+ E1000_EICR_TX_QUEUE3)
#define E1000_EICR_RX_QUEUE ( \
- E1000_EICR_RX_QUEUE0 | \
- E1000_EICR_RX_QUEUE1 | \
- E1000_EICR_RX_QUEUE2 | \
- E1000_EICR_RX_QUEUE3)
+ E1000_EICR_RX_QUEUE0 | \
+ E1000_EICR_RX_QUEUE1 | \
+ E1000_EICR_RX_QUEUE2 | \
+ E1000_EICR_RX_QUEUE3)
/* Immediate Interrupt Rx (A.K.A. Low Latency Interrupt) */
#define E1000_IMIREXT_SIZE_BP 0x00001000 /* Packet size bypass */
@@ -92,8 +89,7 @@ union e1000_adv_rx_desc {
struct {
struct {
__le16 pkt_info; /* RSS type, Packet type */
- __le16 hdr_info; /* Split Header,
- * header buffer length */
+ __le16 hdr_info; /* Split Head, buf len */
} lo_dword;
union {
__le32 rss; /* RSS Hash */
diff --git a/drivers/net/ethernet/intel/igb/e1000_defines.h b/drivers/net/ethernet/intel/igb/e1000_defines.h
index b05bf92..f85be66 100644
--- a/drivers/net/ethernet/intel/igb/e1000_defines.h
+++ b/drivers/net/ethernet/intel/igb/e1000_defines.h
@@ -1,28 +1,25 @@
-/*******************************************************************************
-
- Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-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
-
-*******************************************************************************/
+/* Intel(R) Gigabit Ethernet Linux driver
+ * Copyright(c) 2007-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 _E1000_DEFINES_H_
#define _E1000_DEFINES_H_
@@ -101,11 +98,11 @@
/* Same mask, but for extended and packet split descriptors */
#define E1000_RXDEXT_ERR_FRAME_ERR_MASK ( \
- E1000_RXDEXT_STATERR_CE | \
- E1000_RXDEXT_STATERR_SE | \
- E1000_RXDEXT_STATERR_SEQ | \
- E1000_RXDEXT_STATERR_CXE | \
- E1000_RXDEXT_STATERR_RXE)
+ E1000_RXDEXT_STATERR_CE | \
+ E1000_RXDEXT_STATERR_SE | \
+ E1000_RXDEXT_STATERR_SEQ | \
+ E1000_RXDEXT_STATERR_CXE | \
+ E1000_RXDEXT_STATERR_RXE)
#define E1000_MRQC_RSS_FIELD_IPV4_TCP 0x00010000
#define E1000_MRQC_RSS_FIELD_IPV4 0x00020000
@@ -307,33 +304,25 @@
#define E1000_TCTL_RTLC 0x01000000 /* Re-transmit on late collision */
/* DMA Coalescing register fields */
-#define E1000_DMACR_DMACWT_MASK 0x00003FFF /* DMA Coalescing
- * Watchdog Timer */
-#define E1000_DMACR_DMACTHR_MASK 0x00FF0000 /* DMA Coalescing Receive
- * Threshold */
+#define E1000_DMACR_DMACWT_MASK 0x00003FFF /* DMA Coal Watchdog Timer */
+#define E1000_DMACR_DMACTHR_MASK 0x00FF0000 /* DMA Coal Rx Threshold */
#define E1000_DMACR_DMACTHR_SHIFT 16
-#define E1000_DMACR_DMAC_LX_MASK 0x30000000 /* Lx when no PCIe
- * transactions */
+#define E1000_DMACR_DMAC_LX_MASK 0x30000000 /* Lx when no PCIe trans */
#define E1000_DMACR_DMAC_LX_SHIFT 28
#define E1000_DMACR_DMAC_EN 0x80000000 /* Enable DMA Coalescing */
/* DMA Coalescing BMC-to-OS Watchdog Enable */
#define E1000_DMACR_DC_BMC2OSW_EN 0x00008000
-#define E1000_DMCTXTH_DMCTTHR_MASK 0x00000FFF /* DMA Coalescing Transmit
- * Threshold */
+#define E1000_DMCTXTH_DMCTTHR_MASK 0x00000FFF /* DMA Coal Tx Threshold */
#define E1000_DMCTLX_TTLX_MASK 0x00000FFF /* Time to LX request */
-#define E1000_DMCRTRH_UTRESH_MASK 0x0007FFFF /* Receive Traffic Rate
- * Threshold */
-#define E1000_DMCRTRH_LRPRCW 0x80000000 /* Rcv packet rate in
- * current window */
+#define E1000_DMCRTRH_UTRESH_MASK 0x0007FFFF /* Rx Traffic Rate Thresh */
+#define E1000_DMCRTRH_LRPRCW 0x80000000 /* Rx pkt rate curr window */
-#define E1000_DMCCNT_CCOUNT_MASK 0x01FFFFFF /* DMA Coal Rcv Traffic
- * Current Cnt */
+#define E1000_DMCCNT_CCOUNT_MASK 0x01FFFFFF /* DMA Coal Rx Current Cnt */
-#define E1000_FCRTC_RTH_COAL_MASK 0x0003FFF0 /* Flow ctrl Rcv Threshold
- * High val */
+#define E1000_FCRTC_RTH_COAL_MASK 0x0003FFF0 /* FC Rx Thresh High val */
#define E1000_FCRTC_RTH_COAL_SHIFT 4
#define E1000_PCIEMISC_LX_DECISION 0x00000080 /* Lx power decision */
@@ -406,12 +395,12 @@
* o LSC = Link Status Change
*/
#define IMS_ENABLE_MASK ( \
- E1000_IMS_RXT0 | \
- E1000_IMS_TXDW | \
- E1000_IMS_RXDMT0 | \
- E1000_IMS_RXSEQ | \
- E1000_IMS_LSC | \
- E1000_IMS_DOUTSYNC)
+ E1000_IMS_RXT0 | \
+ E1000_IMS_TXDW | \
+ E1000_IMS_RXDMT0 | \
+ E1000_IMS_RXSEQ | \
+ E1000_IMS_LSC | \
+ E1000_IMS_DOUTSYNC)
/* Interrupt Mask Set */
#define E1000_IMS_TXDW E1000_ICR_TXDW /* Transmit desc written back */
@@ -1011,8 +1000,7 @@
#define E1000_VFTA_ENTRY_BIT_SHIFT_MASK 0x1F
/* DMA Coalescing register fields */
-#define E1000_PCIEMISC_LX_DECISION 0x00000080 /* Lx power decision based
- on DMA coal */
+#define E1000_PCIEMISC_LX_DECISION 0x00000080 /* Lx power on DMA coal */
/* Tx Rate-Scheduler Config fields */
#define E1000_RTTBCNRC_RS_ENA 0x80000000
diff --git a/drivers/net/ethernet/intel/igb/e1000_hw.h b/drivers/net/ethernet/intel/igb/e1000_hw.h
index 10741d1..89925e4 100644
--- a/drivers/net/ethernet/intel/igb/e1000_hw.h
+++ b/drivers/net/ethernet/intel/igb/e1000_hw.h
@@ -1,28 +1,24 @@
-/*******************************************************************************
-
- Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-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
-
-*******************************************************************************/
+/* Intel(R) Gigabit Ethernet Linux driver
+ * Copyright(c) 2007-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,
+ *
+ * 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 _E1000_HW_H_
#define _E1000_HW_H_
@@ -320,15 +316,15 @@ struct e1000_host_mng_command_info {
#include "e1000_mbx.h"
struct e1000_mac_operations {
- s32 (*check_for_link)(struct e1000_hw *);
- s32 (*reset_hw)(struct e1000_hw *);
- s32 (*init_hw)(struct e1000_hw *);
+ s32 (*check_for_link)(struct e1000_hw *);
+ s32 (*reset_hw)(struct e1000_hw *);
+ s32 (*init_hw)(struct e1000_hw *);
bool (*check_mng_mode)(struct e1000_hw *);
- s32 (*setup_physical_interface)(struct e1000_hw *);
+ s32 (*setup_physical_interface)(struct e1000_hw *);
void (*rar_set)(struct e1000_hw *, u8 *, u32);
- s32 (*read_mac_addr)(struct e1000_hw *);
- s32 (*get_speed_and_duplex)(struct e1000_hw *, u16 *, u16 *);
- s32 (*acquire_swfw_sync)(struct e1000_hw *, u16);
+ s32 (*read_mac_addr)(struct e1000_hw *);
+ s32 (*get_speed_and_duplex)(struct e1000_hw *, u16 *, u16 *);
+ s32 (*acquire_swfw_sync)(struct e1000_hw *, u16);
void (*release_swfw_sync)(struct e1000_hw *, u16);
#ifdef CONFIG_IGB_HWMON
s32 (*get_thermal_sensor_data)(struct e1000_hw *);
@@ -338,31 +334,31 @@ struct e1000_mac_operations {
};
struct e1000_phy_operations {
- s32 (*acquire)(struct e1000_hw *);
- s32 (*check_polarity)(struct e1000_hw *);
- s32 (*check_reset_block)(struct e1000_hw *);
- s32 (*force_speed_duplex)(struct e1000_hw *);
- s32 (*get_cfg_done)(struct e1000_hw *hw);
- s32 (*get_cable_length)(struct e1000_hw *);
- s32 (*get_phy_info)(struct e1000_hw *);
- s32 (*read_reg)(struct e1000_hw *, u32, u16 *);
+ s32 (*acquire)(struct e1000_hw *);
+ s32 (*check_polarity)(struct e1000_hw *);
+ s32 (*check_reset_block)(struct e1000_hw *);
+ s32 (*force_speed_duplex)(struct e1000_hw *);
+ s32 (*get_cfg_done)(struct e1000_hw *hw);
+ s32 (*get_cable_length)(struct e1000_hw *);
+ s32 (*get_phy_info)(struct e1000_hw *);
+ s32 (*read_reg)(struct e1000_hw *, u32, u16 *);
void (*release)(struct e1000_hw *);
- s32 (*reset)(struct e1000_hw *);
- s32 (*set_d0_lplu_state)(struct e1000_hw *, bool);
- s32 (*set_d3_lplu_state)(struct e1000_hw *, bool);
- s32 (*write_reg)(struct e1000_hw *, u32, u16);
+ s32 (*reset)(struct e1000_hw *);
+ s32 (*set_d0_lplu_state)(struct e1000_hw *, bool);
+ s32 (*set_d3_lplu_state)(struct e1000_hw *, bool);
+ s32 (*write_reg)(struct e1000_hw *, u32, u16);
s32 (*read_i2c_byte)(struct e1000_hw *, u8, u8, u8 *);
s32 (*write_i2c_byte)(struct e1000_hw *, u8, u8, u8);
};
struct e1000_nvm_operations {
- s32 (*acquire)(struct e1000_hw *);
- s32 (*read)(struct e1000_hw *, u16, u16, u16 *);
+ s32 (*acquire)(struct e1000_hw *);
+ s32 (*read)(struct e1000_hw *, u16, u16, u16 *);
void (*release)(struct e1000_hw *);
- s32 (*write)(struct e1000_hw *, u16, u16, u16 *);
- s32 (*update)(struct e1000_hw *);
- s32 (*validate)(struct e1000_hw *);
- s32 (*valid_led_default)(struct e1000_hw *, u16 *);
+ s32 (*write)(struct e1000_hw *, u16, u16, u16 *);
+ s32 (*update)(struct e1000_hw *);
+ s32 (*validate)(struct e1000_hw *);
+ s32 (*valid_led_default)(struct e1000_hw *, u16 *);
};
#define E1000_MAX_SENSORS 3
diff --git a/drivers/net/ethernet/intel/igb/e1000_i210.c b/drivers/net/ethernet/intel/igb/e1000_i210.c
index db96339..2231598 100644
--- a/drivers/net/ethernet/intel/igb/e1000_i210.c
+++ b/drivers/net/ethernet/intel/igb/e1000_i210.c
@@ -1,28 +1,25 @@
-/*******************************************************************************
-
- Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-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
-
-******************************************************************************/
+/* Intel(R) Gigabit Ethernet Linux driver
+ * Copyright(c) 2007-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
+ */
/* e1000_i210
* e1000_i211
@@ -365,7 +362,7 @@ static s32 igb_read_invm_word_i210(struct e1000_hw *hw, u8 address, u16 *data)
word_address = INVM_DWORD_TO_WORD_ADDRESS(invm_dword);
if (word_address == address) {
*data = INVM_DWORD_TO_WORD_DATA(invm_dword);
- hw_dbg("Read INVM Word 0x%02x = %x",
+ hw_dbg("Read INVM Word 0x%02x = %x\n",
address, *data);
status = E1000_SUCCESS;
break;
@@ -435,6 +432,7 @@ static s32 igb_read_invm_i210(struct e1000_hw *hw, u16 offset,
*data = ID_LED_RESERVED_FFFF;
ret_val = E1000_SUCCESS;
}
+ break;
case NVM_SUB_DEV_ID:
*data = hw->subsystem_device_id;
break;
diff --git a/drivers/net/ethernet/intel/igb/e1000_i210.h b/drivers/net/ethernet/intel/igb/e1000_i210.h
index 907fe99..9f34976 100644
--- a/drivers/net/ethernet/intel/igb/e1000_i210.h
+++ b/drivers/net/ethernet/intel/igb/e1000_i210.h
@@ -1,28 +1,25 @@
-/*******************************************************************************
-
- Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-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
-
-*******************************************************************************/
+/* Intel(R) Gigabit Ethernet Linux driver
+ * Copyright(c) 2007-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 _E1000_I210_H_
#define _E1000_I210_H_
diff --git a/drivers/net/ethernet/intel/igb/e1000_mac.c b/drivers/net/ethernet/intel/igb/e1000_mac.c
index 5910a93..2a88595 100644
--- a/drivers/net/ethernet/intel/igb/e1000_mac.c
+++ b/drivers/net/ethernet/intel/igb/e1000_mac.c
@@ -1,28 +1,25 @@
-/*******************************************************************************
-
- Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-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
-
-*******************************************************************************/
+/* Intel(R) Gigabit Ethernet Linux driver
+ * Copyright(c) 2007-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 <linux/delay.h>
@@ -442,7 +439,7 @@ static u32 igb_hash_mc_addr(struct e1000_hw *hw, u8 *mc_addr)
* The caller must have a packed mc_addr_list of multicast addresses.
**/
void igb_update_mc_addr_list(struct e1000_hw *hw,
- u8 *mc_addr_list, u32 mc_addr_count)
+ u8 *mc_addr_list, u32 mc_addr_count)
{
u32 hash_value, hash_bit, hash_reg;
int i;
@@ -866,8 +863,7 @@ s32 igb_config_fc_after_link_up(struct e1000_hw *hw)
goto out;
if (!(mii_status_reg & MII_SR_AUTONEG_COMPLETE)) {
- hw_dbg("Copper PHY and Auto Neg "
- "has not completed.\n");
+ hw_dbg("Copper PHY and Auto Neg has not completed.\n");
goto out;
}
@@ -929,11 +925,10 @@ s32 igb_config_fc_after_link_up(struct e1000_hw *hw)
*/
if (hw->fc.requested_mode == e1000_fc_full) {
hw->fc.current_mode = e1000_fc_full;
- hw_dbg("Flow Control = FULL.\r\n");
+ hw_dbg("Flow Control = FULL.\n");
} else {
hw->fc.current_mode = e1000_fc_rx_pause;
- hw_dbg("Flow Control = "
- "RX PAUSE frames only.\r\n");
+ hw_dbg("Flow Control = RX PAUSE frames only.\n");
}
}
/* For receiving PAUSE frames ONLY.
@@ -948,7 +943,7 @@ s32 igb_config_fc_after_link_up(struct e1000_hw *hw)
(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
(mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
hw->fc.current_mode = e1000_fc_tx_pause;
- hw_dbg("Flow Control = TX PAUSE frames only.\r\n");
+ hw_dbg("Flow Control = TX PAUSE frames only.\n");
}
/* For transmitting PAUSE frames ONLY.
*
@@ -962,7 +957,7 @@ s32 igb_config_fc_after_link_up(struct e1000_hw *hw)
!(mii_nway_lp_ability_reg & NWAY_LPAR_PAUSE) &&
(mii_nway_lp_ability_reg & NWAY_LPAR_ASM_DIR)) {
hw->fc.current_mode = e1000_fc_rx_pause;
- hw_dbg("Flow Control = RX PAUSE frames only.\r\n");
+ hw_dbg("Flow Control = RX PAUSE frames only.\n");
}
/* Per the IEEE spec, at this point flow control should be
* disabled. However, we want to consider that we could
@@ -988,10 +983,10 @@ s32 igb_config_fc_after_link_up(struct e1000_hw *hw)
(hw->fc.requested_mode == e1000_fc_tx_pause) ||
(hw->fc.strict_ieee)) {
hw->fc.current_mode = e1000_fc_none;
- hw_dbg("Flow Control = NONE.\r\n");
+ hw_dbg("Flow Control = NONE.\n");
} else {
hw->fc.current_mode = e1000_fc_rx_pause;
- hw_dbg("Flow Control = RX PAUSE frames only.\r\n");
+ hw_dbg("Flow Control = RX PAUSE frames only.\n");
}
/* Now we need to do one last check... If we auto-
@@ -1266,7 +1261,7 @@ s32 igb_get_auto_rd_done(struct e1000_hw *hw)
while (i < AUTO_READ_DONE_TIMEOUT) {
if (rd32(E1000_EECD) & E1000_EECD_AUTO_RD)
break;
- msleep(1);
+ usleep_range(1000, 2000);
i++;
}
@@ -1299,7 +1294,7 @@ static s32 igb_valid_led_default(struct e1000_hw *hw, u16 *data)
}
if (*data == ID_LED_RESERVED_0000 || *data == ID_LED_RESERVED_FFFF) {
- switch(hw->phy.media_type) {
+ switch (hw->phy.media_type) {
case e1000_media_type_internal_serdes:
*data = ID_LED_DEFAULT_82575_SERDES;
break;
diff --git a/drivers/net/ethernet/intel/igb/e1000_mac.h b/drivers/net/ethernet/intel/igb/e1000_mac.h
index 99299ba..ea24961b 100644
--- a/drivers/net/ethernet/intel/igb/e1000_mac.h
+++ b/drivers/net/ethernet/intel/igb/e1000_mac.h
@@ -1,28 +1,25 @@
-/*******************************************************************************
-
- Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-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
-
-*******************************************************************************/
+/* Intel(R) Gigabit Ethernet Linux driver
+ * Copyright(c) 2007-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 _E1000_MAC_H_
#define _E1000_MAC_H_
diff --git a/drivers/net/ethernet/intel/igb/e1000_mbx.c b/drivers/net/ethernet/intel/igb/e1000_mbx.c
index d5b1217..162cc49 100644
--- a/drivers/net/ethernet/intel/igb/e1000_mbx.c
+++ b/drivers/net/ethernet/intel/igb/e1000_mbx.c
@@ -1,28 +1,25 @@
-/*******************************************************************************
-
- Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-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
-
-*******************************************************************************/
+/* Intel(R) Gigabit Ethernet Linux driver
+ * Copyright(c) 2007-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 "e1000_mbx.h"
diff --git a/drivers/net/ethernet/intel/igb/e1000_mbx.h b/drivers/net/ethernet/intel/igb/e1000_mbx.h
index f52f551..d20af6b 100644
--- a/drivers/net/ethernet/intel/igb/e1000_mbx.h
+++ b/drivers/net/ethernet/intel/igb/e1000_mbx.h
@@ -1,28 +1,25 @@
-/*******************************************************************************
-
- Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-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
-
-*******************************************************************************/
+/* Intel(R) Gigabit Ethernet Linux driver
+ * Copyright(c) 2007-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 _E1000_MBX_H_
#define _E1000_MBX_H_
diff --git a/drivers/net/ethernet/intel/igb/e1000_nvm.c b/drivers/net/ethernet/intel/igb/e1000_nvm.c
index 9abf829..92bcdbe 100644
--- a/drivers/net/ethernet/intel/igb/e1000_nvm.c
+++ b/drivers/net/ethernet/intel/igb/e1000_nvm.c
@@ -1,28 +1,24 @@
-/*******************************************************************************
-
- Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-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
-
-*******************************************************************************/
+/* Intel(R) Gigabit Ethernet Linux driver
+ * Copyright(c) 2007-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 <linux/delay.h>
@@ -480,6 +476,7 @@ s32 igb_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data)
/* Loop to allow for up to whole page write of eeprom */
while (widx < words) {
u16 word_out = data[widx];
+
word_out = (word_out >> 8) | (word_out << 8);
igb_shift_out_eec_bits(hw, word_out, 16);
widx++;
diff --git a/drivers/net/ethernet/intel/igb/e1000_nvm.h b/drivers/net/ethernet/intel/igb/e1000_nvm.h
index 5b10117..febc9cd 100644
--- a/drivers/net/ethernet/intel/igb/e1000_nvm.h
+++ b/drivers/net/ethernet/intel/igb/e1000_nvm.h
@@ -1,28 +1,25 @@
-/*******************************************************************************
-
- Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-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
-
-*******************************************************************************/
+/* Intel(R) Gigabit Ethernet Linux driver
+ * Copyright(c) 2007-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 _E1000_NVM_H_
#define _E1000_NVM_H_
@@ -32,7 +29,7 @@ void igb_release_nvm(struct e1000_hw *hw);
s32 igb_read_mac_addr(struct e1000_hw *hw);
s32 igb_read_part_num(struct e1000_hw *hw, u32 *part_num);
s32 igb_read_part_string(struct e1000_hw *hw, u8 *part_num,
- u32 part_num_size);
+ u32 part_num_size);
s32 igb_read_nvm_eerd(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
s32 igb_read_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
s32 igb_write_nvm_spi(struct e1000_hw *hw, u16 offset, u16 words, u16 *data);
diff --git a/drivers/net/ethernet/intel/igb/e1000_phy.c b/drivers/net/ethernet/intel/igb/e1000_phy.c
index 4009bba..424f16c 100644
--- a/drivers/net/ethernet/intel/igb/e1000_phy.c
+++ b/drivers/net/ethernet/intel/igb/e1000_phy.c
@@ -1,28 +1,25 @@
-/*******************************************************************************
-
- Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-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
-
-*******************************************************************************/
+/* Intel(R) Gigabit Ethernet Linux driver
+ * Copyright(c) 2007-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 <linux/delay.h>
@@ -924,8 +921,7 @@ static s32 igb_copper_link_autoneg(struct e1000_hw *hw)
if (phy->autoneg_wait_to_complete) {
ret_val = igb_wait_autoneg(hw);
if (ret_val) {
- hw_dbg("Error while waiting for "
- "autoneg to complete\n");
+ hw_dbg("Error while waiting for autoneg to complete\n");
goto out;
}
}
@@ -2244,7 +2240,7 @@ void igb_power_down_phy_copper(struct e1000_hw *hw)
hw->phy.ops.write_reg(hw, GS40G_COPPER_SPEC, power_reg);
}
hw->phy.ops.write_reg(hw, PHY_CONTROL, mii_reg);
- msleep(1);
+ usleep_range(1000, 2000);
}
/**
diff --git a/drivers/net/ethernet/intel/igb/e1000_phy.h b/drivers/net/ethernet/intel/igb/e1000_phy.h
index 4c2c36c..fe921e2 100644
--- a/drivers/net/ethernet/intel/igb/e1000_phy.h
+++ b/drivers/net/ethernet/intel/igb/e1000_phy.h
@@ -1,28 +1,25 @@
-/*******************************************************************************
-
- Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-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
-
-*******************************************************************************/
+/* Intel(R) Gigabit Ethernet Linux driver
+ * Copyright(c) 2007-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 _E1000_PHY_H_
#define _E1000_PHY_H_
diff --git a/drivers/net/ethernet/intel/igb/e1000_regs.h b/drivers/net/ethernet/intel/igb/e1000_regs.h
index bdb246e..833bbb9 100644
--- a/drivers/net/ethernet/intel/igb/e1000_regs.h
+++ b/drivers/net/ethernet/intel/igb/e1000_regs.h
@@ -1,28 +1,25 @@
-/*******************************************************************************
-
- Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-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
-
-*******************************************************************************/
+/* Intel(R) Gigabit Ethernet Linux driver
+ * Copyright(c) 2007-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 _E1000_REGS_H_
#define _E1000_REGS_H_
@@ -301,9 +298,9 @@
#define E1000_RA2 0x054E0 /* 2nd half of Rx address array - RW Array */
#define E1000_PSRTYPE(_i) (0x05480 + ((_i) * 4))
#define E1000_RAL(_i) (((_i) <= 15) ? (0x05400 + ((_i) * 8)) : \
- (0x054E0 + ((_i - 16) * 8)))
+ (0x054E0 + ((_i - 16) * 8)))
#define E1000_RAH(_i) (((_i) <= 15) ? (0x05404 + ((_i) * 8)) : \
- (0x054E4 + ((_i - 16) * 8)))
+ (0x054E4 + ((_i - 16) * 8)))
#define E1000_IP4AT_REG(_i) (0x05840 + ((_i) * 8))
#define E1000_IP6AT_REG(_i) (0x05880 + ((_i) * 4))
#define E1000_WUPM_REG(_i) (0x05A00 + ((_i) * 4))
@@ -358,8 +355,7 @@
#define E1000_VMBMEM(_n) (0x00800 + (64 * (_n)))
#define E1000_VMOLR(_n) (0x05AD0 + (4 * (_n)))
#define E1000_DVMOLR(_n) (0x0C038 + (64 * (_n)))
-#define E1000_VLVF(_n) (0x05D00 + (4 * (_n))) /* VLAN Virtual Machine
- * Filter - RW */
+#define E1000_VLVF(_n) (0x05D00 + (4 * (_n))) /* VLAN VM Filter */
#define E1000_VMVIR(_n) (0x03700 + (4 * (_n)))
struct e1000_hw;
diff --git a/drivers/net/ethernet/intel/igb/igb.h b/drivers/net/ethernet/intel/igb/igb.h
index 2713006..06102d1 100644
--- a/drivers/net/ethernet/intel/igb/igb.h
+++ b/drivers/net/ethernet/intel/igb/igb.h
@@ -1,29 +1,25 @@
-/*******************************************************************************
-
- Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-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
-
-*******************************************************************************/
-
+/* Intel(R) Gigabit Ethernet Linux driver
+ * Copyright(c) 2007-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
+ */
/* Linux PRO/1000 Ethernet Driver main header file */
@@ -198,6 +194,7 @@ struct igb_tx_buffer {
unsigned int bytecount;
u16 gso_segs;
__be16 protocol;
+
DEFINE_DMA_UNMAP_ADDR(dma);
DEFINE_DMA_UNMAP_LEN(len);
u32 tx_flags;
diff --git a/drivers/net/ethernet/intel/igb/igb_ethtool.c b/drivers/net/ethernet/intel/igb/igb_ethtool.c
index e5570ac..333a2b0 100644
--- a/drivers/net/ethernet/intel/igb/igb_ethtool.c
+++ b/drivers/net/ethernet/intel/igb/igb_ethtool.c
@@ -1,28 +1,25 @@
-/*******************************************************************************
-
- Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-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
-
-*******************************************************************************/
+/* Intel(R) Gigabit Ethernet Linux driver
+ * Copyright(c) 2007-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
+ */
/* ethtool support for igb */
@@ -286,7 +283,7 @@ static int igb_set_settings(struct net_device *netdev, struct ethtool_cmd *ecmd)
}
while (test_and_set_bit(__IGB_RESETTING, &adapter->state))
- msleep(1);
+ usleep_range(1000, 2000);
if (ecmd->autoneg == AUTONEG_ENABLE) {
hw->mac.autoneg = 1;
@@ -399,7 +396,7 @@ static int igb_set_pauseparam(struct net_device *netdev,
adapter->fc_autoneg = pause->autoneg;
while (test_and_set_bit(__IGB_RESETTING, &adapter->state))
- msleep(1);
+ usleep_range(1000, 2000);
if (adapter->fc_autoneg == AUTONEG_ENABLE) {
hw->fc.requested_mode = e1000_fc_default;
@@ -886,7 +883,7 @@ static int igb_set_ringparam(struct net_device *netdev,
}
while (test_and_set_bit(__IGB_RESETTING, &adapter->state))
- msleep(1);
+ usleep_range(1000, 2000);
if (!netif_running(adapter->netdev)) {
for (i = 0; i < adapter->num_tx_queues; i++)
@@ -1060,8 +1057,8 @@ static struct igb_reg_test reg_test_i350[] = {
{ E1000_TDT(0), 0x100, 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
{ E1000_TDT(4), 0x40, 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
{ E1000_RCTL, 0x100, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 },
- { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB0FE, 0x003FFFFB },
- { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB0FE, 0xFFFFFFFF },
+ { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB0FE, 0x003FFFFB },
+ { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB0FE, 0xFFFFFFFF },
{ E1000_TCTL, 0x100, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 },
{ E1000_RA, 0, 16, TABLE64_TEST_LO,
0xFFFFFFFF, 0xFFFFFFFF },
@@ -1103,8 +1100,8 @@ static struct igb_reg_test reg_test_82580[] = {
{ E1000_TDT(0), 0x100, 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
{ E1000_TDT(4), 0x40, 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
{ E1000_RCTL, 0x100, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 },
- { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB0FE, 0x003FFFFB },
- { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB0FE, 0xFFFFFFFF },
+ { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB0FE, 0x003FFFFB },
+ { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB0FE, 0xFFFFFFFF },
{ E1000_TCTL, 0x100, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 },
{ E1000_RA, 0, 16, TABLE64_TEST_LO,
0xFFFFFFFF, 0xFFFFFFFF },
@@ -1132,8 +1129,10 @@ static struct igb_reg_test reg_test_82576[] = {
{ E1000_RDBAH(4), 0x40, 12, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
{ E1000_RDLEN(4), 0x40, 12, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF },
/* Enable all RX queues before testing. */
- { E1000_RXDCTL(0), 0x100, 4, WRITE_NO_TEST, 0, E1000_RXDCTL_QUEUE_ENABLE },
- { E1000_RXDCTL(4), 0x40, 12, WRITE_NO_TEST, 0, E1000_RXDCTL_QUEUE_ENABLE },
+ { E1000_RXDCTL(0), 0x100, 4, WRITE_NO_TEST, 0,
+ E1000_RXDCTL_QUEUE_ENABLE },
+ { E1000_RXDCTL(4), 0x40, 12, WRITE_NO_TEST, 0,
+ E1000_RXDCTL_QUEUE_ENABLE },
/* RDH is read-only for 82576, only test RDT. */
{ E1000_RDT(0), 0x100, 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
{ E1000_RDT(4), 0x40, 12, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
@@ -1149,14 +1148,14 @@ static struct igb_reg_test reg_test_82576[] = {
{ E1000_TDBAH(4), 0x40, 12, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
{ E1000_TDLEN(4), 0x40, 12, PATTERN_TEST, 0x000FFFF0, 0x000FFFFF },
{ E1000_RCTL, 0x100, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 },
- { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB0FE, 0x003FFFFB },
- { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB0FE, 0xFFFFFFFF },
+ { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB0FE, 0x003FFFFB },
+ { E1000_RCTL, 0x100, 1, SET_READ_TEST, 0x04CFB0FE, 0xFFFFFFFF },
{ E1000_TCTL, 0x100, 1, SET_READ_TEST, 0xFFFFFFFF, 0x00000000 },
{ E1000_RA, 0, 16, TABLE64_TEST_LO, 0xFFFFFFFF, 0xFFFFFFFF },
{ E1000_RA, 0, 16, TABLE64_TEST_HI, 0x83FFFFFF, 0xFFFFFFFF },
{ E1000_RA2, 0, 8, TABLE64_TEST_LO, 0xFFFFFFFF, 0xFFFFFFFF },
{ E1000_RA2, 0, 8, TABLE64_TEST_HI, 0x83FFFFFF, 0xFFFFFFFF },
- { E1000_MTA, 0, 128,TABLE32_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
+ { E1000_MTA, 0, 128, TABLE32_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
{ 0, 0, 0, 0 }
};
@@ -1170,7 +1169,8 @@ static struct igb_reg_test reg_test_82575[] = {
{ E1000_RDBAH(0), 0x100, 4, PATTERN_TEST, 0xFFFFFFFF, 0xFFFFFFFF },
{ E1000_RDLEN(0), 0x100, 4, PATTERN_TEST, 0x000FFF80, 0x000FFFFF },
/* Enable all four RX queues before testing. */
- { E1000_RXDCTL(0), 0x100, 4, WRITE_NO_TEST, 0, E1000_RXDCTL_QUEUE_ENABLE },
+ { E1000_RXDCTL(0), 0x100, 4, WRITE_NO_TEST, 0,
+ E1000_RXDCTL_QUEUE_ENABLE },
/* RDH is read-only for 82575, only test RDT. */
{ E1000_RDT(0), 0x100, 4, PATTERN_TEST, 0x0000FFFF, 0x0000FFFF },
{ E1000_RXDCTL(0), 0x100, 4, WRITE_NO_TEST, 0, 0 },
@@ -1196,8 +1196,8 @@ static bool reg_pattern_test(struct igb_adapter *adapter, u64 *data,
{
struct e1000_hw *hw = &adapter->hw;
u32 pat, val;
- static const u32 _test[] =
- {0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF};
+ static const u32 _test[] = {
+ 0x5A5A5A5A, 0xA5A5A5A5, 0x00000000, 0xFFFFFFFF};
for (pat = 0; pat < ARRAY_SIZE(_test); pat++) {
wr32(reg, (_test[pat] & write));
val = rd32(reg) & mask;
@@ -1206,11 +1206,11 @@ static bool reg_pattern_test(struct igb_adapter *adapter, u64 *data,
"pattern test reg %04X failed: got 0x%08X expected 0x%08X\n",
reg, val, (_test[pat] & write & mask));
*data = reg;
- return 1;
+ return true;
}
}
- return 0;
+ return false;
}
static bool reg_set_and_check(struct igb_adapter *adapter, u64 *data,
@@ -1218,17 +1218,18 @@ static bool reg_set_and_check(struct igb_adapter *adapter, u64 *data,
{
struct e1000_hw *hw = &adapter->hw;
u32 val;
+
wr32(reg, write & mask);
val = rd32(reg);
if ((write & mask) != (val & mask)) {
dev_err(&adapter->pdev->dev,
- "set/check reg %04X test failed: got 0x%08X expected 0x%08X\n", reg,
- (val & mask), (write & mask));
+ "set/check reg %04X test failed: got 0x%08X expected 0x%08X\n",
+ reg, (val & mask), (write & mask));
*data = reg;
- return 1;
+ return true;
}
- return 0;
+ return false;
}
#define REG_PATTERN_TEST(reg, mask, write) \
@@ -1387,14 +1388,14 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data)
/* Hook up test interrupt handler just for this test */
if (adapter->flags & IGB_FLAG_HAS_MSIX) {
if (request_irq(adapter->msix_entries[0].vector,
- igb_test_intr, 0, netdev->name, adapter)) {
+ igb_test_intr, 0, netdev->name, adapter)) {
*data = 1;
return -1;
}
} else if (adapter->flags & IGB_FLAG_HAS_MSI) {
shared_int = false;
if (request_irq(irq,
- igb_test_intr, 0, netdev->name, adapter)) {
+ igb_test_intr, 0, netdev->name, adapter)) {
*data = 1;
return -1;
}
@@ -1412,7 +1413,7 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data)
/* Disable all the interrupts */
wr32(E1000_IMC, ~0);
wrfl();
- msleep(10);
+ usleep_range(10000, 11000);
/* Define all writable bits for ICS */
switch (hw->mac.type) {
@@ -1459,7 +1460,7 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data)
wr32(E1000_IMC, mask);
wr32(E1000_ICS, mask);
wrfl();
- msleep(10);
+ usleep_range(10000, 11000);
if (adapter->test_icr & mask) {
*data = 3;
@@ -1481,7 +1482,7 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data)
wr32(E1000_IMS, mask);
wr32(E1000_ICS, mask);
wrfl();
- msleep(10);
+ usleep_range(10000, 11000);
if (!(adapter->test_icr & mask)) {
*data = 4;
@@ -1503,7 +1504,7 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data)
wr32(E1000_IMC, ~mask);
wr32(E1000_ICS, ~mask);
wrfl();
- msleep(10);
+ usleep_range(10000, 11000);
if (adapter->test_icr & mask) {
*data = 5;
@@ -1515,7 +1516,7 @@ static int igb_intr_test(struct igb_adapter *adapter, u64 *data)
/* Disable all the interrupts */
wr32(E1000_IMC, ~0);
wrfl();
- msleep(10);
+ usleep_range(10000, 11000);
/* Unhook test interrupt handler */
if (adapter->flags & IGB_FLAG_HAS_MSIX)
@@ -1949,6 +1950,7 @@ static int igb_link_test(struct igb_adapter *adapter, u64 *data)
*data = 0;
if (hw->phy.media_type == e1000_media_type_internal_serdes) {
int i = 0;
+
hw->mac.serdes_has_link = false;
/* On some blade server designs, link establishment
@@ -2413,9 +2415,11 @@ static int igb_get_rss_hash_opts(struct igb_adapter *adapter,
switch (cmd->flow_type) {
case TCP_V4_FLOW:
cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
+ /* Fall through */
case UDP_V4_FLOW:
if (adapter->flags & IGB_FLAG_RSS_FIELD_IPV4_UDP)
cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
+ /* Fall through */
case SCTP_V4_FLOW:
case AH_ESP_V4_FLOW:
case AH_V4_FLOW:
@@ -2425,9 +2429,11 @@ static int igb_get_rss_hash_opts(struct igb_adapter *adapter,
break;
case TCP_V6_FLOW:
cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
+ /* Fall through */
case UDP_V6_FLOW:
if (adapter->flags & IGB_FLAG_RSS_FIELD_IPV6_UDP)
cmd->data |= RXH_L4_B_0_1 | RXH_L4_B_2_3;
+ /* Fall through */
case SCTP_V6_FLOW:
case AH_ESP_V6_FLOW:
case AH_V6_FLOW:
diff --git a/drivers/net/ethernet/intel/igb/igb_hwmon.c b/drivers/net/ethernet/intel/igb/igb_hwmon.c
index 8333f67..44b6a68 100644
--- a/drivers/net/ethernet/intel/igb/igb_hwmon.c
+++ b/drivers/net/ethernet/intel/igb/igb_hwmon.c
@@ -1,28 +1,25 @@
-/*******************************************************************************
-
- Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-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
-
-*******************************************************************************/
+/* Intel(R) Gigabit Ethernet Linux driver
+ * Copyright(c) 2007-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 "igb.h"
#include "e1000_82575.h"
diff --git a/drivers/net/ethernet/intel/igb/igb_main.c b/drivers/net/ethernet/intel/igb/igb_main.c
index fb98d46..bfcda8a 100644
--- a/drivers/net/ethernet/intel/igb/igb_main.c
+++ b/drivers/net/ethernet/intel/igb/igb_main.c
@@ -1,28 +1,25 @@
-/*******************************************************************************
-
- Intel(R) Gigabit Ethernet Linux driver
- Copyright(c) 2007-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
-
-*******************************************************************************/
+/* Intel(R) Gigabit Ethernet Linux driver
+ * Copyright(c) 2007-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
+ */
#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@@ -75,7 +72,7 @@ static const struct e1000_info *igb_info_tbl[] = {
[board_82575] = &e1000_82575_info,
};
-static DEFINE_PCI_DEVICE_TABLE(igb_pci_tbl) = {
+static const struct pci_device_id igb_pci_tbl[] = {
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_I354_BACKPLANE_1GBPS) },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_I354_SGMII) },
{ PCI_VDEVICE(INTEL, E1000_DEV_ID_I354_BACKPLANE_2_5GBPS) },
@@ -117,7 +114,6 @@ static DEFINE_PCI_DEVICE_TABLE(igb_pci_tbl) = {
MODULE_DEVICE_TABLE(pci, igb_pci_tbl);
-void igb_reset(struct igb_adapter *);
static int igb_setup_all_tx_resources(struct igb_adapter *);
static int igb_setup_all_rx_resources(struct igb_adapter *);
static void igb_free_all_tx_resources(struct igb_adapter *);
@@ -141,7 +137,7 @@ static void igb_watchdog(unsigned long);
static void igb_watchdog_task(struct work_struct *);
static netdev_tx_t igb_xmit_frame(struct sk_buff *skb, struct net_device *);
static struct rtnl_link_stats64 *igb_get_stats64(struct net_device *dev,
- struct rtnl_link_stats64 *stats);
+ struct rtnl_link_stats64 *stats);
static int igb_change_mtu(struct net_device *, int);
static int igb_set_mac(struct net_device *, void *);
static void igb_set_uta(struct igb_adapter *adapter);
@@ -159,7 +155,8 @@ static bool igb_clean_rx_irq(struct igb_q_vector *, int);
static int igb_ioctl(struct net_device *, struct ifreq *, int cmd);
static void igb_tx_timeout(struct net_device *);
static void igb_reset_task(struct work_struct *);
-static void igb_vlan_mode(struct net_device *netdev, netdev_features_t features);
+static void igb_vlan_mode(struct net_device *netdev,
+ netdev_features_t features);
static int igb_vlan_rx_add_vid(struct net_device *, __be16, u16);
static int igb_vlan_rx_kill_vid(struct net_device *, __be16, u16);
static void igb_restore_vlan(struct igb_adapter *);
@@ -215,10 +212,9 @@ static struct notifier_block dca_notifier = {
static void igb_netpoll(struct net_device *);
#endif
#ifdef CONFIG_PCI_IOV
-static unsigned int max_vfs = 0;
+static unsigned int max_vfs;
module_param(max_vfs, uint, 0);
-MODULE_PARM_DESC(max_vfs, "Maximum number of virtual functions to allocate "
- "per physical function");
+MODULE_PARM_DESC(max_vfs, "Maximum number of virtual functions to allocate per physical function");
#endif /* CONFIG_PCI_IOV */
static pci_ers_result_t igb_io_error_detected(struct pci_dev *,
@@ -384,8 +380,7 @@ static void igb_dump(struct igb_adapter *adapter)
/* Print netdevice Info */
if (netdev) {
dev_info(&adapter->pdev->dev, "Net device Info\n");
- pr_info("Device Name state trans_start "
- "last_rx\n");
+ pr_info("Device Name state trans_start last_rx\n");
pr_info("%-15s %016lX %016lX %016lX\n", netdev->name,
netdev->state, netdev->trans_start, netdev->last_rx);
}
@@ -438,9 +433,7 @@ static void igb_dump(struct igb_adapter *adapter)
pr_info("------------------------------------\n");
pr_info("TX QUEUE INDEX = %d\n", tx_ring->queue_index);
pr_info("------------------------------------\n");
- pr_info("T [desc] [address 63:0 ] [PlPOCIStDDM Ln] "
- "[bi->dma ] leng ntw timestamp "
- "bi->skb\n");
+ pr_info("T [desc] [address 63:0 ] [PlPOCIStDDM Ln] [bi->dma ] leng ntw timestamp bi->skb\n");
for (i = 0; tx_ring->desc && (i < tx_ring->count); i++) {
const char *next_desc;
@@ -458,9 +451,8 @@ static void igb_dump(struct igb_adapter *adapter)
else
next_desc = "";
- pr_info("T [0x%03X] %016llX %016llX %016llX"
- " %04X %p %016llX %p%s\n", i,
- le64_to_cpu(u0->a),
+ pr_info("T [0x%03X] %016llX %016llX %016llX %04X %p %016llX %p%s\n",
+ i, le64_to_cpu(u0->a),
le64_to_cpu(u0->b),
(u64)dma_unmap_addr(buffer_info, dma),
dma_unmap_len(buffer_info, len),
@@ -519,10 +511,8 @@ rx_ring_summary:
pr_info("------------------------------------\n");
pr_info("RX QUEUE INDEX = %d\n", rx_ring->queue_index);
pr_info("------------------------------------\n");
- pr_info("R [desc] [ PktBuf A0] [ HeadBuf DD] "
- "[bi->dma ] [bi->skb] <-- Adv Rx Read format\n");
- pr_info("RWB[desc] [PcsmIpSHl PtRs] [vl er S cks ln] -----"
- "----------- [bi->skb] <-- Adv Rx Write-Back format\n");
+ pr_info("R [desc] [ PktBuf A0] [ HeadBuf DD] [bi->dma ] [bi->skb] <-- Adv Rx Read format\n");
+ pr_info("RWB[desc] [PcsmIpSHl PtRs] [vl er S cks ln] ---------------- [bi->skb] <-- Adv Rx Write-Back format\n");
for (i = 0; i < rx_ring->count; i++) {
const char *next_desc;
@@ -584,7 +574,7 @@ static int igb_get_i2c_data(void *data)
struct e1000_hw *hw = &adapter->hw;
s32 i2cctl = rd32(E1000_I2CPARAMS);
- return ((i2cctl & E1000_I2C_DATA_IN) != 0);
+ return !!(i2cctl & E1000_I2C_DATA_IN);
}
/**
@@ -648,7 +638,7 @@ static int igb_get_i2c_clk(void *data)
struct e1000_hw *hw = &adapter->hw;
s32 i2cctl = rd32(E1000_I2CPARAMS);
- return ((i2cctl & E1000_I2C_CLK_IN) != 0);
+ return !!(i2cctl & E1000_I2C_CLK_IN);
}
static const struct i2c_algo_bit_data igb_i2c_algo = {
@@ -681,9 +671,9 @@ struct net_device *igb_get_hw_dev(struct e1000_hw *hw)
static int __init igb_init_module(void)
{
int ret;
+
pr_info("%s - version %s\n",
igb_driver_string, igb_driver_version);
-
pr_info("%s\n", igb_copyright);
#ifdef CONFIG_IGB_DCA
@@ -736,12 +726,14 @@ static void igb_cache_ring_register(struct igb_adapter *adapter)
adapter->rx_ring[i]->reg_idx = rbase_offset +
Q_IDX_82576(i);
}
+ /* Fall through */
case e1000_82575:
case e1000_82580:
case e1000_i350:
case e1000_i354:
case e1000_i210:
case e1000_i211:
+ /* Fall through */
default:
for (; i < adapter->num_rx_queues; i++)
adapter->rx_ring[i]->reg_idx = rbase_offset + i;
@@ -1292,8 +1284,7 @@ static int igb_alloc_q_vector(struct igb_adapter *adapter,
if (adapter->hw.mac.type >= e1000_82576)
set_bit(IGB_RING_FLAG_RX_SCTP_CSUM, &ring->flags);
- /*
- * On i350, i354, i210, and i211, loopback VLAN packets
+ /* On i350, i354, i210, and i211, loopback VLAN packets
* have the tag byte-swapped.
*/
if (adapter->hw.mac.type >= e1000_i350)
@@ -1345,6 +1336,7 @@ static int igb_alloc_q_vectors(struct igb_adapter *adapter)
for (; v_idx < q_vectors; v_idx++) {
int rqpv = DIV_ROUND_UP(rxr_remaining, q_vectors - v_idx);
int tqpv = DIV_ROUND_UP(txr_remaining, q_vectors - v_idx);
+
err = igb_alloc_q_vector(adapter, q_vectors, v_idx,
tqpv, txr_idx, rqpv, rxr_idx);
@@ -1484,6 +1476,7 @@ static void igb_irq_disable(struct igb_adapter *adapter)
*/
if (adapter->flags & IGB_FLAG_HAS_MSIX) {
u32 regval = rd32(E1000_EIAM);
+
wr32(E1000_EIAM, regval & ~adapter->eims_enable_mask);
wr32(E1000_EIMC, adapter->eims_enable_mask);
regval = rd32(E1000_EIAC);
@@ -1495,6 +1488,7 @@ static void igb_irq_disable(struct igb_adapter *adapter)
wrfl();
if (adapter->flags & IGB_FLAG_HAS_MSIX) {
int i;
+
for (i = 0; i < adapter->num_q_vectors; i++)
synchronize_irq(adapter->msix_entries[i].vector);
} else {
@@ -1513,6 +1507,7 @@ static void igb_irq_enable(struct igb_adapter *adapter)
if (adapter->flags & IGB_FLAG_HAS_MSIX) {
u32 ims = E1000_IMS_LSC | E1000_IMS_DOUTSYNC | E1000_IMS_DRSTA;
u32 regval = rd32(E1000_EIAC);
+
wr32(E1000_EIAC, regval | adapter->eims_enable_mask);
regval = rd32(E1000_EIAM);
wr32(E1000_EIAM, regval | adapter->eims_enable_mask);
@@ -1745,6 +1740,7 @@ int igb_up(struct igb_adapter *adapter)
/* notify VFs that reset has been completed */
if (adapter->vfs_allocated_count) {
u32 reg_data = rd32(E1000_CTRL_EXT);
+
reg_data |= E1000_CTRL_EXT_PFRSTD;
wr32(E1000_CTRL_EXT, reg_data);
}
@@ -1787,7 +1783,7 @@ void igb_down(struct igb_adapter *adapter)
wr32(E1000_TCTL, tctl);
/* flush both disables and wait for them to finish */
wrfl();
- msleep(10);
+ usleep_range(10000, 11000);
igb_irq_disable(adapter);
@@ -1827,7 +1823,7 @@ void igb_reinit_locked(struct igb_adapter *adapter)
{
WARN_ON(in_interrupt());
while (test_and_set_bit(__IGB_RESETTING, &adapter->state))
- msleep(1);
+ usleep_range(1000, 2000);
igb_down(adapter);
igb_up(adapter);
clear_bit(__IGB_RESETTING, &adapter->state);
@@ -1960,6 +1956,7 @@ void igb_reset(struct igb_adapter *adapter)
/* disable receive for all VFs and wait one second */
if (adapter->vfs_allocated_count) {
int i;
+
for (i = 0 ; i < adapter->vfs_allocated_count; i++)
adapter->vf_data[i].flags &= IGB_VF_FLAG_PF_SET_MAC;
@@ -2529,7 +2526,8 @@ static int igb_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
}
/* let the f/w know that the h/w is now under the control of the
- * driver. */
+ * driver.
+ */
igb_get_hw_control(adapter);
strcpy(netdev->name, "eth%d");
@@ -3077,6 +3075,7 @@ static int __igb_open(struct net_device *netdev, bool resuming)
/* notify VFs that reset has been completed */
if (adapter->vfs_allocated_count) {
u32 reg_data = rd32(E1000_CTRL_EXT);
+
reg_data |= E1000_CTRL_EXT_PFRSTD;
wr32(E1000_CTRL_EXT, reg_data);
}
@@ -3248,7 +3247,7 @@ void igb_setup_tctl(struct igb_adapter *adapter)
* Configure a transmit ring after a reset.
**/
void igb_configure_tx_ring(struct igb_adapter *adapter,
- struct igb_ring *ring)
+ struct igb_ring *ring)
{
struct e1000_hw *hw = &adapter->hw;
u32 txdctl = 0;
@@ -3389,7 +3388,8 @@ static void igb_setup_mrqc(struct igb_adapter *adapter)
if (adapter->rss_indir_tbl_init != num_rx_queues) {
for (j = 0; j < IGB_RETA_SIZE; j++)
- adapter->rss_indir_tbl[j] = (j * num_rx_queues) / IGB_RETA_SIZE;
+ adapter->rss_indir_tbl[j] =
+ (j * num_rx_queues) / IGB_RETA_SIZE;
adapter->rss_indir_tbl_init = num_rx_queues;
}
igb_write_rss_indir_tbl(adapter);
@@ -3430,6 +3430,7 @@ static void igb_setup_mrqc(struct igb_adapter *adapter)
if (hw->mac.type > e1000_82575) {
/* Set the default pool for the PF's first queue */
u32 vtctl = rd32(E1000_VT_CTL);
+
vtctl &= ~(E1000_VT_CTL_DEFAULT_POOL_MASK |
E1000_VT_CTL_DISABLE_DEF_POOL);
vtctl |= adapter->vfs_allocated_count <<
@@ -3511,7 +3512,7 @@ void igb_setup_rctl(struct igb_adapter *adapter)
}
static inline int igb_set_vf_rlpml(struct igb_adapter *adapter, int size,
- int vfn)
+ int vfn)
{
struct e1000_hw *hw = &adapter->hw;
u32 vmolr;
@@ -4058,7 +4059,8 @@ static void igb_check_wvbr(struct igb_adapter *adapter)
switch (hw->mac.type) {
case e1000_82576:
case e1000_i350:
- if (!(wvbr = rd32(E1000_WVBR)))
+ wvbr = rd32(E1000_WVBR);
+ if (!wvbr)
return;
break;
default:
@@ -4077,7 +4079,7 @@ static void igb_spoof_check(struct igb_adapter *adapter)
if (!adapter->wvbr)
return;
- for(j = 0; j < adapter->vfs_allocated_count; j++) {
+ for (j = 0; j < adapter->vfs_allocated_count; j++) {
if (adapter->wvbr & (1 << j) ||
adapter->wvbr & (1 << (j + IGB_STAGGERED_QUEUE_OFFSET))) {
dev_warn(&adapter->pdev->dev,
@@ -4209,14 +4211,15 @@ static void igb_watchdog_task(struct work_struct *work)
if (!netif_carrier_ok(netdev)) {
u32 ctrl;
+
hw->mac.ops.get_speed_and_duplex(hw,
&adapter->link_speed,
&adapter->link_duplex);
ctrl = rd32(E1000_CTRL);
/* Links status message must follow this format */
- printk(KERN_INFO "igb: %s NIC Link is Up %d Mbps %s "
- "Duplex, Flow Control: %s\n",
+ netdev_info(netdev,
+ "igb: %s NIC Link is Up %d Mbps %s Duplex, Flow Control: %s\n",
netdev->name,
adapter->link_speed,
adapter->link_duplex == FULL_DUPLEX ?
@@ -4242,11 +4245,8 @@ static void igb_watchdog_task(struct work_struct *work)
/* check for thermal sensor event */
if (igb_thermal_sensor_event(hw,
- E1000_THSTAT_LINK_THROTTLE)) {
- netdev_info(netdev, "The network adapter link "
- "speed was downshifted because it "
- "overheated\n");
- }
+ E1000_THSTAT_LINK_THROTTLE))
+ netdev_info(netdev, "The network adapter link speed was downshifted because it overheated\n");
/* adjust timeout factor according to speed/duplex */
adapter->tx_timeout_factor = 1;
@@ -4277,12 +4277,11 @@ static void igb_watchdog_task(struct work_struct *work)
/* check for thermal sensor event */
if (igb_thermal_sensor_event(hw,
E1000_THSTAT_PWR_DOWN)) {
- netdev_err(netdev, "The network adapter was "
- "stopped because it overheated\n");
+ netdev_err(netdev, "The network adapter was stopped because it overheated\n");
}
/* Links status message must follow this format */
- printk(KERN_INFO "igb: %s NIC Link is Down\n",
+ netdev_info(netdev, "igb: %s NIC Link is Down\n",
netdev->name);
netif_carrier_off(netdev);
@@ -4344,6 +4343,7 @@ static void igb_watchdog_task(struct work_struct *work)
/* Cause software interrupt to ensure Rx ring is cleaned */
if (adapter->flags & IGB_FLAG_HAS_MSIX) {
u32 eics = 0;
+
for (i = 0; i < adapter->num_q_vectors; i++)
eics |= adapter->q_vector[i]->eims_value;
wr32(E1000_EICS, eics);
@@ -4483,13 +4483,12 @@ static void igb_update_itr(struct igb_q_vector *q_vector,
case low_latency: /* 50 usec aka 20000 ints/s */
if (bytes > 10000) {
/* this if handles the TSO accounting */
- if (bytes/packets > 8000) {
+ if (bytes/packets > 8000)
itrval = bulk_latency;
- } else if ((packets < 10) || ((bytes/packets) > 1200)) {
+ else if ((packets < 10) || ((bytes/packets) > 1200))
itrval = bulk_latency;
- } else if ((packets > 35)) {
+ else if ((packets > 35))
itrval = lowest_latency;
- }
} else if (bytes/packets > 2000) {
itrval = bulk_latency;
} else if (packets <= 2 && bytes < 512) {
@@ -4675,6 +4674,7 @@ static void igb_tx_csum(struct igb_ring *tx_ring, struct igb_tx_buffer *first)
return;
} else {
u8 l4_hdr = 0;
+
switch (first->protocol) {
case htons(ETH_P_IP):
vlan_macip_lens |= skb_network_header_len(skb);
@@ -4962,6 +4962,7 @@ netdev_tx_t igb_xmit_frame_ring(struct sk_buff *skb,
*/
if (NETDEV_FRAG_PAGE_MAX_SIZE > IGB_MAX_DATA_PER_TXD) {
unsigned short f;
+
for (f = 0; f < skb_shinfo(skb)->nr_frags; f++)
count += TXD_USE_COUNT(skb_shinfo(skb)->frags[f].size);
} else {
@@ -5140,7 +5141,7 @@ static int igb_change_mtu(struct net_device *netdev, int new_mtu)
max_frame = ETH_FRAME_LEN + ETH_FCS_LEN;
while (test_and_set_bit(__IGB_RESETTING, &adapter->state))
- msleep(1);
+ usleep_range(1000, 2000);
/* igb_down has a dependency on max_frame_size */
adapter->max_frame_size = max_frame;
@@ -5193,8 +5194,10 @@ void igb_update_stats(struct igb_adapter *adapter,
rcu_read_lock();
for (i = 0; i < adapter->num_rx_queues; i++) {
- u32 rqdpc = rd32(E1000_RQDPC(i));
struct igb_ring *ring = adapter->rx_ring[i];
+ u32 rqdpc = rd32(E1000_RQDPC(i));
+ if (hw->mac.type >= e1000_i210)
+ wr32(E1000_RQDPC(i), 0);
if (rqdpc) {
ring->rx_stats.drops += rqdpc;
@@ -5619,6 +5622,7 @@ static int igb_set_vf_promisc(struct igb_adapter *adapter, u32 *msgbuf, u32 vf)
vmolr |= E1000_VMOLR_MPME;
} else if (vf_data->num_vf_mc_hashes) {
int j;
+
vmolr |= E1000_VMOLR_ROMPE;
for (j = 0; j < vf_data->num_vf_mc_hashes; j++)
igb_mta_set(hw, vf_data->vf_mc_hashes[j]);
@@ -5670,6 +5674,7 @@ static void igb_restore_vf_multicasts(struct igb_adapter *adapter)
for (i = 0; i < adapter->vfs_allocated_count; i++) {
u32 vmolr = rd32(E1000_VMOLR(i));
+
vmolr &= ~(E1000_VMOLR_ROMPE | E1000_VMOLR_MPME);
vf_data = &adapter->vf_data[i];
@@ -5768,6 +5773,7 @@ static s32 igb_vlvf_set(struct igb_adapter *adapter, u32 vid, bool add, u32 vf)
if (!adapter->vf_data[vf].vlans_enabled) {
u32 size;
+
reg = rd32(E1000_VMOLR(vf));
size = reg & E1000_VMOLR_RLPML_MASK;
size += 4;
@@ -5796,6 +5802,7 @@ static s32 igb_vlvf_set(struct igb_adapter *adapter, u32 vid, bool add, u32 vf)
adapter->vf_data[vf].vlans_enabled--;
if (!adapter->vf_data[vf].vlans_enabled) {
u32 size;
+
reg = rd32(E1000_VMOLR(vf));
size = reg & E1000_VMOLR_RLPML_MASK;
size -= 4;
@@ -5900,8 +5907,8 @@ static int igb_set_vf_vlan(struct igb_adapter *adapter, u32 *msgbuf, u32 vf)
*/
if (!add && (adapter->netdev->flags & IFF_PROMISC)) {
u32 vlvf, bits;
-
int regndx = igb_find_vlvf_entry(adapter, vid);
+
if (regndx < 0)
goto out;
/* See if any other pools are set for this VLAN filter
@@ -6492,7 +6499,7 @@ static void igb_reuse_rx_page(struct igb_ring *rx_ring,
rx_ring->next_to_alloc = (nta < rx_ring->count) ? nta : 0;
/* transfer page from old buffer to new buffer */
- memcpy(new_buff, old_buff, sizeof(struct igb_rx_buffer));
+ *new_buff = *old_buff;
/* sync the buffer for use by the device */
dma_sync_single_range_for_device(rx_ring->dev, old_buff->dma,
@@ -6961,6 +6968,7 @@ static void igb_process_skb_fields(struct igb_ring *rx_ring,
if ((dev->features & NETIF_F_HW_VLAN_CTAG_RX) &&
igb_test_staterr(rx_desc, E1000_RXD_STAT_VP)) {
u16 vid;
+
if (igb_test_staterr(rx_desc, E1000_RXDEXT_STATERR_LB) &&
test_bit(IGB_RING_FLAG_RX_LB_VLAN_BSWAP, &rx_ring->flags))
vid = be16_to_cpu(rx_desc->wb.upper.vlan);
@@ -7049,7 +7057,7 @@ static bool igb_clean_rx_irq(struct igb_q_vector *q_vector, const int budget)
if (cleaned_count)
igb_alloc_rx_buffers(rx_ring, cleaned_count);
- return (total_packets < budget);
+ return total_packets < budget;
}
static bool igb_alloc_mapped_page(struct igb_ring *rx_ring,
@@ -7170,7 +7178,7 @@ static int igb_mii_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)
break;
case SIOCGMIIREG:
if (igb_read_phy_reg(&adapter->hw, data->reg_num & 0x1F,
- &data->val_out))
+ &data->val_out))
return -EIO;
break;
case SIOCSMIIREG:
@@ -7953,11 +7961,13 @@ static void igb_vmm_control(struct igb_adapter *adapter)
reg = rd32(E1000_DTXCTL);
reg |= E1000_DTXCTL_VLAN_ADDED;
wr32(E1000_DTXCTL, reg);
+ /* Fall through */
case e1000_82580:
/* enable replication vlan tag stripping */
reg = rd32(E1000_RPLOLR);
reg |= E1000_RPLOLR_STRVLAN;
wr32(E1000_RPLOLR, reg);
+ /* Fall through */
case e1000_i350:
/* none of the above registers are supported by i350 */
break;
@@ -8047,6 +8057,7 @@ static void igb_init_dmac(struct igb_adapter *adapter, u32 pba)
} /* endif adapter->dmac is not disabled */
} else if (hw->mac.type == e1000_82580) {
u32 reg = rd32(E1000_PCIEMISC);
+
wr32(E1000_PCIEMISC, reg & ~E1000_PCIEMISC_LX_DECISION);
wr32(E1000_DMACR, 0);
}
diff --git a/drivers/net/ethernet/intel/igb/igb_ptp.c b/drivers/net/ethernet/intel/igb/igb_ptp.c
index 9209d65..ab25e49 100644
--- a/drivers/net/ethernet/intel/igb/igb_ptp.c
+++ b/drivers/net/ethernet/intel/igb/igb_ptp.c
@@ -389,7 +389,7 @@ static void igb_ptp_tx_work(struct work_struct *work)
adapter->ptp_tx_skb = NULL;
clear_bit_unlock(__IGB_PTP_TX_IN_PROGRESS, &adapter->state);
adapter->tx_hwtstamp_timeouts++;
- dev_warn(&adapter->pdev->dev, "clearing Tx timestamp hang");
+ dev_warn(&adapter->pdev->dev, "clearing Tx timestamp hang\n");
return;
}
@@ -451,7 +451,7 @@ void igb_ptp_rx_hang(struct igb_adapter *adapter)
rd32(E1000_RXSTMPH);
adapter->last_rx_ptp_check = jiffies;
adapter->rx_hwtstamp_cleared++;
- dev_warn(&adapter->pdev->dev, "clearing Rx timestamp hang");
+ dev_warn(&adapter->pdev->dev, "clearing Rx timestamp hang\n");
}
}
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
index 1a12c1d..c688c8a 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe.h
@@ -155,7 +155,6 @@ struct vf_data_storage {
struct vf_macvlans {
struct list_head l;
int vf;
- int rar_entry;
bool free;
bool is_macvlan;
u8 vf_macvlan[ETH_ALEN];
@@ -256,7 +255,6 @@ struct ixgbe_ring {
struct ixgbe_tx_buffer *tx_buffer_info;
struct ixgbe_rx_buffer *rx_buffer_info;
};
- unsigned long last_rx_timestamp;
unsigned long state;
u8 __iomem *tail;
dma_addr_t dma; /* phys. address of descriptor ring */
@@ -614,6 +612,15 @@ static inline void ixgbe_write_tail(struct ixgbe_ring *ring, u32 value)
#define MAX_MSIX_VECTORS_82598 18
#define MAX_Q_VECTORS_82598 16
+struct ixgbe_mac_addr {
+ u8 addr[ETH_ALEN];
+ u16 queue;
+ u16 state; /* bitmask */
+};
+#define IXGBE_MAC_STATE_DEFAULT 0x1
+#define IXGBE_MAC_STATE_MODIFIED 0x2
+#define IXGBE_MAC_STATE_IN_USE 0x4
+
#define MAX_Q_VECTORS MAX_Q_VECTORS_82599
#define MAX_MSIX_COUNT MAX_MSIX_VECTORS_82599
@@ -770,6 +777,7 @@ struct ixgbe_adapter {
unsigned long ptp_tx_start;
unsigned long last_overflow_check;
unsigned long last_rx_ptp_check;
+ unsigned long last_rx_timestamp;
spinlock_t tmreg_lock;
struct cyclecounter cc;
struct timecounter tc;
@@ -785,6 +793,7 @@ struct ixgbe_adapter {
u32 timer_event_accumulator;
u32 vferr_refcount;
+ struct ixgbe_mac_addr *mac_table;
struct kobject *info_kobj;
#ifdef CONFIG_IXGBE_HWMON
struct hwmon_buff *ixgbe_hwmon_buff;
@@ -863,6 +872,13 @@ void ixgbe_update_stats(struct ixgbe_adapter *adapter);
int ixgbe_init_interrupt_scheme(struct ixgbe_adapter *adapter);
int ixgbe_wol_supported(struct ixgbe_adapter *adapter, u16 device_id,
u16 subdevice_id);
+#ifdef CONFIG_PCI_IOV
+void ixgbe_full_sync_mac_table(struct ixgbe_adapter *adapter);
+#endif
+int ixgbe_add_mac_filter(struct ixgbe_adapter *adapter,
+ u8 *addr, u16 queue);
+int ixgbe_del_mac_filter(struct ixgbe_adapter *adapter,
+ u8 *addr, u16 queue);
void ixgbe_clear_interrupt_scheme(struct ixgbe_adapter *adapter);
netdev_tx_t ixgbe_xmit_frame_ring(struct sk_buff *, struct ixgbe_adapter *,
struct ixgbe_ring *);
@@ -944,24 +960,7 @@ void ixgbe_ptp_init(struct ixgbe_adapter *adapter);
void ixgbe_ptp_stop(struct ixgbe_adapter *adapter);
void ixgbe_ptp_overflow_check(struct ixgbe_adapter *adapter);
void ixgbe_ptp_rx_hang(struct ixgbe_adapter *adapter);
-void __ixgbe_ptp_rx_hwtstamp(struct ixgbe_q_vector *q_vector,
- struct sk_buff *skb);
-static inline void ixgbe_ptp_rx_hwtstamp(struct ixgbe_ring *rx_ring,
- union ixgbe_adv_rx_desc *rx_desc,
- struct sk_buff *skb)
-{
- if (unlikely(!ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_STAT_TS)))
- return;
-
- __ixgbe_ptp_rx_hwtstamp(rx_ring->q_vector, skb);
-
- /*
- * Update the last_rx_timestamp timer in order to enable watchdog check
- * for error case of latched timestamp on a dropped packet.
- */
- rx_ring->last_rx_timestamp = jiffies;
-}
-
+void ixgbe_ptp_rx_hwtstamp(struct ixgbe_adapter *adapter, struct sk_buff *skb);
int ixgbe_ptp_set_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr);
int ixgbe_ptp_get_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr);
void ixgbe_ptp_start_cyclecounter(struct ixgbe_adapter *adapter);
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c
index 4c78ea8..1c52e47 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_82598.c
@@ -337,19 +337,25 @@ static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw)
int i;
bool link_up;
- /*
- * Validate the water mark configuration for packet buffer 0. Zero
- * water marks indicate that the packet buffer was not configured
- * and the watermarks for packet buffer 0 should always be configured.
- */
- if (!hw->fc.low_water ||
- !hw->fc.high_water[0] ||
- !hw->fc.pause_time) {
- hw_dbg(hw, "Invalid water mark configuration\n");
+ /* Validate the water mark configuration */
+ if (!hw->fc.pause_time) {
ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
goto out;
}
+ /* Low water mark of zero causes XOFF floods */
+ for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
+ if ((hw->fc.current_mode & ixgbe_fc_tx_pause) &&
+ hw->fc.high_water[i]) {
+ 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;
+ }
+ }
+ }
+
/*
* On 82598 having Rx FC on causes resets while doing 1G
* so if it's on turn it off once we know link_speed. For
@@ -432,12 +438,11 @@ static s32 ixgbe_fc_enable_82598(struct ixgbe_hw *hw)
IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl_reg);
IXGBE_WRITE_REG(hw, IXGBE_RMCS, rmcs_reg);
- fcrtl = (hw->fc.low_water << 10) | IXGBE_FCRTL_XONE;
-
/* Set up and enable Rx high/low water mark thresholds, enable XON. */
for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
if ((hw->fc.current_mode & ixgbe_fc_tx_pause) &&
hw->fc.high_water[i]) {
+ fcrtl = (hw->fc.low_water[i] << 10) | IXGBE_FCRTL_XONE;
fcrth = (hw->fc.high_water[i] << 10) | IXGBE_FCRTH_FCEN;
IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), fcrtl);
IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), fcrth);
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
index 24fba39..bdc5581 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.c
@@ -271,6 +271,7 @@ out:
**/
s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw)
{
+ s32 ret_val;
u32 ctrl_ext;
/* Set the media type */
@@ -292,12 +293,15 @@ s32 ixgbe_start_hw_generic(struct ixgbe_hw *hw)
IXGBE_WRITE_FLUSH(hw);
/* Setup flow control */
- ixgbe_setup_fc(hw);
+ ret_val = ixgbe_setup_fc(hw);
+ if (!ret_val)
+ goto out;
/* Clear adapter stopped flag */
hw->adapter_stopped = false;
- return 0;
+out:
+ return ret_val;
}
/**
@@ -1195,7 +1199,7 @@ static s32 ixgbe_detect_eeprom_page_size_generic(struct ixgbe_hw *hw,
*/
hw->eeprom.word_page_size = IXGBE_EEPROM_PAGE_SIZE_MAX - data[0];
- hw_dbg(hw, "Detected EEPROM page size = %d words.",
+ hw_dbg(hw, "Detected EEPROM page size = %d words.\n",
hw->eeprom.word_page_size);
out:
return status;
@@ -2106,19 +2110,25 @@ s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw)
u32 fcrtl, fcrth;
int i;
- /*
- * Validate the water mark configuration for packet buffer 0. Zero
- * water marks indicate that the packet buffer was not configured
- * and the watermarks for packet buffer 0 should always be configured.
- */
- if (!hw->fc.low_water ||
- !hw->fc.high_water[0] ||
- !hw->fc.pause_time) {
- hw_dbg(hw, "Invalid water mark configuration\n");
+ /* Validate the water mark configuration. */
+ if (!hw->fc.pause_time) {
ret_val = IXGBE_ERR_INVALID_LINK_SETTINGS;
goto out;
}
+ /* Low water mark of zero causes XOFF floods */
+ for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
+ if ((hw->fc.current_mode & ixgbe_fc_tx_pause) &&
+ hw->fc.high_water[i]) {
+ 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;
+ }
+ }
+ }
+
/* Negotiate the fc mode to use */
ixgbe_fc_autoneg(hw);
@@ -2181,12 +2191,11 @@ s32 ixgbe_fc_enable_generic(struct ixgbe_hw *hw)
IXGBE_WRITE_REG(hw, IXGBE_MFLCN, mflcn_reg);
IXGBE_WRITE_REG(hw, IXGBE_FCCFG, fccfg_reg);
- fcrtl = (hw->fc.low_water << 10) | IXGBE_FCRTL_XONE;
-
/* Set up and enable Rx high/low water mark thresholds, enable XON. */
for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
if ((hw->fc.current_mode & ixgbe_fc_tx_pause) &&
hw->fc.high_water[i]) {
+ fcrtl = (hw->fc.low_water[i] << 10) | IXGBE_FCRTL_XONE;
IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), fcrtl);
fcrth = (hw->fc.high_water[i] << 10) | IXGBE_FCRTH_FCEN;
} else {
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.h
index f12c40f..d15ff2e 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_common.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_common.h
@@ -141,8 +141,6 @@ static inline bool ixgbe_removed(void __iomem *addr)
return unlikely(!addr);
}
-void ixgbe_check_remove(struct ixgbe_hw *hw, u32 reg);
-
static inline void ixgbe_write_reg(struct ixgbe_hw *hw, u32 reg, u32 value)
{
u8 __iomem *reg_addr = ACCESS_ONCE(hw->hw_addr);
@@ -172,18 +170,7 @@ static inline void ixgbe_write_reg64(struct ixgbe_hw *hw, u32 reg, u64 value)
}
#define IXGBE_WRITE_REG64(a, reg, value) ixgbe_write_reg64((a), (reg), (value))
-static inline u32 ixgbe_read_reg(struct ixgbe_hw *hw, u32 reg)
-{
- u8 __iomem *reg_addr = ACCESS_ONCE(hw->hw_addr);
- u32 value;
-
- if (ixgbe_removed(reg_addr))
- return IXGBE_FAILED_READ_REG;
- value = readl(reg_addr + reg);
- if (unlikely(value == IXGBE_FAILED_READ_REG))
- ixgbe_check_remove(hw, reg);
- return value;
-}
+u32 ixgbe_read_reg(struct ixgbe_hw *hw, u32 reg);
#define IXGBE_READ_REG(a, reg) ixgbe_read_reg((a), (reg))
#define IXGBE_WRITE_REG_ARRAY(a, reg, offset, value) \
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82598.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82598.c
index 7a77f37..d3ba63f 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82598.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82598.c
@@ -208,7 +208,6 @@ s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *hw, u8 pfc_en)
IXGBE_WRITE_REG(hw, IXGBE_FCTRL, reg);
- fcrtl = (hw->fc.low_water << 10) | IXGBE_FCRTL_XONE;
/* Configure PFC Tx thresholds per TC */
for (i = 0; i < MAX_TRAFFIC_CLASS; i++) {
if (!(pfc_en & (1 << i))) {
@@ -217,6 +216,7 @@ s32 ixgbe_dcb_config_pfc_82598(struct ixgbe_hw *hw, u8 pfc_en)
continue;
}
+ fcrtl = (hw->fc.low_water[i] << 10) | IXGBE_FCRTL_XONE;
reg = (hw->fc.high_water[i] << 10) | IXGBE_FCRTH_FCEN;
IXGBE_WRITE_REG(hw, IXGBE_FCRTL(i), fcrtl);
IXGBE_WRITE_REG(hw, IXGBE_FCRTH(i), reg);
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82599.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82599.c
index bdb99b3..3b932fe 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82599.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_dcb_82599.c
@@ -242,7 +242,6 @@ s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw, u8 pfc_en, u8 *prio_tc)
max_tc = prio_tc[i];
}
- fcrtl = (hw->fc.low_water << 10) | IXGBE_FCRTL_XONE;
/* Configure PFC Tx thresholds per TC */
for (i = 0; i <= max_tc; i++) {
@@ -257,6 +256,7 @@ s32 ixgbe_dcb_config_pfc_82599(struct ixgbe_hw *hw, u8 pfc_en, u8 *prio_tc)
if (enabled) {
reg = (hw->fc.high_water[i] << 10) | IXGBE_FCRTH_FCEN;
+ fcrtl = (hw->fc.low_water[i] << 10) | IXGBE_FCRTL_XONE;
IXGBE_WRITE_REG(hw, IXGBE_FCRTL_82599(i), fcrtl);
} else {
reg = IXGBE_READ_REG(hw, IXGBE_RXPBSIZE(i)) - 32;
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.h
index b16cc78..0772b77 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_fcoe.h
@@ -81,9 +81,7 @@ struct ixgbe_fcoe {
void *extra_ddp_buffer;
dma_addr_t extra_ddp_buffer_dma;
unsigned long mode;
-#ifdef CONFIG_IXGBE_DCB
u8 up;
-#endif
};
#endif /* _IXGBE_FCOE_H */
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
index c4c526b..8089ea9 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_main.c
@@ -301,7 +301,7 @@ static void ixgbe_remove_adapter(struct ixgbe_hw *hw)
ixgbe_service_event_schedule(adapter);
}
-void ixgbe_check_remove(struct ixgbe_hw *hw, u32 reg)
+static void ixgbe_check_remove(struct ixgbe_hw *hw, u32 reg)
{
u32 value;
@@ -320,6 +320,32 @@ void ixgbe_check_remove(struct ixgbe_hw *hw, u32 reg)
ixgbe_remove_adapter(hw);
}
+/**
+ * ixgbe_read_reg - Read from device register
+ * @hw: hw specific details
+ * @reg: offset of register to read
+ *
+ * Returns : value read or IXGBE_FAILED_READ_REG if removed
+ *
+ * This function is used to read device registers. It checks for device
+ * removal by confirming any read that returns all ones by checking the
+ * status register value for all ones. This function avoids reading from
+ * the hardware if a removal was previously detected in which case it
+ * returns IXGBE_FAILED_READ_REG (all ones).
+ */
+u32 ixgbe_read_reg(struct ixgbe_hw *hw, u32 reg)
+{
+ u8 __iomem *reg_addr = ACCESS_ONCE(hw->hw_addr);
+ u32 value;
+
+ if (ixgbe_removed(reg_addr))
+ return IXGBE_FAILED_READ_REG;
+ value = readl(reg_addr + reg);
+ if (unlikely(value == IXGBE_FAILED_READ_REG))
+ ixgbe_check_remove(hw, reg);
+ return value;
+}
+
static bool ixgbe_check_cfg_remove(struct ixgbe_hw *hw, struct pci_dev *pdev)
{
u16 value;
@@ -1664,7 +1690,8 @@ static void ixgbe_process_skb_fields(struct ixgbe_ring *rx_ring,
ixgbe_rx_checksum(rx_ring, rx_desc, skb);
- ixgbe_ptp_rx_hwtstamp(rx_ring, rx_desc, skb);
+ if (unlikely(ixgbe_test_staterr(rx_desc, IXGBE_RXDADV_STAT_TS)))
+ ixgbe_ptp_rx_hwtstamp(rx_ring->q_vector->adapter, skb);
if ((dev->features & NETIF_F_HW_VLAN_CTAG_RX) &&
ixgbe_test_staterr(rx_desc, IXGBE_RXD_STAT_VP)) {
@@ -3742,35 +3769,6 @@ static int ixgbe_vlan_rx_kill_vid(struct net_device *netdev,
}
/**
- * ixgbe_vlan_filter_disable - helper to disable hw vlan filtering
- * @adapter: driver data
- */
-static void ixgbe_vlan_filter_disable(struct ixgbe_adapter *adapter)
-{
- struct ixgbe_hw *hw = &adapter->hw;
- u32 vlnctrl;
-
- vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
- vlnctrl &= ~(IXGBE_VLNCTRL_VFE | IXGBE_VLNCTRL_CFIEN);
- IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
-}
-
-/**
- * ixgbe_vlan_filter_enable - helper to enable hw vlan filtering
- * @adapter: driver data
- */
-static void ixgbe_vlan_filter_enable(struct ixgbe_adapter *adapter)
-{
- struct ixgbe_hw *hw = &adapter->hw;
- u32 vlnctrl;
-
- vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
- vlnctrl |= IXGBE_VLNCTRL_VFE;
- vlnctrl &= ~IXGBE_VLNCTRL_CFIEN;
- IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
-}
-
-/**
* ixgbe_vlan_strip_disable - helper to disable hw vlan stripping
* @adapter: driver data
*/
@@ -3849,6 +3847,158 @@ static void ixgbe_restore_vlan(struct ixgbe_adapter *adapter)
}
/**
+ * ixgbe_write_mc_addr_list - write multicast addresses to MTA
+ * @netdev: network interface device structure
+ *
+ * Writes multicast address list to the MTA hash table.
+ * Returns: -ENOMEM on failure
+ * 0 on no addresses written
+ * X on writing X addresses to MTA
+ **/
+static int ixgbe_write_mc_addr_list(struct net_device *netdev)
+{
+ struct ixgbe_adapter *adapter = netdev_priv(netdev);
+ struct ixgbe_hw *hw = &adapter->hw;
+
+ if (!netif_running(netdev))
+ return 0;
+
+ if (hw->mac.ops.update_mc_addr_list)
+ hw->mac.ops.update_mc_addr_list(hw, netdev);
+ else
+ return -ENOMEM;
+
+#ifdef CONFIG_PCI_IOV
+ ixgbe_restore_vf_multicasts(adapter);
+#endif
+
+ return netdev_mc_count(netdev);
+}
+
+#ifdef CONFIG_PCI_IOV
+void ixgbe_full_sync_mac_table(struct ixgbe_adapter *adapter)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ int i;
+ for (i = 0; i < hw->mac.num_rar_entries; i++) {
+ if (adapter->mac_table[i].state & IXGBE_MAC_STATE_IN_USE)
+ hw->mac.ops.set_rar(hw, i, adapter->mac_table[i].addr,
+ adapter->mac_table[i].queue,
+ IXGBE_RAH_AV);
+ else
+ hw->mac.ops.clear_rar(hw, i);
+
+ adapter->mac_table[i].state &= ~(IXGBE_MAC_STATE_MODIFIED);
+ }
+}
+#endif
+
+static void ixgbe_sync_mac_table(struct ixgbe_adapter *adapter)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ int i;
+ for (i = 0; i < hw->mac.num_rar_entries; i++) {
+ if (adapter->mac_table[i].state & IXGBE_MAC_STATE_MODIFIED) {
+ if (adapter->mac_table[i].state &
+ IXGBE_MAC_STATE_IN_USE)
+ hw->mac.ops.set_rar(hw, i,
+ adapter->mac_table[i].addr,
+ adapter->mac_table[i].queue,
+ IXGBE_RAH_AV);
+ else
+ hw->mac.ops.clear_rar(hw, i);
+
+ adapter->mac_table[i].state &=
+ ~(IXGBE_MAC_STATE_MODIFIED);
+ }
+ }
+}
+
+static void ixgbe_flush_sw_mac_table(struct ixgbe_adapter *adapter)
+{
+ int i;
+ struct ixgbe_hw *hw = &adapter->hw;
+
+ for (i = 0; i < hw->mac.num_rar_entries; i++) {
+ adapter->mac_table[i].state |= IXGBE_MAC_STATE_MODIFIED;
+ adapter->mac_table[i].state &= ~IXGBE_MAC_STATE_IN_USE;
+ memset(adapter->mac_table[i].addr, 0, ETH_ALEN);
+ adapter->mac_table[i].queue = 0;
+ }
+ ixgbe_sync_mac_table(adapter);
+}
+
+static int ixgbe_available_rars(struct ixgbe_adapter *adapter)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ int i, count = 0;
+
+ for (i = 0; i < hw->mac.num_rar_entries; i++) {
+ if (adapter->mac_table[i].state == 0)
+ count++;
+ }
+ return count;
+}
+
+/* this function destroys the first RAR entry */
+static void ixgbe_mac_set_default_filter(struct ixgbe_adapter *adapter,
+ u8 *addr)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+
+ memcpy(&adapter->mac_table[0].addr, addr, ETH_ALEN);
+ adapter->mac_table[0].queue = VMDQ_P(0);
+ adapter->mac_table[0].state = (IXGBE_MAC_STATE_DEFAULT |
+ IXGBE_MAC_STATE_IN_USE);
+ hw->mac.ops.set_rar(hw, 0, adapter->mac_table[0].addr,
+ adapter->mac_table[0].queue,
+ IXGBE_RAH_AV);
+}
+
+int ixgbe_add_mac_filter(struct ixgbe_adapter *adapter, u8 *addr, u16 queue)
+{
+ struct ixgbe_hw *hw = &adapter->hw;
+ int i;
+
+ if (is_zero_ether_addr(addr))
+ return -EINVAL;
+
+ for (i = 0; i < hw->mac.num_rar_entries; i++) {
+ if (adapter->mac_table[i].state & IXGBE_MAC_STATE_IN_USE)
+ continue;
+ adapter->mac_table[i].state |= (IXGBE_MAC_STATE_MODIFIED |
+ IXGBE_MAC_STATE_IN_USE);
+ ether_addr_copy(adapter->mac_table[i].addr, addr);
+ adapter->mac_table[i].queue = queue;
+ ixgbe_sync_mac_table(adapter);
+ return i;
+ }
+ return -ENOMEM;
+}
+
+int ixgbe_del_mac_filter(struct ixgbe_adapter *adapter, u8 *addr, u16 queue)
+{
+ /* search table for addr, if found, set to 0 and sync */
+ int i;
+ struct ixgbe_hw *hw = &adapter->hw;
+
+ if (is_zero_ether_addr(addr))
+ return -EINVAL;
+
+ for (i = 0; i < hw->mac.num_rar_entries; i++) {
+ if (ether_addr_equal(addr, adapter->mac_table[i].addr) &&
+ adapter->mac_table[i].queue == queue) {
+ adapter->mac_table[i].state |= IXGBE_MAC_STATE_MODIFIED;
+ adapter->mac_table[i].state &= ~IXGBE_MAC_STATE_IN_USE;
+ memset(adapter->mac_table[i].addr, 0, ETH_ALEN);
+ adapter->mac_table[i].queue = 0;
+ ixgbe_sync_mac_table(adapter);
+ return 0;
+ }
+ }
+ return -ENOMEM;
+}
+/**
* ixgbe_write_uc_addr_list - write unicast addresses to RAR table
* @netdev: network interface device structure
*
@@ -3857,39 +4007,23 @@ static void ixgbe_restore_vlan(struct ixgbe_adapter *adapter)
* 0 on no addresses written
* X on writing X addresses to the RAR table
**/
-static int ixgbe_write_uc_addr_list(struct net_device *netdev)
+static int ixgbe_write_uc_addr_list(struct net_device *netdev, int vfn)
{
struct ixgbe_adapter *adapter = netdev_priv(netdev);
- struct ixgbe_hw *hw = &adapter->hw;
- unsigned int rar_entries = hw->mac.num_rar_entries - 1;
int count = 0;
- /* In SR-IOV/VMDQ modes significantly less RAR entries are available */
- if (adapter->flags & IXGBE_FLAG_SRIOV_ENABLED)
- rar_entries = IXGBE_MAX_PF_MACVLANS - 1;
-
/* return ENOMEM indicating insufficient memory for addresses */
- if (netdev_uc_count(netdev) > rar_entries)
+ if (netdev_uc_count(netdev) > ixgbe_available_rars(adapter))
return -ENOMEM;
if (!netdev_uc_empty(netdev)) {
struct netdev_hw_addr *ha;
- /* return error if we do not support writing to RAR table */
- if (!hw->mac.ops.set_rar)
- return -ENOMEM;
-
netdev_for_each_uc_addr(ha, netdev) {
- if (!rar_entries)
- break;
- hw->mac.ops.set_rar(hw, rar_entries--, ha->addr,
- VMDQ_P(0), IXGBE_RAH_AV);
+ ixgbe_del_mac_filter(adapter, ha->addr, vfn);
+ ixgbe_add_mac_filter(adapter, ha->addr, vfn);
count++;
}
}
- /* write the addresses in reverse order to avoid write combining */
- for (; rar_entries > 0 ; rar_entries--)
- hw->mac.ops.clear_rar(hw, rar_entries);
-
return count;
}
@@ -3907,11 +4041,12 @@ void ixgbe_set_rx_mode(struct net_device *netdev)
struct ixgbe_adapter *adapter = netdev_priv(netdev);
struct ixgbe_hw *hw = &adapter->hw;
u32 fctrl, vmolr = IXGBE_VMOLR_BAM | IXGBE_VMOLR_AUPE;
+ u32 vlnctrl;
int count;
/* Check for Promiscuous and All Multicast modes */
-
fctrl = IXGBE_READ_REG(hw, IXGBE_FCTRL);
+ vlnctrl = IXGBE_READ_REG(hw, IXGBE_VLNCTRL);
/* set all bits that we expect to always be set */
fctrl &= ~IXGBE_FCTRL_SBP; /* disable store-bad-packets */
@@ -3921,26 +4056,24 @@ void ixgbe_set_rx_mode(struct net_device *netdev)
/* clear the bits we are changing the status of */
fctrl &= ~(IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
-
+ vlnctrl &= ~(IXGBE_VLNCTRL_VFE | IXGBE_VLNCTRL_CFIEN);
if (netdev->flags & IFF_PROMISC) {
hw->addr_ctrl.user_set_promisc = true;
fctrl |= (IXGBE_FCTRL_UPE | IXGBE_FCTRL_MPE);
- vmolr |= (IXGBE_VMOLR_ROPE | IXGBE_VMOLR_MPE);
+ vmolr |= IXGBE_VMOLR_MPE;
/* Only disable hardware filter vlans in promiscuous mode
* if SR-IOV and VMDQ are disabled - otherwise ensure
* that hardware VLAN filters remain enabled.
*/
if (!(adapter->flags & (IXGBE_FLAG_VMDQ_ENABLED |
IXGBE_FLAG_SRIOV_ENABLED)))
- ixgbe_vlan_filter_disable(adapter);
- else
- ixgbe_vlan_filter_enable(adapter);
+ vlnctrl |= (IXGBE_VLNCTRL_VFE | IXGBE_VLNCTRL_CFIEN);
} else {
if (netdev->flags & IFF_ALLMULTI) {
fctrl |= IXGBE_FCTRL_MPE;
vmolr |= IXGBE_VMOLR_MPE;
}
- ixgbe_vlan_filter_enable(adapter);
+ vlnctrl |= IXGBE_VLNCTRL_VFE;
hw->addr_ctrl.user_set_promisc = false;
}
@@ -3949,7 +4082,7 @@ void ixgbe_set_rx_mode(struct net_device *netdev)
* sufficient space to store all the addresses then enable
* unicast promiscuous mode
*/
- count = ixgbe_write_uc_addr_list(netdev);
+ count = ixgbe_write_uc_addr_list(netdev, VMDQ_P(0));
if (count < 0) {
fctrl |= IXGBE_FCTRL_UPE;
vmolr |= IXGBE_VMOLR_ROPE;
@@ -3959,11 +4092,13 @@ void ixgbe_set_rx_mode(struct net_device *netdev)
* then we should just turn on promiscuous mode so
* that we can at least receive multicast traffic
*/
- hw->mac.ops.update_mc_addr_list(hw, netdev);
- vmolr |= IXGBE_VMOLR_ROMPE;
-
- if (adapter->num_vfs)
- ixgbe_restore_vf_multicasts(adapter);
+ count = ixgbe_write_mc_addr_list(netdev);
+ if (count < 0) {
+ fctrl |= IXGBE_FCTRL_MPE;
+ vmolr |= IXGBE_VMOLR_MPE;
+ } else if (count) {
+ vmolr |= IXGBE_VMOLR_ROMPE;
+ }
if (hw->mac.type != ixgbe_mac_82598EB) {
vmolr |= IXGBE_READ_REG(hw, IXGBE_VMOLR(VMDQ_P(0))) &
@@ -3984,6 +4119,7 @@ void ixgbe_set_rx_mode(struct net_device *netdev)
/* NOTE: VLAN filtering is disabled by setting PROMISC */
}
+ IXGBE_WRITE_REG(hw, IXGBE_VLNCTRL, vlnctrl);
IXGBE_WRITE_REG(hw, IXGBE_FCTRL, fctrl);
if (netdev->features & NETIF_F_HW_VLAN_CTAG_RX)
@@ -4100,8 +4236,8 @@ static int ixgbe_hpbthresh(struct ixgbe_adapter *adapter, int pb)
(tc < IXGBE_FCOE_JUMBO_FRAME_SIZE) &&
(pb == ixgbe_fcoe_get_tc(adapter)))
tc = IXGBE_FCOE_JUMBO_FRAME_SIZE;
-
#endif
+
/* Calculate delay value for device */
switch (hw->mac.type) {
case ixgbe_mac_X540:
@@ -4142,7 +4278,7 @@ static int ixgbe_hpbthresh(struct ixgbe_adapter *adapter, int pb)
* @adapter: board private structure to calculate for
* @pb: packet buffer to calculate
*/
-static int ixgbe_lpbthresh(struct ixgbe_adapter *adapter)
+static int ixgbe_lpbthresh(struct ixgbe_adapter *adapter, int pb)
{
struct ixgbe_hw *hw = &adapter->hw;
struct net_device *dev = adapter->netdev;
@@ -4152,6 +4288,14 @@ static int ixgbe_lpbthresh(struct ixgbe_adapter *adapter)
/* Calculate max LAN frame size */
tc = dev->mtu + ETH_HLEN + ETH_FCS_LEN;
+#ifdef IXGBE_FCOE
+ /* FCoE traffic class uses FCOE jumbo frames */
+ if ((dev->features & NETIF_F_FCOE_MTU) &&
+ (tc < IXGBE_FCOE_JUMBO_FRAME_SIZE) &&
+ (pb == netdev_get_prio_tc_map(dev, adapter->fcoe.up)))
+ tc = IXGBE_FCOE_JUMBO_FRAME_SIZE;
+#endif
+
/* Calculate delay value for device */
switch (hw->mac.type) {
case ixgbe_mac_X540:
@@ -4178,15 +4322,17 @@ static void ixgbe_pbthresh_setup(struct ixgbe_adapter *adapter)
if (!num_tc)
num_tc = 1;
- hw->fc.low_water = ixgbe_lpbthresh(adapter);
-
for (i = 0; i < num_tc; i++) {
hw->fc.high_water[i] = ixgbe_hpbthresh(adapter, i);
+ hw->fc.low_water[i] = ixgbe_lpbthresh(adapter, i);
/* Low water marks must not be larger than high water marks */
- if (hw->fc.low_water > hw->fc.high_water[i])
- hw->fc.low_water = 0;
+ if (hw->fc.low_water[i] > hw->fc.high_water[i])
+ hw->fc.low_water[i] = 0;
}
+
+ for (; i < MAX_TRAFFIC_CLASS; i++)
+ hw->fc.high_water[i] = 0;
}
static void ixgbe_configure_pb(struct ixgbe_adapter *adapter)
@@ -4248,20 +4394,10 @@ static void ixgbe_macvlan_set_rx_mode(struct net_device *dev, unsigned int pool,
vmolr |= IXGBE_VMOLR_ROMPE;
hw->mac.ops.update_mc_addr_list(hw, dev);
}
- ixgbe_write_uc_addr_list(adapter->netdev);
+ ixgbe_write_uc_addr_list(adapter->netdev, pool);
IXGBE_WRITE_REG(hw, IXGBE_VMOLR(pool), vmolr);
}
-static void ixgbe_add_mac_filter(struct ixgbe_adapter *adapter,
- u8 *addr, u16 pool)
-{
- struct ixgbe_hw *hw = &adapter->hw;
- unsigned int entry;
-
- entry = hw->mac.num_rar_entries - pool;
- hw->mac.ops.set_rar(hw, entry, addr, VMDQ_P(pool), IXGBE_RAH_AV);
-}
-
static void ixgbe_fwd_psrtype(struct ixgbe_fwd_adapter *vadapter)
{
struct ixgbe_adapter *adapter = vadapter->real_adapter;
@@ -4741,7 +4877,9 @@ void ixgbe_up(struct ixgbe_adapter *adapter)
void ixgbe_reset(struct ixgbe_adapter *adapter)
{
struct ixgbe_hw *hw = &adapter->hw;
+ struct net_device *netdev = adapter->netdev;
int err;
+ u8 old_addr[ETH_ALEN];
if (ixgbe_removed(hw->hw_addr))
return;
@@ -4777,9 +4915,10 @@ void ixgbe_reset(struct ixgbe_adapter *adapter)
}
clear_bit(__IXGBE_IN_SFP_INIT, &adapter->state);
-
- /* reprogram the RAR[0] in case user changed it. */
- hw->mac.ops.set_rar(hw, 0, hw->mac.addr, VMDQ_P(0), IXGBE_RAH_AV);
+ /* do not flush user set addresses */
+ memcpy(old_addr, &adapter->mac_table[0].addr, netdev->addr_len);
+ ixgbe_flush_sw_mac_table(adapter);
+ ixgbe_mac_set_default_filter(adapter, old_addr);
/* update SAN MAC vmdq pool selection */
if (hw->mac.san_mac_rar_index)
@@ -5025,6 +5164,10 @@ static int ixgbe_sw_init(struct ixgbe_adapter *adapter)
#endif /* CONFIG_IXGBE_DCB */
#endif /* IXGBE_FCOE */
+ adapter->mac_table = kzalloc(sizeof(struct ixgbe_mac_addr) *
+ hw->mac.num_rar_entries,
+ GFP_ATOMIC);
+
/* Set MAC specific capability flags and exceptions */
switch (hw->mac.type) {
case ixgbe_mac_82598EB:
@@ -7171,16 +7314,17 @@ static int ixgbe_set_mac(struct net_device *netdev, void *p)
struct ixgbe_adapter *adapter = netdev_priv(netdev);
struct ixgbe_hw *hw = &adapter->hw;
struct sockaddr *addr = p;
+ int ret;
if (!is_valid_ether_addr(addr->sa_data))
return -EADDRNOTAVAIL;
+ ixgbe_del_mac_filter(adapter, hw->mac.addr, VMDQ_P(0));
memcpy(netdev->dev_addr, addr->sa_data, netdev->addr_len);
memcpy(hw->mac.addr, addr->sa_data, netdev->addr_len);
- hw->mac.ops.set_rar(hw, 0, hw->mac.addr, VMDQ_P(0), IXGBE_RAH_AV);
-
- return 0;
+ ret = ixgbe_add_mac_filter(adapter, hw->mac.addr, VMDQ_P(0));
+ return ret > 0 ? 0 : ret;
}
static int
@@ -8186,6 +8330,8 @@ skip_sriov:
goto err_sw_init;
}
+ ixgbe_mac_set_default_filter(adapter, hw->mac.perm_addr);
+
setup_timer(&adapter->service_timer, &ixgbe_service_timer,
(unsigned long) adapter);
@@ -8318,6 +8464,7 @@ err_sw_init:
ixgbe_disable_sriov(adapter);
adapter->flags2 &= ~IXGBE_FLAG2_SEARCH_FOR_SFP;
iounmap(adapter->io_addr);
+ kfree(adapter->mac_table);
err_ioremap:
free_netdev(netdev);
err_alloc_etherdev:
@@ -8391,6 +8538,7 @@ static void ixgbe_remove(struct pci_dev *pdev)
e_dev_info("complete\n");
+ kfree(adapter->mac_table);
free_netdev(netdev);
pci_disable_pcie_error_reporting(pdev);
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c
index 23f7652..a76af8e2 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_phy.c
@@ -536,7 +536,7 @@ 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");
+ hw_dbg(hw, "ixgbe_setup_phy_link_generic: time out\n");
}
return status;
@@ -745,7 +745,7 @@ 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");
+ hw_dbg(hw, "ixgbe_setup_phy_link_tnx: time out\n");
}
return status;
@@ -1175,7 +1175,7 @@ s32 ixgbe_identify_sfp_module_generic(struct ixgbe_hw *hw)
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.");
+ 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,
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
index 63515a6..8902ae6 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c
@@ -435,10 +435,8 @@ void ixgbe_ptp_overflow_check(struct ixgbe_adapter *adapter)
void ixgbe_ptp_rx_hang(struct ixgbe_adapter *adapter)
{
struct ixgbe_hw *hw = &adapter->hw;
- struct ixgbe_ring *rx_ring;
u32 tsyncrxctl = IXGBE_READ_REG(hw, IXGBE_TSYNCRXCTL);
unsigned long rx_event;
- int n;
/* if we don't have a valid timestamp in the registers, just update the
* timeout counter and exit
@@ -450,18 +448,15 @@ void ixgbe_ptp_rx_hang(struct ixgbe_adapter *adapter)
/* determine the most recent watchdog or rx_timestamp event */
rx_event = adapter->last_rx_ptp_check;
- for (n = 0; n < adapter->num_rx_queues; n++) {
- rx_ring = adapter->rx_ring[n];
- if (time_after(rx_ring->last_rx_timestamp, rx_event))
- rx_event = rx_ring->last_rx_timestamp;
- }
+ if (time_after(adapter->last_rx_timestamp, rx_event))
+ rx_event = adapter->last_rx_timestamp;
/* only need to read the high RXSTMP register to clear the lock */
if (time_is_before_jiffies(rx_event + 5*HZ)) {
IXGBE_READ_REG(hw, IXGBE_RXSTMPH);
adapter->last_rx_ptp_check = jiffies;
- e_warn(drv, "clearing RX Timestamp hang");
+ e_warn(drv, "clearing RX Timestamp hang\n");
}
}
@@ -517,7 +512,7 @@ static void ixgbe_ptp_tx_hwtstamp_work(struct work_struct *work)
dev_kfree_skb_any(adapter->ptp_tx_skb);
adapter->ptp_tx_skb = NULL;
clear_bit_unlock(__IXGBE_PTP_TX_IN_PROGRESS, &adapter->state);
- e_warn(drv, "clearing Tx Timestamp hang");
+ e_warn(drv, "clearing Tx Timestamp hang\n");
return;
}
@@ -530,35 +525,22 @@ static void ixgbe_ptp_tx_hwtstamp_work(struct work_struct *work)
}
/**
- * __ixgbe_ptp_rx_hwtstamp - utility function which checks for RX time stamp
- * @q_vector: structure containing interrupt and ring information
+ * ixgbe_ptp_rx_hwtstamp - utility function which checks for RX time stamp
+ * @adapter: pointer to adapter struct
* @skb: particular skb to send timestamp with
*
* if the timestamp is valid, we convert it into the timecounter ns
* value, then store that result into the shhwtstamps structure which
* is passed up the network stack
*/
-void __ixgbe_ptp_rx_hwtstamp(struct ixgbe_q_vector *q_vector,
- struct sk_buff *skb)
+void ixgbe_ptp_rx_hwtstamp(struct ixgbe_adapter *adapter, struct sk_buff *skb)
{
- struct ixgbe_adapter *adapter;
- struct ixgbe_hw *hw;
+ struct ixgbe_hw *hw = &adapter->hw;
struct skb_shared_hwtstamps *shhwtstamps;
u64 regval = 0, ns;
u32 tsyncrxctl;
unsigned long flags;
- /* we cannot process timestamps on a ring without a q_vector */
- if (!q_vector || !q_vector->adapter)
- return;
-
- adapter = q_vector->adapter;
- hw = &adapter->hw;
-
- /*
- * Read the tsyncrxctl register afterwards in order to prevent taking an
- * I/O hit on every packet.
- */
tsyncrxctl = IXGBE_READ_REG(hw, IXGBE_TSYNCRXCTL);
if (!(tsyncrxctl & IXGBE_TSYNCRXCTL_VALID))
return;
@@ -566,13 +548,17 @@ void __ixgbe_ptp_rx_hwtstamp(struct ixgbe_q_vector *q_vector,
regval |= (u64)IXGBE_READ_REG(hw, IXGBE_RXSTMPL);
regval |= (u64)IXGBE_READ_REG(hw, IXGBE_RXSTMPH) << 32;
-
spin_lock_irqsave(&adapter->tmreg_lock, flags);
ns = timecounter_cyc2time(&adapter->tc, regval);
spin_unlock_irqrestore(&adapter->tmreg_lock, flags);
shhwtstamps = skb_hwtstamps(skb);
shhwtstamps->hwtstamp = ns_to_ktime(ns);
+
+ /* Update the last_rx_timestamp timer in order to enable watchdog check
+ * for error case of latched timestamp on a dropped packet.
+ */
+ adapter->last_rx_timestamp = jiffies;
}
int ixgbe_ptp_get_ts_config(struct ixgbe_adapter *adapter, struct ifreq *ifr)
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
index e6c68d3..a01417c 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.c
@@ -72,8 +72,6 @@ static int __ixgbe_enable_sriov(struct ixgbe_adapter *adapter)
for (i = 0; i < num_vf_macvlans; i++) {
mv_list->vf = -1;
mv_list->free = true;
- mv_list->rar_entry = hw->mac.num_rar_entries -
- (i + adapter->num_vfs + 1);
list_add(&mv_list->l, &adapter->vf_mvs.l);
mv_list++;
}
@@ -327,6 +325,7 @@ static int ixgbe_set_vf_multicasts(struct ixgbe_adapter *adapter,
u32 vector_bit;
u32 vector_reg;
u32 mta_reg;
+ u32 vmolr = IXGBE_READ_REG(hw, IXGBE_VMOLR(vf));
/* only so many hash values supported */
entries = min(entries, IXGBE_MAX_VF_MC_ENTRIES);
@@ -353,25 +352,13 @@ static int ixgbe_set_vf_multicasts(struct ixgbe_adapter *adapter,
mta_reg |= (1 << vector_bit);
IXGBE_WRITE_REG(hw, IXGBE_MTA(vector_reg), mta_reg);
}
+ vmolr |= IXGBE_VMOLR_ROMPE;
+ IXGBE_WRITE_REG(hw, IXGBE_VMOLR(vf), vmolr);
return 0;
}
-static void ixgbe_restore_vf_macvlans(struct ixgbe_adapter *adapter)
-{
- struct ixgbe_hw *hw = &adapter->hw;
- struct list_head *pos;
- struct vf_macvlans *entry;
-
- list_for_each(pos, &adapter->vf_mvs.l) {
- entry = list_entry(pos, struct vf_macvlans, l);
- if (!entry->free)
- hw->mac.ops.set_rar(hw, entry->rar_entry,
- entry->vf_macvlan,
- entry->vf, IXGBE_RAH_AV);
- }
-}
-
+#ifdef CONFIG_PCI_IOV
void ixgbe_restore_vf_multicasts(struct ixgbe_adapter *adapter)
{
struct ixgbe_hw *hw = &adapter->hw;
@@ -382,6 +369,7 @@ void ixgbe_restore_vf_multicasts(struct ixgbe_adapter *adapter)
u32 mta_reg;
for (i = 0; i < adapter->num_vfs; i++) {
+ u32 vmolr = IXGBE_READ_REG(hw, IXGBE_VMOLR(i));
vfinfo = &adapter->vfinfo[i];
for (j = 0; j < vfinfo->num_vf_mc_hashes; j++) {
hw->addr_ctrl.mta_in_use++;
@@ -391,11 +379,18 @@ void ixgbe_restore_vf_multicasts(struct ixgbe_adapter *adapter)
mta_reg |= (1 << vector_bit);
IXGBE_WRITE_REG(hw, IXGBE_MTA(vector_reg), mta_reg);
}
+
+ if (vfinfo->num_vf_mc_hashes)
+ vmolr |= IXGBE_VMOLR_ROMPE;
+ else
+ vmolr &= ~IXGBE_VMOLR_ROMPE;
+ IXGBE_WRITE_REG(hw, IXGBE_VMOLR(i), vmolr);
}
/* Restore any VF macvlans */
- ixgbe_restore_vf_macvlans(adapter);
+ ixgbe_full_sync_mac_table(adapter);
}
+#endif
static int ixgbe_set_vf_vlan(struct ixgbe_adapter *adapter, int add, int vid,
u32 vf)
@@ -495,8 +490,7 @@ static s32 ixgbe_set_vf_lpe(struct ixgbe_adapter *adapter, u32 *msgbuf, u32 vf)
static void ixgbe_set_vmolr(struct ixgbe_hw *hw, u32 vf, bool aupe)
{
u32 vmolr = IXGBE_READ_REG(hw, IXGBE_VMOLR(vf));
- vmolr |= (IXGBE_VMOLR_ROMPE |
- IXGBE_VMOLR_BAM);
+ vmolr |= IXGBE_VMOLR_BAM;
if (aupe)
vmolr |= IXGBE_VMOLR_AUPE;
else
@@ -514,7 +508,6 @@ static inline void ixgbe_vf_reset_event(struct ixgbe_adapter *adapter, u32 vf)
{
struct ixgbe_hw *hw = &adapter->hw;
struct vf_data_storage *vfinfo = &adapter->vfinfo[vf];
- int rar_entry = hw->mac.num_rar_entries - (vf + 1);
u8 num_tcs = netdev_get_num_tc(adapter->netdev);
/* add PF assigned VLAN or VLAN 0 */
@@ -544,7 +537,7 @@ static inline void ixgbe_vf_reset_event(struct ixgbe_adapter *adapter, u32 vf)
/* Flush and reset the mta with the new values */
ixgbe_set_rx_mode(adapter->netdev);
- hw->mac.ops.clear_rar(hw, rar_entry);
+ ixgbe_del_mac_filter(adapter, adapter->vfinfo[vf].vf_mac_addresses, vf);
/* reset VF api back to unknown */
adapter->vfinfo[vf].vf_api = ixgbe_mbox_api_10;
@@ -553,11 +546,9 @@ static inline void ixgbe_vf_reset_event(struct ixgbe_adapter *adapter, u32 vf)
static int ixgbe_set_vf_mac(struct ixgbe_adapter *adapter,
int vf, unsigned char *mac_addr)
{
- struct ixgbe_hw *hw = &adapter->hw;
- int rar_entry = hw->mac.num_rar_entries - (vf + 1);
-
+ ixgbe_del_mac_filter(adapter, adapter->vfinfo[vf].vf_mac_addresses, vf);
memcpy(adapter->vfinfo[vf].vf_mac_addresses, mac_addr, ETH_ALEN);
- hw->mac.ops.set_rar(hw, rar_entry, mac_addr, vf, IXGBE_RAH_AV);
+ ixgbe_add_mac_filter(adapter, adapter->vfinfo[vf].vf_mac_addresses, vf);
return 0;
}
@@ -565,7 +556,6 @@ static int ixgbe_set_vf_mac(struct ixgbe_adapter *adapter,
static int ixgbe_set_vf_macvlan(struct ixgbe_adapter *adapter,
int vf, int index, unsigned char *mac_addr)
{
- struct ixgbe_hw *hw = &adapter->hw;
struct list_head *pos;
struct vf_macvlans *entry;
@@ -576,7 +566,8 @@ static int ixgbe_set_vf_macvlan(struct ixgbe_adapter *adapter,
entry->vf = -1;
entry->free = true;
entry->is_macvlan = false;
- hw->mac.ops.clear_rar(hw, entry->rar_entry);
+ ixgbe_del_mac_filter(adapter,
+ entry->vf_macvlan, vf);
}
}
}
@@ -612,7 +603,7 @@ static int ixgbe_set_vf_macvlan(struct ixgbe_adapter *adapter,
entry->vf = vf;
memcpy(entry->vf_macvlan, mac_addr, ETH_ALEN);
- hw->mac.ops.set_rar(hw, entry->rar_entry, mac_addr, vf, IXGBE_RAH_AV);
+ ixgbe_add_mac_filter(adapter, mac_addr, vf);
return 0;
}
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.h
index 139eadd..cea6401 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_sriov.h
@@ -34,7 +34,9 @@
*/
#define IXGBE_MAX_VFS_DRV_LIMIT (IXGBE_MAX_VF_FUNCTIONS - 1)
+#ifdef CONFIG_PCI_IOV
void ixgbe_restore_vf_multicasts(struct ixgbe_adapter *adapter);
+#endif
void ixgbe_msg_task(struct ixgbe_adapter *adapter);
int ixgbe_vf_configuration(struct pci_dev *pdev, unsigned int event_mask);
void ixgbe_disable_tx_rx(struct ixgbe_adapter *adapter);
diff --git a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
index 8a6ff24..551d608 100644
--- a/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
+++ b/drivers/net/ethernet/intel/ixgbe/ixgbe_type.h
@@ -2746,7 +2746,7 @@ struct ixgbe_bus_info {
/* Flow control parameters */
struct ixgbe_fc_info {
u32 high_water[MAX_TRAFFIC_CLASS]; /* Flow Control High-water */
- u32 low_water; /* Flow Control Low-water */
+ u32 low_water[MAX_TRAFFIC_CLASS]; /* Flow Control Low-water */
u16 pause_time; /* Flow Control Pause timer */
bool send_xon; /* Flow control send XON */
bool strict_ieee; /* Strict IEEE mode */
diff --git a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
index d0799e8..eacce3a 100644
--- a/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
+++ b/drivers/net/ethernet/intel/ixgbevf/ixgbevf_main.c
@@ -85,7 +85,7 @@ static DEFINE_PCI_DEVICE_TABLE(ixgbevf_pci_tbl) = {
MODULE_DEVICE_TABLE(pci, ixgbevf_pci_tbl);
MODULE_AUTHOR("Intel Corporation, <linux.nics@intel.com>");
-MODULE_DESCRIPTION("Intel(R) 82599 Virtual Function Driver");
+MODULE_DESCRIPTION("Intel(R) 10 Gigabit Virtual Function Network Driver");
MODULE_LICENSE("GPL");
MODULE_VERSION(DRV_VERSION);
diff --git a/drivers/net/ethernet/neterion/s2io.c b/drivers/net/ethernet/neterion/s2io.c
index a2844ff..e900c1a 100644
--- a/drivers/net/ethernet/neterion/s2io.c
+++ b/drivers/net/ethernet/neterion/s2io.c
@@ -534,15 +534,6 @@ static inline void s2io_start_all_tx_queue(struct s2io_nic *sp)
netif_tx_start_all_queues(sp->dev);
}
-static inline void s2io_start_tx_queue(struct s2io_nic *sp, int fifo_no)
-{
- if (!sp->config.multiq)
- sp->mac_control.fifos[fifo_no].queue_state =
- FIFO_QUEUE_START;
-
- netif_tx_start_all_queues(sp->dev);
-}
-
static inline void s2io_wake_all_tx_queue(struct s2io_nic *sp)
{
if (!sp->config.multiq) {
diff --git a/drivers/net/ethernet/qlogic/Kconfig b/drivers/net/ethernet/qlogic/Kconfig
index c14bd31..b818432 100644
--- a/drivers/net/ethernet/qlogic/Kconfig
+++ b/drivers/net/ethernet/qlogic/Kconfig
@@ -66,6 +66,17 @@ config QLCNIC_VXLAN
Say Y here if you want to enable hardware offload support for
Virtual eXtensible Local Area Network (VXLAN) in the driver.
+config QLCNIC_HWMON
+ bool "QLOGIC QLCNIC 82XX and 83XX family HWMON support"
+ depends on QLCNIC && HWMON
+ default y
+ ---help---
+ This configuration parameter can be used to read the
+ board temperature in Converged Ethernet devices
+ supported by qlcnic.
+
+ This data is available via the hwmon sysfs interface.
+
config QLGE
tristate "QLogic QLGE 10Gb Ethernet Driver Support"
depends on PCI
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h b/drivers/net/ethernet/qlogic/qlcnic/qlcnic.h
index 7b52a88..09fe9c2 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 57
-#define QLCNIC_LINUX_VERSIONID "5.3.57"
+#define _QLCNIC_LINUX_SUBVERSION 58
+#define QLCNIC_LINUX_VERSIONID "5.3.58"
#define QLCNIC_DRV_IDC_VER 0x01
#define QLCNIC_DRIVER_VERSION ((_QLCNIC_LINUX_MAJOR << 16) |\
(_QLCNIC_LINUX_MINOR << 8) | (_QLCNIC_LINUX_SUBVERSION))
@@ -537,6 +537,7 @@ struct qlcnic_hardware_context {
u8 phys_port_id[ETH_ALEN];
u8 lb_mode;
u16 vxlan_port;
+ struct device *hwmon_dev;
};
struct qlcnic_adapter_stats {
@@ -2361,4 +2362,18 @@ static inline u32 qlcnic_get_vnic_func_count(struct qlcnic_adapter *adapter)
else
return QLC_DEFAULT_VNIC_COUNT;
}
+
+#ifdef CONFIG_QLCNIC_HWMON
+void qlcnic_register_hwmon_dev(struct qlcnic_adapter *);
+void qlcnic_unregister_hwmon_dev(struct qlcnic_adapter *);
+#else
+static inline void qlcnic_register_hwmon_dev(struct qlcnic_adapter *adapter)
+{
+ return;
+}
+static inline void qlcnic_unregister_hwmon_dev(struct qlcnic_adapter *adapter)
+{
+ return;
+}
+#endif
#endif /* __QLCNIC_H_ */
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
index b7cffb4..7c125d7 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_hw.c
@@ -33,6 +33,7 @@ static void qlcnic_83xx_get_beacon_state(struct qlcnic_adapter *);
#define RSS_HASHTYPE_IP_TCP 0x3
#define QLC_83XX_FW_MBX_CMD 0
#define QLC_SKIP_INACTIVE_PCI_REGS 7
+#define QLC_MAX_LEGACY_FUNC_SUPP 8
static const struct qlcnic_mailbox_metadata qlcnic_83xx_mbx_tbl[] = {
{QLCNIC_CMD_CONFIGURE_IP_ADDR, 6, 1},
@@ -357,8 +358,15 @@ int qlcnic_83xx_setup_intr(struct qlcnic_adapter *adapter)
if (!ahw->intr_tbl)
return -ENOMEM;
- if (!(adapter->flags & QLCNIC_MSIX_ENABLED))
+ if (!(adapter->flags & QLCNIC_MSIX_ENABLED)) {
+ if (adapter->ahw->pci_func >= QLC_MAX_LEGACY_FUNC_SUPP) {
+ dev_err(&adapter->pdev->dev, "PCI function number 8 and higher are not supported with legacy interrupt, func 0x%x\n",
+ ahw->pci_func);
+ return -EOPNOTSUPP;
+ }
+
qlcnic_83xx_enable_legacy(adapter);
+ }
for (i = 0; i < num_msix; i++) {
if (adapter->flags & QLCNIC_MSIX_ENABLED)
@@ -879,6 +887,9 @@ int qlcnic_83xx_alloc_mbx_args(struct qlcnic_cmd_args *mbx,
return 0;
}
}
+
+ dev_err(&adapter->pdev->dev, "%s: Invalid mailbox command opcode 0x%x\n",
+ __func__, type);
return -EINVAL;
}
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
index ba20c72..34d2737 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_83xx_init.c
@@ -2181,6 +2181,8 @@ int qlcnic_83xx_configure_opmode(struct qlcnic_adapter *adapter)
max_sds_rings = QLCNIC_MAX_SDS_RINGS;
max_tx_rings = QLCNIC_MAX_TX_RINGS;
} else {
+ dev_err(&adapter->pdev->dev, "%s: Invalid opmode %d\n",
+ __func__, ret);
return -EIO;
}
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c
index c1e11f5..304e247 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_ctx.c
@@ -1027,8 +1027,11 @@ int qlcnic_config_port_mirroring(struct qlcnic_adapter *adapter, u8 id,
u32 arg1;
if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC ||
- !(adapter->eswitch[id].flags & QLCNIC_SWITCH_ENABLE))
+ !(adapter->eswitch[id].flags & QLCNIC_SWITCH_ENABLE)) {
+ dev_err(&adapter->pdev->dev, "%s: Not a management function\n",
+ __func__);
return err;
+ }
arg1 = id | (enable_mirroring ? BIT_4 : 0);
arg1 |= pci_func << 8;
@@ -1318,8 +1321,12 @@ int qlcnic_config_switch_port(struct qlcnic_adapter *adapter,
u32 arg1, arg2 = 0;
u8 pci_func;
- if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC)
+ if (adapter->ahw->op_mode != QLCNIC_MGMT_FUNC) {
+ dev_err(&adapter->pdev->dev, "%s: Not a management function\n",
+ __func__);
return err;
+ }
+
pci_func = esw_cfg->pci_func;
index = qlcnic_is_valid_nic_func(adapter, pci_func);
if (index < 0)
@@ -1363,6 +1370,8 @@ int qlcnic_config_switch_port(struct qlcnic_adapter *adapter,
arg1 &= ~(0x0ffff << 16);
break;
default:
+ dev_err(&adapter->pdev->dev, "%s: Invalid opmode 0x%x\n",
+ __func__, esw_cfg->op_mode);
return err;
}
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
index 173b3d1..deb2278 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_io.c
@@ -305,7 +305,6 @@ static void qlcnic_send_filter(struct qlcnic_adapter *adapter,
{
struct vlan_ethhdr *vh = (struct vlan_ethhdr *)(skb->data);
struct ethhdr *phdr = (struct ethhdr *)(skb->data);
- struct net_device *netdev = adapter->netdev;
u16 protocol = ntohs(skb->protocol);
struct qlcnic_filter *fil, *tmp_fil;
struct hlist_head *head;
@@ -330,13 +329,6 @@ static void qlcnic_send_filter(struct qlcnic_adapter *adapter,
return;
}
- if (adapter->fhash.fnum >= adapter->fhash.fmax) {
- adapter->stats.mac_filter_limit_overrun++;
- netdev_info(netdev, "Can not add more than %d mac-vlan filters, configured %d\n",
- adapter->fhash.fmax, adapter->fhash.fnum);
- return;
- }
-
memcpy(&src_addr, phdr->h_source, ETH_ALEN);
hval = qlcnic_mac_hash(src_addr, vlan_id);
hindex = hval & (adapter->fhash.fbucket_size - 1);
@@ -353,6 +345,11 @@ static void qlcnic_send_filter(struct qlcnic_adapter *adapter,
}
}
+ if (unlikely(adapter->fhash.fnum >= adapter->fhash.fmax)) {
+ adapter->stats.mac_filter_limit_overrun++;
+ return;
+ }
+
fil = kzalloc(sizeof(struct qlcnic_filter), GFP_ATOMIC);
if (!fil)
return;
@@ -1216,8 +1213,7 @@ qlcnic_process_rcv(struct qlcnic_adapter *adapter,
if (!skb)
return buffer;
- if (adapter->drv_mac_learn &&
- (adapter->flags & QLCNIC_ESWITCH_ENABLED)) {
+ if (adapter->rx_mac_learn) {
t_vid = 0;
is_lb_pkt = qlcnic_82xx_is_lb_pkt(sts_data0);
qlcnic_add_lb_filter(adapter, skb, is_lb_pkt, t_vid);
@@ -1293,8 +1289,7 @@ qlcnic_process_lro(struct qlcnic_adapter *adapter,
if (!skb)
return buffer;
- if (adapter->drv_mac_learn &&
- (adapter->flags & QLCNIC_ESWITCH_ENABLED)) {
+ if (adapter->rx_mac_learn) {
t_vid = 0;
is_lb_pkt = qlcnic_82xx_is_lb_pkt(sts_data0);
qlcnic_add_lb_filter(adapter, skb, is_lb_pkt, t_vid);
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
index dbf7539..7023d35 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_main.c
@@ -690,10 +690,10 @@ int qlcnic_setup_tss_rss_intr(struct qlcnic_adapter *adapter)
adapter->msix_entries[vector].entry = vector;
restore:
- err = pci_enable_msix(pdev, adapter->msix_entries, num_msix);
- if (err > 0) {
+ err = pci_enable_msix_exact(pdev, adapter->msix_entries, num_msix);
+ if (err == -ENOSPC) {
if (!adapter->drv_tss_rings && !adapter->drv_rss_rings)
- return -ENOSPC;
+ return err;
netdev_info(adapter->netdev,
"Unable to allocate %d MSI-X vectors, Available vectors %d\n",
@@ -1014,6 +1014,8 @@ int qlcnic_init_pci_info(struct qlcnic_adapter *adapter)
if (pfn >= ahw->max_vnic_func) {
ret = QL_STATUS_INVALID_PARAM;
+ dev_err(&adapter->pdev->dev, "%s: Invalid function 0x%x, max 0x%x\n",
+ __func__, pfn, ahw->max_vnic_func);
goto err_eswitch;
}
@@ -2052,6 +2054,7 @@ out:
static int qlcnic_alloc_adapter_resources(struct qlcnic_adapter *adapter)
{
+ struct qlcnic_hardware_context *ahw = adapter->ahw;
int err = 0;
adapter->recv_ctx = kzalloc(sizeof(struct qlcnic_recv_context),
@@ -2061,6 +2064,18 @@ static int qlcnic_alloc_adapter_resources(struct qlcnic_adapter *adapter)
goto err_out;
}
+ if (qlcnic_83xx_check(adapter)) {
+ ahw->coal.type = QLCNIC_INTR_COAL_TYPE_RX_TX;
+ ahw->coal.tx_time_us = QLCNIC_DEF_INTR_COALESCE_TX_TIME_US;
+ ahw->coal.tx_packets = QLCNIC_DEF_INTR_COALESCE_TX_PACKETS;
+ ahw->coal.rx_time_us = QLCNIC_DEF_INTR_COALESCE_RX_TIME_US;
+ ahw->coal.rx_packets = QLCNIC_DEF_INTR_COALESCE_RX_PACKETS;
+ } else {
+ ahw->coal.type = QLCNIC_INTR_COAL_TYPE_RX;
+ ahw->coal.rx_time_us = QLCNIC_DEF_INTR_COALESCE_RX_TIME_US;
+ ahw->coal.rx_packets = QLCNIC_DEF_INTR_COALESCE_RX_PACKETS;
+ }
+
/* clear stats */
memset(&adapter->stats, 0, sizeof(adapter->stats));
err_out:
@@ -2517,9 +2532,11 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
case -ENOMEM:
dev_err(&pdev->dev, "Adapter initialization failed. Please reboot\n");
goto err_out_free_hw;
+ case -EOPNOTSUPP:
+ dev_err(&pdev->dev, "Adapter initialization failed\n");
+ goto err_out_free_hw;
default:
- dev_err(&pdev->dev, "Adapter initialization failed. A reboot may be required to recover from this failure\n");
- dev_err(&pdev->dev, "If reboot does not help to recover from this failure, try a flash update of the adapter\n");
+ dev_err(&pdev->dev, "Adapter initialization failed. Driver will load in maintenance mode to recover the adapter using the application\n");
goto err_out_maintenance_mode;
}
}
@@ -2593,7 +2610,7 @@ qlcnic_probe(struct pci_dev *pdev, const struct pci_device_id *ent)
qlcnic_alloc_lb_filters_mem(adapter);
qlcnic_add_sysfs(adapter);
-
+ qlcnic_register_hwmon_dev(adapter);
return 0;
err_out_disable_mbx_intr:
@@ -2700,6 +2717,8 @@ static void qlcnic_remove(struct pci_dev *pdev)
qlcnic_remove_sysfs(adapter);
+ qlcnic_unregister_hwmon_dev(adapter);
+
qlcnic_cleanup_pci_map(adapter->ahw);
qlcnic_release_firmware(adapter);
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c
index 2801379..c7926ce 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sriov_pf.c
@@ -16,6 +16,7 @@
#define QLC_VF_FLOOD_BIT BIT_16
#define QLC_FLOOD_MODE 0x5
#define QLC_SRIOV_ALLOW_VLAN0 BIT_19
+#define QLC_INTR_COAL_TYPE_MASK 0x7
static int qlcnic_sriov_pf_get_vport_handle(struct qlcnic_adapter *, u8);
@@ -1178,19 +1179,41 @@ static int qlcnic_sriov_validate_cfg_intrcoal(struct qlcnic_adapter *adapter,
{
struct qlcnic_nic_intr_coalesce *coal = &adapter->ahw->coal;
u16 ctx_id, pkts, time;
+ int err = -EINVAL;
+ u8 type;
+ type = cmd->req.arg[1] & QLC_INTR_COAL_TYPE_MASK;
ctx_id = cmd->req.arg[1] >> 16;
pkts = cmd->req.arg[2] & 0xffff;
time = cmd->req.arg[2] >> 16;
- if (ctx_id != vf->rx_ctx_id)
- return -EINVAL;
- if (pkts > coal->rx_packets)
- return -EINVAL;
- if (time < coal->rx_time_us)
- return -EINVAL;
+ switch (type) {
+ case QLCNIC_INTR_COAL_TYPE_RX:
+ if (ctx_id != vf->rx_ctx_id || pkts > coal->rx_packets ||
+ time < coal->rx_time_us)
+ goto err_label;
+ break;
+ case QLCNIC_INTR_COAL_TYPE_TX:
+ if (ctx_id != vf->tx_ctx_id || pkts > coal->tx_packets ||
+ time < coal->tx_time_us)
+ goto err_label;
+ break;
+ default:
+ netdev_err(adapter->netdev, "Invalid coalescing type 0x%x received\n",
+ type);
+ return err;
+ }
return 0;
+
+err_label:
+ netdev_err(adapter->netdev, "Expected: rx_ctx_id 0x%x rx_packets 0x%x rx_time_us 0x%x tx_ctx_id 0x%x tx_packets 0x%x tx_time_us 0x%x\n",
+ vf->rx_ctx_id, coal->rx_packets, coal->rx_time_us,
+ vf->tx_ctx_id, coal->tx_packets, coal->tx_time_us);
+ netdev_err(adapter->netdev, "Received: ctx_id 0x%x packets 0x%x time_us 0x%x type 0x%x\n",
+ ctx_id, pkts, time, type);
+
+ return err;
}
static int qlcnic_sriov_pf_cfg_intrcoal_cmd(struct qlcnic_bc_trans *tran,
diff --git a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c
index cd346e2..f5786d5 100644
--- a/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c
+++ b/drivers/net/ethernet/qlogic/qlcnic/qlcnic_sysfs.c
@@ -19,6 +19,10 @@
#include <linux/sysfs.h>
#include <linux/aer.h>
#include <linux/log2.h>
+#ifdef CONFIG_QLCNIC_HWMON
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#endif
#define QLC_STATUS_UNSUPPORTED_CMD -2
@@ -358,6 +362,8 @@ int qlcnic_is_valid_nic_func(struct qlcnic_adapter *adapter, u8 pci_func)
if (adapter->npars[i].pci_func == pci_func)
return i;
}
+
+ dev_err(&adapter->pdev->dev, "%s: Invalid nic function\n", __func__);
return -EINVAL;
}
@@ -1243,6 +1249,68 @@ static struct bin_attribute bin_attr_flash = {
.write = qlcnic_83xx_sysfs_flash_write_handler,
};
+#ifdef CONFIG_QLCNIC_HWMON
+
+static ssize_t qlcnic_hwmon_show_temp(struct device *dev,
+ struct device_attribute *dev_attr,
+ char *buf)
+{
+ struct qlcnic_adapter *adapter = dev_get_drvdata(dev);
+ unsigned int temperature = 0, value = 0;
+
+ if (qlcnic_83xx_check(adapter))
+ value = QLCRDX(adapter->ahw, QLC_83XX_ASIC_TEMP);
+ else if (qlcnic_82xx_check(adapter))
+ value = QLC_SHARED_REG_RD32(adapter, QLCNIC_ASIC_TEMP);
+
+ temperature = qlcnic_get_temp_val(value);
+ /* display millidegree celcius */
+ temperature *= 1000;
+ return sprintf(buf, "%u\n", temperature);
+}
+
+/* hwmon-sysfs attributes */
+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO,
+ qlcnic_hwmon_show_temp, NULL, 1);
+
+static struct attribute *qlcnic_hwmon_attrs[] = {
+ &sensor_dev_attr_temp1_input.dev_attr.attr,
+ NULL
+};
+
+ATTRIBUTE_GROUPS(qlcnic_hwmon);
+
+void qlcnic_register_hwmon_dev(struct qlcnic_adapter *adapter)
+{
+ struct device *dev = &adapter->pdev->dev;
+ struct device *hwmon_dev;
+
+ /* Skip hwmon registration for a VF device */
+ if (qlcnic_sriov_vf_check(adapter)) {
+ adapter->ahw->hwmon_dev = NULL;
+ return;
+ }
+ hwmon_dev = hwmon_device_register_with_groups(dev, qlcnic_driver_name,
+ adapter,
+ qlcnic_hwmon_groups);
+ if (IS_ERR(hwmon_dev)) {
+ dev_err(dev, "Cannot register with hwmon, err=%ld\n",
+ PTR_ERR(hwmon_dev));
+ hwmon_dev = NULL;
+ }
+ adapter->ahw->hwmon_dev = hwmon_dev;
+}
+
+void qlcnic_unregister_hwmon_dev(struct qlcnic_adapter *adapter)
+{
+ struct device *hwmon_dev = adapter->ahw->hwmon_dev;
+ if (hwmon_dev) {
+ hwmon_device_unregister(hwmon_dev);
+ adapter->ahw->hwmon_dev = NULL;
+ }
+}
+#endif
+
void qlcnic_create_sysfs_entries(struct qlcnic_adapter *adapter)
{
struct device *dev = &adapter->pdev->dev;
diff --git a/drivers/net/ethernet/qlogic/qlge/qlge_main.c b/drivers/net/ethernet/qlogic/qlge/qlge_main.c
index 0a1d76ac..6e36fe1 100644
--- a/drivers/net/ethernet/qlogic/qlge/qlge_main.c
+++ b/drivers/net/ethernet/qlogic/qlge/qlge_main.c
@@ -3595,7 +3595,7 @@ static int ql_request_irq(struct ql_adapter *qdev)
}
return status;
err_irq:
- netif_err(qdev, ifup, qdev->ndev, "Failed to get the interrupts!!!/n");
+ netif_err(qdev, ifup, qdev->ndev, "Failed to get the interrupts!!!\n");
ql_free_irq(qdev);
return status;
}
diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_desc.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_desc.c
index e896dbb..d71691b 100644
--- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_desc.c
+++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_desc.c
@@ -45,10 +45,10 @@ static void sxgbe_prepare_tx_desc(struct sxgbe_tx_norm_desc *p, u8 is_fd,
p->tdes23.tx_rd_des23.first_desc = is_fd;
p->tdes23.tx_rd_des23.buf1_size = buf1_len;
- p->tdes23.tx_rd_des23.tx_pkt_len.cksum_pktlen.total_pkt_len = pkt_len;
+ p->tdes23.tx_rd_des23.tx_pkt_len.pkt_len.total_pkt_len = pkt_len;
if (cksum)
- p->tdes23.tx_rd_des23.tx_pkt_len.cksum_pktlen.cksum_ctl = cic_full;
+ p->tdes23.tx_rd_des23.cksum_ctl = cic_full;
}
/* Set VLAN control information */
diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_desc.h b/drivers/net/ethernet/samsung/sxgbe/sxgbe_desc.h
index 838cb9f..0226300 100644
--- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_desc.h
+++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_desc.h
@@ -39,22 +39,22 @@ struct sxgbe_tx_norm_desc {
u32 int_on_com:1;
/* TDES3 */
union {
- u32 tcp_payload_len:18;
+ u16 tcp_payload_len;
struct {
u32 total_pkt_len:15;
u32 reserved1:1;
- u32 cksum_ctl:2;
- } cksum_pktlen;
+ } pkt_len;
} tx_pkt_len;
- u32 tse_bit:1;
- u32 tcp_hdr_len:4;
- u32 sa_insert_ctl:3;
- u32 crc_pad_ctl:2;
- u32 last_desc:1;
- u32 first_desc:1;
- u32 ctxt_bit:1;
- u32 own_bit:1;
+ u16 cksum_ctl:2;
+ u16 tse_bit:1;
+ u16 tcp_hdr_len:4;
+ u16 sa_insert_ctl:3;
+ u16 crc_pad_ctl:2;
+ u16 last_desc:1;
+ u16 first_desc:1;
+ u16 ctxt_bit:1;
+ u16 own_bit:1;
} tx_rd_des23;
/* tx write back Desc 2,3 */
@@ -70,25 +70,20 @@ struct sxgbe_tx_norm_desc {
struct sxgbe_rx_norm_desc {
union {
- u32 rdes0; /* buf1 address */
- struct {
+ u64 rdes01; /* buf1 address */
+ union {
u32 out_vlan_tag:16;
u32 in_vlan_tag:16;
- } wb_rx_des0;
- } rd_wb_des0;
-
- union {
- u32 rdes1; /* buf2 address or buf1[63:32] */
- u32 rss_hash; /* Write-back RX */
- } rd_wb_des1;
+ u32 rss_hash;
+ } rx_wb_des01;
+ } rdes01;
union {
/* RX Read format Desc 2,3 */
struct{
/* RDES2 */
- u32 buf2_addr;
+ u64 buf2_addr:62;
/* RDES3 */
- u32 buf2_hi_addr:30;
u32 int_on_com:1;
u32 own_bit:1;
} rx_rd_des23;
diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
index 27e8c82..137f366 100644
--- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
+++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_main.c
@@ -425,8 +425,8 @@ dmamem_err:
* @rx_rsize: ring size
* Description: this function initializes the DMA RX descriptor
*/
-void free_rx_ring(struct device *dev, struct sxgbe_rx_queue *rx_ring,
- int rx_rsize)
+static void free_rx_ring(struct device *dev, struct sxgbe_rx_queue *rx_ring,
+ int rx_rsize)
{
dma_free_coherent(dev, rx_rsize * sizeof(struct sxgbe_rx_norm_desc),
rx_ring->dma_rx, rx_ring->dma_rx_phy);
@@ -519,8 +519,8 @@ error:
* @tx_rsize: ring size
* Description: this function initializes the DMA TX descriptor
*/
-void free_tx_ring(struct device *dev, struct sxgbe_tx_queue *tx_ring,
- int tx_rsize)
+static void free_tx_ring(struct device *dev, struct sxgbe_tx_queue *tx_ring,
+ int tx_rsize)
{
dma_free_coherent(dev, tx_rsize * sizeof(struct sxgbe_tx_norm_desc),
tx_ring->dma_tx, tx_ring->dma_tx_phy);
@@ -1218,11 +1218,10 @@ static int sxgbe_release(struct net_device *dev)
return 0;
}
-
/* Prepare first Tx descriptor for doing TSO operation */
-void sxgbe_tso_prepare(struct sxgbe_priv_data *priv,
- struct sxgbe_tx_norm_desc *first_desc,
- struct sk_buff *skb)
+static void sxgbe_tso_prepare(struct sxgbe_priv_data *priv,
+ struct sxgbe_tx_norm_desc *first_desc,
+ struct sk_buff *skb)
{
unsigned int total_hdr_len, tcp_hdr_len;
@@ -1910,40 +1909,6 @@ static void sxgbe_set_rx_mode(struct net_device *dev)
readl(ioaddr + SXGBE_HASH_LOW));
}
-/**
- * sxgbe_config - entry point for changing configuration mode passed on by
- * ifconfig
- * @dev : pointer to the device structure
- * @map : pointer to the device mapping structure
- * Description:
- * This function is a driver entry point which gets called by the kernel
- * whenever some device configuration is changed.
- * Return value:
- * This function returns 0 if success and appropriate error otherwise.
- */
-static int sxgbe_config(struct net_device *dev, struct ifmap *map)
-{
- struct sxgbe_priv_data *priv = netdev_priv(dev);
-
- /* Can't act on a running interface */
- if (dev->flags & IFF_UP)
- return -EBUSY;
-
- /* Don't allow changing the I/O address */
- if (map->base_addr != (unsigned long)priv->ioaddr) {
- netdev_warn(dev, "can't change I/O address\n");
- return -EOPNOTSUPP;
- }
-
- /* Don't allow changing the IRQ */
- if (map->irq != priv->irq) {
- netdev_warn(dev, "not change IRQ number %d\n", priv->irq);
- return -EOPNOTSUPP;
- }
-
- return 0;
-}
-
#ifdef CONFIG_NET_POLL_CONTROLLER
/**
* sxgbe_poll_controller - entry point for polling receive by device
@@ -2005,7 +1970,6 @@ static const struct net_device_ops sxgbe_netdev_ops = {
.ndo_set_rx_mode = sxgbe_set_rx_mode,
.ndo_tx_timeout = sxgbe_tx_timeout,
.ndo_do_ioctl = sxgbe_ioctl,
- .ndo_set_config = sxgbe_config,
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = sxgbe_poll_controller,
#endif
diff --git a/drivers/net/ethernet/samsung/sxgbe/sxgbe_mdio.c b/drivers/net/ethernet/samsung/sxgbe/sxgbe_mdio.c
index 01af2cb..43ccb4a 100644
--- a/drivers/net/ethernet/samsung/sxgbe/sxgbe_mdio.c
+++ b/drivers/net/ethernet/samsung/sxgbe/sxgbe_mdio.c
@@ -27,7 +27,7 @@
#define SXGBE_SMA_PREAD_CMD 0x02 /* post read increament address */
#define SXGBE_SMA_READ_CMD 0x03 /* read command */
#define SXGBE_SMA_SKIP_ADDRFRM 0x00040000 /* skip the address frame */
-#define SXGBE_MII_BUSY 0x00800000 /* mii busy */
+#define SXGBE_MII_BUSY 0x00400000 /* mii busy */
static int sxgbe_mdio_busy_wait(void __iomem *ioaddr, unsigned int mii_data)
{
@@ -147,6 +147,7 @@ int sxgbe_mdio_register(struct net_device *ndev)
struct sxgbe_mdio_bus_data *mdio_data = priv->plat->mdio_bus_data;
int err, phy_addr;
int *irqlist;
+ bool phy_found = false;
bool act;
/* allocate the new mdio bus */
@@ -162,7 +163,7 @@ int sxgbe_mdio_register(struct net_device *ndev)
irqlist = priv->mii_irq;
/* assign mii bus fields */
- mdio_bus->name = "samsxgbe";
+ mdio_bus->name = "sxgbe";
mdio_bus->read = &sxgbe_mdio_read;
mdio_bus->write = &sxgbe_mdio_write;
snprintf(mdio_bus->id, MII_BUS_ID_SIZE, "%s-%x",
@@ -216,13 +217,22 @@ int sxgbe_mdio_register(struct net_device *ndev)
netdev_info(ndev, "PHY ID %08x at %d IRQ %s (%s)%s\n",
phy->phy_id, phy_addr, irq_str,
dev_name(&phy->dev), act ? " active" : "");
+ phy_found = true;
}
}
+ if (!phy_found) {
+ netdev_err(ndev, "PHY not found\n");
+ goto phyfound_err;
+ }
+
priv->mii = mdio_bus;
return 0;
+phyfound_err:
+ err = -ENODEV;
+ mdiobus_unregister(mdio_bus);
mdiobus_err:
mdiobus_free(mdio_bus);
return err;
diff --git a/drivers/net/ethernet/smsc/smc91x.c b/drivers/net/ethernet/smsc/smc91x.c
index d1b4dca..bcaa41a 100644
--- a/drivers/net/ethernet/smsc/smc91x.c
+++ b/drivers/net/ethernet/smsc/smc91x.c
@@ -147,18 +147,19 @@ MODULE_ALIAS("platform:smc91x");
*/
#define MII_DELAY 1
-#if SMC_DEBUG > 0
-#define DBG(n, dev, args...) \
- do { \
- if (SMC_DEBUG >= (n)) \
- netdev_dbg(dev, args); \
+#define DBG(n, dev, fmt, ...) \
+ do { \
+ if (SMC_DEBUG >= (n)) \
+ netdev_dbg(dev, fmt, ##__VA_ARGS__); \
} while (0)
-#define PRINTK(dev, args...) netdev_info(dev, args)
-#else
-#define DBG(n, dev, args...) do { } while (0)
-#define PRINTK(dev, args...) netdev_dbg(dev, args)
-#endif
+#define PRINTK(dev, fmt, ...) \
+ do { \
+ if (SMC_DEBUG > 0) \
+ netdev_info(dev, fmt, ##__VA_ARGS__); \
+ else \
+ netdev_dbg(dev, fmt, ##__VA_ARGS__); \
+ } while (0)
#if SMC_DEBUG > 3
static void PRINT_PKT(u_char *buf, int length)
@@ -191,7 +192,7 @@ static void PRINT_PKT(u_char *buf, int length)
pr_cont("\n");
}
#else
-#define PRINT_PKT(x...) do { } while (0)
+static inline void PRINT_PKT(u_char *buf, int length) { }
#endif
@@ -1781,7 +1782,7 @@ static int smc_findirq(struct smc_local *lp)
int timeout = 20;
unsigned long cookie;
- DBG(2, dev, "%s: %s\n", CARDNAME, __func__);
+ DBG(2, lp->dev, "%s: %s\n", CARDNAME, __func__);
cookie = probe_irq_on();
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
index d940034..93cf4f6 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
@@ -2214,27 +2214,6 @@ static void stmmac_tx_timeout(struct net_device *dev)
stmmac_tx_err(priv);
}
-/* Configuration changes (passed on by ifconfig) */
-static int stmmac_config(struct net_device *dev, struct ifmap *map)
-{
- if (dev->flags & IFF_UP) /* can't act on a running interface */
- return -EBUSY;
-
- /* Don't allow changing the I/O address */
- if (map->base_addr != dev->base_addr) {
- pr_warn("%s: can't change I/O address\n", dev->name);
- return -EOPNOTSUPP;
- }
-
- /* Don't allow changing the IRQ */
- if (map->irq != dev->irq) {
- pr_warn("%s: not change IRQ number %d\n", dev->name, dev->irq);
- return -EOPNOTSUPP;
- }
-
- return 0;
-}
-
/**
* stmmac_set_rx_mode - entry point for multicast addressing
* @dev : pointer to the device structure
@@ -2600,7 +2579,6 @@ static const struct net_device_ops stmmac_netdev_ops = {
.ndo_set_rx_mode = stmmac_set_rx_mode,
.ndo_tx_timeout = stmmac_tx_timeout,
.ndo_do_ioctl = stmmac_ioctl,
- .ndo_set_config = stmmac_config,
#ifdef CONFIG_NET_POLL_CONTROLLER
.ndo_poll_controller = stmmac_poll_controller,
#endif
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
index a468eb1..a5b1e1b 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_mdio.c
@@ -205,10 +205,13 @@ int stmmac_mdio_register(struct net_device *ndev)
if (new_bus == NULL)
return -ENOMEM;
- if (mdio_bus_data->irqs)
+ if (mdio_bus_data->irqs) {
irqlist = mdio_bus_data->irqs;
- else
+ } else {
+ for (addr = 0; addr < PHY_MAX_ADDR; addr++)
+ priv->mii_irq[addr] = PHY_POLL;
irqlist = priv->mii_irq;
+ }
#ifdef CONFIG_OF
if (priv->device->of_node)
diff --git a/drivers/net/ethernet/ti/cpmac.c b/drivers/net/ethernet/ti/cpmac.c
index 73f74f3..7399a52 100644
--- a/drivers/net/ethernet/ti/cpmac.c
+++ b/drivers/net/ethernet/ti/cpmac.c
@@ -313,19 +313,6 @@ static int mii_irqs[PHY_MAX_ADDR] = { PHY_POLL, };
static struct mii_bus *cpmac_mii;
-static int cpmac_config(struct net_device *dev, struct ifmap *map)
-{
- if (dev->flags & IFF_UP)
- return -EBUSY;
-
- /* Don't allow changing the I/O address */
- if (map->base_addr != dev->base_addr)
- return -EOPNOTSUPP;
-
- /* ignore other fields */
- return 0;
-}
-
static void cpmac_set_multicast_list(struct net_device *dev)
{
struct netdev_hw_addr *ha;
@@ -1100,7 +1087,6 @@ static const struct net_device_ops cpmac_netdev_ops = {
.ndo_tx_timeout = cpmac_tx_timeout,
.ndo_set_rx_mode = cpmac_set_multicast_list,
.ndo_do_ioctl = cpmac_ioctl,
- .ndo_set_config = cpmac_config,
.ndo_change_mtu = eth_change_mtu,
.ndo_validate_addr = eth_validate_addr,
.ndo_set_mac_address = eth_mac_addr,
diff --git a/drivers/net/ethernet/via/Kconfig b/drivers/net/ethernet/via/Kconfig
index 8a049a2..f66ddae 100644
--- a/drivers/net/ethernet/via/Kconfig
+++ b/drivers/net/ethernet/via/Kconfig
@@ -19,7 +19,7 @@ if NET_VENDOR_VIA
config VIA_RHINE
tristate "VIA Rhine support"
- depends on PCI
+ depends on (PCI || USE_OF)
select CRC32
select MII
---help---
diff --git a/drivers/net/ethernet/via/via-rhine.c b/drivers/net/ethernet/via/via-rhine.c
index f61dc2b..4fa9201 100644
--- a/drivers/net/ethernet/via/via-rhine.c
+++ b/drivers/net/ethernet/via/via-rhine.c
@@ -94,6 +94,10 @@ static const int multicast_filter_limit = 32;
#include <linux/ioport.h>
#include <linux/interrupt.h>
#include <linux/pci.h>
+#include <linux/of_address.h>
+#include <linux/of_device.h>
+#include <linux/of_irq.h>
+#include <linux/platform_device.h>
#include <linux/dma-mapping.h>
#include <linux/netdevice.h>
#include <linux/etherdevice.h>
@@ -279,6 +283,15 @@ static DEFINE_PCI_DEVICE_TABLE(rhine_pci_tbl) = {
};
MODULE_DEVICE_TABLE(pci, rhine_pci_tbl);
+/* OpenFirmware identifiers for platform-bus devices
+ * The .data field is currently only used to store chip revision
+ * (for quirks etc.)
+ */
+static struct of_device_id rhine_of_tbl[] = {
+ { .compatible = "via,vt8500-rhine", .data = (void *)0x84 },
+ { } /* terminate list */
+};
+MODULE_DEVICE_TABLE(of, rhine_of_tbl);
/* Offsets to the device registers. */
enum register_offsets {
@@ -446,7 +459,8 @@ struct rhine_private {
unsigned char *tx_bufs;
dma_addr_t tx_bufs_dma;
- struct pci_dev *pdev;
+ int revision;
+ int irq;
long pioaddr;
struct net_device *dev;
struct napi_struct napi;
@@ -701,7 +715,7 @@ static void rhine_reload_eeprom(long pioaddr, struct net_device *dev)
static void rhine_poll(struct net_device *dev)
{
struct rhine_private *rp = netdev_priv(dev);
- const int irq = rp->pdev->irq;
+ const int irq = rp->irq;
disable_irq(irq);
rhine_interrupt(irq, dev);
@@ -846,7 +860,8 @@ static void rhine_hw_init(struct net_device *dev, long pioaddr)
msleep(5);
/* Reload EEPROM controlled bytes cleared by soft reset */
- rhine_reload_eeprom(pioaddr, dev);
+ if (dev_is_pci(dev->dev.parent))
+ rhine_reload_eeprom(pioaddr, dev);
}
static const struct net_device_ops rhine_netdev_ops = {
@@ -867,125 +882,55 @@ static const struct net_device_ops rhine_netdev_ops = {
#endif
};
-static int rhine_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
+static int rhine_init_one_common(struct device *hwdev, int revision,
+ long pioaddr, void __iomem *ioaddr, int irq)
{
struct net_device *dev;
struct rhine_private *rp;
- int i, rc;
- u32 quirks;
- long pioaddr;
- long memaddr;
- void __iomem *ioaddr;
- int io_size, phy_id;
+ int i, rc, phy_id;
const char *name;
-#ifdef USE_MMIO
- int bar = 1;
-#else
- int bar = 0;
-#endif
-
-/* when built into the kernel, we only print version if device is found */
-#ifndef MODULE
- pr_info_once("%s\n", version);
-#endif
-
- io_size = 256;
- phy_id = 0;
- quirks = 0;
- name = "Rhine";
- if (pdev->revision < VTunknown0) {
- quirks = rqRhineI;
- io_size = 128;
- }
- else if (pdev->revision >= VT6102) {
- quirks = rqWOL | rqForceReset;
- if (pdev->revision < VT6105) {
- name = "Rhine II";
- quirks |= rqStatusWBRace; /* Rhine-II exclusive */
- }
- else {
- phy_id = 1; /* Integrated PHY, phy_id fixed to 1 */
- if (pdev->revision >= VT6105_B0)
- quirks |= rq6patterns;
- if (pdev->revision < VT6105M)
- name = "Rhine III";
- else
- name = "Rhine III (Management Adapter)";
- }
- }
-
- rc = pci_enable_device(pdev);
- if (rc)
- goto err_out;
/* this should always be supported */
- rc = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
+ rc = dma_set_mask(hwdev, DMA_BIT_MASK(32));
if (rc) {
- dev_err(&pdev->dev,
- "32-bit PCI DMA addresses not supported by the card!?\n");
- goto err_out_pci_disable;
- }
-
- /* sanity check */
- if ((pci_resource_len(pdev, 0) < io_size) ||
- (pci_resource_len(pdev, 1) < io_size)) {
- rc = -EIO;
- dev_err(&pdev->dev, "Insufficient PCI resources, aborting\n");
- goto err_out_pci_disable;
+ dev_err(hwdev, "32-bit DMA addresses not supported by the card!?\n");
+ goto err_out;
}
- pioaddr = pci_resource_start(pdev, 0);
- memaddr = pci_resource_start(pdev, 1);
-
- pci_set_master(pdev);
-
dev = alloc_etherdev(sizeof(struct rhine_private));
if (!dev) {
rc = -ENOMEM;
- goto err_out_pci_disable;
+ goto err_out;
}
- SET_NETDEV_DEV(dev, &pdev->dev);
+ SET_NETDEV_DEV(dev, hwdev);
rp = netdev_priv(dev);
rp->dev = dev;
- rp->quirks = quirks;
+ rp->revision = revision;
rp->pioaddr = pioaddr;
- rp->pdev = pdev;
+ rp->base = ioaddr;
+ rp->irq = irq;
rp->msg_enable = netif_msg_init(debug, RHINE_MSG_DEFAULT);
- rc = pci_request_regions(pdev, DRV_NAME);
- if (rc)
- goto err_out_free_netdev;
-
- ioaddr = pci_iomap(pdev, bar, io_size);
- if (!ioaddr) {
- rc = -EIO;
- dev_err(&pdev->dev,
- "ioremap failed for device %s, region 0x%X @ 0x%lX\n",
- pci_name(pdev), io_size, memaddr);
- goto err_out_free_res;
- }
-
-#ifdef USE_MMIO
- enable_mmio(pioaddr, quirks);
-
- /* Check that selected MMIO registers match the PIO ones */
- i = 0;
- while (mmio_verify_registers[i]) {
- int reg = mmio_verify_registers[i++];
- unsigned char a = inb(pioaddr+reg);
- unsigned char b = readb(ioaddr+reg);
- if (a != b) {
- rc = -EIO;
- dev_err(&pdev->dev,
- "MMIO do not match PIO [%02x] (%02x != %02x)\n",
- reg, a, b);
- goto err_out_unmap;
+ phy_id = 0;
+ name = "Rhine";
+ if (revision < VTunknown0) {
+ rp->quirks = rqRhineI;
+ } else if (revision >= VT6102) {
+ rp->quirks = rqWOL | rqForceReset;
+ if (revision < VT6105) {
+ name = "Rhine II";
+ rp->quirks |= rqStatusWBRace; /* Rhine-II exclusive */
+ } else {
+ phy_id = 1; /* Integrated PHY, phy_id fixed to 1 */
+ if (revision >= VT6105_B0)
+ rp->quirks |= rq6patterns;
+ if (revision < VT6105M)
+ name = "Rhine III";
+ else
+ name = "Rhine III (Management Adapter)";
}
}
-#endif /* USE_MMIO */
-
- rp->base = ioaddr;
u64_stats_init(&rp->tx_stats.syncp);
u64_stats_init(&rp->rx_stats.syncp);
@@ -1030,7 +975,7 @@ static int rhine_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (rp->quirks & rqRhineI)
dev->features |= NETIF_F_SG|NETIF_F_HW_CSUM;
- if (pdev->revision >= VT6105M)
+ if (rp->revision >= VT6105M)
dev->features |= NETIF_F_HW_VLAN_CTAG_TX |
NETIF_F_HW_VLAN_CTAG_RX |
NETIF_F_HW_VLAN_CTAG_FILTER;
@@ -1038,18 +983,12 @@ static int rhine_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
/* dev->name not defined before register_netdev()! */
rc = register_netdev(dev);
if (rc)
- goto err_out_unmap;
+ goto err_out_free_netdev;
netdev_info(dev, "VIA %s at 0x%lx, %pM, IRQ %d\n",
- name,
-#ifdef USE_MMIO
- memaddr,
-#else
- (long)ioaddr,
-#endif
- dev->dev_addr, pdev->irq);
+ name, (long)ioaddr, dev->dev_addr, rp->irq);
- pci_set_drvdata(pdev, dev);
+ dev_set_drvdata(hwdev, dev);
{
u16 mii_cmd;
@@ -1078,41 +1017,152 @@ static int rhine_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
return 0;
+err_out_free_netdev:
+ free_netdev(dev);
+err_out:
+ return rc;
+}
+
+static int rhine_init_one_pci(struct pci_dev *pdev,
+ const struct pci_device_id *ent)
+{
+ struct device *hwdev = &pdev->dev;
+ int i, rc;
+ long pioaddr, memaddr;
+ void __iomem *ioaddr;
+ int io_size = pdev->revision < VTunknown0 ? 128 : 256;
+ u32 quirks = pdev->revision < VTunknown0 ? rqRhineI : 0;
+#ifdef USE_MMIO
+ int bar = 1;
+#else
+ int bar = 0;
+#endif
+
+/* when built into the kernel, we only print version if device is found */
+#ifndef MODULE
+ pr_info_once("%s\n", version);
+#endif
+
+ rc = pci_enable_device(pdev);
+ if (rc)
+ goto err_out;
+
+ /* sanity check */
+ if ((pci_resource_len(pdev, 0) < io_size) ||
+ (pci_resource_len(pdev, 1) < io_size)) {
+ rc = -EIO;
+ dev_err(hwdev, "Insufficient PCI resources, aborting\n");
+ goto err_out_pci_disable;
+ }
+
+ pioaddr = pci_resource_start(pdev, 0);
+ memaddr = pci_resource_start(pdev, 1);
+
+ pci_set_master(pdev);
+
+ rc = pci_request_regions(pdev, DRV_NAME);
+ if (rc)
+ goto err_out_pci_disable;
+
+ ioaddr = pci_iomap(pdev, bar, io_size);
+ if (!ioaddr) {
+ rc = -EIO;
+ dev_err(hwdev,
+ "ioremap failed for device %s, region 0x%X @ 0x%lX\n",
+ dev_name(hwdev), io_size, memaddr);
+ goto err_out_free_res;
+ }
+
+#ifdef USE_MMIO
+ enable_mmio(pioaddr, quirks);
+
+ /* Check that selected MMIO registers match the PIO ones */
+ i = 0;
+ while (mmio_verify_registers[i]) {
+ int reg = mmio_verify_registers[i++];
+ unsigned char a = inb(pioaddr+reg);
+ unsigned char b = readb(ioaddr+reg);
+
+ if (a != b) {
+ rc = -EIO;
+ dev_err(hwdev,
+ "MMIO do not match PIO [%02x] (%02x != %02x)\n",
+ reg, a, b);
+ goto err_out_unmap;
+ }
+ }
+#endif /* USE_MMIO */
+
+ rc = rhine_init_one_common(&pdev->dev, pdev->revision,
+ pioaddr, ioaddr, pdev->irq);
+ if (!rc)
+ return 0;
+
err_out_unmap:
pci_iounmap(pdev, ioaddr);
err_out_free_res:
pci_release_regions(pdev);
-err_out_free_netdev:
- free_netdev(dev);
err_out_pci_disable:
pci_disable_device(pdev);
err_out:
return rc;
}
+static int rhine_init_one_platform(struct platform_device *pdev)
+{
+ const struct of_device_id *match;
+ u32 revision;
+ int irq;
+ struct resource *res;
+ void __iomem *ioaddr;
+
+ match = of_match_device(rhine_of_tbl, &pdev->dev);
+ if (!match)
+ return -EINVAL;
+
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ ioaddr = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(ioaddr))
+ return PTR_ERR(ioaddr);
+
+ irq = irq_of_parse_and_map(pdev->dev.of_node, 0);
+ if (!irq)
+ return -EINVAL;
+
+ revision = (u32)match->data;
+ if (!revision)
+ return -EINVAL;
+
+ return rhine_init_one_common(&pdev->dev, revision,
+ (long)ioaddr, ioaddr, irq);
+}
+
static int alloc_ring(struct net_device* dev)
{
struct rhine_private *rp = netdev_priv(dev);
+ struct device *hwdev = dev->dev.parent;
void *ring;
dma_addr_t ring_dma;
- ring = pci_alloc_consistent(rp->pdev,
- RX_RING_SIZE * sizeof(struct rx_desc) +
- TX_RING_SIZE * sizeof(struct tx_desc),
- &ring_dma);
+ ring = dma_alloc_coherent(hwdev,
+ RX_RING_SIZE * sizeof(struct rx_desc) +
+ TX_RING_SIZE * sizeof(struct tx_desc),
+ &ring_dma,
+ GFP_ATOMIC);
if (!ring) {
netdev_err(dev, "Could not allocate DMA memory\n");
return -ENOMEM;
}
if (rp->quirks & rqRhineI) {
- rp->tx_bufs = pci_alloc_consistent(rp->pdev,
- PKT_BUF_SZ * TX_RING_SIZE,
- &rp->tx_bufs_dma);
+ rp->tx_bufs = dma_alloc_coherent(hwdev,
+ PKT_BUF_SZ * TX_RING_SIZE,
+ &rp->tx_bufs_dma,
+ GFP_ATOMIC);
if (rp->tx_bufs == NULL) {
- pci_free_consistent(rp->pdev,
- RX_RING_SIZE * sizeof(struct rx_desc) +
- TX_RING_SIZE * sizeof(struct tx_desc),
- ring, ring_dma);
+ dma_free_coherent(hwdev,
+ RX_RING_SIZE * sizeof(struct rx_desc) +
+ TX_RING_SIZE * sizeof(struct tx_desc),
+ ring, ring_dma);
return -ENOMEM;
}
}
@@ -1128,16 +1178,17 @@ static int alloc_ring(struct net_device* dev)
static void free_ring(struct net_device* dev)
{
struct rhine_private *rp = netdev_priv(dev);
+ struct device *hwdev = dev->dev.parent;
- pci_free_consistent(rp->pdev,
- RX_RING_SIZE * sizeof(struct rx_desc) +
- TX_RING_SIZE * sizeof(struct tx_desc),
- rp->rx_ring, rp->rx_ring_dma);
+ dma_free_coherent(hwdev,
+ RX_RING_SIZE * sizeof(struct rx_desc) +
+ TX_RING_SIZE * sizeof(struct tx_desc),
+ rp->rx_ring, rp->rx_ring_dma);
rp->tx_ring = NULL;
if (rp->tx_bufs)
- pci_free_consistent(rp->pdev, PKT_BUF_SZ * TX_RING_SIZE,
- rp->tx_bufs, rp->tx_bufs_dma);
+ dma_free_coherent(hwdev, PKT_BUF_SZ * TX_RING_SIZE,
+ rp->tx_bufs, rp->tx_bufs_dma);
rp->tx_bufs = NULL;
@@ -1146,6 +1197,7 @@ static void free_ring(struct net_device* dev)
static void alloc_rbufs(struct net_device *dev)
{
struct rhine_private *rp = netdev_priv(dev);
+ struct device *hwdev = dev->dev.parent;
dma_addr_t next;
int i;
@@ -1174,9 +1226,9 @@ static void alloc_rbufs(struct net_device *dev)
break;
rp->rx_skbuff_dma[i] =
- pci_map_single(rp->pdev, skb->data, rp->rx_buf_sz,
- PCI_DMA_FROMDEVICE);
- if (dma_mapping_error(&rp->pdev->dev, rp->rx_skbuff_dma[i])) {
+ dma_map_single(hwdev, skb->data, rp->rx_buf_sz,
+ DMA_FROM_DEVICE);
+ if (dma_mapping_error(hwdev, rp->rx_skbuff_dma[i])) {
rp->rx_skbuff_dma[i] = 0;
dev_kfree_skb(skb);
break;
@@ -1190,6 +1242,7 @@ static void alloc_rbufs(struct net_device *dev)
static void free_rbufs(struct net_device* dev)
{
struct rhine_private *rp = netdev_priv(dev);
+ struct device *hwdev = dev->dev.parent;
int i;
/* Free all the skbuffs in the Rx queue. */
@@ -1197,9 +1250,9 @@ static void free_rbufs(struct net_device* dev)
rp->rx_ring[i].rx_status = 0;
rp->rx_ring[i].addr = cpu_to_le32(0xBADF00D0); /* An invalid address. */
if (rp->rx_skbuff[i]) {
- pci_unmap_single(rp->pdev,
+ dma_unmap_single(hwdev,
rp->rx_skbuff_dma[i],
- rp->rx_buf_sz, PCI_DMA_FROMDEVICE);
+ rp->rx_buf_sz, DMA_FROM_DEVICE);
dev_kfree_skb(rp->rx_skbuff[i]);
}
rp->rx_skbuff[i] = NULL;
@@ -1230,6 +1283,7 @@ static void alloc_tbufs(struct net_device* dev)
static void free_tbufs(struct net_device* dev)
{
struct rhine_private *rp = netdev_priv(dev);
+ struct device *hwdev = dev->dev.parent;
int i;
for (i = 0; i < TX_RING_SIZE; i++) {
@@ -1238,10 +1292,10 @@ static void free_tbufs(struct net_device* dev)
rp->tx_ring[i].addr = cpu_to_le32(0xBADF00D0); /* An invalid address. */
if (rp->tx_skbuff[i]) {
if (rp->tx_skbuff_dma[i]) {
- pci_unmap_single(rp->pdev,
+ dma_unmap_single(hwdev,
rp->tx_skbuff_dma[i],
rp->tx_skbuff[i]->len,
- PCI_DMA_TODEVICE);
+ DMA_TO_DEVICE);
}
dev_kfree_skb(rp->tx_skbuff[i]);
}
@@ -1469,7 +1523,7 @@ static void init_registers(struct net_device *dev)
rhine_set_rx_mode(dev);
- if (rp->pdev->revision >= VT6105M)
+ if (rp->revision >= VT6105M)
rhine_init_cam_filter(dev);
napi_enable(&rp->napi);
@@ -1581,16 +1635,15 @@ static int rhine_open(struct net_device *dev)
void __iomem *ioaddr = rp->base;
int rc;
- rc = request_irq(rp->pdev->irq, rhine_interrupt, IRQF_SHARED, dev->name,
- dev);
+ rc = request_irq(rp->irq, rhine_interrupt, IRQF_SHARED, dev->name, dev);
if (rc)
return rc;
- netif_dbg(rp, ifup, dev, "%s() irq %d\n", __func__, rp->pdev->irq);
+ netif_dbg(rp, ifup, dev, "%s() irq %d\n", __func__, rp->irq);
rc = alloc_ring(dev);
if (rc) {
- free_irq(rp->pdev->irq, dev);
+ free_irq(rp->irq, dev);
return rc;
}
alloc_rbufs(dev);
@@ -1659,6 +1712,7 @@ static netdev_tx_t rhine_start_tx(struct sk_buff *skb,
struct net_device *dev)
{
struct rhine_private *rp = netdev_priv(dev);
+ struct device *hwdev = dev->dev.parent;
void __iomem *ioaddr = rp->base;
unsigned entry;
@@ -1695,9 +1749,9 @@ static netdev_tx_t rhine_start_tx(struct sk_buff *skb,
rp->tx_bufs));
} else {
rp->tx_skbuff_dma[entry] =
- pci_map_single(rp->pdev, skb->data, skb->len,
- PCI_DMA_TODEVICE);
- if (dma_mapping_error(&rp->pdev->dev, rp->tx_skbuff_dma[entry])) {
+ dma_map_single(hwdev, skb->data, skb->len,
+ DMA_TO_DEVICE);
+ if (dma_mapping_error(hwdev, rp->tx_skbuff_dma[entry])) {
dev_kfree_skb_any(skb);
rp->tx_skbuff_dma[entry] = 0;
dev->stats.tx_dropped++;
@@ -1788,6 +1842,7 @@ static irqreturn_t rhine_interrupt(int irq, void *dev_instance)
static void rhine_tx(struct net_device *dev)
{
struct rhine_private *rp = netdev_priv(dev);
+ struct device *hwdev = dev->dev.parent;
int txstatus = 0, entry = rp->dirty_tx % TX_RING_SIZE;
/* find and cleanup dirty tx descriptors */
@@ -1831,10 +1886,10 @@ static void rhine_tx(struct net_device *dev)
}
/* Free the original skb. */
if (rp->tx_skbuff_dma[entry]) {
- pci_unmap_single(rp->pdev,
+ dma_unmap_single(hwdev,
rp->tx_skbuff_dma[entry],
rp->tx_skbuff[entry]->len,
- PCI_DMA_TODEVICE);
+ DMA_TO_DEVICE);
}
dev_consume_skb_any(rp->tx_skbuff[entry]);
rp->tx_skbuff[entry] = NULL;
@@ -1863,6 +1918,7 @@ static inline u16 rhine_get_vlan_tci(struct sk_buff *skb, int data_size)
static int rhine_rx(struct net_device *dev, int limit)
{
struct rhine_private *rp = netdev_priv(dev);
+ struct device *hwdev = dev->dev.parent;
int count;
int entry = rp->cur_rx % RX_RING_SIZE;
@@ -1924,19 +1980,19 @@ static int rhine_rx(struct net_device *dev, int limit)
if (pkt_len < rx_copybreak)
skb = netdev_alloc_skb_ip_align(dev, pkt_len);
if (skb) {
- pci_dma_sync_single_for_cpu(rp->pdev,
- rp->rx_skbuff_dma[entry],
- rp->rx_buf_sz,
- PCI_DMA_FROMDEVICE);
+ dma_sync_single_for_cpu(hwdev,
+ rp->rx_skbuff_dma[entry],
+ rp->rx_buf_sz,
+ DMA_FROM_DEVICE);
skb_copy_to_linear_data(skb,
rp->rx_skbuff[entry]->data,
pkt_len);
skb_put(skb, pkt_len);
- pci_dma_sync_single_for_device(rp->pdev,
- rp->rx_skbuff_dma[entry],
- rp->rx_buf_sz,
- PCI_DMA_FROMDEVICE);
+ dma_sync_single_for_device(hwdev,
+ rp->rx_skbuff_dma[entry],
+ rp->rx_buf_sz,
+ DMA_FROM_DEVICE);
} else {
skb = rp->rx_skbuff[entry];
if (skb == NULL) {
@@ -1945,10 +2001,10 @@ static int rhine_rx(struct net_device *dev, int limit)
}
rp->rx_skbuff[entry] = NULL;
skb_put(skb, pkt_len);
- pci_unmap_single(rp->pdev,
+ dma_unmap_single(hwdev,
rp->rx_skbuff_dma[entry],
rp->rx_buf_sz,
- PCI_DMA_FROMDEVICE);
+ DMA_FROM_DEVICE);
}
if (unlikely(desc_length & DescTag))
@@ -1979,10 +2035,11 @@ static int rhine_rx(struct net_device *dev, int limit)
if (skb == NULL)
break; /* Better luck next round. */
rp->rx_skbuff_dma[entry] =
- pci_map_single(rp->pdev, skb->data,
+ dma_map_single(hwdev, skb->data,
rp->rx_buf_sz,
- PCI_DMA_FROMDEVICE);
- if (dma_mapping_error(&rp->pdev->dev, rp->rx_skbuff_dma[entry])) {
+ DMA_FROM_DEVICE);
+ if (dma_mapping_error(hwdev,
+ rp->rx_skbuff_dma[entry])) {
dev_kfree_skb(skb);
rp->rx_skbuff_dma[entry] = 0;
break;
@@ -2103,7 +2160,7 @@ static void rhine_set_rx_mode(struct net_device *dev)
/* Too many to match, or accept all multicasts. */
iowrite32(0xffffffff, ioaddr + MulticastFilter0);
iowrite32(0xffffffff, ioaddr + MulticastFilter1);
- } else if (rp->pdev->revision >= VT6105M) {
+ } else if (rp->revision >= VT6105M) {
int i = 0;
u32 mCAMmask = 0; /* 32 mCAMs (6105M and better) */
netdev_for_each_mc_addr(ha, dev) {
@@ -2125,7 +2182,7 @@ static void rhine_set_rx_mode(struct net_device *dev)
iowrite32(mc_filter[1], ioaddr + MulticastFilter1);
}
/* enable/disable VLAN receive filtering */
- if (rp->pdev->revision >= VT6105M) {
+ if (rp->revision >= VT6105M) {
if (dev->flags & IFF_PROMISC)
BYTE_REG_BITS_OFF(BCR1_VIDFR, ioaddr + PCIBusConfig1);
else
@@ -2136,11 +2193,11 @@ static void rhine_set_rx_mode(struct net_device *dev)
static void netdev_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
{
- struct rhine_private *rp = netdev_priv(dev);
+ struct device *hwdev = dev->dev.parent;
strlcpy(info->driver, DRV_NAME, sizeof(info->driver));
strlcpy(info->version, DRV_VERSION, sizeof(info->version));
- strlcpy(info->bus_info, pci_name(rp->pdev), sizeof(info->bus_info));
+ strlcpy(info->bus_info, dev_name(hwdev), sizeof(info->bus_info));
}
static int netdev_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
@@ -2277,7 +2334,7 @@ static int rhine_close(struct net_device *dev)
/* Stop the chip's Tx and Rx processes. */
iowrite16(CmdStop, ioaddr + ChipCmd);
- free_irq(rp->pdev->irq, dev);
+ free_irq(rp->irq, dev);
free_rbufs(dev);
free_tbufs(dev);
free_ring(dev);
@@ -2286,7 +2343,7 @@ static int rhine_close(struct net_device *dev)
}
-static void rhine_remove_one(struct pci_dev *pdev)
+static void rhine_remove_one_pci(struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata(pdev);
struct rhine_private *rp = netdev_priv(dev);
@@ -2300,7 +2357,21 @@ static void rhine_remove_one(struct pci_dev *pdev)
pci_disable_device(pdev);
}
-static void rhine_shutdown (struct pci_dev *pdev)
+static int rhine_remove_one_platform(struct platform_device *pdev)
+{
+ struct net_device *dev = platform_get_drvdata(pdev);
+ struct rhine_private *rp = netdev_priv(dev);
+
+ unregister_netdev(dev);
+
+ iounmap(rp->base);
+
+ free_netdev(dev);
+
+ return 0;
+}
+
+static void rhine_shutdown_pci(struct pci_dev *pdev)
{
struct net_device *dev = pci_get_drvdata(pdev);
struct rhine_private *rp = netdev_priv(dev);
@@ -2354,8 +2425,7 @@ static void rhine_shutdown (struct pci_dev *pdev)
#ifdef CONFIG_PM_SLEEP
static int rhine_suspend(struct device *device)
{
- struct pci_dev *pdev = to_pci_dev(device);
- struct net_device *dev = pci_get_drvdata(pdev);
+ struct net_device *dev = dev_get_drvdata(device);
struct rhine_private *rp = netdev_priv(dev);
if (!netif_running(dev))
@@ -2367,15 +2437,15 @@ static int rhine_suspend(struct device *device)
netif_device_detach(dev);
- rhine_shutdown(pdev);
+ if (dev_is_pci(device))
+ rhine_shutdown_pci(to_pci_dev(device));
return 0;
}
static int rhine_resume(struct device *device)
{
- struct pci_dev *pdev = to_pci_dev(device);
- struct net_device *dev = pci_get_drvdata(pdev);
+ struct net_device *dev = dev_get_drvdata(device);
struct rhine_private *rp = netdev_priv(dev);
if (!netif_running(dev))
@@ -2408,15 +2478,26 @@ static SIMPLE_DEV_PM_OPS(rhine_pm_ops, rhine_suspend, rhine_resume);
#endif /* !CONFIG_PM_SLEEP */
-static struct pci_driver rhine_driver = {
+static struct pci_driver rhine_driver_pci = {
.name = DRV_NAME,
.id_table = rhine_pci_tbl,
- .probe = rhine_init_one,
- .remove = rhine_remove_one,
- .shutdown = rhine_shutdown,
+ .probe = rhine_init_one_pci,
+ .remove = rhine_remove_one_pci,
+ .shutdown = rhine_shutdown_pci,
.driver.pm = RHINE_PM_OPS,
};
+static struct platform_driver rhine_driver_platform = {
+ .probe = rhine_init_one_platform,
+ .remove = rhine_remove_one_platform,
+ .driver = {
+ .name = DRV_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = rhine_of_tbl,
+ .pm = RHINE_PM_OPS,
+ }
+};
+
static struct dmi_system_id rhine_dmi_table[] __initdata = {
{
.ident = "EPIA-M",
@@ -2437,6 +2518,8 @@ static struct dmi_system_id rhine_dmi_table[] __initdata = {
static int __init rhine_init(void)
{
+ int ret_pci, ret_platform;
+
/* when a module, this is printed whether or not devices are found in probe */
#ifdef MODULE
pr_info("%s\n", version);
@@ -2449,13 +2532,19 @@ static int __init rhine_init(void)
else if (avoid_D3)
pr_info("avoid_D3 set\n");
- return pci_register_driver(&rhine_driver);
+ ret_pci = pci_register_driver(&rhine_driver_pci);
+ ret_platform = platform_driver_register(&rhine_driver_platform);
+ if ((ret_pci < 0) && (ret_platform < 0))
+ return ret_pci;
+
+ return 0;
}
static void __exit rhine_cleanup(void)
{
- pci_unregister_driver(&rhine_driver);
+ platform_driver_unregister(&rhine_driver_platform);
+ pci_unregister_driver(&rhine_driver_pci);
}
diff --git a/drivers/net/hyperv/hyperv_net.h b/drivers/net/hyperv/hyperv_net.h
index d18f711d..4b7df5a 100644
--- a/drivers/net/hyperv/hyperv_net.h
+++ b/drivers/net/hyperv/hyperv_net.h
@@ -28,50 +28,119 @@
#include <linux/hyperv.h>
#include <linux/rndis.h>
-/* Fwd declaration */
-struct hv_netvsc_packet;
-struct ndis_tcp_ip_checksum_info;
+/* RSS related */
+#define OID_GEN_RECEIVE_SCALE_CAPABILITIES 0x00010203 /* query only */
+#define OID_GEN_RECEIVE_SCALE_PARAMETERS 0x00010204 /* query and set */
-/* Represent the xfer page packet which contains 1 or more netvsc packet */
-struct xferpage_packet {
- struct list_head list_ent;
- u32 status;
+#define NDIS_OBJECT_TYPE_RSS_CAPABILITIES 0x88
+#define NDIS_OBJECT_TYPE_RSS_PARAMETERS 0x89
- /* # of netvsc packets this xfer packet contains */
- u32 count;
+#define NDIS_RECEIVE_SCALE_CAPABILITIES_REVISION_2 2
+#define NDIS_RECEIVE_SCALE_PARAMETERS_REVISION_2 2
+
+struct ndis_obj_header {
+ u8 type;
+ u8 rev;
+ u16 size;
+} __packed;
+
+/* ndis_recv_scale_cap/cap_flag */
+#define NDIS_RSS_CAPS_MESSAGE_SIGNALED_INTERRUPTS 0x01000000
+#define NDIS_RSS_CAPS_CLASSIFICATION_AT_ISR 0x02000000
+#define NDIS_RSS_CAPS_CLASSIFICATION_AT_DPC 0x04000000
+#define NDIS_RSS_CAPS_USING_MSI_X 0x08000000
+#define NDIS_RSS_CAPS_RSS_AVAILABLE_ON_PORTS 0x10000000
+#define NDIS_RSS_CAPS_SUPPORTS_MSI_X 0x20000000
+#define NDIS_RSS_CAPS_HASH_TYPE_TCP_IPV4 0x00000100
+#define NDIS_RSS_CAPS_HASH_TYPE_TCP_IPV6 0x00000200
+#define NDIS_RSS_CAPS_HASH_TYPE_TCP_IPV6_EX 0x00000400
+
+struct ndis_recv_scale_cap { /* NDIS_RECEIVE_SCALE_CAPABILITIES */
+ struct ndis_obj_header hdr;
+ u32 cap_flag;
+ u32 num_int_msg;
+ u32 num_recv_que;
+ u16 num_indirect_tabent;
+} __packed;
+
+
+/* ndis_recv_scale_param flags */
+#define NDIS_RSS_PARAM_FLAG_BASE_CPU_UNCHANGED 0x0001
+#define NDIS_RSS_PARAM_FLAG_HASH_INFO_UNCHANGED 0x0002
+#define NDIS_RSS_PARAM_FLAG_ITABLE_UNCHANGED 0x0004
+#define NDIS_RSS_PARAM_FLAG_HASH_KEY_UNCHANGED 0x0008
+#define NDIS_RSS_PARAM_FLAG_DISABLE_RSS 0x0010
+
+/* Hash info bits */
+#define NDIS_HASH_FUNC_TOEPLITZ 0x00000001
+#define NDIS_HASH_IPV4 0x00000100
+#define NDIS_HASH_TCP_IPV4 0x00000200
+#define NDIS_HASH_IPV6 0x00000400
+#define NDIS_HASH_IPV6_EX 0x00000800
+#define NDIS_HASH_TCP_IPV6 0x00001000
+#define NDIS_HASH_TCP_IPV6_EX 0x00002000
+
+#define NDIS_RSS_INDIRECTION_TABLE_MAX_SIZE_REVISION_2 (128 * 4)
+#define NDIS_RSS_HASH_SECRET_KEY_MAX_SIZE_REVISION_2 40
+
+#define ITAB_NUM 128
+#define HASH_KEYLEN NDIS_RSS_HASH_SECRET_KEY_MAX_SIZE_REVISION_2
+extern u8 netvsc_hash_key[];
+
+struct ndis_recv_scale_param { /* NDIS_RECEIVE_SCALE_PARAMETERS */
+ struct ndis_obj_header hdr;
+
+ /* Qualifies the rest of the information */
+ u16 flag;
+
+ /* The base CPU number to do receive processing. not used */
+ u16 base_cpu_number;
+
+ /* This describes the hash function and type being enabled */
+ u32 hashinfo;
+
+ /* The size of indirection table array */
+ u16 indirect_tabsize;
+
+ /* The offset of the indirection table from the beginning of this
+ * structure
+ */
+ u32 indirect_taboffset;
+
+ /* The size of the hash secret key */
+ u16 hashkey_size;
+
+ /* The offset of the secret key from the beginning of this structure */
+ u32 kashkey_offset;
+
+ u32 processor_masks_offset;
+ u32 num_processor_masks;
+ u32 processor_masks_entry_size;
};
+/* Fwd declaration */
+struct ndis_tcp_ip_checksum_info;
+
/*
* Represent netvsc packet which contains 1 RNDIS and 1 ethernet frame
* within the RNDIS
*/
struct hv_netvsc_packet {
/* Bookkeeping stuff */
- struct list_head list_ent;
u32 status;
struct hv_device *device;
bool is_data_pkt;
u16 vlan_tci;
- /*
- * Valid only for receives when we break a xfer page packet
- * into multiple netvsc packets
- */
- struct xferpage_packet *xfer_page_pkt;
+ u16 q_idx;
+ struct vmbus_channel *channel;
- union {
- struct {
- u64 recv_completion_tid;
- void *recv_completion_ctx;
- void (*recv_completion)(void *context);
- } recv;
- struct {
- u64 send_completion_tid;
- void *send_completion_ctx;
- void (*send_completion)(void *context);
- } send;
- } completion;
+ u64 send_completion_tid;
+ void *send_completion_ctx;
+ void (*send_completion)(void *context);
+
+ u32 send_buf_index;
/* This points to the memory after page_buf */
struct rndis_message *rndis_msg;
@@ -120,6 +189,7 @@ void netvsc_linkstatus_callback(struct hv_device *device_obj,
int netvsc_recv_callback(struct hv_device *device_obj,
struct hv_netvsc_packet *packet,
struct ndis_tcp_ip_checksum_info *csum_info);
+void netvsc_channel_cb(void *context);
int rndis_filter_open(struct hv_device *dev);
int rndis_filter_close(struct hv_device *dev);
int rndis_filter_device_add(struct hv_device *dev,
@@ -514,14 +584,16 @@ 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_INVALID_INDEX -1
-#define NETVSC_RECEIVE_BUFFER_ID 0xcafe
-/* Preallocated receive packets */
-#define NETVSC_RECEIVE_PACKETLIST_COUNT 256
+#define NETVSC_RECEIVE_BUFFER_ID 0xcafe
#define NETVSC_PACKET_SIZE 2048
+#define VRSS_SEND_TAB_SIZE 16
+
/* Per netvsc channel-specific */
struct netvsc_device {
struct hv_device *dev;
@@ -532,12 +604,6 @@ struct netvsc_device {
wait_queue_head_t wait_drain;
bool start_remove;
bool destroy;
- /*
- * List of free preallocated hv_netvsc_packet to represent receive
- * packet
- */
- struct list_head recv_pkt_list;
- spinlock_t recv_pkt_list_lock;
/* Receive buffer allocated by us but manages by NetVSP */
void *recv_buf;
@@ -546,6 +612,15 @@ struct netvsc_device {
u32 recv_section_cnt;
struct nvsp_1_receive_buffer_section *recv_section;
+ /* Send buffer allocated by us */
+ void *send_buf;
+ u32 send_buf_size;
+ u32 send_buf_gpadl_handle;
+ u32 send_section_cnt;
+ u32 send_section_size;
+ unsigned long *send_section_map;
+ int map_words;
+
/* Used for NetVSP initialization protocol */
struct completion channel_init_wait;
struct nvsp_message channel_init_pkt;
@@ -555,10 +630,20 @@ struct netvsc_device {
struct net_device *ndev;
+ struct vmbus_channel *chn_table[NR_CPUS];
+ u32 send_table[VRSS_SEND_TAB_SIZE];
+ u32 num_chn;
+ atomic_t queue_sends[NR_CPUS];
+
/* Holds rndis device info */
void *extension;
- /* The recive buffer for this device */
+
+ int ring_size;
+
+ /* The primary channel callback buffer */
unsigned char cb_buffer[NETVSC_PACKET_SIZE];
+ /* The sub channel callback buffer */
+ unsigned char *sub_cb_buf;
};
/* NdisInitialize message */
diff --git a/drivers/net/hyperv/netvsc.c b/drivers/net/hyperv/netvsc.c
index f7629ec..c041f63 100644
--- a/drivers/net/hyperv/netvsc.c
+++ b/drivers/net/hyperv/netvsc.c
@@ -28,6 +28,7 @@
#include <linux/slab.h>
#include <linux/netdevice.h>
#include <linux/if_ether.h>
+#include <asm/sync_bitops.h>
#include "hyperv_net.h"
@@ -80,7 +81,7 @@ get_in_err:
}
-static int netvsc_destroy_recv_buf(struct netvsc_device *net_device)
+static int netvsc_destroy_buf(struct netvsc_device *net_device)
{
struct nvsp_message *revoke_packet;
int ret = 0;
@@ -146,10 +147,62 @@ static int netvsc_destroy_recv_buf(struct netvsc_device *net_device)
net_device->recv_section = NULL;
}
+ /* Deal with the send buffer we may have setup.
+ * If we got a send section size, it means we received a
+ * SendsendBufferComplete msg (ie sent
+ * NvspMessage1TypeSendReceiveBuffer msg) therefore, we need
+ * to send a revoke msg here
+ */
+ if (net_device->send_section_size) {
+ /* Send the revoke receive buffer */
+ revoke_packet = &net_device->revoke_packet;
+ memset(revoke_packet, 0, sizeof(struct nvsp_message));
+
+ revoke_packet->hdr.msg_type =
+ NVSP_MSG1_TYPE_REVOKE_SEND_BUF;
+ revoke_packet->msg.v1_msg.revoke_recv_buf.id = 0;
+
+ ret = vmbus_sendpacket(net_device->dev->channel,
+ revoke_packet,
+ sizeof(struct nvsp_message),
+ (unsigned long)revoke_packet,
+ VM_PKT_DATA_INBAND, 0);
+ /* If we failed here, we might as well return and
+ * have a leak rather than continue and a bugchk
+ */
+ if (ret != 0) {
+ netdev_err(ndev, "unable to send "
+ "revoke send buffer to netvsp\n");
+ return ret;
+ }
+ }
+ /* Teardown the gpadl on the vsp end */
+ if (net_device->send_buf_gpadl_handle) {
+ ret = vmbus_teardown_gpadl(net_device->dev->channel,
+ net_device->send_buf_gpadl_handle);
+
+ /* If we failed here, we might as well return and have a leak
+ * rather than continue and a bugchk
+ */
+ if (ret != 0) {
+ netdev_err(ndev,
+ "unable to teardown send buffer's gpadl\n");
+ return ret;
+ }
+ net_device->recv_buf_gpadl_handle = 0;
+ }
+ 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));
+ net_device->send_buf = NULL;
+ }
+ kfree(net_device->send_section_map);
+
return ret;
}
-static int netvsc_init_recv_buf(struct hv_device *device)
+static int netvsc_init_buf(struct hv_device *device)
{
int ret = 0;
int t;
@@ -248,10 +301,90 @@ static int netvsc_init_recv_buf(struct hv_device *device)
goto cleanup;
}
+ /* Now setup the send buffer.
+ */
+ net_device->send_buf =
+ (void *)__get_free_pages(GFP_KERNEL|__GFP_ZERO,
+ get_order(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);
+ ret = -ENOMEM;
+ goto cleanup;
+ }
+
+ /* Establish the gpadl handle for this buffer on this
+ * channel. Note: This call uses the vmbus connection rather
+ * than the channel to establish the gpadl handle.
+ */
+ ret = vmbus_establish_gpadl(device->channel, net_device->send_buf,
+ net_device->send_buf_size,
+ &net_device->send_buf_gpadl_handle);
+ if (ret != 0) {
+ netdev_err(ndev,
+ "unable to establish send buffer's gpadl\n");
+ goto cleanup;
+ }
+
+ /* Notify the NetVsp of the gpadl handle */
+ init_packet = &net_device->channel_init_pkt;
+ memset(init_packet, 0, sizeof(struct nvsp_message));
+ init_packet->hdr.msg_type = NVSP_MSG1_TYPE_SEND_SEND_BUF;
+ init_packet->msg.v1_msg.send_recv_buf.gpadl_handle =
+ net_device->send_buf_gpadl_handle;
+ init_packet->msg.v1_msg.send_recv_buf.id = 0;
+
+ /* Send the gpadl notification request */
+ ret = vmbus_sendpacket(device->channel, init_packet,
+ sizeof(struct nvsp_message),
+ (unsigned long)init_packet,
+ VM_PKT_DATA_INBAND,
+ VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
+ if (ret != 0) {
+ netdev_err(ndev,
+ "unable to send send buffer's gpadl to netvsp\n");
+ goto cleanup;
+ }
+
+ t = wait_for_completion_timeout(&net_device->channel_init_wait, 5*HZ);
+ BUG_ON(t == 0);
+
+ /* Check the response */
+ if (init_packet->msg.v1_msg.
+ send_send_buf_complete.status != NVSP_STAT_SUCCESS) {
+ netdev_err(ndev, "Unable to complete send buffer "
+ "initialization with NetVsp - status %d\n",
+ init_packet->msg.v1_msg.
+ send_recv_buf_complete.status);
+ ret = -EINVAL;
+ goto cleanup;
+ }
+
+ /* Parse the response */
+ net_device->send_section_size = init_packet->msg.
+ v1_msg.send_send_buf_complete.section_size;
+
+ /* Section count is simply the size divided by the section size.
+ */
+ net_device->send_section_cnt =
+ net_device->send_buf_size/net_device->send_section_size;
+
+ dev_info(&device->device, "Send section size: %d, Section count:%d\n",
+ net_device->send_section_size, net_device->send_section_cnt);
+
+ /* Setup state for managing the send buffer. */
+ net_device->map_words = DIV_ROUND_UP(net_device->send_section_cnt,
+ BITS_PER_LONG);
+
+ net_device->send_section_map =
+ kzalloc(net_device->map_words * sizeof(ulong), GFP_KERNEL);
+ if (net_device->send_section_map == NULL)
+ goto cleanup;
+
goto exit;
cleanup:
- netvsc_destroy_recv_buf(net_device);
+ netvsc_destroy_buf(net_device);
exit:
return ret;
@@ -369,8 +502,9 @@ static int netvsc_connect_vsp(struct hv_device *device)
net_device->recv_buf_size = NETVSC_RECEIVE_BUFFER_SIZE_LEGACY;
else
net_device->recv_buf_size = NETVSC_RECEIVE_BUFFER_SIZE;
+ net_device->send_buf_size = NETVSC_SEND_BUFFER_SIZE;
- ret = netvsc_init_recv_buf(device);
+ ret = netvsc_init_buf(device);
cleanup:
return ret;
@@ -378,7 +512,7 @@ cleanup:
static void netvsc_disconnect_vsp(struct netvsc_device *net_device)
{
- netvsc_destroy_recv_buf(net_device);
+ netvsc_destroy_buf(net_device);
}
/*
@@ -387,7 +521,6 @@ static void netvsc_disconnect_vsp(struct netvsc_device *net_device)
int netvsc_device_remove(struct hv_device *device)
{
struct netvsc_device *net_device;
- struct hv_netvsc_packet *netvsc_packet, *pos;
unsigned long flags;
net_device = hv_get_drvdata(device);
@@ -416,11 +549,8 @@ int netvsc_device_remove(struct hv_device *device)
vmbus_close(device->channel);
/* Release all resources */
- list_for_each_entry_safe(netvsc_packet, pos,
- &net_device->recv_pkt_list, list_ent) {
- list_del(&netvsc_packet->list_ent);
- kfree(netvsc_packet);
- }
+ if (net_device->sub_cb_buf)
+ vfree(net_device->sub_cb_buf);
kfree(net_device);
return 0;
@@ -444,6 +574,12 @@ static inline u32 hv_ringbuf_avail_percent(
return avail_write * 100 / ring_info->ring_datasize;
}
+static inline void netvsc_free_send_slot(struct netvsc_device *net_device,
+ u32 index)
+{
+ sync_change_bit(index, net_device->send_section_map);
+}
+
static void netvsc_send_completion(struct netvsc_device *net_device,
struct hv_device *device,
struct vmpacket_descriptor *packet)
@@ -451,6 +587,7 @@ static void netvsc_send_completion(struct netvsc_device *net_device,
struct nvsp_message *nvsp_packet;
struct hv_netvsc_packet *nvsc_packet;
struct net_device *ndev;
+ u32 send_index;
ndev = net_device->ndev;
@@ -461,7 +598,9 @@ static void netvsc_send_completion(struct netvsc_device *net_device,
(nvsp_packet->hdr.msg_type ==
NVSP_MSG1_TYPE_SEND_RECV_BUF_COMPLETE) ||
(nvsp_packet->hdr.msg_type ==
- NVSP_MSG1_TYPE_SEND_SEND_BUF_COMPLETE)) {
+ NVSP_MSG1_TYPE_SEND_SEND_BUF_COMPLETE) ||
+ (nvsp_packet->hdr.msg_type ==
+ NVSP_MSG5_TYPE_SUBCHANNEL)) {
/* Copy the response back */
memcpy(&net_device->channel_init_pkt, nvsp_packet,
sizeof(struct nvsp_message));
@@ -469,28 +608,39 @@ static void netvsc_send_completion(struct netvsc_device *net_device,
} else if (nvsp_packet->hdr.msg_type ==
NVSP_MSG1_TYPE_SEND_RNDIS_PKT_COMPLETE) {
int num_outstanding_sends;
+ u16 q_idx = 0;
+ struct vmbus_channel *channel = device->channel;
+ int queue_sends;
/* Get the send context */
nvsc_packet = (struct hv_netvsc_packet *)(unsigned long)
packet->trans_id;
/* Notify the layer above us */
- if (nvsc_packet)
- nvsc_packet->completion.send.send_completion(
- nvsc_packet->completion.send.
- send_completion_ctx);
+ if (nvsc_packet) {
+ send_index = nvsc_packet->send_buf_index;
+ if (send_index != NETVSC_INVALID_INDEX)
+ netvsc_free_send_slot(net_device, send_index);
+ q_idx = nvsc_packet->q_idx;
+ channel = nvsc_packet->channel;
+ nvsc_packet->send_completion(nvsc_packet->
+ send_completion_ctx);
+ }
num_outstanding_sends =
atomic_dec_return(&net_device->num_outstanding_sends);
+ queue_sends = atomic_dec_return(&net_device->
+ queue_sends[q_idx]);
if (net_device->destroy && num_outstanding_sends == 0)
wake_up(&net_device->wait_drain);
- if (netif_queue_stopped(ndev) && !net_device->start_remove &&
- (hv_ringbuf_avail_percent(&device->channel->outbound)
- > RING_AVAIL_PERCENT_HIWATER ||
- num_outstanding_sends < 1))
- netif_wake_queue(ndev);
+ if (netif_tx_queue_stopped(netdev_get_tx_queue(ndev, q_idx)) &&
+ !net_device->start_remove &&
+ (hv_ringbuf_avail_percent(&channel->outbound) >
+ RING_AVAIL_PERCENT_HIWATER || queue_sends < 1))
+ netif_tx_wake_queue(netdev_get_tx_queue(
+ ndev, q_idx));
} else {
netdev_err(ndev, "Unknown send completion packet type- "
"%d received!!\n", nvsp_packet->hdr.msg_type);
@@ -498,6 +648,52 @@ static void netvsc_send_completion(struct netvsc_device *net_device,
}
+static u32 netvsc_get_next_send_section(struct netvsc_device *net_device)
+{
+ unsigned long index;
+ u32 max_words = net_device->map_words;
+ unsigned long *map_addr = (unsigned long *)net_device->send_section_map;
+ u32 section_cnt = net_device->send_section_cnt;
+ int ret_val = NETVSC_INVALID_INDEX;
+ int i;
+ int prev_val;
+
+ for (i = 0; i < max_words; i++) {
+ if (!~(map_addr[i]))
+ continue;
+ index = ffz(map_addr[i]);
+ prev_val = sync_test_and_set_bit(index, &map_addr[i]);
+ if (prev_val)
+ continue;
+ if ((index + (i * BITS_PER_LONG)) >= section_cnt)
+ break;
+ ret_val = (index + (i * BITS_PER_LONG));
+ break;
+ }
+ return ret_val;
+}
+
+u32 netvsc_copy_to_send_buf(struct netvsc_device *net_device,
+ unsigned int section_index,
+ struct hv_netvsc_packet *packet)
+{
+ char *start = net_device->send_buf;
+ char *dest = (start + (section_index * net_device->send_section_size));
+ int i;
+ u32 msg_size = 0;
+
+ for (i = 0; i < packet->page_buf_cnt; i++) {
+ char *src = phys_to_virt(packet->page_buf[i].pfn << PAGE_SHIFT);
+ u32 offset = packet->page_buf[i].offset;
+ u32 len = packet->page_buf[i].len;
+
+ memcpy(dest, (src + offset), len);
+ msg_size += len;
+ dest += len;
+ }
+ return msg_size;
+}
+
int netvsc_send(struct hv_device *device,
struct hv_netvsc_packet *packet)
{
@@ -505,7 +701,12 @@ int netvsc_send(struct hv_device *device,
int ret = 0;
struct nvsp_message sendMessage;
struct net_device *ndev;
+ struct vmbus_channel *out_channel = NULL;
u64 req_id;
+ unsigned int section_index = NETVSC_INVALID_INDEX;
+ u32 msg_size = 0;
+ struct sk_buff *skb;
+
net_device = get_outbound_net_device(device);
if (!net_device)
@@ -521,25 +722,46 @@ int netvsc_send(struct hv_device *device,
sendMessage.msg.v1_msg.send_rndis_pkt.channel_type = 1;
}
- /* Not using send buffer section */
+ /* Attempt to send via sendbuf */
+ if (packet->total_data_buflen < net_device->send_section_size) {
+ section_index = netvsc_get_next_send_section(net_device);
+ if (section_index != NETVSC_INVALID_INDEX) {
+ msg_size = netvsc_copy_to_send_buf(net_device,
+ section_index,
+ packet);
+ skb = (struct sk_buff *)
+ (unsigned long)packet->send_completion_tid;
+ if (skb)
+ dev_kfree_skb_any(skb);
+ packet->page_buf_cnt = 0;
+ }
+ }
+ packet->send_buf_index = section_index;
+
+
sendMessage.msg.v1_msg.send_rndis_pkt.send_buf_section_index =
- 0xFFFFFFFF;
- sendMessage.msg.v1_msg.send_rndis_pkt.send_buf_section_size = 0;
+ section_index;
+ sendMessage.msg.v1_msg.send_rndis_pkt.send_buf_section_size = msg_size;
- if (packet->completion.send.send_completion)
+ if (packet->send_completion)
req_id = (ulong)packet;
else
req_id = 0;
+ out_channel = net_device->chn_table[packet->q_idx];
+ if (out_channel == NULL)
+ out_channel = device->channel;
+ packet->channel = out_channel;
+
if (packet->page_buf_cnt) {
- ret = vmbus_sendpacket_pagebuffer(device->channel,
+ ret = vmbus_sendpacket_pagebuffer(out_channel,
packet->page_buf,
packet->page_buf_cnt,
&sendMessage,
sizeof(struct nvsp_message),
req_id);
} else {
- ret = vmbus_sendpacket(device->channel, &sendMessage,
+ ret = vmbus_sendpacket(out_channel, &sendMessage,
sizeof(struct nvsp_message),
req_id,
VM_PKT_DATA_INBAND,
@@ -548,17 +770,24 @@ int netvsc_send(struct hv_device *device,
if (ret == 0) {
atomic_inc(&net_device->num_outstanding_sends);
- if (hv_ringbuf_avail_percent(&device->channel->outbound) <
+ atomic_inc(&net_device->queue_sends[packet->q_idx]);
+
+ if (hv_ringbuf_avail_percent(&out_channel->outbound) <
RING_AVAIL_PERCENT_LOWATER) {
- netif_stop_queue(ndev);
+ netif_tx_stop_queue(netdev_get_tx_queue(
+ ndev, packet->q_idx));
+
if (atomic_read(&net_device->
- num_outstanding_sends) < 1)
- netif_wake_queue(ndev);
+ queue_sends[packet->q_idx]) < 1)
+ netif_tx_wake_queue(netdev_get_tx_queue(
+ ndev, packet->q_idx));
}
} else if (ret == -EAGAIN) {
- netif_stop_queue(ndev);
- if (atomic_read(&net_device->num_outstanding_sends) < 1) {
- netif_wake_queue(ndev);
+ netif_tx_stop_queue(netdev_get_tx_queue(
+ ndev, packet->q_idx));
+ if (atomic_read(&net_device->queue_sends[packet->q_idx]) < 1) {
+ netif_tx_wake_queue(netdev_get_tx_queue(
+ ndev, packet->q_idx));
ret = -ENOSPC;
}
} else {
@@ -570,6 +799,7 @@ int netvsc_send(struct hv_device *device,
}
static void netvsc_send_recv_completion(struct hv_device *device,
+ struct vmbus_channel *channel,
struct netvsc_device *net_device,
u64 transaction_id, u32 status)
{
@@ -587,7 +817,7 @@ static void netvsc_send_recv_completion(struct hv_device *device,
retry_send_cmplt:
/* Send the completion */
- ret = vmbus_sendpacket(device->channel, &recvcompMessage,
+ ret = vmbus_sendpacket(channel, &recvcompMessage,
sizeof(struct nvsp_message), transaction_id,
VM_PKT_COMP, 0);
if (ret == 0) {
@@ -613,76 +843,20 @@ retry_send_cmplt:
}
}
-/* Send a receive completion packet to RNDIS device (ie NetVsp) */
-static void netvsc_receive_completion(void *context)
-{
- struct hv_netvsc_packet *packet = context;
- struct hv_device *device = packet->device;
- struct netvsc_device *net_device;
- u64 transaction_id = 0;
- bool fsend_receive_comp = false;
- unsigned long flags;
- struct net_device *ndev;
- u32 status = NVSP_STAT_NONE;
-
- /*
- * Even though it seems logical to do a GetOutboundNetDevice() here to
- * send out receive completion, we are using GetInboundNetDevice()
- * since we may have disable outbound traffic already.
- */
- net_device = get_inbound_net_device(device);
- if (!net_device)
- return;
- ndev = net_device->ndev;
-
- /* Overloading use of the lock. */
- spin_lock_irqsave(&net_device->recv_pkt_list_lock, flags);
-
- if (packet->status != NVSP_STAT_SUCCESS)
- packet->xfer_page_pkt->status = NVSP_STAT_FAIL;
-
- packet->xfer_page_pkt->count--;
-
- /*
- * Last one in the line that represent 1 xfer page packet.
- * Return the xfer page packet itself to the freelist
- */
- if (packet->xfer_page_pkt->count == 0) {
- fsend_receive_comp = true;
- transaction_id = packet->completion.recv.recv_completion_tid;
- status = packet->xfer_page_pkt->status;
- list_add_tail(&packet->xfer_page_pkt->list_ent,
- &net_device->recv_pkt_list);
-
- }
-
- /* Put the packet back */
- list_add_tail(&packet->list_ent, &net_device->recv_pkt_list);
- spin_unlock_irqrestore(&net_device->recv_pkt_list_lock, flags);
-
- /* Send a receive completion for the xfer page packet */
- if (fsend_receive_comp)
- netvsc_send_recv_completion(device, net_device, transaction_id,
- status);
-
-}
-
static void netvsc_receive(struct netvsc_device *net_device,
+ struct vmbus_channel *channel,
struct hv_device *device,
struct vmpacket_descriptor *packet)
{
struct vmtransfer_page_packet_header *vmxferpage_packet;
struct nvsp_message *nvsp_packet;
- struct hv_netvsc_packet *netvsc_packet = NULL;
- /* struct netvsc_driver *netvscDriver; */
- struct xferpage_packet *xferpage_packet = NULL;
+ struct hv_netvsc_packet nv_pkt;
+ struct hv_netvsc_packet *netvsc_packet = &nv_pkt;
+ u32 status = NVSP_STAT_SUCCESS;
int i;
int count = 0;
- unsigned long flags;
struct net_device *ndev;
- LIST_HEAD(listHead);
-
ndev = net_device->ndev;
/*
@@ -715,77 +889,14 @@ static void netvsc_receive(struct netvsc_device *net_device,
return;
}
- /*
- * Grab free packets (range count + 1) to represent this xfer
- * page packet. +1 to represent the xfer page packet itself.
- * We grab it here so that we know exactly how many we can
- * fulfil
- */
- spin_lock_irqsave(&net_device->recv_pkt_list_lock, flags);
- while (!list_empty(&net_device->recv_pkt_list)) {
- list_move_tail(net_device->recv_pkt_list.next, &listHead);
- if (++count == vmxferpage_packet->range_cnt + 1)
- break;
- }
- spin_unlock_irqrestore(&net_device->recv_pkt_list_lock, flags);
-
- /*
- * We need at least 2 netvsc pkts (1 to represent the xfer
- * page and at least 1 for the range) i.e. we can handled
- * some of the xfer page packet ranges...
- */
- if (count < 2) {
- netdev_err(ndev, "Got only %d netvsc pkt...needed "
- "%d pkts. Dropping this xfer page packet completely!\n",
- count, vmxferpage_packet->range_cnt + 1);
-
- /* Return it to the freelist */
- spin_lock_irqsave(&net_device->recv_pkt_list_lock, flags);
- for (i = count; i != 0; i--) {
- list_move_tail(listHead.next,
- &net_device->recv_pkt_list);
- }
- spin_unlock_irqrestore(&net_device->recv_pkt_list_lock,
- flags);
-
- netvsc_send_recv_completion(device, net_device,
- vmxferpage_packet->d.trans_id,
- NVSP_STAT_FAIL);
-
- return;
- }
-
- /* Remove the 1st packet to represent the xfer page packet itself */
- xferpage_packet = (struct xferpage_packet *)listHead.next;
- list_del(&xferpage_packet->list_ent);
- xferpage_packet->status = NVSP_STAT_SUCCESS;
-
- /* This is how much we can satisfy */
- xferpage_packet->count = count - 1;
-
- if (xferpage_packet->count != vmxferpage_packet->range_cnt) {
- netdev_err(ndev, "Needed %d netvsc pkts to satisfy "
- "this xfer page...got %d\n",
- vmxferpage_packet->range_cnt, xferpage_packet->count);
- }
+ count = vmxferpage_packet->range_cnt;
+ netvsc_packet->device = device;
+ netvsc_packet->channel = channel;
/* Each range represents 1 RNDIS pkt that contains 1 ethernet frame */
- for (i = 0; i < (count - 1); i++) {
- netvsc_packet = (struct hv_netvsc_packet *)listHead.next;
- list_del(&netvsc_packet->list_ent);
-
+ for (i = 0; i < count; i++) {
/* Initialize the netvsc packet */
netvsc_packet->status = NVSP_STAT_SUCCESS;
- netvsc_packet->xfer_page_pkt = xferpage_packet;
- netvsc_packet->completion.recv.recv_completion =
- netvsc_receive_completion;
- netvsc_packet->completion.recv.recv_completion_ctx =
- netvsc_packet;
- netvsc_packet->device = device;
- /* Save this so that we can send it back */
- netvsc_packet->completion.recv.recv_completion_tid =
- vmxferpage_packet->d.trans_id;
-
netvsc_packet->data = (void *)((unsigned long)net_device->
recv_buf + vmxferpage_packet->ranges[i].byte_offset);
netvsc_packet->total_data_buflen =
@@ -794,16 +905,53 @@ static void netvsc_receive(struct netvsc_device *net_device,
/* Pass it to the upper layer */
rndis_filter_receive(device, netvsc_packet);
- netvsc_receive_completion(netvsc_packet->
- completion.recv.recv_completion_ctx);
+ if (netvsc_packet->status != NVSP_STAT_SUCCESS)
+ status = NVSP_STAT_FAIL;
+ }
+
+ netvsc_send_recv_completion(device, channel, net_device,
+ vmxferpage_packet->d.trans_id, status);
+}
+
+
+static void netvsc_send_table(struct hv_device *hdev,
+ struct vmpacket_descriptor *vmpkt)
+{
+ struct netvsc_device *nvscdev;
+ struct net_device *ndev;
+ struct nvsp_message *nvmsg;
+ int i;
+ u32 count, *tab;
+
+ nvscdev = get_outbound_net_device(hdev);
+ if (!nvscdev)
+ return;
+ ndev = nvscdev->ndev;
+
+ nvmsg = (struct nvsp_message *)((unsigned long)vmpkt +
+ (vmpkt->offset8 << 3));
+
+ if (nvmsg->hdr.msg_type != NVSP_MSG5_TYPE_SEND_INDIRECTION_TABLE)
+ return;
+
+ count = nvmsg->msg.v5_msg.send_table.count;
+ if (count != VRSS_SEND_TAB_SIZE) {
+ netdev_err(ndev, "Received wrong send-table size:%u\n", count);
+ return;
}
+ tab = (u32 *)((unsigned long)&nvmsg->msg.v5_msg.send_table +
+ nvmsg->msg.v5_msg.send_table.offset);
+
+ for (i = 0; i < count; i++)
+ nvscdev->send_table[i] = tab[i];
}
-static void netvsc_channel_cb(void *context)
+void netvsc_channel_cb(void *context)
{
int ret;
- struct hv_device *device = context;
+ struct vmbus_channel *channel = (struct vmbus_channel *)context;
+ struct hv_device *device;
struct netvsc_device *net_device;
u32 bytes_recvd;
u64 request_id;
@@ -812,14 +960,19 @@ static void netvsc_channel_cb(void *context)
int bufferlen = NETVSC_PACKET_SIZE;
struct net_device *ndev;
+ if (channel->primary_channel != NULL)
+ device = channel->primary_channel->device_obj;
+ else
+ device = channel->device_obj;
+
net_device = get_inbound_net_device(device);
if (!net_device)
return;
ndev = net_device->ndev;
- buffer = net_device->cb_buffer;
+ buffer = get_per_channel_state(channel);
do {
- ret = vmbus_recvpacket_raw(device->channel, buffer, bufferlen,
+ ret = vmbus_recvpacket_raw(channel, buffer, bufferlen,
&bytes_recvd, &request_id);
if (ret == 0) {
if (bytes_recvd > 0) {
@@ -831,8 +984,12 @@ static void netvsc_channel_cb(void *context)
break;
case VM_PKT_DATA_USING_XFER_PAGES:
- netvsc_receive(net_device,
- device, desc);
+ netvsc_receive(net_device, channel,
+ device, desc);
+ break;
+
+ case VM_PKT_DATA_INBAND:
+ netvsc_send_table(device, desc);
break;
default:
@@ -880,11 +1037,9 @@ static void netvsc_channel_cb(void *context)
int netvsc_device_add(struct hv_device *device, void *additional_info)
{
int ret = 0;
- int i;
int ring_size =
((struct netvsc_device_info *)additional_info)->ring_size;
struct netvsc_device *net_device;
- struct hv_netvsc_packet *packet, *pos;
struct net_device *ndev;
net_device = alloc_net_device(device);
@@ -893,6 +1048,8 @@ int netvsc_device_add(struct hv_device *device, void *additional_info)
goto cleanup;
}
+ net_device->ring_size = ring_size;
+
/*
* Coming into this function, struct net_device * is
* registered as the driver private data.
@@ -903,24 +1060,14 @@ int netvsc_device_add(struct hv_device *device, void *additional_info)
ndev = net_device->ndev;
/* Initialize the NetVSC channel extension */
- spin_lock_init(&net_device->recv_pkt_list_lock);
-
- INIT_LIST_HEAD(&net_device->recv_pkt_list);
-
- for (i = 0; i < NETVSC_RECEIVE_PACKETLIST_COUNT; i++) {
- packet = kzalloc(sizeof(struct hv_netvsc_packet), GFP_KERNEL);
- if (!packet)
- break;
-
- list_add_tail(&packet->list_ent,
- &net_device->recv_pkt_list);
- }
init_completion(&net_device->channel_init_wait);
+ set_per_channel_state(device->channel, net_device->cb_buffer);
+
/* Open the channel */
ret = vmbus_open(device->channel, ring_size * PAGE_SIZE,
ring_size * PAGE_SIZE, NULL, 0,
- netvsc_channel_cb, device);
+ netvsc_channel_cb, device->channel);
if (ret != 0) {
netdev_err(ndev, "unable to open channel: %d\n", ret);
@@ -930,6 +1077,8 @@ int netvsc_device_add(struct hv_device *device, void *additional_info)
/* Channel is opened */
pr_info("hv_netvsc channel opened successfully\n");
+ net_device->chn_table[0] = device->channel;
+
/* Connect with the NetVsp */
ret = netvsc_connect_vsp(device);
if (ret != 0) {
@@ -946,16 +1095,8 @@ close:
cleanup:
- if (net_device) {
- list_for_each_entry_safe(packet, pos,
- &net_device->recv_pkt_list,
- list_ent) {
- list_del(&packet->list_ent);
- kfree(packet);
- }
-
+ if (net_device)
kfree(net_device);
- }
return ret;
}
diff --git a/drivers/net/hyperv/netvsc_drv.c b/drivers/net/hyperv/netvsc_drv.c
index 31e55fb..939e3af 100644
--- a/drivers/net/hyperv/netvsc_drv.c
+++ b/drivers/net/hyperv/netvsc_drv.c
@@ -101,7 +101,7 @@ static int netvsc_open(struct net_device *net)
return ret;
}
- netif_start_queue(net);
+ netif_tx_start_all_queues(net);
nvdev = hv_get_drvdata(device_obj);
rdev = nvdev->extension;
@@ -149,15 +149,98 @@ static void *init_ppi_data(struct rndis_message *msg, u32 ppi_size,
return ppi;
}
+union sub_key {
+ u64 k;
+ struct {
+ u8 pad[3];
+ u8 kb;
+ u32 ka;
+ };
+};
+
+/* Toeplitz hash function
+ * data: network byte order
+ * return: host byte order
+ */
+static u32 comp_hash(u8 *key, int klen, u8 *data, int dlen)
+{
+ union sub_key subk;
+ int k_next = 4;
+ u8 dt;
+ int i, j;
+ u32 ret = 0;
+
+ subk.k = 0;
+ subk.ka = ntohl(*(u32 *)key);
+
+ for (i = 0; i < dlen; i++) {
+ subk.kb = key[k_next];
+ k_next = (k_next + 1) % klen;
+ dt = data[i];
+ for (j = 0; j < 8; j++) {
+ if (dt & 0x80)
+ ret ^= subk.ka;
+ dt <<= 1;
+ subk.k <<= 1;
+ }
+ }
+
+ return ret;
+}
+
+static bool netvsc_set_hash(u32 *hash, struct sk_buff *skb)
+{
+ struct iphdr *iphdr;
+ int data_len;
+ bool ret = false;
+
+ if (eth_hdr(skb)->h_proto != htons(ETH_P_IP))
+ return false;
+
+ iphdr = ip_hdr(skb);
+
+ if (iphdr->version == 4) {
+ if (iphdr->protocol == IPPROTO_TCP)
+ data_len = 12;
+ else
+ data_len = 8;
+ *hash = comp_hash(netvsc_hash_key, HASH_KEYLEN,
+ (u8 *)&iphdr->saddr, data_len);
+ ret = true;
+ }
+
+ return ret;
+}
+
+static u16 netvsc_select_queue(struct net_device *ndev, struct sk_buff *skb,
+ void *accel_priv, select_queue_fallback_t fallback)
+{
+ struct net_device_context *net_device_ctx = netdev_priv(ndev);
+ struct hv_device *hdev = net_device_ctx->device_ctx;
+ struct netvsc_device *nvsc_dev = hv_get_drvdata(hdev);
+ u32 hash;
+ u16 q_idx = 0;
+
+ if (nvsc_dev == NULL || ndev->real_num_tx_queues <= 1)
+ return 0;
+
+ if (netvsc_set_hash(&hash, skb))
+ q_idx = nvsc_dev->send_table[hash % VRSS_SEND_TAB_SIZE] %
+ ndev->real_num_tx_queues;
+
+ return q_idx;
+}
+
static void netvsc_xmit_completion(void *context)
{
struct hv_netvsc_packet *packet = (struct hv_netvsc_packet *)context;
struct sk_buff *skb = (struct sk_buff *)
- (unsigned long)packet->completion.send.send_completion_tid;
+ (unsigned long)packet->send_completion_tid;
+ u32 index = packet->send_buf_index;
kfree(packet);
- if (skb)
+ if (skb && (index == NETVSC_INVALID_INDEX))
dev_kfree_skb_any(skb);
}
@@ -333,6 +416,8 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net)
packet->vlan_tci = skb->vlan_tci;
+ packet->q_idx = skb_get_queue_mapping(skb);
+
packet->is_data_pkt = true;
packet->total_data_buflen = skb->len;
@@ -341,9 +426,9 @@ static int netvsc_start_xmit(struct sk_buff *skb, struct net_device *net)
(num_data_pgs * sizeof(struct hv_page_buffer)));
/* Set the completion routine */
- packet->completion.send.send_completion = netvsc_xmit_completion;
- packet->completion.send.send_completion_ctx = packet;
- packet->completion.send.send_completion_tid = (unsigned long)skb;
+ packet->send_completion = netvsc_xmit_completion;
+ packet->send_completion_ctx = packet;
+ packet->send_completion_tid = (unsigned long)skb;
isvlan = packet->vlan_tci & VLAN_TAG_PRESENT;
@@ -554,6 +639,10 @@ int netvsc_recv_callback(struct hv_device *device_obj,
__vlan_hwaccel_put_tag(skb, htons(ETH_P_8021Q),
packet->vlan_tci);
+ skb_record_rx_queue(skb, packet->channel->
+ offermsg.offer.sub_channel_index %
+ net->real_num_rx_queues);
+
net->stats.rx_packets++;
net->stats.rx_bytes += packet->total_data_buflen;
@@ -602,7 +691,7 @@ static int netvsc_change_mtu(struct net_device *ndev, int mtu)
hv_set_drvdata(hdev, ndev);
device_info.ring_size = ring_size;
rndis_filter_device_add(hdev, &device_info);
- netif_wake_queue(ndev);
+ netif_tx_wake_all_queues(ndev);
return 0;
}
@@ -648,6 +737,7 @@ static const struct net_device_ops device_ops = {
.ndo_change_mtu = netvsc_change_mtu,
.ndo_validate_addr = eth_validate_addr,
.ndo_set_mac_address = netvsc_set_mac_addr,
+ .ndo_select_queue = netvsc_select_queue,
};
/*
@@ -694,9 +784,11 @@ static int netvsc_probe(struct hv_device *dev,
struct net_device *net = NULL;
struct net_device_context *net_device_ctx;
struct netvsc_device_info device_info;
+ struct netvsc_device *nvdev;
int ret;
- net = alloc_etherdev(sizeof(struct net_device_context));
+ net = alloc_etherdev_mq(sizeof(struct net_device_context),
+ num_online_cpus());
if (!net)
return -ENOMEM;
@@ -729,6 +821,12 @@ static int netvsc_probe(struct hv_device *dev,
}
memcpy(net->dev_addr, device_info.mac_adr, ETH_ALEN);
+ nvdev = hv_get_drvdata(dev);
+ netif_set_real_num_tx_queues(net, nvdev->num_chn);
+ netif_set_real_num_rx_queues(net, nvdev->num_chn);
+ dev_info(&dev->device, "real num tx,rx queues:%u, %u\n",
+ net->real_num_tx_queues, net->real_num_rx_queues);
+
ret = register_netdev(net);
if (ret != 0) {
pr_err("Unable to register netdev.\n");
diff --git a/drivers/net/hyperv/rndis_filter.c b/drivers/net/hyperv/rndis_filter.c
index 143a98c..99c527a 100644
--- a/drivers/net/hyperv/rndis_filter.c
+++ b/drivers/net/hyperv/rndis_filter.c
@@ -31,7 +31,7 @@
#include "hyperv_net.h"
-#define RNDIS_EXT_LEN 100
+#define RNDIS_EXT_LEN PAGE_SIZE
struct rndis_request {
struct list_head list_ent;
struct completion wait_event;
@@ -94,6 +94,8 @@ static struct rndis_request *get_rndis_request(struct rndis_device *dev,
rndis_msg->ndis_msg_type = msg_type;
rndis_msg->msg_len = msg_len;
+ request->pkt.q_idx = 0;
+
/*
* Set the request id. This field is always after the rndis header for
* request/response packet types so we just used the SetRequest as a
@@ -234,7 +236,7 @@ static int rndis_filter_send_request(struct rndis_device *dev,
packet->page_buf[0].len;
}
- packet->completion.send.send_completion = NULL;
+ packet->send_completion = NULL;
ret = netvsc_send(dev->net_dev->dev, packet);
return ret;
@@ -399,8 +401,6 @@ static void rndis_filter_receive_data(struct rndis_device *dev,
pkt->total_data_buflen = rndis_pkt->data_len;
pkt->data = (void *)((unsigned long)pkt->data + data_offset);
- pkt->is_data_pkt = true;
-
vlan = rndis_get_ppi(rndis_pkt, IEEE_8021Q_INFO);
if (vlan) {
pkt->vlan_tci = VLAN_TAG_PRESENT | vlan->vlanid |
@@ -509,6 +509,19 @@ static int rndis_filter_query_device(struct rndis_device *dev, u32 oid,
query->info_buflen = 0;
query->dev_vc_handle = 0;
+ if (oid == OID_GEN_RECEIVE_SCALE_CAPABILITIES) {
+ struct ndis_recv_scale_cap *cap;
+
+ request->request_msg.msg_len +=
+ sizeof(struct ndis_recv_scale_cap);
+ query->info_buflen = sizeof(struct ndis_recv_scale_cap);
+ cap = (struct ndis_recv_scale_cap *)((unsigned long)query +
+ query->info_buf_offset);
+ cap->hdr.type = NDIS_OBJECT_TYPE_RSS_CAPABILITIES;
+ cap->hdr.rev = NDIS_RECEIVE_SCALE_CAPABILITIES_REVISION_2;
+ cap->hdr.size = sizeof(struct ndis_recv_scale_cap);
+ }
+
ret = rndis_filter_send_request(dev, request);
if (ret != 0)
goto cleanup;
@@ -695,6 +708,89 @@ cleanup:
return ret;
}
+u8 netvsc_hash_key[HASH_KEYLEN] = {
+ 0x6d, 0x5a, 0x56, 0xda, 0x25, 0x5b, 0x0e, 0xc2,
+ 0x41, 0x67, 0x25, 0x3d, 0x43, 0xa3, 0x8f, 0xb0,
+ 0xd0, 0xca, 0x2b, 0xcb, 0xae, 0x7b, 0x30, 0xb4,
+ 0x77, 0xcb, 0x2d, 0xa3, 0x80, 0x30, 0xf2, 0x0c,
+ 0x6a, 0x42, 0xb7, 0x3b, 0xbe, 0xac, 0x01, 0xfa
+};
+
+int rndis_filter_set_rss_param(struct rndis_device *rdev, int num_queue)
+{
+ struct net_device *ndev = rdev->net_dev->ndev;
+ struct rndis_request *request;
+ struct rndis_set_request *set;
+ struct rndis_set_complete *set_complete;
+ u32 extlen = sizeof(struct ndis_recv_scale_param) +
+ 4*ITAB_NUM + HASH_KEYLEN;
+ struct ndis_recv_scale_param *rssp;
+ u32 *itab;
+ u8 *keyp;
+ int i, t, ret;
+
+ request = get_rndis_request(
+ rdev, RNDIS_MSG_SET,
+ RNDIS_MESSAGE_SIZE(struct rndis_set_request) + extlen);
+ if (!request)
+ return -ENOMEM;
+
+ set = &request->request_msg.msg.set_req;
+ set->oid = OID_GEN_RECEIVE_SCALE_PARAMETERS;
+ set->info_buflen = extlen;
+ set->info_buf_offset = sizeof(struct rndis_set_request);
+ set->dev_vc_handle = 0;
+
+ rssp = (struct ndis_recv_scale_param *)(set + 1);
+ rssp->hdr.type = NDIS_OBJECT_TYPE_RSS_PARAMETERS;
+ rssp->hdr.rev = NDIS_RECEIVE_SCALE_PARAMETERS_REVISION_2;
+ rssp->hdr.size = sizeof(struct ndis_recv_scale_param);
+ rssp->flag = 0;
+ rssp->hashinfo = NDIS_HASH_FUNC_TOEPLITZ | NDIS_HASH_IPV4 |
+ NDIS_HASH_TCP_IPV4;
+ rssp->indirect_tabsize = 4*ITAB_NUM;
+ rssp->indirect_taboffset = sizeof(struct ndis_recv_scale_param);
+ rssp->hashkey_size = HASH_KEYLEN;
+ rssp->kashkey_offset = rssp->indirect_taboffset +
+ rssp->indirect_tabsize;
+
+ /* Set indirection table entries */
+ itab = (u32 *)(rssp + 1);
+ for (i = 0; i < ITAB_NUM; i++)
+ itab[i] = i % num_queue;
+
+ /* Set hask key values */
+ keyp = (u8 *)((unsigned long)rssp + rssp->kashkey_offset);
+ for (i = 0; i < HASH_KEYLEN; i++)
+ keyp[i] = netvsc_hash_key[i];
+
+
+ ret = rndis_filter_send_request(rdev, request);
+ if (ret != 0)
+ goto cleanup;
+
+ t = wait_for_completion_timeout(&request->wait_event, 5*HZ);
+ if (t == 0) {
+ netdev_err(ndev, "timeout before we got a set response...\n");
+ /* can't put_rndis_request, since we may still receive a
+ * send-completion.
+ */
+ return -ETIMEDOUT;
+ } else {
+ set_complete = &request->response_msg.msg.set_complete;
+ if (set_complete->status != RNDIS_STATUS_SUCCESS) {
+ netdev_err(ndev, "Fail to set RSS parameters:0x%x\n",
+ set_complete->status);
+ ret = -EINVAL;
+ }
+ }
+
+cleanup:
+ put_rndis_request(rdev, request);
+ return ret;
+}
+
+
static int rndis_filter_query_device_link_status(struct rndis_device *dev)
{
u32 size = sizeof(u32);
@@ -886,6 +982,28 @@ static int rndis_filter_close_device(struct rndis_device *dev)
return ret;
}
+static void netvsc_sc_open(struct vmbus_channel *new_sc)
+{
+ struct netvsc_device *nvscdev;
+ u16 chn_index = new_sc->offermsg.offer.sub_channel_index;
+ int ret;
+
+ nvscdev = hv_get_drvdata(new_sc->primary_channel->device_obj);
+
+ if (chn_index >= nvscdev->num_chn)
+ return;
+
+ set_per_channel_state(new_sc, nvscdev->sub_cb_buf + (chn_index - 1) *
+ NETVSC_PACKET_SIZE);
+
+ ret = vmbus_open(new_sc, nvscdev->ring_size * PAGE_SIZE,
+ nvscdev->ring_size * PAGE_SIZE, NULL, 0,
+ netvsc_channel_cb, new_sc);
+
+ if (ret == 0)
+ nvscdev->chn_table[chn_index] = new_sc;
+}
+
int rndis_filter_device_add(struct hv_device *dev,
void *additional_info)
{
@@ -894,6 +1012,10 @@ int rndis_filter_device_add(struct hv_device *dev,
struct rndis_device *rndis_device;
struct netvsc_device_info *device_info = additional_info;
struct ndis_offload_params offloads;
+ struct nvsp_message *init_packet;
+ int t;
+ struct ndis_recv_scale_cap rsscap;
+ u32 rsscap_size = sizeof(struct ndis_recv_scale_cap);
rndis_device = get_rndis_device();
if (!rndis_device)
@@ -913,6 +1035,7 @@ int rndis_filter_device_add(struct hv_device *dev,
/* Initialize the rndis device */
net_device = hv_get_drvdata(dev);
+ net_device->num_chn = 1;
net_device->extension = rndis_device;
rndis_device->net_dev = net_device;
@@ -952,7 +1075,6 @@ int rndis_filter_device_add(struct hv_device *dev,
if (ret)
goto err_dev_remv;
-
rndis_filter_query_device_link_status(rndis_device);
device_info->link_state = rndis_device->link_state;
@@ -961,7 +1083,66 @@ int rndis_filter_device_add(struct hv_device *dev,
rndis_device->hw_mac_adr,
device_info->link_state ? "down" : "up");
- return ret;
+ if (net_device->nvsp_version < NVSP_PROTOCOL_VERSION_5)
+ return 0;
+
+ /* vRSS setup */
+ memset(&rsscap, 0, rsscap_size);
+ ret = rndis_filter_query_device(rndis_device,
+ OID_GEN_RECEIVE_SCALE_CAPABILITIES,
+ &rsscap, &rsscap_size);
+ if (ret || rsscap.num_recv_que < 2)
+ goto out;
+
+ net_device->num_chn = (num_online_cpus() < rsscap.num_recv_que) ?
+ num_online_cpus() : rsscap.num_recv_que;
+ if (net_device->num_chn == 1)
+ goto out;
+
+ net_device->sub_cb_buf = vzalloc((net_device->num_chn - 1) *
+ NETVSC_PACKET_SIZE);
+ if (!net_device->sub_cb_buf) {
+ net_device->num_chn = 1;
+ dev_info(&dev->device, "No memory for subchannels.\n");
+ goto out;
+ }
+
+ vmbus_set_sc_create_callback(dev->channel, netvsc_sc_open);
+
+ init_packet = &net_device->channel_init_pkt;
+ memset(init_packet, 0, sizeof(struct nvsp_message));
+ init_packet->hdr.msg_type = NVSP_MSG5_TYPE_SUBCHANNEL;
+ init_packet->msg.v5_msg.subchn_req.op = NVSP_SUBCHANNEL_ALLOCATE;
+ init_packet->msg.v5_msg.subchn_req.num_subchannels =
+ net_device->num_chn - 1;
+ ret = vmbus_sendpacket(dev->channel, init_packet,
+ sizeof(struct nvsp_message),
+ (unsigned long)init_packet,
+ VM_PKT_DATA_INBAND,
+ VMBUS_DATA_PACKET_FLAG_COMPLETION_REQUESTED);
+ if (ret)
+ goto out;
+ t = wait_for_completion_timeout(&net_device->channel_init_wait, 5*HZ);
+ if (t == 0) {
+ ret = -ETIMEDOUT;
+ goto out;
+ }
+ if (init_packet->msg.v5_msg.subchn_comp.status !=
+ NVSP_STAT_SUCCESS) {
+ ret = -ENODEV;
+ goto out;
+ }
+ net_device->num_chn = 1 +
+ init_packet->msg.v5_msg.subchn_comp.num_subchannels;
+
+ vmbus_are_subchannels_present(dev->channel);
+
+ ret = rndis_filter_set_rss_param(rndis_device, net_device->num_chn);
+
+out:
+ if (ret)
+ net_device->num_chn = 1;
+ return 0; /* return 0 because primary channel can be used alone */
err_dev_remv:
rndis_filter_device_remove(dev);
diff --git a/drivers/net/ieee802154/at86rf230.c b/drivers/net/ieee802154/at86rf230.c
index e36f194..4517b14 100644
--- a/drivers/net/ieee802154/at86rf230.c
+++ b/drivers/net/ieee802154/at86rf230.c
@@ -23,6 +23,7 @@
#include <linux/kernel.h>
#include <linux/module.h>
#include <linux/interrupt.h>
+#include <linux/irq.h>
#include <linux/gpio.h>
#include <linux/delay.h>
#include <linux/mutex.h>
@@ -692,10 +693,7 @@ at86rf230_xmit(struct ieee802154_dev *dev, struct sk_buff *skb)
if (rc < 0)
goto err_rx;
- rc = at86rf230_start(dev);
-
- return rc;
-
+ return at86rf230_start(dev);
err_rx:
at86rf230_start(dev);
err:
@@ -963,33 +961,24 @@ static irqreturn_t at86rf230_isr_level(int irq, void *data)
return at86rf230_isr(irq, data);
}
-static int at86rf230_irq_polarity(struct at86rf230_local *lp, int pol)
-{
- return at86rf230_write_subreg(lp, SR_IRQ_POLARITY, pol);
-}
-
static int at86rf230_hw_init(struct at86rf230_local *lp)
{
- struct at86rf230_platform_data *pdata = lp->spi->dev.platform_data;
- int rc, irq_pol;
- u8 status;
+ int rc, irq_pol, irq_type;
+ u8 dvdd;
u8 csma_seed[2];
- rc = at86rf230_read_subreg(lp, SR_TRX_STATUS, &status);
- if (rc)
- return rc;
-
rc = at86rf230_write_subreg(lp, SR_TRX_CMD, 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 (pdata->irq_type & (IRQF_TRIGGER_FALLING | IRQF_TRIGGER_LOW))
+ if (irq_type & (IRQF_TRIGGER_FALLING | IRQF_TRIGGER_LOW))
irq_pol = IRQ_ACTIVE_LOW;
else
irq_pol = IRQ_ACTIVE_HIGH;
- rc = at86rf230_irq_polarity(lp, irq_pol);
+ rc = at86rf230_write_subreg(lp, SR_IRQ_POLARITY, irq_pol);
if (rc)
return rc;
@@ -1017,10 +1006,10 @@ static int at86rf230_hw_init(struct at86rf230_local *lp)
/* Wait the next SLEEP cycle */
msleep(100);
- rc = at86rf230_read_subreg(lp, SR_DVDD_OK, &status);
+ rc = at86rf230_read_subreg(lp, SR_DVDD_OK, &dvdd);
if (rc)
return rc;
- if (!status) {
+ if (!dvdd) {
dev_err(&lp->spi->dev, "DVDD error\n");
return -EINVAL;
}
@@ -1032,7 +1021,6 @@ static struct at86rf230_platform_data *
at86rf230_get_pdata(struct spi_device *spi)
{
struct at86rf230_platform_data *pdata;
- const char *irq_type;
if (!IS_ENABLED(CONFIG_OF) || !spi->dev.of_node)
return spi->dev.platform_data;
@@ -1044,19 +1032,6 @@ at86rf230_get_pdata(struct spi_device *spi)
pdata->rstn = of_get_named_gpio(spi->dev.of_node, "reset-gpio", 0);
pdata->slp_tr = of_get_named_gpio(spi->dev.of_node, "sleep-gpio", 0);
- pdata->irq_type = IRQF_TRIGGER_RISING;
- of_property_read_string(spi->dev.of_node, "irq-type", &irq_type);
- if (!strcmp(irq_type, "level-high"))
- pdata->irq_type = IRQF_TRIGGER_HIGH;
- else if (!strcmp(irq_type, "level-low"))
- pdata->irq_type = IRQF_TRIGGER_LOW;
- else if (!strcmp(irq_type, "edge-rising"))
- pdata->irq_type = IRQF_TRIGGER_RISING;
- else if (!strcmp(irq_type, "edge-falling"))
- pdata->irq_type = IRQF_TRIGGER_FALLING;
- else
- dev_warn(&spi->dev, "wrong irq-type specified using edge-rising\n");
-
spi->dev.platform_data = pdata;
done:
return pdata;
@@ -1071,7 +1046,7 @@ static int at86rf230_probe(struct spi_device *spi)
u8 part = 0, version = 0, status;
irq_handler_t irq_handler;
work_func_t irq_worker;
- int rc;
+ int rc, irq_type;
const char *chip;
struct ieee802154_ops *ops = NULL;
@@ -1087,27 +1062,17 @@ static int at86rf230_probe(struct spi_device *spi)
}
if (gpio_is_valid(pdata->rstn)) {
- rc = gpio_request(pdata->rstn, "rstn");
+ rc = devm_gpio_request_one(&spi->dev, pdata->rstn,
+ GPIOF_OUT_INIT_HIGH, "rstn");
if (rc)
return rc;
}
if (gpio_is_valid(pdata->slp_tr)) {
- rc = gpio_request(pdata->slp_tr, "slp_tr");
- if (rc)
- goto err_slp_tr;
- }
-
- if (gpio_is_valid(pdata->rstn)) {
- rc = gpio_direction_output(pdata->rstn, 1);
- if (rc)
- goto err_gpio_dir;
- }
-
- if (gpio_is_valid(pdata->slp_tr)) {
- rc = gpio_direction_output(pdata->slp_tr, 0);
+ rc = devm_gpio_request_one(&spi->dev, pdata->slp_tr,
+ GPIOF_OUT_INIT_LOW, "slp_tr");
if (rc)
- goto err_gpio_dir;
+ return rc;
}
/* Reset */
@@ -1121,13 +1086,12 @@ static int at86rf230_probe(struct spi_device *spi)
rc = __at86rf230_detect_device(spi, &man_id, &part, &version);
if (rc < 0)
- goto err_gpio_dir;
+ 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);
- rc = -EINVAL;
- goto err_gpio_dir;
+ return -EINVAL;
}
switch (part) {
@@ -1154,16 +1118,12 @@ static int at86rf230_probe(struct spi_device *spi)
}
dev_info(&spi->dev, "Detected %s chip version %d\n", chip, version);
- if (!ops) {
- rc = -ENOTSUPP;
- goto err_gpio_dir;
- }
+ if (!ops)
+ return -ENOTSUPP;
dev = ieee802154_alloc_device(sizeof(*lp), ops);
- if (!dev) {
- rc = -ENOMEM;
- goto err_gpio_dir;
- }
+ if (!dev)
+ return -ENOMEM;
lp = dev->priv;
lp->dev = dev;
@@ -1176,7 +1136,8 @@ static int at86rf230_probe(struct spi_device *spi)
dev->extra_tx_headroom = 0;
dev->flags = IEEE802154_HW_OMIT_CKSUM | IEEE802154_HW_AACK;
- if (pdata->irq_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) {
+ irq_type = irq_get_trigger_type(spi->irq);
+ if (irq_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) {
irq_worker = at86rf230_irqwork;
irq_handler = at86rf230_isr;
} else {
@@ -1202,75 +1163,65 @@ static int at86rf230_probe(struct spi_device *spi)
if (rc)
goto err_hw_init;
- rc = request_irq(spi->irq, irq_handler,
- IRQF_SHARED | pdata->irq_type,
- dev_name(&spi->dev), lp);
+ /* 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;
- /* Read irq status register to reset irq line */
- rc = at86rf230_read_subreg(lp, RG_IRQ_STATUS, 0xff, 0, &status);
+ rc = devm_request_irq(&spi->dev, spi->irq, irq_handler, IRQF_SHARED,
+ dev_name(&spi->dev), lp);
if (rc)
- goto err_irq;
+ goto err_hw_init;
rc = ieee802154_register_device(lp->dev);
if (rc)
- goto err_irq;
+ goto err_hw_init;
return rc;
-err_irq:
- free_irq(spi->irq, lp);
err_hw_init:
flush_work(&lp->irqwork);
- spi_set_drvdata(spi, NULL);
mutex_destroy(&lp->bmux);
ieee802154_free_device(lp->dev);
-err_gpio_dir:
- if (gpio_is_valid(pdata->slp_tr))
- gpio_free(pdata->slp_tr);
-err_slp_tr:
- if (gpio_is_valid(pdata->rstn))
- gpio_free(pdata->rstn);
return rc;
}
static int at86rf230_remove(struct spi_device *spi)
{
struct at86rf230_local *lp = spi_get_drvdata(spi);
- struct at86rf230_platform_data *pdata = spi->dev.platform_data;
/* mask all at86rf230 irq's */
at86rf230_write_subreg(lp, SR_IRQ_MASK, 0);
ieee802154_unregister_device(lp->dev);
-
- free_irq(spi->irq, lp);
flush_work(&lp->irqwork);
-
- if (gpio_is_valid(pdata->slp_tr))
- gpio_free(pdata->slp_tr);
- if (gpio_is_valid(pdata->rstn))
- gpio_free(pdata->rstn);
-
mutex_destroy(&lp->bmux);
ieee802154_free_device(lp->dev);
-
dev_dbg(&spi->dev, "unregistered at86rf230\n");
+
return 0;
}
-#if IS_ENABLED(CONFIG_OF)
-static struct of_device_id at86rf230_of_match[] = {
+static const struct of_device_id at86rf230_of_match[] = {
{ .compatible = "atmel,at86rf230", },
{ .compatible = "atmel,at86rf231", },
{ .compatible = "atmel,at86rf233", },
{ .compatible = "atmel,at86rf212", },
{ },
};
-#endif
+MODULE_DEVICE_TABLE(of, at86rf230_of_match);
+
+static const struct spi_device_id at86rf230_device_id[] = {
+ { .name = "at86rf230", },
+ { .name = "at86rf231", },
+ { .name = "at86rf233", },
+ { .name = "at86rf212", },
+ { },
+};
+MODULE_DEVICE_TABLE(spi, at86rf230_device_id);
static struct spi_driver at86rf230_driver = {
+ .id_table = at86rf230_device_id,
.driver = {
.of_match_table = of_match_ptr(at86rf230_of_match),
.name = "at86rf230",
diff --git a/drivers/net/macvlan.c b/drivers/net/macvlan.c
index 753a8c2..cfb27c8 100644
--- a/drivers/net/macvlan.c
+++ b/drivers/net/macvlan.c
@@ -30,6 +30,7 @@
#include <linux/if_link.h>
#include <linux/if_macvlan.h>
#include <linux/hash.h>
+#include <linux/workqueue.h>
#include <net/rtnetlink.h>
#include <net/xfrm.h>
@@ -40,10 +41,18 @@ struct macvlan_port {
struct hlist_head vlan_hash[MACVLAN_HASH_SIZE];
struct list_head vlans;
struct rcu_head rcu;
+ struct sk_buff_head bc_queue;
+ struct work_struct bc_work;
bool passthru;
int count;
};
+struct macvlan_skb_cb {
+ const struct macvlan_dev *src;
+};
+
+#define MACVLAN_SKB_CB(__skb) ((struct macvlan_skb_cb *)&((__skb)->cb[0]))
+
static void macvlan_port_destroy(struct net_device *dev);
static struct macvlan_port *macvlan_port_get_rcu(const struct net_device *dev)
@@ -120,7 +129,7 @@ static int macvlan_broadcast_one(struct sk_buff *skb,
struct net_device *dev = vlan->dev;
if (local)
- return dev_forward_skb(dev, skb);
+ return __dev_forward_skb(dev, skb);
skb->dev = dev;
if (ether_addr_equal_64bits(eth->h_dest, dev->broadcast))
@@ -128,7 +137,7 @@ static int macvlan_broadcast_one(struct sk_buff *skb,
else
skb->pkt_type = PACKET_MULTICAST;
- return netif_rx(skb);
+ return 0;
}
static u32 macvlan_hash_mix(const struct macvlan_dev *vlan)
@@ -175,32 +184,32 @@ static void macvlan_broadcast(struct sk_buff *skb,
if (likely(nskb))
err = macvlan_broadcast_one(
nskb, vlan, eth,
- mode == MACVLAN_MODE_BRIDGE);
+ mode == MACVLAN_MODE_BRIDGE) ?:
+ netif_rx_ni(nskb);
macvlan_count_rx(vlan, skb->len + ETH_HLEN,
err == NET_RX_SUCCESS, 1);
}
}
}
-/* called under rcu_read_lock() from netif_receive_skb */
-static rx_handler_result_t macvlan_handle_frame(struct sk_buff **pskb)
+static void macvlan_process_broadcast(struct work_struct *w)
{
- struct macvlan_port *port;
- struct sk_buff *skb = *pskb;
- const struct ethhdr *eth = eth_hdr(skb);
- const struct macvlan_dev *vlan;
- const struct macvlan_dev *src;
- struct net_device *dev;
- unsigned int len = 0;
- int ret = NET_RX_DROP;
+ struct macvlan_port *port = container_of(w, struct macvlan_port,
+ bc_work);
+ struct sk_buff *skb;
+ struct sk_buff_head list;
+
+ skb_queue_head_init(&list);
+
+ spin_lock_bh(&port->bc_queue.lock);
+ skb_queue_splice_tail_init(&port->bc_queue, &list);
+ spin_unlock_bh(&port->bc_queue.lock);
+
+ while ((skb = __skb_dequeue(&list))) {
+ const struct macvlan_dev *src = MACVLAN_SKB_CB(skb)->src;
+
+ rcu_read_lock();
- port = macvlan_port_get_rcu(skb->dev);
- if (is_multicast_ether_addr(eth->h_dest)) {
- skb = ip_check_defrag(skb, IP_DEFRAG_MACVLAN);
- if (!skb)
- return RX_HANDLER_CONSUMED;
- eth = eth_hdr(skb);
- src = macvlan_hash_lookup(port, eth->h_source);
if (!src)
/* frame comes from an external address */
macvlan_broadcast(skb, port, NULL,
@@ -213,20 +222,80 @@ static rx_handler_result_t macvlan_handle_frame(struct sk_buff **pskb)
macvlan_broadcast(skb, port, src->dev,
MACVLAN_MODE_VEPA |
MACVLAN_MODE_BRIDGE);
- else if (src->mode == MACVLAN_MODE_BRIDGE)
+ else
/*
* flood only to VEPA ports, bridge ports
* already saw the frame on the way out.
*/
macvlan_broadcast(skb, port, src->dev,
MACVLAN_MODE_VEPA);
- else {
+
+ rcu_read_unlock();
+
+ kfree_skb(skb);
+ }
+}
+
+static void macvlan_broadcast_enqueue(struct macvlan_port *port,
+ struct sk_buff *skb)
+{
+ struct sk_buff *nskb;
+ int err = -ENOMEM;
+
+ nskb = skb_clone(skb, GFP_ATOMIC);
+ if (!nskb)
+ goto err;
+
+ spin_lock(&port->bc_queue.lock);
+ if (skb_queue_len(&port->bc_queue) < skb->dev->tx_queue_len) {
+ __skb_queue_tail(&port->bc_queue, nskb);
+ err = 0;
+ }
+ spin_unlock(&port->bc_queue.lock);
+
+ if (err)
+ goto free_nskb;
+
+ schedule_work(&port->bc_work);
+ return;
+
+free_nskb:
+ kfree_skb(nskb);
+err:
+ atomic_long_inc(&skb->dev->rx_dropped);
+}
+
+/* called under rcu_read_lock() from netif_receive_skb */
+static rx_handler_result_t macvlan_handle_frame(struct sk_buff **pskb)
+{
+ struct macvlan_port *port;
+ struct sk_buff *skb = *pskb;
+ const struct ethhdr *eth = eth_hdr(skb);
+ const struct macvlan_dev *vlan;
+ const struct macvlan_dev *src;
+ struct net_device *dev;
+ unsigned int len = 0;
+ int ret = NET_RX_DROP;
+
+ port = macvlan_port_get_rcu(skb->dev);
+ if (is_multicast_ether_addr(eth->h_dest)) {
+ skb = ip_check_defrag(skb, IP_DEFRAG_MACVLAN);
+ if (!skb)
+ return RX_HANDLER_CONSUMED;
+ eth = eth_hdr(skb);
+ src = macvlan_hash_lookup(port, eth->h_source);
+ if (src && src->mode != MACVLAN_MODE_VEPA &&
+ src->mode != MACVLAN_MODE_BRIDGE) {
/* forward to original port. */
vlan = src;
- ret = macvlan_broadcast_one(skb, vlan, eth, 0);
+ ret = macvlan_broadcast_one(skb, vlan, eth, 0) ?:
+ netif_rx(skb);
goto out;
}
+ MACVLAN_SKB_CB(skb)->src = src;
+ macvlan_broadcast_enqueue(port, skb);
+
return RX_HANDLER_PASS;
}
@@ -764,6 +833,9 @@ static int macvlan_port_create(struct net_device *dev)
for (i = 0; i < MACVLAN_HASH_SIZE; i++)
INIT_HLIST_HEAD(&port->vlan_hash[i]);
+ skb_queue_head_init(&port->bc_queue);
+ INIT_WORK(&port->bc_work, macvlan_process_broadcast);
+
err = netdev_rx_handler_register(dev, macvlan_handle_frame, port);
if (err)
kfree(port);
@@ -776,6 +848,7 @@ static void macvlan_port_destroy(struct net_device *dev)
{
struct macvlan_port *port = macvlan_port_get_rtnl(dev);
+ cancel_work_sync(&port->bc_work);
dev->priv_flags &= ~IFF_MACVLAN_PORT;
netdev_rx_handler_unregister(dev);
kfree_rcu(port, rcu);
diff --git a/drivers/net/phy/at803x.c b/drivers/net/phy/at803x.c
index 643464d..6c622ae 100644
--- a/drivers/net/phy/at803x.c
+++ b/drivers/net/phy/at803x.c
@@ -144,41 +144,11 @@ static int at803x_resume(struct phy_device *phydev)
static int at803x_config_init(struct phy_device *phydev)
{
- int val;
int ret;
- u32 features;
-
- features = SUPPORTED_TP | SUPPORTED_MII | SUPPORTED_AUI |
- SUPPORTED_FIBRE | SUPPORTED_BNC;
-
- val = phy_read(phydev, MII_BMSR);
- if (val < 0)
- return val;
-
- if (val & BMSR_ANEGCAPABLE)
- features |= SUPPORTED_Autoneg;
- if (val & BMSR_100FULL)
- features |= SUPPORTED_100baseT_Full;
- if (val & BMSR_100HALF)
- features |= SUPPORTED_100baseT_Half;
- if (val & BMSR_10FULL)
- features |= SUPPORTED_10baseT_Full;
- if (val & BMSR_10HALF)
- features |= SUPPORTED_10baseT_Half;
-
- if (val & BMSR_ESTATEN) {
- val = phy_read(phydev, MII_ESTATUS);
- if (val < 0)
- return val;
-
- if (val & ESTATUS_1000_TFULL)
- features |= SUPPORTED_1000baseT_Full;
- if (val & ESTATUS_1000_THALF)
- features |= SUPPORTED_1000baseT_Half;
- }
- phydev->supported = features;
- phydev->advertising = features;
+ ret = genphy_config_init(phydev);
+ if (ret < 0)
+ return ret;
if (phydev->interface == PHY_INTERFACE_MODE_RGMII_TXID) {
ret = phy_write(phydev, AT803X_DEBUG_ADDR,
@@ -283,8 +253,7 @@ static int __init atheros_init(void)
static void __exit atheros_exit(void)
{
- return phy_drivers_unregister(at803x_driver,
- ARRAY_SIZE(at803x_driver));
+ phy_drivers_unregister(at803x_driver, ARRAY_SIZE(at803x_driver));
}
module_init(atheros_init);
diff --git a/drivers/net/phy/micrel.c b/drivers/net/phy/micrel.c
index 5ad971a..d849684 100644
--- a/drivers/net/phy/micrel.c
+++ b/drivers/net/phy/micrel.c
@@ -246,13 +246,13 @@ static int ksz9021_load_values_from_of(struct phy_device *phydev,
if (val1 != -1)
newval = ((newval & 0xfff0) | ((val1 / PS_TO_REG) & 0xf) << 0);
- if (val2 != -1)
+ if (val2 != -2)
newval = ((newval & 0xff0f) | ((val2 / PS_TO_REG) & 0xf) << 4);
- if (val3 != -1)
+ if (val3 != -3)
newval = ((newval & 0xf0ff) | ((val3 / PS_TO_REG) & 0xf) << 8);
- if (val4 != -1)
+ if (val4 != -4)
newval = ((newval & 0x0fff) | ((val4 / PS_TO_REG) & 0xf) << 12);
return kszphy_extended_write(phydev, reg, newval);
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 0ce6066..466ae3e 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -1067,7 +1067,7 @@ int genphy_soft_reset(struct phy_device *phydev)
}
EXPORT_SYMBOL(genphy_soft_reset);
-static int genphy_config_init(struct phy_device *phydev)
+int genphy_config_init(struct phy_device *phydev)
{
int val;
u32 features;
@@ -1118,6 +1118,7 @@ static int gen10g_soft_reset(struct phy_device *phydev)
/* Do nothing for now */
return 0;
}
+EXPORT_SYMBOL(genphy_config_init);
static int gen10g_config_init(struct phy_device *phydev)
{
diff --git a/drivers/net/phy/smsc.c b/drivers/net/phy/smsc.c
index 11f3481..180c494 100644
--- a/drivers/net/phy/smsc.c
+++ b/drivers/net/phy/smsc.c
@@ -249,8 +249,7 @@ static int __init smsc_init(void)
static void __exit smsc_exit(void)
{
- return phy_drivers_unregister(smsc_phy_driver,
- ARRAY_SIZE(smsc_phy_driver));
+ phy_drivers_unregister(smsc_phy_driver, ARRAY_SIZE(smsc_phy_driver));
}
MODULE_DESCRIPTION("SMSC PHY driver");
diff --git a/drivers/net/phy/vitesse.c b/drivers/net/phy/vitesse.c
index 14372c6..5dc0935d 100644
--- a/drivers/net/phy/vitesse.c
+++ b/drivers/net/phy/vitesse.c
@@ -319,8 +319,7 @@ static int __init vsc82xx_init(void)
static void __exit vsc82xx_exit(void)
{
- return phy_drivers_unregister(vsc82xx_driver,
- ARRAY_SIZE(vsc82xx_driver));
+ phy_drivers_unregister(vsc82xx_driver, ARRAY_SIZE(vsc82xx_driver));
}
module_init(vsc82xx_init);
diff --git a/drivers/net/virtio_net.c b/drivers/net/virtio_net.c
index 7b68746..b852bb3 100644
--- a/drivers/net/virtio_net.c
+++ b/drivers/net/virtio_net.c
@@ -1285,7 +1285,7 @@ static int virtnet_set_channels(struct net_device *dev,
if (channels->rx_count || channels->tx_count || channels->other_count)
return -EINVAL;
- if (queue_pairs > vi->max_queue_pairs)
+ if (queue_pairs > vi->max_queue_pairs || queue_pairs == 0)
return -EINVAL;
get_online_cpus();
@@ -1724,6 +1724,13 @@ static int virtnet_probe(struct virtio_device *vdev)
if (virtio_has_feature(vdev, VIRTIO_NET_F_CTRL_VQ))
vi->has_cvq = true;
+ if (vi->any_header_sg) {
+ if (vi->mergeable_rx_bufs)
+ dev->needed_headroom = sizeof(struct virtio_net_hdr_mrg_rxbuf);
+ else
+ dev->needed_headroom = sizeof(struct virtio_net_hdr);
+ }
+
/* Use single tx/rx queue pair as default */
vi->curr_queue_pairs = 1;
vi->max_queue_pairs = max_queue_pairs;
diff --git a/drivers/net/vxlan.c b/drivers/net/vxlan.c
index 82355d5..1dfee9a 100644
--- a/drivers/net/vxlan.c
+++ b/drivers/net/vxlan.c
@@ -127,6 +127,7 @@ struct vxlan_dev {
struct list_head next; /* vxlan's per namespace list */
struct vxlan_sock *vn_sock; /* listening socket */
struct net_device *dev;
+ struct net *net; /* netns for packet i/o */
struct vxlan_rdst default_dst; /* default destination */
union vxlan_addr saddr; /* source address */
__be16 dst_port;
@@ -389,8 +390,8 @@ static inline size_t vxlan_nlmsg_size(void)
+ nla_total_size(sizeof(struct nda_cacheinfo));
}
-static void vxlan_fdb_notify(struct vxlan_dev *vxlan,
- struct vxlan_fdb *fdb, int type)
+static void vxlan_fdb_notify(struct vxlan_dev *vxlan, struct vxlan_fdb *fdb,
+ struct vxlan_rdst *rd, int type)
{
struct net *net = dev_net(vxlan->dev);
struct sk_buff *skb;
@@ -400,8 +401,7 @@ static void vxlan_fdb_notify(struct vxlan_dev *vxlan,
if (skb == NULL)
goto errout;
- err = vxlan_fdb_info(skb, vxlan, fdb, 0, 0, type, 0,
- first_remote_rtnl(fdb));
+ err = vxlan_fdb_info(skb, vxlan, fdb, 0, 0, type, 0, rd);
if (err < 0) {
/* -EMSGSIZE implies BUG in vxlan_nlmsg_size() */
WARN_ON(err == -EMSGSIZE);
@@ -427,10 +427,7 @@ static void vxlan_ip_miss(struct net_device *dev, union vxlan_addr *ipa)
.remote_vni = VXLAN_N_VID,
};
- INIT_LIST_HEAD(&f.remotes);
- list_add_rcu(&remote.list, &f.remotes);
-
- vxlan_fdb_notify(vxlan, &f, RTM_GETNEIGH);
+ vxlan_fdb_notify(vxlan, &f, &remote, RTM_GETNEIGH);
}
static void vxlan_fdb_miss(struct vxlan_dev *vxlan, const u8 eth_addr[ETH_ALEN])
@@ -438,11 +435,11 @@ static void vxlan_fdb_miss(struct vxlan_dev *vxlan, const u8 eth_addr[ETH_ALEN])
struct vxlan_fdb f = {
.state = NUD_STALE,
};
+ struct vxlan_rdst remote = { };
- INIT_LIST_HEAD(&f.remotes);
memcpy(f.eth_addr, eth_addr, ETH_ALEN);
- vxlan_fdb_notify(vxlan, &f, RTM_GETNEIGH);
+ vxlan_fdb_notify(vxlan, &f, &remote, RTM_GETNEIGH);
}
/* Hash Ethernet address */
@@ -533,7 +530,8 @@ static int vxlan_fdb_replace(struct vxlan_fdb *f,
/* Add/update destinations for multicast */
static int vxlan_fdb_append(struct vxlan_fdb *f,
- union vxlan_addr *ip, __be16 port, __u32 vni, __u32 ifindex)
+ union vxlan_addr *ip, __be16 port, __u32 vni,
+ __u32 ifindex, struct vxlan_rdst **rdp)
{
struct vxlan_rdst *rd;
@@ -551,6 +549,7 @@ static int vxlan_fdb_append(struct vxlan_fdb *f,
list_add_tail_rcu(&rd->list, &f->remotes);
+ *rdp = rd;
return 1;
}
@@ -690,6 +689,7 @@ static int vxlan_fdb_create(struct vxlan_dev *vxlan,
__be16 port, __u32 vni, __u32 ifindex,
__u8 ndm_flags)
{
+ struct vxlan_rdst *rd = NULL;
struct vxlan_fdb *f;
int notify = 0;
@@ -726,7 +726,8 @@ static int vxlan_fdb_create(struct vxlan_dev *vxlan,
if ((flags & NLM_F_APPEND) &&
(is_multicast_ether_addr(f->eth_addr) ||
is_zero_ether_addr(f->eth_addr))) {
- int rc = vxlan_fdb_append(f, ip, port, vni, ifindex);
+ int rc = vxlan_fdb_append(f, ip, port, vni, ifindex,
+ &rd);
if (rc < 0)
return rc;
@@ -756,15 +757,18 @@ static int vxlan_fdb_create(struct vxlan_dev *vxlan,
INIT_LIST_HEAD(&f->remotes);
memcpy(f->eth_addr, mac, ETH_ALEN);
- vxlan_fdb_append(f, ip, port, vni, ifindex);
+ vxlan_fdb_append(f, ip, port, vni, ifindex, &rd);
++vxlan->addrcnt;
hlist_add_head_rcu(&f->hlist,
vxlan_fdb_head(vxlan, mac));
}
- if (notify)
- vxlan_fdb_notify(vxlan, f, RTM_NEWNEIGH);
+ if (notify) {
+ if (rd == NULL)
+ rd = first_remote_rtnl(f);
+ vxlan_fdb_notify(vxlan, f, rd, RTM_NEWNEIGH);
+ }
return 0;
}
@@ -785,7 +789,7 @@ static void vxlan_fdb_destroy(struct vxlan_dev *vxlan, struct vxlan_fdb *f)
"delete %pM\n", f->eth_addr);
--vxlan->addrcnt;
- vxlan_fdb_notify(vxlan, f, RTM_DELNEIGH);
+ vxlan_fdb_notify(vxlan, f, first_remote_rtnl(f), RTM_DELNEIGH);
hlist_del_rcu(&f->hlist);
call_rcu(&f->rcu, vxlan_fdb_free);
@@ -919,6 +923,7 @@ static int vxlan_fdb_delete(struct ndmsg *ndm, struct nlattr *tb[],
*/
if (rd && !list_is_singular(&f->remotes)) {
list_del_rcu(&rd->list);
+ vxlan_fdb_notify(vxlan, f, rd, RTM_DELNEIGH);
kfree_rcu(rd, rcu);
goto out;
}
@@ -993,7 +998,7 @@ static bool vxlan_snoop(struct net_device *dev,
rdst->remote_ip = *src_ip;
f->updated = jiffies;
- vxlan_fdb_notify(vxlan, f, RTM_NEWNEIGH);
+ vxlan_fdb_notify(vxlan, f, rdst, RTM_NEWNEIGH);
} else {
/* learned new entry */
spin_lock(&vxlan->hash_lock);
@@ -1199,6 +1204,7 @@ static void vxlan_rcv(struct vxlan_sock *vs,
remote_ip = &vxlan->default_dst.remote_ip;
skb_reset_mac_header(skb);
+ skb_scrub_packet(skb, !net_eq(vxlan->net, dev_net(vxlan->dev)));
skb->protocol = eth_type_trans(skb, vxlan->dev);
/* Ignore packet loops (and multicast echo) */
@@ -1614,7 +1620,8 @@ static int vxlan6_xmit_skb(struct vxlan_sock *vs,
struct dst_entry *dst, struct sk_buff *skb,
struct net_device *dev, struct in6_addr *saddr,
struct in6_addr *daddr, __u8 prio, __u8 ttl,
- __be16 src_port, __be16 dst_port, __be32 vni)
+ __be16 src_port, __be16 dst_port, __be32 vni,
+ bool xnet)
{
struct ipv6hdr *ip6h;
struct vxlanhdr *vxh;
@@ -1627,7 +1634,7 @@ static int vxlan6_xmit_skb(struct vxlan_sock *vs,
skb->encapsulation = 1;
}
- skb_scrub_packet(skb, false);
+ skb_scrub_packet(skb, xnet);
min_headroom = LL_RESERVED_SPACE(dst->dev) + dst->header_len
+ VXLAN_HLEN + sizeof(struct ipv6hdr)
@@ -1707,7 +1714,7 @@ static int vxlan6_xmit_skb(struct vxlan_sock *vs,
int vxlan_xmit_skb(struct vxlan_sock *vs,
struct rtable *rt, struct sk_buff *skb,
__be32 src, __be32 dst, __u8 tos, __u8 ttl, __be16 df,
- __be16 src_port, __be16 dst_port, __be32 vni)
+ __be16 src_port, __be16 dst_port, __be32 vni, bool xnet)
{
struct vxlanhdr *vxh;
struct udphdr *uh;
@@ -1756,7 +1763,7 @@ int vxlan_xmit_skb(struct vxlan_sock *vs,
return err;
return iptunnel_xmit(vs->sock->sk, rt, skb, src, dst, IPPROTO_UDP,
- tos, ttl, df, false);
+ tos, ttl, df, xnet);
}
EXPORT_SYMBOL_GPL(vxlan_xmit_skb);
@@ -1849,7 +1856,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
fl4.daddr = dst->sin.sin_addr.s_addr;
fl4.saddr = vxlan->saddr.sin.sin_addr.s_addr;
- rt = ip_route_output_key(dev_net(dev), &fl4);
+ rt = ip_route_output_key(vxlan->net, &fl4);
if (IS_ERR(rt)) {
netdev_dbg(dev, "no route to %pI4\n",
&dst->sin.sin_addr.s_addr);
@@ -1870,7 +1877,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
struct vxlan_dev *dst_vxlan;
ip_rt_put(rt);
- dst_vxlan = vxlan_find_vni(dev_net(dev), vni, dst_port);
+ dst_vxlan = vxlan_find_vni(vxlan->net, vni, dst_port);
if (!dst_vxlan)
goto tx_error;
vxlan_encap_bypass(skb, vxlan, dst_vxlan);
@@ -1883,7 +1890,8 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
err = vxlan_xmit_skb(vxlan->vn_sock, rt, skb,
fl4.saddr, dst->sin.sin_addr.s_addr,
tos, ttl, df, src_port, dst_port,
- htonl(vni << 8));
+ htonl(vni << 8),
+ !net_eq(vxlan->net, dev_net(vxlan->dev)));
if (err < 0)
goto rt_tx_error;
@@ -1923,7 +1931,7 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
struct vxlan_dev *dst_vxlan;
dst_release(ndst);
- dst_vxlan = vxlan_find_vni(dev_net(dev), vni, dst_port);
+ dst_vxlan = vxlan_find_vni(vxlan->net, vni, dst_port);
if (!dst_vxlan)
goto tx_error;
vxlan_encap_bypass(skb, vxlan, dst_vxlan);
@@ -1934,7 +1942,8 @@ static void vxlan_xmit_one(struct sk_buff *skb, struct net_device *dev,
err = vxlan6_xmit_skb(vxlan->vn_sock, ndst, skb,
dev, &fl6.saddr, &fl6.daddr, 0, ttl,
- src_port, dst_port, htonl(vni << 8));
+ src_port, dst_port, htonl(vni << 8),
+ !net_eq(vxlan->net, dev_net(vxlan->dev)));
#endif
}
@@ -2078,7 +2087,7 @@ static void vxlan_vs_add_dev(struct vxlan_sock *vs, struct vxlan_dev *vxlan)
static int vxlan_init(struct net_device *dev)
{
struct vxlan_dev *vxlan = netdev_priv(dev);
- struct vxlan_net *vn = net_generic(dev_net(dev), vxlan_net_id);
+ struct vxlan_net *vn = net_generic(vxlan->net, vxlan_net_id);
struct vxlan_sock *vs;
dev->tstats = netdev_alloc_pcpu_stats(struct pcpu_sw_netstats);
@@ -2086,7 +2095,7 @@ static int vxlan_init(struct net_device *dev)
return -ENOMEM;
spin_lock(&vn->sock_lock);
- vs = vxlan_find_sock(dev_net(dev), vxlan->dst_port);
+ vs = vxlan_find_sock(vxlan->net, vxlan->dst_port);
if (vs) {
/* If we have a socket with same port already, reuse it */
atomic_inc(&vs->refcnt);
@@ -2168,8 +2177,8 @@ static void vxlan_flush(struct vxlan_dev *vxlan)
/* Cleanup timer and forwarding table on shutdown */
static int vxlan_stop(struct net_device *dev)
{
- struct vxlan_net *vn = net_generic(dev_net(dev), vxlan_net_id);
struct vxlan_dev *vxlan = netdev_priv(dev);
+ struct vxlan_net *vn = net_generic(vxlan->net, vxlan_net_id);
struct vxlan_sock *vs = vxlan->vn_sock;
if (vs && vxlan_addr_multicast(&vxlan->default_dst.remote_ip) &&
@@ -2198,7 +2207,7 @@ static int vxlan_change_mtu(struct net_device *dev, int new_mtu)
struct net_device *lowerdev;
int max_mtu;
- lowerdev = __dev_get_by_index(dev_net(dev), dst->remote_ifindex);
+ lowerdev = __dev_get_by_index(vxlan->net, dst->remote_ifindex);
if (lowerdev == NULL)
return eth_change_mtu(dev, new_mtu);
@@ -2281,7 +2290,6 @@ static void vxlan_setup(struct net_device *dev)
dev->tx_queue_len = 0;
dev->features |= NETIF_F_LLTX;
- dev->features |= NETIF_F_NETNS_LOCAL;
dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM;
dev->features |= NETIF_F_RXCSUM;
dev->features |= NETIF_F_GSO_SOFTWARE;
@@ -2574,7 +2582,7 @@ EXPORT_SYMBOL_GPL(vxlan_sock_add);
static void vxlan_sock_work(struct work_struct *work)
{
struct vxlan_dev *vxlan = container_of(work, struct vxlan_dev, sock_work);
- struct net *net = dev_net(vxlan->dev);
+ struct net *net = vxlan->net;
struct vxlan_net *vn = net_generic(net, vxlan_net_id);
__be16 port = vxlan->dst_port;
struct vxlan_sock *nvs;
@@ -2601,6 +2609,8 @@ static int vxlan_newlink(struct net *net, struct net_device *dev,
if (!data[IFLA_VXLAN_ID])
return -EINVAL;
+ vxlan->net = dev_net(dev);
+
vni = nla_get_u32(data[IFLA_VXLAN_ID]);
dst->remote_vni = vni;
@@ -2735,8 +2745,8 @@ static int vxlan_newlink(struct net *net, struct net_device *dev,
static void vxlan_dellink(struct net_device *dev, struct list_head *head)
{
- struct vxlan_net *vn = net_generic(dev_net(dev), vxlan_net_id);
struct vxlan_dev *vxlan = netdev_priv(dev);
+ struct vxlan_net *vn = net_generic(vxlan->net, vxlan_net_id);
spin_lock(&vn->sock_lock);
if (!hlist_unhashed(&vxlan->hlist))
@@ -2901,8 +2911,33 @@ static __net_init int vxlan_init_net(struct net *net)
return 0;
}
+static void __net_exit vxlan_exit_net(struct net *net)
+{
+ struct vxlan_net *vn = net_generic(net, vxlan_net_id);
+ struct vxlan_dev *vxlan, *next;
+ struct net_device *dev, *aux;
+ LIST_HEAD(list);
+
+ rtnl_lock();
+ for_each_netdev_safe(net, dev, aux)
+ if (dev->rtnl_link_ops == &vxlan_link_ops)
+ unregister_netdevice_queue(dev, &list);
+
+ list_for_each_entry_safe(vxlan, next, &vn->vxlan_list, next) {
+ /* If vxlan->dev is in the same netns, it has already been added
+ * to the list by the previous loop.
+ */
+ if (!net_eq(dev_net(vxlan->dev), net))
+ unregister_netdevice_queue(dev, &list);
+ }
+
+ unregister_netdevice_many(&list);
+ rtnl_unlock();
+}
+
static struct pernet_operations vxlan_net_ops = {
.init = vxlan_init_net,
+ .exit = vxlan_exit_net,
.id = &vxlan_net_id,
.size = sizeof(struct vxlan_net),
};
diff --git a/drivers/of/base.c b/drivers/of/base.c
index f72d19b..6d4ee22 100644
--- a/drivers/of/base.c
+++ b/drivers/of/base.c
@@ -1828,17 +1828,13 @@ int of_update_property(struct device_node *np, struct property *newprop)
next = &(*next)->next;
}
raw_spin_unlock_irqrestore(&devtree_lock, flags);
- if (rc)
- return rc;
+ if (!found)
+ return -ENODEV;
/* Update the sysfs attribute */
- if (oldprop)
- sysfs_remove_bin_file(&np->kobj, &oldprop->attr);
+ sysfs_remove_bin_file(&np->kobj, &oldprop->attr);
__of_add_property_sysfs(np, newprop);
- if (!found)
- return -ENODEV;
-
return 0;
}
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index fa16a91..7a2ef7b 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -491,7 +491,7 @@ static int __init __reserved_mem_reserve_reg(unsigned long node,
* in /reserved-memory matches the values supported by the current implementation,
* also check if ranges property has been provided
*/
-static int __reserved_mem_check_root(unsigned long node)
+static int __init __reserved_mem_check_root(unsigned long node)
{
__be32 *prop;
diff --git a/drivers/pci/host/pci-rcar-gen2.c b/drivers/pci/host/pci-rcar-gen2.c
index fd3e3ab..4fe349d 100644
--- a/drivers/pci/host/pci-rcar-gen2.c
+++ b/drivers/pci/host/pci-rcar-gen2.c
@@ -15,6 +15,7 @@
#include <linux/io.h>
#include <linux/kernel.h>
#include <linux/module.h>
+#include <linux/of_pci.h>
#include <linux/pci.h>
#include <linux/platform_device.h>
#include <linux/pm_runtime.h>
@@ -180,8 +181,13 @@ static int rcar_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
{
struct pci_sys_data *sys = dev->bus->sysdata;
struct rcar_pci_priv *priv = sys->private_data;
+ int irq;
+
+ irq = of_irq_parse_and_map_pci(dev, slot, pin);
+ if (!irq)
+ irq = priv->irq;
- return priv->irq;
+ return irq;
}
#ifdef CONFIG_PCI_DEBUG
diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c
index 330f7e3..083cf37 100644
--- a/drivers/pci/host/pci-tegra.c
+++ b/drivers/pci/host/pci-tegra.c
@@ -639,10 +639,15 @@ static int tegra_pcie_setup(int nr, struct pci_sys_data *sys)
static int tegra_pcie_map_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
{
struct tegra_pcie *pcie = sys_to_pcie(pdev->bus->sysdata);
+ int irq;
tegra_cpuidle_pcie_irqs_in_use();
- return pcie->irq;
+ irq = of_irq_parse_and_map_pci(pdev, slot, pin);
+ if (!irq)
+ irq = pcie->irq;
+
+ return irq;
}
static void tegra_pcie_add_bus(struct pci_bus *bus)
diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c
index 509a29d..c4e3732 100644
--- a/drivers/pci/host/pcie-designware.c
+++ b/drivers/pci/host/pcie-designware.c
@@ -17,6 +17,7 @@
#include <linux/module.h>
#include <linux/msi.h>
#include <linux/of_address.h>
+#include <linux/of_pci.h>
#include <linux/pci.h>
#include <linux/pci_regs.h>
#include <linux/types.h>
@@ -490,7 +491,7 @@ int __init dw_pcie_host_init(struct pcie_port *pp)
dw_pci.nr_controllers = 1;
dw_pci.private_data = (void **)&pp;
- pci_common_init(&dw_pci);
+ pci_common_init_dev(pp->dev, &dw_pci);
pci_assign_unassigned_resources();
#ifdef CONFIG_PCI_DOMAINS
dw_pci.domain++;
@@ -520,13 +521,13 @@ static void dw_pcie_prog_viewport_cfg1(struct pcie_port *pp, u32 busdev)
dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX1,
PCIE_ATU_VIEWPORT);
dw_pcie_writel_rc(pp, PCIE_ATU_TYPE_CFG1, PCIE_ATU_CR1);
- dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2);
dw_pcie_writel_rc(pp, pp->cfg1_base, PCIE_ATU_LOWER_BASE);
dw_pcie_writel_rc(pp, (pp->cfg1_base >> 32), PCIE_ATU_UPPER_BASE);
dw_pcie_writel_rc(pp, pp->cfg1_base + pp->config.cfg1_size - 1,
PCIE_ATU_LIMIT);
dw_pcie_writel_rc(pp, busdev, PCIE_ATU_LOWER_TARGET);
dw_pcie_writel_rc(pp, 0, PCIE_ATU_UPPER_TARGET);
+ dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2);
}
static void dw_pcie_prog_viewport_mem_outbound(struct pcie_port *pp)
@@ -535,7 +536,6 @@ static void dw_pcie_prog_viewport_mem_outbound(struct pcie_port *pp)
dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX0,
PCIE_ATU_VIEWPORT);
dw_pcie_writel_rc(pp, PCIE_ATU_TYPE_MEM, PCIE_ATU_CR1);
- dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2);
dw_pcie_writel_rc(pp, pp->mem_base, PCIE_ATU_LOWER_BASE);
dw_pcie_writel_rc(pp, (pp->mem_base >> 32), PCIE_ATU_UPPER_BASE);
dw_pcie_writel_rc(pp, pp->mem_base + pp->config.mem_size - 1,
@@ -543,6 +543,7 @@ static void dw_pcie_prog_viewport_mem_outbound(struct pcie_port *pp)
dw_pcie_writel_rc(pp, pp->config.mem_bus_addr, PCIE_ATU_LOWER_TARGET);
dw_pcie_writel_rc(pp, upper_32_bits(pp->config.mem_bus_addr),
PCIE_ATU_UPPER_TARGET);
+ dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2);
}
static void dw_pcie_prog_viewport_io_outbound(struct pcie_port *pp)
@@ -551,7 +552,6 @@ static void dw_pcie_prog_viewport_io_outbound(struct pcie_port *pp)
dw_pcie_writel_rc(pp, PCIE_ATU_REGION_OUTBOUND | PCIE_ATU_REGION_INDEX1,
PCIE_ATU_VIEWPORT);
dw_pcie_writel_rc(pp, PCIE_ATU_TYPE_IO, PCIE_ATU_CR1);
- dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2);
dw_pcie_writel_rc(pp, pp->io_base, PCIE_ATU_LOWER_BASE);
dw_pcie_writel_rc(pp, (pp->io_base >> 32), PCIE_ATU_UPPER_BASE);
dw_pcie_writel_rc(pp, pp->io_base + pp->config.io_size - 1,
@@ -559,6 +559,7 @@ static void dw_pcie_prog_viewport_io_outbound(struct pcie_port *pp)
dw_pcie_writel_rc(pp, pp->config.io_bus_addr, PCIE_ATU_LOWER_TARGET);
dw_pcie_writel_rc(pp, upper_32_bits(pp->config.io_bus_addr),
PCIE_ATU_UPPER_TARGET);
+ dw_pcie_writel_rc(pp, PCIE_ATU_ENABLE, PCIE_ATU_CR2);
}
static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
@@ -723,7 +724,7 @@ static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data *sys)
if (pp) {
pp->root_bus_nr = sys->busnr;
- bus = pci_scan_root_bus(NULL, sys->busnr, &dw_pcie_ops,
+ bus = pci_scan_root_bus(pp->dev, sys->busnr, &dw_pcie_ops,
sys, &sys->resources);
} else {
bus = NULL;
@@ -736,8 +737,13 @@ static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data *sys)
static int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
{
struct pcie_port *pp = sys_to_pcie(dev->bus->sysdata);
+ int irq;
+
+ irq = of_irq_parse_and_map_pci(dev, slot, pin);
+ if (!irq)
+ irq = pp->irq;
- return pp->irq;
+ return irq;
}
static void dw_pcie_add_bus(struct pci_bus *bus)
@@ -764,7 +770,7 @@ void dw_pcie_setup_rc(struct pcie_port *pp)
u32 membase;
u32 memlimit;
- /* set the number of lines as 4 */
+ /* set the number of lanes */
dw_pcie_readl_rc(pp, PCIE_PORT_LINK_CONTROL, &val);
val &= ~PORT_LINK_MODE_MASK;
switch (pp->lanes) {
diff --git a/drivers/pinctrl/Kconfig b/drivers/pinctrl/Kconfig
index e493240..e00c02d 100644
--- a/drivers/pinctrl/Kconfig
+++ b/drivers/pinctrl/Kconfig
@@ -104,16 +104,16 @@ config PINCTRL_BCM2835
select PINMUX
select PINCONF
-config PINCTRL_CAPRI
- bool "Broadcom Capri pinctrl driver"
+config PINCTRL_BCM281XX
+ bool "Broadcom BCM281xx pinctrl driver"
depends on OF
select PINMUX
select PINCONF
select GENERIC_PINCONF
select REGMAP_MMIO
help
- Say Y here to support Broadcom Capri pinctrl driver, which is used for
- the BCM281xx SoC family, including BCM11130, BCM11140, BCM11351,
+ Say Y here to support Broadcom BCM281xx pinctrl driver, which is used
+ for the BCM281xx SoC family, including BCM11130, BCM11140, BCM11351,
BCM28145, and BCM28155 SoCs. This driver requires the pinctrl
framework. GPIO is provided by a separate GPIO driver.
diff --git a/drivers/pinctrl/Makefile b/drivers/pinctrl/Makefile
index 4b83588..6d3fd62 100644
--- a/drivers/pinctrl/Makefile
+++ b/drivers/pinctrl/Makefile
@@ -21,7 +21,7 @@ obj-$(CONFIG_PINCTRL_BF60x) += pinctrl-adi2-bf60x.o
obj-$(CONFIG_PINCTRL_AT91) += pinctrl-at91.o
obj-$(CONFIG_PINCTRL_BCM2835) += pinctrl-bcm2835.o
obj-$(CONFIG_PINCTRL_BAYTRAIL) += pinctrl-baytrail.o
-obj-$(CONFIG_PINCTRL_CAPRI) += pinctrl-capri.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_IMX27) += pinctrl-imx27.o
diff --git a/drivers/pinctrl/pinctrl-bcm281xx.c b/drivers/pinctrl/pinctrl-bcm281xx.c
new file mode 100644
index 0000000..3bed792
--- /dev/null
+++ b/drivers/pinctrl/pinctrl-bcm281xx.c
@@ -0,0 +1,1461 @@
+/*
+ * 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/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pinctrl/pinctrl.h>
+#include <linux/pinctrl/pinmux.h>
+#include <linux/pinctrl/pinconf.h>
+#include <linux/pinctrl/pinconf-generic.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+#include "core.h"
+#include "pinctrl-utils.h"
+
+/* BCM281XX Pin Control Registers Definitions */
+
+/* Function Select bits are the same for all pin control registers */
+#define BCM281XX_PIN_REG_F_SEL_MASK 0x0700
+#define BCM281XX_PIN_REG_F_SEL_SHIFT 8
+
+/* Standard pin register */
+#define BCM281XX_STD_PIN_REG_DRV_STR_MASK 0x0007
+#define BCM281XX_STD_PIN_REG_DRV_STR_SHIFT 0
+#define BCM281XX_STD_PIN_REG_INPUT_DIS_MASK 0x0008
+#define BCM281XX_STD_PIN_REG_INPUT_DIS_SHIFT 3
+#define BCM281XX_STD_PIN_REG_SLEW_MASK 0x0010
+#define BCM281XX_STD_PIN_REG_SLEW_SHIFT 4
+#define BCM281XX_STD_PIN_REG_PULL_UP_MASK 0x0020
+#define BCM281XX_STD_PIN_REG_PULL_UP_SHIFT 5
+#define BCM281XX_STD_PIN_REG_PULL_DN_MASK 0x0040
+#define BCM281XX_STD_PIN_REG_PULL_DN_SHIFT 6
+#define BCM281XX_STD_PIN_REG_HYST_MASK 0x0080
+#define BCM281XX_STD_PIN_REG_HYST_SHIFT 7
+
+/* I2C pin register */
+#define BCM281XX_I2C_PIN_REG_INPUT_DIS_MASK 0x0004
+#define BCM281XX_I2C_PIN_REG_INPUT_DIS_SHIFT 2
+#define BCM281XX_I2C_PIN_REG_SLEW_MASK 0x0008
+#define BCM281XX_I2C_PIN_REG_SLEW_SHIFT 3
+#define BCM281XX_I2C_PIN_REG_PULL_UP_STR_MASK 0x0070
+#define BCM281XX_I2C_PIN_REG_PULL_UP_STR_SHIFT 4
+
+/* HDMI pin register */
+#define BCM281XX_HDMI_PIN_REG_INPUT_DIS_MASK 0x0008
+#define BCM281XX_HDMI_PIN_REG_INPUT_DIS_SHIFT 3
+#define BCM281XX_HDMI_PIN_REG_MODE_MASK 0x0010
+#define BCM281XX_HDMI_PIN_REG_MODE_SHIFT 4
+
+/**
+ * bcm281xx_pin_type - types of pin register
+ */
+enum bcm281xx_pin_type {
+ BCM281XX_PIN_TYPE_UNKNOWN = 0,
+ BCM281XX_PIN_TYPE_STD,
+ BCM281XX_PIN_TYPE_I2C,
+ BCM281XX_PIN_TYPE_HDMI,
+};
+
+static enum bcm281xx_pin_type std_pin = BCM281XX_PIN_TYPE_STD;
+static enum bcm281xx_pin_type i2c_pin = BCM281XX_PIN_TYPE_I2C;
+static enum bcm281xx_pin_type hdmi_pin = BCM281XX_PIN_TYPE_HDMI;
+
+/**
+ * bcm281xx_pin_function- define pin function
+ */
+struct bcm281xx_pin_function {
+ const char *name;
+ const char * const *groups;
+ const unsigned ngroups;
+};
+
+/**
+ * bcm281xx_pinctrl_data - Broadcom-specific pinctrl data
+ * @reg_base - base of pinctrl registers
+ */
+struct bcm281xx_pinctrl_data {
+ void __iomem *reg_base;
+
+ /* List of all pins */
+ const struct pinctrl_pin_desc *pins;
+ const unsigned npins;
+
+ const struct bcm281xx_pin_function *functions;
+ const unsigned nfunctions;
+
+ struct regmap *regmap;
+};
+
+/*
+ * Pin number definition. The order here must be the same as defined in the
+ * PADCTRLREG block in the RDB.
+ */
+#define BCM281XX_PIN_ADCSYNC 0
+#define BCM281XX_PIN_BAT_RM 1
+#define BCM281XX_PIN_BSC1_SCL 2
+#define BCM281XX_PIN_BSC1_SDA 3
+#define BCM281XX_PIN_BSC2_SCL 4
+#define BCM281XX_PIN_BSC2_SDA 5
+#define BCM281XX_PIN_CLASSGPWR 6
+#define BCM281XX_PIN_CLK_CX8 7
+#define BCM281XX_PIN_CLKOUT_0 8
+#define BCM281XX_PIN_CLKOUT_1 9
+#define BCM281XX_PIN_CLKOUT_2 10
+#define BCM281XX_PIN_CLKOUT_3 11
+#define BCM281XX_PIN_CLKREQ_IN_0 12
+#define BCM281XX_PIN_CLKREQ_IN_1 13
+#define BCM281XX_PIN_CWS_SYS_REQ1 14
+#define BCM281XX_PIN_CWS_SYS_REQ2 15
+#define BCM281XX_PIN_CWS_SYS_REQ3 16
+#define BCM281XX_PIN_DIGMIC1_CLK 17
+#define BCM281XX_PIN_DIGMIC1_DQ 18
+#define BCM281XX_PIN_DIGMIC2_CLK 19
+#define BCM281XX_PIN_DIGMIC2_DQ 20
+#define BCM281XX_PIN_GPEN13 21
+#define BCM281XX_PIN_GPEN14 22
+#define BCM281XX_PIN_GPEN15 23
+#define BCM281XX_PIN_GPIO00 24
+#define BCM281XX_PIN_GPIO01 25
+#define BCM281XX_PIN_GPIO02 26
+#define BCM281XX_PIN_GPIO03 27
+#define BCM281XX_PIN_GPIO04 28
+#define BCM281XX_PIN_GPIO05 29
+#define BCM281XX_PIN_GPIO06 30
+#define BCM281XX_PIN_GPIO07 31
+#define BCM281XX_PIN_GPIO08 32
+#define BCM281XX_PIN_GPIO09 33
+#define BCM281XX_PIN_GPIO10 34
+#define BCM281XX_PIN_GPIO11 35
+#define BCM281XX_PIN_GPIO12 36
+#define BCM281XX_PIN_GPIO13 37
+#define BCM281XX_PIN_GPIO14 38
+#define BCM281XX_PIN_GPS_PABLANK 39
+#define BCM281XX_PIN_GPS_TMARK 40
+#define BCM281XX_PIN_HDMI_SCL 41
+#define BCM281XX_PIN_HDMI_SDA 42
+#define BCM281XX_PIN_IC_DM 43
+#define BCM281XX_PIN_IC_DP 44
+#define BCM281XX_PIN_KP_COL_IP_0 45
+#define BCM281XX_PIN_KP_COL_IP_1 46
+#define BCM281XX_PIN_KP_COL_IP_2 47
+#define BCM281XX_PIN_KP_COL_IP_3 48
+#define BCM281XX_PIN_KP_ROW_OP_0 49
+#define BCM281XX_PIN_KP_ROW_OP_1 50
+#define BCM281XX_PIN_KP_ROW_OP_2 51
+#define BCM281XX_PIN_KP_ROW_OP_3 52
+#define BCM281XX_PIN_LCD_B_0 53
+#define BCM281XX_PIN_LCD_B_1 54
+#define BCM281XX_PIN_LCD_B_2 55
+#define BCM281XX_PIN_LCD_B_3 56
+#define BCM281XX_PIN_LCD_B_4 57
+#define BCM281XX_PIN_LCD_B_5 58
+#define BCM281XX_PIN_LCD_B_6 59
+#define BCM281XX_PIN_LCD_B_7 60
+#define BCM281XX_PIN_LCD_G_0 61
+#define BCM281XX_PIN_LCD_G_1 62
+#define BCM281XX_PIN_LCD_G_2 63
+#define BCM281XX_PIN_LCD_G_3 64
+#define BCM281XX_PIN_LCD_G_4 65
+#define BCM281XX_PIN_LCD_G_5 66
+#define BCM281XX_PIN_LCD_G_6 67
+#define BCM281XX_PIN_LCD_G_7 68
+#define BCM281XX_PIN_LCD_HSYNC 69
+#define BCM281XX_PIN_LCD_OE 70
+#define BCM281XX_PIN_LCD_PCLK 71
+#define BCM281XX_PIN_LCD_R_0 72
+#define BCM281XX_PIN_LCD_R_1 73
+#define BCM281XX_PIN_LCD_R_2 74
+#define BCM281XX_PIN_LCD_R_3 75
+#define BCM281XX_PIN_LCD_R_4 76
+#define BCM281XX_PIN_LCD_R_5 77
+#define BCM281XX_PIN_LCD_R_6 78
+#define BCM281XX_PIN_LCD_R_7 79
+#define BCM281XX_PIN_LCD_VSYNC 80
+#define BCM281XX_PIN_MDMGPIO0 81
+#define BCM281XX_PIN_MDMGPIO1 82
+#define BCM281XX_PIN_MDMGPIO2 83
+#define BCM281XX_PIN_MDMGPIO3 84
+#define BCM281XX_PIN_MDMGPIO4 85
+#define BCM281XX_PIN_MDMGPIO5 86
+#define BCM281XX_PIN_MDMGPIO6 87
+#define BCM281XX_PIN_MDMGPIO7 88
+#define BCM281XX_PIN_MDMGPIO8 89
+#define BCM281XX_PIN_MPHI_DATA_0 90
+#define BCM281XX_PIN_MPHI_DATA_1 91
+#define BCM281XX_PIN_MPHI_DATA_2 92
+#define BCM281XX_PIN_MPHI_DATA_3 93
+#define BCM281XX_PIN_MPHI_DATA_4 94
+#define BCM281XX_PIN_MPHI_DATA_5 95
+#define BCM281XX_PIN_MPHI_DATA_6 96
+#define BCM281XX_PIN_MPHI_DATA_7 97
+#define BCM281XX_PIN_MPHI_DATA_8 98
+#define BCM281XX_PIN_MPHI_DATA_9 99
+#define BCM281XX_PIN_MPHI_DATA_10 100
+#define BCM281XX_PIN_MPHI_DATA_11 101
+#define BCM281XX_PIN_MPHI_DATA_12 102
+#define BCM281XX_PIN_MPHI_DATA_13 103
+#define BCM281XX_PIN_MPHI_DATA_14 104
+#define BCM281XX_PIN_MPHI_DATA_15 105
+#define BCM281XX_PIN_MPHI_HA0 106
+#define BCM281XX_PIN_MPHI_HAT0 107
+#define BCM281XX_PIN_MPHI_HAT1 108
+#define BCM281XX_PIN_MPHI_HCE0_N 109
+#define BCM281XX_PIN_MPHI_HCE1_N 110
+#define BCM281XX_PIN_MPHI_HRD_N 111
+#define BCM281XX_PIN_MPHI_HWR_N 112
+#define BCM281XX_PIN_MPHI_RUN0 113
+#define BCM281XX_PIN_MPHI_RUN1 114
+#define BCM281XX_PIN_MTX_SCAN_CLK 115
+#define BCM281XX_PIN_MTX_SCAN_DATA 116
+#define BCM281XX_PIN_NAND_AD_0 117
+#define BCM281XX_PIN_NAND_AD_1 118
+#define BCM281XX_PIN_NAND_AD_2 119
+#define BCM281XX_PIN_NAND_AD_3 120
+#define BCM281XX_PIN_NAND_AD_4 121
+#define BCM281XX_PIN_NAND_AD_5 122
+#define BCM281XX_PIN_NAND_AD_6 123
+#define BCM281XX_PIN_NAND_AD_7 124
+#define BCM281XX_PIN_NAND_ALE 125
+#define BCM281XX_PIN_NAND_CEN_0 126
+#define BCM281XX_PIN_NAND_CEN_1 127
+#define BCM281XX_PIN_NAND_CLE 128
+#define BCM281XX_PIN_NAND_OEN 129
+#define BCM281XX_PIN_NAND_RDY_0 130
+#define BCM281XX_PIN_NAND_RDY_1 131
+#define BCM281XX_PIN_NAND_WEN 132
+#define BCM281XX_PIN_NAND_WP 133
+#define BCM281XX_PIN_PC1 134
+#define BCM281XX_PIN_PC2 135
+#define BCM281XX_PIN_PMU_INT 136
+#define BCM281XX_PIN_PMU_SCL 137
+#define BCM281XX_PIN_PMU_SDA 138
+#define BCM281XX_PIN_RFST2G_MTSLOTEN3G 139
+#define BCM281XX_PIN_RGMII_0_RX_CTL 140
+#define BCM281XX_PIN_RGMII_0_RXC 141
+#define BCM281XX_PIN_RGMII_0_RXD_0 142
+#define BCM281XX_PIN_RGMII_0_RXD_1 143
+#define BCM281XX_PIN_RGMII_0_RXD_2 144
+#define BCM281XX_PIN_RGMII_0_RXD_3 145
+#define BCM281XX_PIN_RGMII_0_TX_CTL 146
+#define BCM281XX_PIN_RGMII_0_TXC 147
+#define BCM281XX_PIN_RGMII_0_TXD_0 148
+#define BCM281XX_PIN_RGMII_0_TXD_1 149
+#define BCM281XX_PIN_RGMII_0_TXD_2 150
+#define BCM281XX_PIN_RGMII_0_TXD_3 151
+#define BCM281XX_PIN_RGMII_1_RX_CTL 152
+#define BCM281XX_PIN_RGMII_1_RXC 153
+#define BCM281XX_PIN_RGMII_1_RXD_0 154
+#define BCM281XX_PIN_RGMII_1_RXD_1 155
+#define BCM281XX_PIN_RGMII_1_RXD_2 156
+#define BCM281XX_PIN_RGMII_1_RXD_3 157
+#define BCM281XX_PIN_RGMII_1_TX_CTL 158
+#define BCM281XX_PIN_RGMII_1_TXC 159
+#define BCM281XX_PIN_RGMII_1_TXD_0 160
+#define BCM281XX_PIN_RGMII_1_TXD_1 161
+#define BCM281XX_PIN_RGMII_1_TXD_2 162
+#define BCM281XX_PIN_RGMII_1_TXD_3 163
+#define BCM281XX_PIN_RGMII_GPIO_0 164
+#define BCM281XX_PIN_RGMII_GPIO_1 165
+#define BCM281XX_PIN_RGMII_GPIO_2 166
+#define BCM281XX_PIN_RGMII_GPIO_3 167
+#define BCM281XX_PIN_RTXDATA2G_TXDATA3G1 168
+#define BCM281XX_PIN_RTXEN2G_TXDATA3G2 169
+#define BCM281XX_PIN_RXDATA3G0 170
+#define BCM281XX_PIN_RXDATA3G1 171
+#define BCM281XX_PIN_RXDATA3G2 172
+#define BCM281XX_PIN_SDIO1_CLK 173
+#define BCM281XX_PIN_SDIO1_CMD 174
+#define BCM281XX_PIN_SDIO1_DATA_0 175
+#define BCM281XX_PIN_SDIO1_DATA_1 176
+#define BCM281XX_PIN_SDIO1_DATA_2 177
+#define BCM281XX_PIN_SDIO1_DATA_3 178
+#define BCM281XX_PIN_SDIO4_CLK 179
+#define BCM281XX_PIN_SDIO4_CMD 180
+#define BCM281XX_PIN_SDIO4_DATA_0 181
+#define BCM281XX_PIN_SDIO4_DATA_1 182
+#define BCM281XX_PIN_SDIO4_DATA_2 183
+#define BCM281XX_PIN_SDIO4_DATA_3 184
+#define BCM281XX_PIN_SIM_CLK 185
+#define BCM281XX_PIN_SIM_DATA 186
+#define BCM281XX_PIN_SIM_DET 187
+#define BCM281XX_PIN_SIM_RESETN 188
+#define BCM281XX_PIN_SIM2_CLK 189
+#define BCM281XX_PIN_SIM2_DATA 190
+#define BCM281XX_PIN_SIM2_DET 191
+#define BCM281XX_PIN_SIM2_RESETN 192
+#define BCM281XX_PIN_SRI_C 193
+#define BCM281XX_PIN_SRI_D 194
+#define BCM281XX_PIN_SRI_E 195
+#define BCM281XX_PIN_SSP_EXTCLK 196
+#define BCM281XX_PIN_SSP0_CLK 197
+#define BCM281XX_PIN_SSP0_FS 198
+#define BCM281XX_PIN_SSP0_RXD 199
+#define BCM281XX_PIN_SSP0_TXD 200
+#define BCM281XX_PIN_SSP2_CLK 201
+#define BCM281XX_PIN_SSP2_FS_0 202
+#define BCM281XX_PIN_SSP2_FS_1 203
+#define BCM281XX_PIN_SSP2_FS_2 204
+#define BCM281XX_PIN_SSP2_FS_3 205
+#define BCM281XX_PIN_SSP2_RXD_0 206
+#define BCM281XX_PIN_SSP2_RXD_1 207
+#define BCM281XX_PIN_SSP2_TXD_0 208
+#define BCM281XX_PIN_SSP2_TXD_1 209
+#define BCM281XX_PIN_SSP3_CLK 210
+#define BCM281XX_PIN_SSP3_FS 211
+#define BCM281XX_PIN_SSP3_RXD 212
+#define BCM281XX_PIN_SSP3_TXD 213
+#define BCM281XX_PIN_SSP4_CLK 214
+#define BCM281XX_PIN_SSP4_FS 215
+#define BCM281XX_PIN_SSP4_RXD 216
+#define BCM281XX_PIN_SSP4_TXD 217
+#define BCM281XX_PIN_SSP5_CLK 218
+#define BCM281XX_PIN_SSP5_FS 219
+#define BCM281XX_PIN_SSP5_RXD 220
+#define BCM281XX_PIN_SSP5_TXD 221
+#define BCM281XX_PIN_SSP6_CLK 222
+#define BCM281XX_PIN_SSP6_FS 223
+#define BCM281XX_PIN_SSP6_RXD 224
+#define BCM281XX_PIN_SSP6_TXD 225
+#define BCM281XX_PIN_STAT_1 226
+#define BCM281XX_PIN_STAT_2 227
+#define BCM281XX_PIN_SYSCLKEN 228
+#define BCM281XX_PIN_TRACECLK 229
+#define BCM281XX_PIN_TRACEDT00 230
+#define BCM281XX_PIN_TRACEDT01 231
+#define BCM281XX_PIN_TRACEDT02 232
+#define BCM281XX_PIN_TRACEDT03 233
+#define BCM281XX_PIN_TRACEDT04 234
+#define BCM281XX_PIN_TRACEDT05 235
+#define BCM281XX_PIN_TRACEDT06 236
+#define BCM281XX_PIN_TRACEDT07 237
+#define BCM281XX_PIN_TRACEDT08 238
+#define BCM281XX_PIN_TRACEDT09 239
+#define BCM281XX_PIN_TRACEDT10 240
+#define BCM281XX_PIN_TRACEDT11 241
+#define BCM281XX_PIN_TRACEDT12 242
+#define BCM281XX_PIN_TRACEDT13 243
+#define BCM281XX_PIN_TRACEDT14 244
+#define BCM281XX_PIN_TRACEDT15 245
+#define BCM281XX_PIN_TXDATA3G0 246
+#define BCM281XX_PIN_TXPWRIND 247
+#define BCM281XX_PIN_UARTB1_UCTS 248
+#define BCM281XX_PIN_UARTB1_URTS 249
+#define BCM281XX_PIN_UARTB1_URXD 250
+#define BCM281XX_PIN_UARTB1_UTXD 251
+#define BCM281XX_PIN_UARTB2_URXD 252
+#define BCM281XX_PIN_UARTB2_UTXD 253
+#define BCM281XX_PIN_UARTB3_UCTS 254
+#define BCM281XX_PIN_UARTB3_URTS 255
+#define BCM281XX_PIN_UARTB3_URXD 256
+#define BCM281XX_PIN_UARTB3_UTXD 257
+#define BCM281XX_PIN_UARTB4_UCTS 258
+#define BCM281XX_PIN_UARTB4_URTS 259
+#define BCM281XX_PIN_UARTB4_URXD 260
+#define BCM281XX_PIN_UARTB4_UTXD 261
+#define BCM281XX_PIN_VC_CAM1_SCL 262
+#define BCM281XX_PIN_VC_CAM1_SDA 263
+#define BCM281XX_PIN_VC_CAM2_SCL 264
+#define BCM281XX_PIN_VC_CAM2_SDA 265
+#define BCM281XX_PIN_VC_CAM3_SCL 266
+#define BCM281XX_PIN_VC_CAM3_SDA 267
+
+#define BCM281XX_PIN_DESC(a, b, c) \
+ { .number = a, .name = b, .drv_data = &c##_pin }
+
+/*
+ * Pin description definition. The order here must be the same as defined in
+ * the PADCTRLREG block in the RDB, since the pin number is used as an index
+ * into this array.
+ */
+static const struct pinctrl_pin_desc bcm281xx_pinctrl_pins[] = {
+ BCM281XX_PIN_DESC(BCM281XX_PIN_ADCSYNC, "adcsync", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_BAT_RM, "bat_rm", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_BSC1_SCL, "bsc1_scl", i2c),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_BSC1_SDA, "bsc1_sda", i2c),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_BSC2_SCL, "bsc2_scl", i2c),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_BSC2_SDA, "bsc2_sda", i2c),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_CLASSGPWR, "classgpwr", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_CLK_CX8, "clk_cx8", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_CLKOUT_0, "clkout_0", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_CLKOUT_1, "clkout_1", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_CLKOUT_2, "clkout_2", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_CLKOUT_3, "clkout_3", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_CLKREQ_IN_0, "clkreq_in_0", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_CLKREQ_IN_1, "clkreq_in_1", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_CWS_SYS_REQ1, "cws_sys_req1", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_CWS_SYS_REQ2, "cws_sys_req2", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_CWS_SYS_REQ3, "cws_sys_req3", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_DIGMIC1_CLK, "digmic1_clk", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_DIGMIC1_DQ, "digmic1_dq", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_DIGMIC2_CLK, "digmic2_clk", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_DIGMIC2_DQ, "digmic2_dq", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_GPEN13, "gpen13", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_GPEN14, "gpen14", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_GPEN15, "gpen15", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO00, "gpio00", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO01, "gpio01", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO02, "gpio02", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO03, "gpio03", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO04, "gpio04", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO05, "gpio05", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO06, "gpio06", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO07, "gpio07", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO08, "gpio08", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO09, "gpio09", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO10, "gpio10", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO11, "gpio11", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO12, "gpio12", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO13, "gpio13", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_GPIO14, "gpio14", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_GPS_PABLANK, "gps_pablank", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_GPS_TMARK, "gps_tmark", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_HDMI_SCL, "hdmi_scl", hdmi),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_HDMI_SDA, "hdmi_sda", hdmi),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_IC_DM, "ic_dm", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_IC_DP, "ic_dp", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_KP_COL_IP_0, "kp_col_ip_0", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_KP_COL_IP_1, "kp_col_ip_1", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_KP_COL_IP_2, "kp_col_ip_2", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_KP_COL_IP_3, "kp_col_ip_3", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_KP_ROW_OP_0, "kp_row_op_0", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_KP_ROW_OP_1, "kp_row_op_1", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_KP_ROW_OP_2, "kp_row_op_2", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_KP_ROW_OP_3, "kp_row_op_3", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_B_0, "lcd_b_0", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_B_1, "lcd_b_1", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_B_2, "lcd_b_2", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_B_3, "lcd_b_3", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_B_4, "lcd_b_4", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_B_5, "lcd_b_5", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_B_6, "lcd_b_6", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_B_7, "lcd_b_7", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_G_0, "lcd_g_0", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_G_1, "lcd_g_1", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_G_2, "lcd_g_2", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_G_3, "lcd_g_3", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_G_4, "lcd_g_4", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_G_5, "lcd_g_5", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_G_6, "lcd_g_6", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_G_7, "lcd_g_7", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_HSYNC, "lcd_hsync", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_OE, "lcd_oe", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_PCLK, "lcd_pclk", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_R_0, "lcd_r_0", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_R_1, "lcd_r_1", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_R_2, "lcd_r_2", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_R_3, "lcd_r_3", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_R_4, "lcd_r_4", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_R_5, "lcd_r_5", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_R_6, "lcd_r_6", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_R_7, "lcd_r_7", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_LCD_VSYNC, "lcd_vsync", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MDMGPIO0, "mdmgpio0", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MDMGPIO1, "mdmgpio1", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MDMGPIO2, "mdmgpio2", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MDMGPIO3, "mdmgpio3", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MDMGPIO4, "mdmgpio4", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MDMGPIO5, "mdmgpio5", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MDMGPIO6, "mdmgpio6", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MDMGPIO7, "mdmgpio7", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MDMGPIO8, "mdmgpio8", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_0, "mphi_data_0", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_1, "mphi_data_1", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_2, "mphi_data_2", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_3, "mphi_data_3", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_4, "mphi_data_4", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_5, "mphi_data_5", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_6, "mphi_data_6", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_7, "mphi_data_7", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_8, "mphi_data_8", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_9, "mphi_data_9", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_10, "mphi_data_10", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_11, "mphi_data_11", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_12, "mphi_data_12", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_13, "mphi_data_13", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_14, "mphi_data_14", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_DATA_15, "mphi_data_15", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_HA0, "mphi_ha0", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_HAT0, "mphi_hat0", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_HAT1, "mphi_hat1", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_HCE0_N, "mphi_hce0_n", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_HCE1_N, "mphi_hce1_n", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_HRD_N, "mphi_hrd_n", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_HWR_N, "mphi_hwr_n", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_RUN0, "mphi_run0", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MPHI_RUN1, "mphi_run1", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MTX_SCAN_CLK, "mtx_scan_clk", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_MTX_SCAN_DATA, "mtx_scan_data", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_AD_0, "nand_ad_0", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_AD_1, "nand_ad_1", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_AD_2, "nand_ad_2", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_AD_3, "nand_ad_3", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_AD_4, "nand_ad_4", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_AD_5, "nand_ad_5", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_AD_6, "nand_ad_6", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_AD_7, "nand_ad_7", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_ALE, "nand_ale", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_CEN_0, "nand_cen_0", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_CEN_1, "nand_cen_1", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_CLE, "nand_cle", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_OEN, "nand_oen", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_RDY_0, "nand_rdy_0", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_RDY_1, "nand_rdy_1", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_WEN, "nand_wen", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_NAND_WP, "nand_wp", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_PC1, "pc1", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_PC2, "pc2", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_PMU_INT, "pmu_int", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_PMU_SCL, "pmu_scl", i2c),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_PMU_SDA, "pmu_sda", i2c),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RFST2G_MTSLOTEN3G, "rfst2g_mtsloten3g",
+ std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_0_RX_CTL, "rgmii_0_rx_ctl", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_0_RXC, "rgmii_0_rxc", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_0_RXD_0, "rgmii_0_rxd_0", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_0_RXD_1, "rgmii_0_rxd_1", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_0_RXD_2, "rgmii_0_rxd_2", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_0_RXD_3, "rgmii_0_rxd_3", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_0_TX_CTL, "rgmii_0_tx_ctl", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_0_TXC, "rgmii_0_txc", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_0_TXD_0, "rgmii_0_txd_0", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_0_TXD_1, "rgmii_0_txd_1", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_0_TXD_2, "rgmii_0_txd_2", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_0_TXD_3, "rgmii_0_txd_3", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_1_RX_CTL, "rgmii_1_rx_ctl", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_1_RXC, "rgmii_1_rxc", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_1_RXD_0, "rgmii_1_rxd_0", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_1_RXD_1, "rgmii_1_rxd_1", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_1_RXD_2, "rgmii_1_rxd_2", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_1_RXD_3, "rgmii_1_rxd_3", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_1_TX_CTL, "rgmii_1_tx_ctl", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_1_TXC, "rgmii_1_txc", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_1_TXD_0, "rgmii_1_txd_0", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_1_TXD_1, "rgmii_1_txd_1", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_1_TXD_2, "rgmii_1_txd_2", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_1_TXD_3, "rgmii_1_txd_3", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_GPIO_0, "rgmii_gpio_0", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_GPIO_1, "rgmii_gpio_1", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_GPIO_2, "rgmii_gpio_2", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RGMII_GPIO_3, "rgmii_gpio_3", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RTXDATA2G_TXDATA3G1,
+ "rtxdata2g_txdata3g1", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RTXEN2G_TXDATA3G2, "rtxen2g_txdata3g2",
+ std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RXDATA3G0, "rxdata3g0", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RXDATA3G1, "rxdata3g1", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_RXDATA3G2, "rxdata3g2", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SDIO1_CLK, "sdio1_clk", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SDIO1_CMD, "sdio1_cmd", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SDIO1_DATA_0, "sdio1_data_0", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SDIO1_DATA_1, "sdio1_data_1", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SDIO1_DATA_2, "sdio1_data_2", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SDIO1_DATA_3, "sdio1_data_3", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SDIO4_CLK, "sdio4_clk", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SDIO4_CMD, "sdio4_cmd", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SDIO4_DATA_0, "sdio4_data_0", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SDIO4_DATA_1, "sdio4_data_1", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SDIO4_DATA_2, "sdio4_data_2", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SDIO4_DATA_3, "sdio4_data_3", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SIM_CLK, "sim_clk", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SIM_DATA, "sim_data", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SIM_DET, "sim_det", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SIM_RESETN, "sim_resetn", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SIM2_CLK, "sim2_clk", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SIM2_DATA, "sim2_data", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SIM2_DET, "sim2_det", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SIM2_RESETN, "sim2_resetn", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SRI_C, "sri_c", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SRI_D, "sri_d", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SRI_E, "sri_e", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP_EXTCLK, "ssp_extclk", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP0_CLK, "ssp0_clk", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP0_FS, "ssp0_fs", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP0_RXD, "ssp0_rxd", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP0_TXD, "ssp0_txd", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP2_CLK, "ssp2_clk", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP2_FS_0, "ssp2_fs_0", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP2_FS_1, "ssp2_fs_1", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP2_FS_2, "ssp2_fs_2", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP2_FS_3, "ssp2_fs_3", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP2_RXD_0, "ssp2_rxd_0", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP2_RXD_1, "ssp2_rxd_1", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP2_TXD_0, "ssp2_txd_0", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP2_TXD_1, "ssp2_txd_1", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP3_CLK, "ssp3_clk", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP3_FS, "ssp3_fs", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP3_RXD, "ssp3_rxd", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP3_TXD, "ssp3_txd", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP4_CLK, "ssp4_clk", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP4_FS, "ssp4_fs", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP4_RXD, "ssp4_rxd", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP4_TXD, "ssp4_txd", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP5_CLK, "ssp5_clk", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP5_FS, "ssp5_fs", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP5_RXD, "ssp5_rxd", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP5_TXD, "ssp5_txd", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP6_CLK, "ssp6_clk", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP6_FS, "ssp6_fs", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP6_RXD, "ssp6_rxd", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SSP6_TXD, "ssp6_txd", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_STAT_1, "stat_1", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_STAT_2, "stat_2", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_SYSCLKEN, "sysclken", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_TRACECLK, "traceclk", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT00, "tracedt00", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT01, "tracedt01", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT02, "tracedt02", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT03, "tracedt03", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT04, "tracedt04", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT05, "tracedt05", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT06, "tracedt06", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT07, "tracedt07", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT08, "tracedt08", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT09, "tracedt09", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT10, "tracedt10", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT11, "tracedt11", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT12, "tracedt12", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT13, "tracedt13", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT14, "tracedt14", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_TRACEDT15, "tracedt15", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_TXDATA3G0, "txdata3g0", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_TXPWRIND, "txpwrind", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_UARTB1_UCTS, "uartb1_ucts", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_UARTB1_URTS, "uartb1_urts", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_UARTB1_URXD, "uartb1_urxd", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_UARTB1_UTXD, "uartb1_utxd", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_UARTB2_URXD, "uartb2_urxd", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_UARTB2_UTXD, "uartb2_utxd", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_UARTB3_UCTS, "uartb3_ucts", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_UARTB3_URTS, "uartb3_urts", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_UARTB3_URXD, "uartb3_urxd", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_UARTB3_UTXD, "uartb3_utxd", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_UARTB4_UCTS, "uartb4_ucts", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_UARTB4_URTS, "uartb4_urts", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_UARTB4_URXD, "uartb4_urxd", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_UARTB4_UTXD, "uartb4_utxd", std),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_VC_CAM1_SCL, "vc_cam1_scl", i2c),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_VC_CAM1_SDA, "vc_cam1_sda", i2c),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_VC_CAM2_SCL, "vc_cam2_scl", i2c),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_VC_CAM2_SDA, "vc_cam2_sda", i2c),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_VC_CAM3_SCL, "vc_cam3_scl", i2c),
+ BCM281XX_PIN_DESC(BCM281XX_PIN_VC_CAM3_SDA, "vc_cam3_sda", i2c),
+};
+
+static const char * const bcm281xx_alt_groups[] = {
+ "adcsync",
+ "bat_rm",
+ "bsc1_scl",
+ "bsc1_sda",
+ "bsc2_scl",
+ "bsc2_sda",
+ "classgpwr",
+ "clk_cx8",
+ "clkout_0",
+ "clkout_1",
+ "clkout_2",
+ "clkout_3",
+ "clkreq_in_0",
+ "clkreq_in_1",
+ "cws_sys_req1",
+ "cws_sys_req2",
+ "cws_sys_req3",
+ "digmic1_clk",
+ "digmic1_dq",
+ "digmic2_clk",
+ "digmic2_dq",
+ "gpen13",
+ "gpen14",
+ "gpen15",
+ "gpio00",
+ "gpio01",
+ "gpio02",
+ "gpio03",
+ "gpio04",
+ "gpio05",
+ "gpio06",
+ "gpio07",
+ "gpio08",
+ "gpio09",
+ "gpio10",
+ "gpio11",
+ "gpio12",
+ "gpio13",
+ "gpio14",
+ "gps_pablank",
+ "gps_tmark",
+ "hdmi_scl",
+ "hdmi_sda",
+ "ic_dm",
+ "ic_dp",
+ "kp_col_ip_0",
+ "kp_col_ip_1",
+ "kp_col_ip_2",
+ "kp_col_ip_3",
+ "kp_row_op_0",
+ "kp_row_op_1",
+ "kp_row_op_2",
+ "kp_row_op_3",
+ "lcd_b_0",
+ "lcd_b_1",
+ "lcd_b_2",
+ "lcd_b_3",
+ "lcd_b_4",
+ "lcd_b_5",
+ "lcd_b_6",
+ "lcd_b_7",
+ "lcd_g_0",
+ "lcd_g_1",
+ "lcd_g_2",
+ "lcd_g_3",
+ "lcd_g_4",
+ "lcd_g_5",
+ "lcd_g_6",
+ "lcd_g_7",
+ "lcd_hsync",
+ "lcd_oe",
+ "lcd_pclk",
+ "lcd_r_0",
+ "lcd_r_1",
+ "lcd_r_2",
+ "lcd_r_3",
+ "lcd_r_4",
+ "lcd_r_5",
+ "lcd_r_6",
+ "lcd_r_7",
+ "lcd_vsync",
+ "mdmgpio0",
+ "mdmgpio1",
+ "mdmgpio2",
+ "mdmgpio3",
+ "mdmgpio4",
+ "mdmgpio5",
+ "mdmgpio6",
+ "mdmgpio7",
+ "mdmgpio8",
+ "mphi_data_0",
+ "mphi_data_1",
+ "mphi_data_2",
+ "mphi_data_3",
+ "mphi_data_4",
+ "mphi_data_5",
+ "mphi_data_6",
+ "mphi_data_7",
+ "mphi_data_8",
+ "mphi_data_9",
+ "mphi_data_10",
+ "mphi_data_11",
+ "mphi_data_12",
+ "mphi_data_13",
+ "mphi_data_14",
+ "mphi_data_15",
+ "mphi_ha0",
+ "mphi_hat0",
+ "mphi_hat1",
+ "mphi_hce0_n",
+ "mphi_hce1_n",
+ "mphi_hrd_n",
+ "mphi_hwr_n",
+ "mphi_run0",
+ "mphi_run1",
+ "mtx_scan_clk",
+ "mtx_scan_data",
+ "nand_ad_0",
+ "nand_ad_1",
+ "nand_ad_2",
+ "nand_ad_3",
+ "nand_ad_4",
+ "nand_ad_5",
+ "nand_ad_6",
+ "nand_ad_7",
+ "nand_ale",
+ "nand_cen_0",
+ "nand_cen_1",
+ "nand_cle",
+ "nand_oen",
+ "nand_rdy_0",
+ "nand_rdy_1",
+ "nand_wen",
+ "nand_wp",
+ "pc1",
+ "pc2",
+ "pmu_int",
+ "pmu_scl",
+ "pmu_sda",
+ "rfst2g_mtsloten3g",
+ "rgmii_0_rx_ctl",
+ "rgmii_0_rxc",
+ "rgmii_0_rxd_0",
+ "rgmii_0_rxd_1",
+ "rgmii_0_rxd_2",
+ "rgmii_0_rxd_3",
+ "rgmii_0_tx_ctl",
+ "rgmii_0_txc",
+ "rgmii_0_txd_0",
+ "rgmii_0_txd_1",
+ "rgmii_0_txd_2",
+ "rgmii_0_txd_3",
+ "rgmii_1_rx_ctl",
+ "rgmii_1_rxc",
+ "rgmii_1_rxd_0",
+ "rgmii_1_rxd_1",
+ "rgmii_1_rxd_2",
+ "rgmii_1_rxd_3",
+ "rgmii_1_tx_ctl",
+ "rgmii_1_txc",
+ "rgmii_1_txd_0",
+ "rgmii_1_txd_1",
+ "rgmii_1_txd_2",
+ "rgmii_1_txd_3",
+ "rgmii_gpio_0",
+ "rgmii_gpio_1",
+ "rgmii_gpio_2",
+ "rgmii_gpio_3",
+ "rtxdata2g_txdata3g1",
+ "rtxen2g_txdata3g2",
+ "rxdata3g0",
+ "rxdata3g1",
+ "rxdata3g2",
+ "sdio1_clk",
+ "sdio1_cmd",
+ "sdio1_data_0",
+ "sdio1_data_1",
+ "sdio1_data_2",
+ "sdio1_data_3",
+ "sdio4_clk",
+ "sdio4_cmd",
+ "sdio4_data_0",
+ "sdio4_data_1",
+ "sdio4_data_2",
+ "sdio4_data_3",
+ "sim_clk",
+ "sim_data",
+ "sim_det",
+ "sim_resetn",
+ "sim2_clk",
+ "sim2_data",
+ "sim2_det",
+ "sim2_resetn",
+ "sri_c",
+ "sri_d",
+ "sri_e",
+ "ssp_extclk",
+ "ssp0_clk",
+ "ssp0_fs",
+ "ssp0_rxd",
+ "ssp0_txd",
+ "ssp2_clk",
+ "ssp2_fs_0",
+ "ssp2_fs_1",
+ "ssp2_fs_2",
+ "ssp2_fs_3",
+ "ssp2_rxd_0",
+ "ssp2_rxd_1",
+ "ssp2_txd_0",
+ "ssp2_txd_1",
+ "ssp3_clk",
+ "ssp3_fs",
+ "ssp3_rxd",
+ "ssp3_txd",
+ "ssp4_clk",
+ "ssp4_fs",
+ "ssp4_rxd",
+ "ssp4_txd",
+ "ssp5_clk",
+ "ssp5_fs",
+ "ssp5_rxd",
+ "ssp5_txd",
+ "ssp6_clk",
+ "ssp6_fs",
+ "ssp6_rxd",
+ "ssp6_txd",
+ "stat_1",
+ "stat_2",
+ "sysclken",
+ "traceclk",
+ "tracedt00",
+ "tracedt01",
+ "tracedt02",
+ "tracedt03",
+ "tracedt04",
+ "tracedt05",
+ "tracedt06",
+ "tracedt07",
+ "tracedt08",
+ "tracedt09",
+ "tracedt10",
+ "tracedt11",
+ "tracedt12",
+ "tracedt13",
+ "tracedt14",
+ "tracedt15",
+ "txdata3g0",
+ "txpwrind",
+ "uartb1_ucts",
+ "uartb1_urts",
+ "uartb1_urxd",
+ "uartb1_utxd",
+ "uartb2_urxd",
+ "uartb2_utxd",
+ "uartb3_ucts",
+ "uartb3_urts",
+ "uartb3_urxd",
+ "uartb3_utxd",
+ "uartb4_ucts",
+ "uartb4_urts",
+ "uartb4_urxd",
+ "uartb4_utxd",
+ "vc_cam1_scl",
+ "vc_cam1_sda",
+ "vc_cam2_scl",
+ "vc_cam2_sda",
+ "vc_cam3_scl",
+ "vc_cam3_sda",
+};
+
+/* Every pin can implement all ALT1-ALT4 functions */
+#define BCM281XX_PIN_FUNCTION(fcn_name) \
+{ \
+ .name = #fcn_name, \
+ .groups = bcm281xx_alt_groups, \
+ .ngroups = ARRAY_SIZE(bcm281xx_alt_groups), \
+}
+
+static const struct bcm281xx_pin_function bcm281xx_functions[] = {
+ BCM281XX_PIN_FUNCTION(alt1),
+ BCM281XX_PIN_FUNCTION(alt2),
+ BCM281XX_PIN_FUNCTION(alt3),
+ BCM281XX_PIN_FUNCTION(alt4),
+};
+
+static struct bcm281xx_pinctrl_data bcm281xx_pinctrl = {
+ .pins = bcm281xx_pinctrl_pins,
+ .npins = ARRAY_SIZE(bcm281xx_pinctrl_pins),
+ .functions = bcm281xx_functions,
+ .nfunctions = ARRAY_SIZE(bcm281xx_functions),
+};
+
+static inline enum bcm281xx_pin_type pin_type_get(struct pinctrl_dev *pctldev,
+ unsigned pin)
+{
+ struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
+
+ if (pin >= pdata->npins)
+ return BCM281XX_PIN_TYPE_UNKNOWN;
+
+ return *(enum bcm281xx_pin_type *)(pdata->pins[pin].drv_data);
+}
+
+#define BCM281XX_PIN_SHIFT(type, param) \
+ (BCM281XX_ ## type ## _PIN_REG_ ## param ## _SHIFT)
+
+#define BCM281XX_PIN_MASK(type, param) \
+ (BCM281XX_ ## type ## _PIN_REG_ ## param ## _MASK)
+
+/*
+ * This helper function is used to build up the value and mask used to write to
+ * a pin register, but does not actually write to the register.
+ */
+static inline void bcm281xx_pin_update(u32 *reg_val, u32 *reg_mask,
+ u32 param_val, u32 param_shift,
+ u32 param_mask)
+{
+ *reg_val &= ~param_mask;
+ *reg_val |= (param_val << param_shift) & param_mask;
+ *reg_mask |= param_mask;
+}
+
+static struct regmap_config bcm281xx_pinctrl_regmap_config = {
+ .reg_bits = 32,
+ .reg_stride = 4,
+ .val_bits = 32,
+ .max_register = BCM281XX_PIN_VC_CAM3_SDA,
+};
+
+static int bcm281xx_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
+{
+ struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
+
+ return pdata->npins;
+}
+
+static const char *bcm281xx_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
+ unsigned group)
+{
+ struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
+
+ return pdata->pins[group].name;
+}
+
+static int bcm281xx_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
+ unsigned group,
+ const unsigned **pins,
+ unsigned *num_pins)
+{
+ struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
+
+ *pins = &pdata->pins[group].number;
+ *num_pins = 1;
+
+ return 0;
+}
+
+static void bcm281xx_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev,
+ struct seq_file *s,
+ unsigned offset)
+{
+ seq_printf(s, " %s", dev_name(pctldev->dev));
+}
+
+static struct pinctrl_ops bcm281xx_pinctrl_ops = {
+ .get_groups_count = bcm281xx_pinctrl_get_groups_count,
+ .get_group_name = bcm281xx_pinctrl_get_group_name,
+ .get_group_pins = bcm281xx_pinctrl_get_group_pins,
+ .pin_dbg_show = bcm281xx_pinctrl_pin_dbg_show,
+ .dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
+ .dt_free_map = pinctrl_utils_dt_free_map,
+};
+
+static int bcm281xx_pinctrl_get_fcns_count(struct pinctrl_dev *pctldev)
+{
+ struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
+
+ return pdata->nfunctions;
+}
+
+static const char *bcm281xx_pinctrl_get_fcn_name(struct pinctrl_dev *pctldev,
+ unsigned function)
+{
+ struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
+
+ return pdata->functions[function].name;
+}
+
+static int bcm281xx_pinctrl_get_fcn_groups(struct pinctrl_dev *pctldev,
+ unsigned function,
+ const char * const **groups,
+ unsigned * const num_groups)
+{
+ struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
+
+ *groups = pdata->functions[function].groups;
+ *num_groups = pdata->functions[function].ngroups;
+
+ return 0;
+}
+
+static int bcm281xx_pinmux_enable(struct pinctrl_dev *pctldev,
+ unsigned function,
+ unsigned group)
+{
+ struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
+ const struct bcm281xx_pin_function *f = &pdata->functions[function];
+ u32 offset = 4 * pdata->pins[group].number;
+ int rc = 0;
+
+ dev_dbg(pctldev->dev,
+ "%s(): Enable function %s (%d) of pin %s (%d) @offset 0x%x.\n",
+ __func__, f->name, function, pdata->pins[group].name,
+ pdata->pins[group].number, offset);
+
+ rc = regmap_update_bits(pdata->regmap, offset,
+ BCM281XX_PIN_REG_F_SEL_MASK,
+ function << BCM281XX_PIN_REG_F_SEL_SHIFT);
+ if (rc)
+ dev_err(pctldev->dev,
+ "Error updating register for pin %s (%d).\n",
+ pdata->pins[group].name, pdata->pins[group].number);
+
+ return rc;
+}
+
+static struct pinmux_ops bcm281xx_pinctrl_pinmux_ops = {
+ .get_functions_count = bcm281xx_pinctrl_get_fcns_count,
+ .get_function_name = bcm281xx_pinctrl_get_fcn_name,
+ .get_function_groups = bcm281xx_pinctrl_get_fcn_groups,
+ .enable = bcm281xx_pinmux_enable,
+};
+
+static int bcm281xx_pinctrl_pin_config_get(struct pinctrl_dev *pctldev,
+ unsigned pin,
+ unsigned long *config)
+{
+ return -ENOTSUPP;
+}
+
+
+/* Goes through the configs and update register val/mask */
+static int bcm281xx_std_pin_update(struct pinctrl_dev *pctldev,
+ unsigned pin,
+ unsigned long *configs,
+ unsigned num_configs,
+ u32 *val,
+ u32 *mask)
+{
+ struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
+ int i;
+ enum pin_config_param param;
+ u16 arg;
+
+ for (i = 0; i < num_configs; i++) {
+ param = pinconf_to_config_param(configs[i]);
+ arg = pinconf_to_config_argument(configs[i]);
+
+ switch (param) {
+ case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
+ arg = (arg >= 1 ? 1 : 0);
+ bcm281xx_pin_update(val, mask, arg,
+ BCM281XX_PIN_SHIFT(STD, HYST),
+ BCM281XX_PIN_MASK(STD, HYST));
+ break;
+ /*
+ * The pin bias can only be one of pull-up, pull-down, or
+ * disable. The user does not need to specify a value for the
+ * property, and the default value from pinconf-generic is
+ * ignored.
+ */
+ case PIN_CONFIG_BIAS_DISABLE:
+ bcm281xx_pin_update(val, mask, 0,
+ BCM281XX_PIN_SHIFT(STD, PULL_UP),
+ BCM281XX_PIN_MASK(STD, PULL_UP));
+ bcm281xx_pin_update(val, mask, 0,
+ BCM281XX_PIN_SHIFT(STD, PULL_DN),
+ BCM281XX_PIN_MASK(STD, PULL_DN));
+ break;
+
+ case PIN_CONFIG_BIAS_PULL_UP:
+ bcm281xx_pin_update(val, mask, 1,
+ BCM281XX_PIN_SHIFT(STD, PULL_UP),
+ BCM281XX_PIN_MASK(STD, PULL_UP));
+ bcm281xx_pin_update(val, mask, 0,
+ BCM281XX_PIN_SHIFT(STD, PULL_DN),
+ BCM281XX_PIN_MASK(STD, PULL_DN));
+ break;
+
+ case PIN_CONFIG_BIAS_PULL_DOWN:
+ bcm281xx_pin_update(val, mask, 0,
+ BCM281XX_PIN_SHIFT(STD, PULL_UP),
+ BCM281XX_PIN_MASK(STD, PULL_UP));
+ bcm281xx_pin_update(val, mask, 1,
+ BCM281XX_PIN_SHIFT(STD, PULL_DN),
+ BCM281XX_PIN_MASK(STD, PULL_DN));
+ break;
+
+ case PIN_CONFIG_SLEW_RATE:
+ arg = (arg >= 1 ? 1 : 0);
+ bcm281xx_pin_update(val, mask, arg,
+ BCM281XX_PIN_SHIFT(STD, SLEW),
+ BCM281XX_PIN_MASK(STD, SLEW));
+ break;
+
+ case PIN_CONFIG_INPUT_ENABLE:
+ /* inversed since register is for input _disable_ */
+ arg = (arg >= 1 ? 0 : 1);
+ bcm281xx_pin_update(val, mask, arg,
+ BCM281XX_PIN_SHIFT(STD, INPUT_DIS),
+ BCM281XX_PIN_MASK(STD, INPUT_DIS));
+ break;
+
+ case PIN_CONFIG_DRIVE_STRENGTH:
+ /* Valid range is 2-16 mA, even numbers only */
+ if ((arg < 2) || (arg > 16) || (arg % 2)) {
+ dev_err(pctldev->dev,
+ "Invalid Drive Strength value (%d) for "
+ "pin %s (%d). Valid values are "
+ "(2..16) mA, even numbers only.\n",
+ arg, pdata->pins[pin].name, pin);
+ return -EINVAL;
+ }
+ bcm281xx_pin_update(val, mask, (arg/2)-1,
+ BCM281XX_PIN_SHIFT(STD, DRV_STR),
+ BCM281XX_PIN_MASK(STD, DRV_STR));
+ break;
+
+ default:
+ dev_err(pctldev->dev,
+ "Unrecognized pin config %d for pin %s (%d).\n",
+ param, pdata->pins[pin].name, pin);
+ return -EINVAL;
+
+ } /* switch config */
+ } /* for each config */
+
+ return 0;
+}
+
+/*
+ * The pull-up strength for an I2C pin is represented by bits 4-6 in the
+ * register with the following mapping:
+ * 0b000: No pull-up
+ * 0b001: 1200 Ohm
+ * 0b010: 1800 Ohm
+ * 0b011: 720 Ohm
+ * 0b100: 2700 Ohm
+ * 0b101: 831 Ohm
+ * 0b110: 1080 Ohm
+ * 0b111: 568 Ohm
+ * This array maps pull-up strength in Ohms to register values (1+index).
+ */
+static const u16 bcm281xx_pullup_map[] = {
+ 1200, 1800, 720, 2700, 831, 1080, 568
+};
+
+/* Goes through the configs and update register val/mask */
+static int bcm281xx_i2c_pin_update(struct pinctrl_dev *pctldev,
+ unsigned pin,
+ unsigned long *configs,
+ unsigned num_configs,
+ u32 *val,
+ u32 *mask)
+{
+ struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
+ int i, j;
+ enum pin_config_param param;
+ u16 arg;
+
+ for (i = 0; i < num_configs; i++) {
+ param = pinconf_to_config_param(configs[i]);
+ arg = pinconf_to_config_argument(configs[i]);
+
+ switch (param) {
+ case PIN_CONFIG_BIAS_PULL_UP:
+ for (j = 0; j < ARRAY_SIZE(bcm281xx_pullup_map); j++)
+ if (bcm281xx_pullup_map[j] == arg)
+ break;
+
+ if (j == ARRAY_SIZE(bcm281xx_pullup_map)) {
+ dev_err(pctldev->dev,
+ "Invalid pull-up value (%d) for pin %s "
+ "(%d). Valid values are 568, 720, 831, "
+ "1080, 1200, 1800, 2700 Ohms.\n",
+ arg, pdata->pins[pin].name, pin);
+ return -EINVAL;
+ }
+
+ bcm281xx_pin_update(val, mask, j+1,
+ BCM281XX_PIN_SHIFT(I2C, PULL_UP_STR),
+ BCM281XX_PIN_MASK(I2C, PULL_UP_STR));
+ break;
+
+ case PIN_CONFIG_BIAS_DISABLE:
+ bcm281xx_pin_update(val, mask, 0,
+ BCM281XX_PIN_SHIFT(I2C, PULL_UP_STR),
+ BCM281XX_PIN_MASK(I2C, PULL_UP_STR));
+ break;
+
+ case PIN_CONFIG_SLEW_RATE:
+ arg = (arg >= 1 ? 1 : 0);
+ bcm281xx_pin_update(val, mask, arg,
+ BCM281XX_PIN_SHIFT(I2C, SLEW),
+ BCM281XX_PIN_MASK(I2C, SLEW));
+ break;
+
+ case PIN_CONFIG_INPUT_ENABLE:
+ /* inversed since register is for input _disable_ */
+ arg = (arg >= 1 ? 0 : 1);
+ bcm281xx_pin_update(val, mask, arg,
+ BCM281XX_PIN_SHIFT(I2C, INPUT_DIS),
+ BCM281XX_PIN_MASK(I2C, INPUT_DIS));
+ break;
+
+ default:
+ dev_err(pctldev->dev,
+ "Unrecognized pin config %d for pin %s (%d).\n",
+ param, pdata->pins[pin].name, pin);
+ return -EINVAL;
+
+ } /* switch config */
+ } /* for each config */
+
+ return 0;
+}
+
+/* Goes through the configs and update register val/mask */
+static int bcm281xx_hdmi_pin_update(struct pinctrl_dev *pctldev,
+ unsigned pin,
+ unsigned long *configs,
+ unsigned num_configs,
+ u32 *val,
+ u32 *mask)
+{
+ struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
+ int i;
+ enum pin_config_param param;
+ u16 arg;
+
+ for (i = 0; i < num_configs; i++) {
+ param = pinconf_to_config_param(configs[i]);
+ arg = pinconf_to_config_argument(configs[i]);
+
+ switch (param) {
+ case PIN_CONFIG_SLEW_RATE:
+ arg = (arg >= 1 ? 1 : 0);
+ bcm281xx_pin_update(val, mask, arg,
+ BCM281XX_PIN_SHIFT(HDMI, MODE),
+ BCM281XX_PIN_MASK(HDMI, MODE));
+ break;
+
+ case PIN_CONFIG_INPUT_ENABLE:
+ /* inversed since register is for input _disable_ */
+ arg = (arg >= 1 ? 0 : 1);
+ bcm281xx_pin_update(val, mask, arg,
+ BCM281XX_PIN_SHIFT(HDMI, INPUT_DIS),
+ BCM281XX_PIN_MASK(HDMI, INPUT_DIS));
+ break;
+
+ default:
+ dev_err(pctldev->dev,
+ "Unrecognized pin config %d for pin %s (%d).\n",
+ param, pdata->pins[pin].name, pin);
+ return -EINVAL;
+
+ } /* switch config */
+ } /* for each config */
+
+ return 0;
+}
+
+static int bcm281xx_pinctrl_pin_config_set(struct pinctrl_dev *pctldev,
+ unsigned pin,
+ unsigned long *configs,
+ unsigned num_configs)
+{
+ struct bcm281xx_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
+ enum bcm281xx_pin_type pin_type;
+ u32 offset = 4 * pin;
+ u32 cfg_val, cfg_mask;
+ int rc;
+
+ cfg_val = 0;
+ cfg_mask = 0;
+ pin_type = pin_type_get(pctldev, pin);
+
+ /* Different pins have different configuration options */
+ switch (pin_type) {
+ case BCM281XX_PIN_TYPE_STD:
+ rc = bcm281xx_std_pin_update(pctldev, pin, configs,
+ num_configs, &cfg_val, &cfg_mask);
+ break;
+
+ case BCM281XX_PIN_TYPE_I2C:
+ rc = bcm281xx_i2c_pin_update(pctldev, pin, configs,
+ num_configs, &cfg_val, &cfg_mask);
+ break;
+
+ case BCM281XX_PIN_TYPE_HDMI:
+ rc = bcm281xx_hdmi_pin_update(pctldev, pin, configs,
+ num_configs, &cfg_val, &cfg_mask);
+ break;
+
+ default:
+ dev_err(pctldev->dev, "Unknown pin type for pin %s (%d).\n",
+ pdata->pins[pin].name, pin);
+ return -EINVAL;
+
+ } /* switch pin type */
+
+ if (rc)
+ return rc;
+
+ dev_dbg(pctldev->dev,
+ "%s(): Set pin %s (%d) with config 0x%x, mask 0x%x\n",
+ __func__, pdata->pins[pin].name, pin, cfg_val, cfg_mask);
+
+ rc = regmap_update_bits(pdata->regmap, offset, cfg_mask, cfg_val);
+ if (rc) {
+ dev_err(pctldev->dev,
+ "Error updating register for pin %s (%d).\n",
+ pdata->pins[pin].name, pin);
+ return rc;
+ }
+
+ return 0;
+}
+
+static struct pinconf_ops bcm281xx_pinctrl_pinconf_ops = {
+ .pin_config_get = bcm281xx_pinctrl_pin_config_get,
+ .pin_config_set = bcm281xx_pinctrl_pin_config_set,
+};
+
+static struct pinctrl_desc bcm281xx_pinctrl_desc = {
+ /* name, pins, npins members initialized in probe function */
+ .pctlops = &bcm281xx_pinctrl_ops,
+ .pmxops = &bcm281xx_pinctrl_pinmux_ops,
+ .confops = &bcm281xx_pinctrl_pinconf_ops,
+ .owner = THIS_MODULE,
+};
+
+int __init bcm281xx_pinctrl_probe(struct platform_device *pdev)
+{
+ struct bcm281xx_pinctrl_data *pdata = &bcm281xx_pinctrl;
+ struct resource *res;
+ struct pinctrl_dev *pctl;
+
+ /* So far We can assume there is only 1 bank of registers */
+ res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+ if (!res) {
+ dev_err(&pdev->dev, "Missing MEM resource\n");
+ return -ENODEV;
+ }
+
+ pdata->reg_base = devm_ioremap_resource(&pdev->dev, res);
+ if (IS_ERR(pdata->reg_base)) {
+ dev_err(&pdev->dev, "Failed to ioremap MEM resource\n");
+ return -ENODEV;
+ }
+
+ /* Initialize the dynamic part of pinctrl_desc */
+ pdata->regmap = devm_regmap_init_mmio(&pdev->dev, pdata->reg_base,
+ &bcm281xx_pinctrl_regmap_config);
+ if (IS_ERR(pdata->regmap)) {
+ dev_err(&pdev->dev, "Regmap MMIO init failed.\n");
+ return -ENODEV;
+ }
+
+ bcm281xx_pinctrl_desc.name = dev_name(&pdev->dev);
+ bcm281xx_pinctrl_desc.pins = bcm281xx_pinctrl.pins;
+ bcm281xx_pinctrl_desc.npins = bcm281xx_pinctrl.npins;
+
+ pctl = pinctrl_register(&bcm281xx_pinctrl_desc,
+ &pdev->dev,
+ pdata);
+ if (!pctl) {
+ dev_err(&pdev->dev, "Failed to register pinctrl\n");
+ return -ENODEV;
+ }
+
+ platform_set_drvdata(pdev, pdata);
+
+ return 0;
+}
+
+static struct of_device_id bcm281xx_pinctrl_of_match[] = {
+ { .compatible = "brcm,bcm11351-pinctrl", },
+ { },
+};
+
+static struct platform_driver bcm281xx_pinctrl_driver = {
+ .driver = {
+ .name = "bcm281xx-pinctrl",
+ .owner = THIS_MODULE,
+ .of_match_table = bcm281xx_pinctrl_of_match,
+ },
+};
+
+module_platform_driver_probe(bcm281xx_pinctrl_driver, bcm281xx_pinctrl_probe);
+
+MODULE_AUTHOR("Broadcom Corporation <bcm-kernel-feedback-list@broadcom.com>");
+MODULE_AUTHOR("Sherman Yin <syin@broadcom.com>");
+MODULE_DESCRIPTION("Broadcom BCM281xx pinctrl driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/pinctrl-capri.c b/drivers/pinctrl/pinctrl-capri.c
deleted file mode 100644
index eb25002..0000000
--- a/drivers/pinctrl/pinctrl-capri.c
+++ /dev/null
@@ -1,1454 +0,0 @@
-/*
- * 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/err.h>
-#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/of.h>
-#include <linux/platform_device.h>
-#include <linux/pinctrl/pinctrl.h>
-#include <linux/pinctrl/pinmux.h>
-#include <linux/pinctrl/pinconf.h>
-#include <linux/pinctrl/pinconf-generic.h>
-#include <linux/regmap.h>
-#include <linux/slab.h>
-#include "core.h"
-#include "pinctrl-utils.h"
-
-/* Capri Pin Control Registers Definitions */
-
-/* Function Select bits are the same for all pin control registers */
-#define CAPRI_PIN_REG_F_SEL_MASK 0x0700
-#define CAPRI_PIN_REG_F_SEL_SHIFT 8
-
-/* Standard pin register */
-#define CAPRI_STD_PIN_REG_DRV_STR_MASK 0x0007
-#define CAPRI_STD_PIN_REG_DRV_STR_SHIFT 0
-#define CAPRI_STD_PIN_REG_INPUT_DIS_MASK 0x0008
-#define CAPRI_STD_PIN_REG_INPUT_DIS_SHIFT 3
-#define CAPRI_STD_PIN_REG_SLEW_MASK 0x0010
-#define CAPRI_STD_PIN_REG_SLEW_SHIFT 4
-#define CAPRI_STD_PIN_REG_PULL_UP_MASK 0x0020
-#define CAPRI_STD_PIN_REG_PULL_UP_SHIFT 5
-#define CAPRI_STD_PIN_REG_PULL_DN_MASK 0x0040
-#define CAPRI_STD_PIN_REG_PULL_DN_SHIFT 6
-#define CAPRI_STD_PIN_REG_HYST_MASK 0x0080
-#define CAPRI_STD_PIN_REG_HYST_SHIFT 7
-
-/* I2C pin register */
-#define CAPRI_I2C_PIN_REG_INPUT_DIS_MASK 0x0004
-#define CAPRI_I2C_PIN_REG_INPUT_DIS_SHIFT 2
-#define CAPRI_I2C_PIN_REG_SLEW_MASK 0x0008
-#define CAPRI_I2C_PIN_REG_SLEW_SHIFT 3
-#define CAPRI_I2C_PIN_REG_PULL_UP_STR_MASK 0x0070
-#define CAPRI_I2C_PIN_REG_PULL_UP_STR_SHIFT 4
-
-/* HDMI pin register */
-#define CAPRI_HDMI_PIN_REG_INPUT_DIS_MASK 0x0008
-#define CAPRI_HDMI_PIN_REG_INPUT_DIS_SHIFT 3
-#define CAPRI_HDMI_PIN_REG_MODE_MASK 0x0010
-#define CAPRI_HDMI_PIN_REG_MODE_SHIFT 4
-
-/**
- * capri_pin_type - types of pin register
- */
-enum capri_pin_type {
- CAPRI_PIN_TYPE_UNKNOWN = 0,
- CAPRI_PIN_TYPE_STD,
- CAPRI_PIN_TYPE_I2C,
- CAPRI_PIN_TYPE_HDMI,
-};
-
-static enum capri_pin_type std_pin = CAPRI_PIN_TYPE_STD;
-static enum capri_pin_type i2c_pin = CAPRI_PIN_TYPE_I2C;
-static enum capri_pin_type hdmi_pin = CAPRI_PIN_TYPE_HDMI;
-
-/**
- * capri_pin_function- define pin function
- */
-struct capri_pin_function {
- const char *name;
- const char * const *groups;
- const unsigned ngroups;
-};
-
-/**
- * capri_pinctrl_data - Broadcom-specific pinctrl data
- * @reg_base - base of pinctrl registers
- */
-struct capri_pinctrl_data {
- void __iomem *reg_base;
-
- /* List of all pins */
- const struct pinctrl_pin_desc *pins;
- const unsigned npins;
-
- const struct capri_pin_function *functions;
- const unsigned nfunctions;
-
- struct regmap *regmap;
-};
-
-/*
- * Pin number definition. The order here must be the same as defined in the
- * PADCTRLREG block in the RDB.
- */
-#define CAPRI_PIN_ADCSYNC 0
-#define CAPRI_PIN_BAT_RM 1
-#define CAPRI_PIN_BSC1_SCL 2
-#define CAPRI_PIN_BSC1_SDA 3
-#define CAPRI_PIN_BSC2_SCL 4
-#define CAPRI_PIN_BSC2_SDA 5
-#define CAPRI_PIN_CLASSGPWR 6
-#define CAPRI_PIN_CLK_CX8 7
-#define CAPRI_PIN_CLKOUT_0 8
-#define CAPRI_PIN_CLKOUT_1 9
-#define CAPRI_PIN_CLKOUT_2 10
-#define CAPRI_PIN_CLKOUT_3 11
-#define CAPRI_PIN_CLKREQ_IN_0 12
-#define CAPRI_PIN_CLKREQ_IN_1 13
-#define CAPRI_PIN_CWS_SYS_REQ1 14
-#define CAPRI_PIN_CWS_SYS_REQ2 15
-#define CAPRI_PIN_CWS_SYS_REQ3 16
-#define CAPRI_PIN_DIGMIC1_CLK 17
-#define CAPRI_PIN_DIGMIC1_DQ 18
-#define CAPRI_PIN_DIGMIC2_CLK 19
-#define CAPRI_PIN_DIGMIC2_DQ 20
-#define CAPRI_PIN_GPEN13 21
-#define CAPRI_PIN_GPEN14 22
-#define CAPRI_PIN_GPEN15 23
-#define CAPRI_PIN_GPIO00 24
-#define CAPRI_PIN_GPIO01 25
-#define CAPRI_PIN_GPIO02 26
-#define CAPRI_PIN_GPIO03 27
-#define CAPRI_PIN_GPIO04 28
-#define CAPRI_PIN_GPIO05 29
-#define CAPRI_PIN_GPIO06 30
-#define CAPRI_PIN_GPIO07 31
-#define CAPRI_PIN_GPIO08 32
-#define CAPRI_PIN_GPIO09 33
-#define CAPRI_PIN_GPIO10 34
-#define CAPRI_PIN_GPIO11 35
-#define CAPRI_PIN_GPIO12 36
-#define CAPRI_PIN_GPIO13 37
-#define CAPRI_PIN_GPIO14 38
-#define CAPRI_PIN_GPS_PABLANK 39
-#define CAPRI_PIN_GPS_TMARK 40
-#define CAPRI_PIN_HDMI_SCL 41
-#define CAPRI_PIN_HDMI_SDA 42
-#define CAPRI_PIN_IC_DM 43
-#define CAPRI_PIN_IC_DP 44
-#define CAPRI_PIN_KP_COL_IP_0 45
-#define CAPRI_PIN_KP_COL_IP_1 46
-#define CAPRI_PIN_KP_COL_IP_2 47
-#define CAPRI_PIN_KP_COL_IP_3 48
-#define CAPRI_PIN_KP_ROW_OP_0 49
-#define CAPRI_PIN_KP_ROW_OP_1 50
-#define CAPRI_PIN_KP_ROW_OP_2 51
-#define CAPRI_PIN_KP_ROW_OP_3 52
-#define CAPRI_PIN_LCD_B_0 53
-#define CAPRI_PIN_LCD_B_1 54
-#define CAPRI_PIN_LCD_B_2 55
-#define CAPRI_PIN_LCD_B_3 56
-#define CAPRI_PIN_LCD_B_4 57
-#define CAPRI_PIN_LCD_B_5 58
-#define CAPRI_PIN_LCD_B_6 59
-#define CAPRI_PIN_LCD_B_7 60
-#define CAPRI_PIN_LCD_G_0 61
-#define CAPRI_PIN_LCD_G_1 62
-#define CAPRI_PIN_LCD_G_2 63
-#define CAPRI_PIN_LCD_G_3 64
-#define CAPRI_PIN_LCD_G_4 65
-#define CAPRI_PIN_LCD_G_5 66
-#define CAPRI_PIN_LCD_G_6 67
-#define CAPRI_PIN_LCD_G_7 68
-#define CAPRI_PIN_LCD_HSYNC 69
-#define CAPRI_PIN_LCD_OE 70
-#define CAPRI_PIN_LCD_PCLK 71
-#define CAPRI_PIN_LCD_R_0 72
-#define CAPRI_PIN_LCD_R_1 73
-#define CAPRI_PIN_LCD_R_2 74
-#define CAPRI_PIN_LCD_R_3 75
-#define CAPRI_PIN_LCD_R_4 76
-#define CAPRI_PIN_LCD_R_5 77
-#define CAPRI_PIN_LCD_R_6 78
-#define CAPRI_PIN_LCD_R_7 79
-#define CAPRI_PIN_LCD_VSYNC 80
-#define CAPRI_PIN_MDMGPIO0 81
-#define CAPRI_PIN_MDMGPIO1 82
-#define CAPRI_PIN_MDMGPIO2 83
-#define CAPRI_PIN_MDMGPIO3 84
-#define CAPRI_PIN_MDMGPIO4 85
-#define CAPRI_PIN_MDMGPIO5 86
-#define CAPRI_PIN_MDMGPIO6 87
-#define CAPRI_PIN_MDMGPIO7 88
-#define CAPRI_PIN_MDMGPIO8 89
-#define CAPRI_PIN_MPHI_DATA_0 90
-#define CAPRI_PIN_MPHI_DATA_1 91
-#define CAPRI_PIN_MPHI_DATA_2 92
-#define CAPRI_PIN_MPHI_DATA_3 93
-#define CAPRI_PIN_MPHI_DATA_4 94
-#define CAPRI_PIN_MPHI_DATA_5 95
-#define CAPRI_PIN_MPHI_DATA_6 96
-#define CAPRI_PIN_MPHI_DATA_7 97
-#define CAPRI_PIN_MPHI_DATA_8 98
-#define CAPRI_PIN_MPHI_DATA_9 99
-#define CAPRI_PIN_MPHI_DATA_10 100
-#define CAPRI_PIN_MPHI_DATA_11 101
-#define CAPRI_PIN_MPHI_DATA_12 102
-#define CAPRI_PIN_MPHI_DATA_13 103
-#define CAPRI_PIN_MPHI_DATA_14 104
-#define CAPRI_PIN_MPHI_DATA_15 105
-#define CAPRI_PIN_MPHI_HA0 106
-#define CAPRI_PIN_MPHI_HAT0 107
-#define CAPRI_PIN_MPHI_HAT1 108
-#define CAPRI_PIN_MPHI_HCE0_N 109
-#define CAPRI_PIN_MPHI_HCE1_N 110
-#define CAPRI_PIN_MPHI_HRD_N 111
-#define CAPRI_PIN_MPHI_HWR_N 112
-#define CAPRI_PIN_MPHI_RUN0 113
-#define CAPRI_PIN_MPHI_RUN1 114
-#define CAPRI_PIN_MTX_SCAN_CLK 115
-#define CAPRI_PIN_MTX_SCAN_DATA 116
-#define CAPRI_PIN_NAND_AD_0 117
-#define CAPRI_PIN_NAND_AD_1 118
-#define CAPRI_PIN_NAND_AD_2 119
-#define CAPRI_PIN_NAND_AD_3 120
-#define CAPRI_PIN_NAND_AD_4 121
-#define CAPRI_PIN_NAND_AD_5 122
-#define CAPRI_PIN_NAND_AD_6 123
-#define CAPRI_PIN_NAND_AD_7 124
-#define CAPRI_PIN_NAND_ALE 125
-#define CAPRI_PIN_NAND_CEN_0 126
-#define CAPRI_PIN_NAND_CEN_1 127
-#define CAPRI_PIN_NAND_CLE 128
-#define CAPRI_PIN_NAND_OEN 129
-#define CAPRI_PIN_NAND_RDY_0 130
-#define CAPRI_PIN_NAND_RDY_1 131
-#define CAPRI_PIN_NAND_WEN 132
-#define CAPRI_PIN_NAND_WP 133
-#define CAPRI_PIN_PC1 134
-#define CAPRI_PIN_PC2 135
-#define CAPRI_PIN_PMU_INT 136
-#define CAPRI_PIN_PMU_SCL 137
-#define CAPRI_PIN_PMU_SDA 138
-#define CAPRI_PIN_RFST2G_MTSLOTEN3G 139
-#define CAPRI_PIN_RGMII_0_RX_CTL 140
-#define CAPRI_PIN_RGMII_0_RXC 141
-#define CAPRI_PIN_RGMII_0_RXD_0 142
-#define CAPRI_PIN_RGMII_0_RXD_1 143
-#define CAPRI_PIN_RGMII_0_RXD_2 144
-#define CAPRI_PIN_RGMII_0_RXD_3 145
-#define CAPRI_PIN_RGMII_0_TX_CTL 146
-#define CAPRI_PIN_RGMII_0_TXC 147
-#define CAPRI_PIN_RGMII_0_TXD_0 148
-#define CAPRI_PIN_RGMII_0_TXD_1 149
-#define CAPRI_PIN_RGMII_0_TXD_2 150
-#define CAPRI_PIN_RGMII_0_TXD_3 151
-#define CAPRI_PIN_RGMII_1_RX_CTL 152
-#define CAPRI_PIN_RGMII_1_RXC 153
-#define CAPRI_PIN_RGMII_1_RXD_0 154
-#define CAPRI_PIN_RGMII_1_RXD_1 155
-#define CAPRI_PIN_RGMII_1_RXD_2 156
-#define CAPRI_PIN_RGMII_1_RXD_3 157
-#define CAPRI_PIN_RGMII_1_TX_CTL 158
-#define CAPRI_PIN_RGMII_1_TXC 159
-#define CAPRI_PIN_RGMII_1_TXD_0 160
-#define CAPRI_PIN_RGMII_1_TXD_1 161
-#define CAPRI_PIN_RGMII_1_TXD_2 162
-#define CAPRI_PIN_RGMII_1_TXD_3 163
-#define CAPRI_PIN_RGMII_GPIO_0 164
-#define CAPRI_PIN_RGMII_GPIO_1 165
-#define CAPRI_PIN_RGMII_GPIO_2 166
-#define CAPRI_PIN_RGMII_GPIO_3 167
-#define CAPRI_PIN_RTXDATA2G_TXDATA3G1 168
-#define CAPRI_PIN_RTXEN2G_TXDATA3G2 169
-#define CAPRI_PIN_RXDATA3G0 170
-#define CAPRI_PIN_RXDATA3G1 171
-#define CAPRI_PIN_RXDATA3G2 172
-#define CAPRI_PIN_SDIO1_CLK 173
-#define CAPRI_PIN_SDIO1_CMD 174
-#define CAPRI_PIN_SDIO1_DATA_0 175
-#define CAPRI_PIN_SDIO1_DATA_1 176
-#define CAPRI_PIN_SDIO1_DATA_2 177
-#define CAPRI_PIN_SDIO1_DATA_3 178
-#define CAPRI_PIN_SDIO4_CLK 179
-#define CAPRI_PIN_SDIO4_CMD 180
-#define CAPRI_PIN_SDIO4_DATA_0 181
-#define CAPRI_PIN_SDIO4_DATA_1 182
-#define CAPRI_PIN_SDIO4_DATA_2 183
-#define CAPRI_PIN_SDIO4_DATA_3 184
-#define CAPRI_PIN_SIM_CLK 185
-#define CAPRI_PIN_SIM_DATA 186
-#define CAPRI_PIN_SIM_DET 187
-#define CAPRI_PIN_SIM_RESETN 188
-#define CAPRI_PIN_SIM2_CLK 189
-#define CAPRI_PIN_SIM2_DATA 190
-#define CAPRI_PIN_SIM2_DET 191
-#define CAPRI_PIN_SIM2_RESETN 192
-#define CAPRI_PIN_SRI_C 193
-#define CAPRI_PIN_SRI_D 194
-#define CAPRI_PIN_SRI_E 195
-#define CAPRI_PIN_SSP_EXTCLK 196
-#define CAPRI_PIN_SSP0_CLK 197
-#define CAPRI_PIN_SSP0_FS 198
-#define CAPRI_PIN_SSP0_RXD 199
-#define CAPRI_PIN_SSP0_TXD 200
-#define CAPRI_PIN_SSP2_CLK 201
-#define CAPRI_PIN_SSP2_FS_0 202
-#define CAPRI_PIN_SSP2_FS_1 203
-#define CAPRI_PIN_SSP2_FS_2 204
-#define CAPRI_PIN_SSP2_FS_3 205
-#define CAPRI_PIN_SSP2_RXD_0 206
-#define CAPRI_PIN_SSP2_RXD_1 207
-#define CAPRI_PIN_SSP2_TXD_0 208
-#define CAPRI_PIN_SSP2_TXD_1 209
-#define CAPRI_PIN_SSP3_CLK 210
-#define CAPRI_PIN_SSP3_FS 211
-#define CAPRI_PIN_SSP3_RXD 212
-#define CAPRI_PIN_SSP3_TXD 213
-#define CAPRI_PIN_SSP4_CLK 214
-#define CAPRI_PIN_SSP4_FS 215
-#define CAPRI_PIN_SSP4_RXD 216
-#define CAPRI_PIN_SSP4_TXD 217
-#define CAPRI_PIN_SSP5_CLK 218
-#define CAPRI_PIN_SSP5_FS 219
-#define CAPRI_PIN_SSP5_RXD 220
-#define CAPRI_PIN_SSP5_TXD 221
-#define CAPRI_PIN_SSP6_CLK 222
-#define CAPRI_PIN_SSP6_FS 223
-#define CAPRI_PIN_SSP6_RXD 224
-#define CAPRI_PIN_SSP6_TXD 225
-#define CAPRI_PIN_STAT_1 226
-#define CAPRI_PIN_STAT_2 227
-#define CAPRI_PIN_SYSCLKEN 228
-#define CAPRI_PIN_TRACECLK 229
-#define CAPRI_PIN_TRACEDT00 230
-#define CAPRI_PIN_TRACEDT01 231
-#define CAPRI_PIN_TRACEDT02 232
-#define CAPRI_PIN_TRACEDT03 233
-#define CAPRI_PIN_TRACEDT04 234
-#define CAPRI_PIN_TRACEDT05 235
-#define CAPRI_PIN_TRACEDT06 236
-#define CAPRI_PIN_TRACEDT07 237
-#define CAPRI_PIN_TRACEDT08 238
-#define CAPRI_PIN_TRACEDT09 239
-#define CAPRI_PIN_TRACEDT10 240
-#define CAPRI_PIN_TRACEDT11 241
-#define CAPRI_PIN_TRACEDT12 242
-#define CAPRI_PIN_TRACEDT13 243
-#define CAPRI_PIN_TRACEDT14 244
-#define CAPRI_PIN_TRACEDT15 245
-#define CAPRI_PIN_TXDATA3G0 246
-#define CAPRI_PIN_TXPWRIND 247
-#define CAPRI_PIN_UARTB1_UCTS 248
-#define CAPRI_PIN_UARTB1_URTS 249
-#define CAPRI_PIN_UARTB1_URXD 250
-#define CAPRI_PIN_UARTB1_UTXD 251
-#define CAPRI_PIN_UARTB2_URXD 252
-#define CAPRI_PIN_UARTB2_UTXD 253
-#define CAPRI_PIN_UARTB3_UCTS 254
-#define CAPRI_PIN_UARTB3_URTS 255
-#define CAPRI_PIN_UARTB3_URXD 256
-#define CAPRI_PIN_UARTB3_UTXD 257
-#define CAPRI_PIN_UARTB4_UCTS 258
-#define CAPRI_PIN_UARTB4_URTS 259
-#define CAPRI_PIN_UARTB4_URXD 260
-#define CAPRI_PIN_UARTB4_UTXD 261
-#define CAPRI_PIN_VC_CAM1_SCL 262
-#define CAPRI_PIN_VC_CAM1_SDA 263
-#define CAPRI_PIN_VC_CAM2_SCL 264
-#define CAPRI_PIN_VC_CAM2_SDA 265
-#define CAPRI_PIN_VC_CAM3_SCL 266
-#define CAPRI_PIN_VC_CAM3_SDA 267
-
-#define CAPRI_PIN_DESC(a, b, c) \
- { .number = a, .name = b, .drv_data = &c##_pin }
-
-/*
- * Pin description definition. The order here must be the same as defined in
- * the PADCTRLREG block in the RDB, since the pin number is used as an index
- * into this array.
- */
-static const struct pinctrl_pin_desc capri_pinctrl_pins[] = {
- CAPRI_PIN_DESC(CAPRI_PIN_ADCSYNC, "adcsync", std),
- CAPRI_PIN_DESC(CAPRI_PIN_BAT_RM, "bat_rm", std),
- CAPRI_PIN_DESC(CAPRI_PIN_BSC1_SCL, "bsc1_scl", i2c),
- CAPRI_PIN_DESC(CAPRI_PIN_BSC1_SDA, "bsc1_sda", i2c),
- CAPRI_PIN_DESC(CAPRI_PIN_BSC2_SCL, "bsc2_scl", i2c),
- CAPRI_PIN_DESC(CAPRI_PIN_BSC2_SDA, "bsc2_sda", i2c),
- CAPRI_PIN_DESC(CAPRI_PIN_CLASSGPWR, "classgpwr", std),
- CAPRI_PIN_DESC(CAPRI_PIN_CLK_CX8, "clk_cx8", std),
- CAPRI_PIN_DESC(CAPRI_PIN_CLKOUT_0, "clkout_0", std),
- CAPRI_PIN_DESC(CAPRI_PIN_CLKOUT_1, "clkout_1", std),
- CAPRI_PIN_DESC(CAPRI_PIN_CLKOUT_2, "clkout_2", std),
- CAPRI_PIN_DESC(CAPRI_PIN_CLKOUT_3, "clkout_3", std),
- CAPRI_PIN_DESC(CAPRI_PIN_CLKREQ_IN_0, "clkreq_in_0", std),
- CAPRI_PIN_DESC(CAPRI_PIN_CLKREQ_IN_1, "clkreq_in_1", std),
- CAPRI_PIN_DESC(CAPRI_PIN_CWS_SYS_REQ1, "cws_sys_req1", std),
- CAPRI_PIN_DESC(CAPRI_PIN_CWS_SYS_REQ2, "cws_sys_req2", std),
- CAPRI_PIN_DESC(CAPRI_PIN_CWS_SYS_REQ3, "cws_sys_req3", std),
- CAPRI_PIN_DESC(CAPRI_PIN_DIGMIC1_CLK, "digmic1_clk", std),
- CAPRI_PIN_DESC(CAPRI_PIN_DIGMIC1_DQ, "digmic1_dq", std),
- CAPRI_PIN_DESC(CAPRI_PIN_DIGMIC2_CLK, "digmic2_clk", std),
- CAPRI_PIN_DESC(CAPRI_PIN_DIGMIC2_DQ, "digmic2_dq", std),
- CAPRI_PIN_DESC(CAPRI_PIN_GPEN13, "gpen13", std),
- CAPRI_PIN_DESC(CAPRI_PIN_GPEN14, "gpen14", std),
- CAPRI_PIN_DESC(CAPRI_PIN_GPEN15, "gpen15", std),
- CAPRI_PIN_DESC(CAPRI_PIN_GPIO00, "gpio00", std),
- CAPRI_PIN_DESC(CAPRI_PIN_GPIO01, "gpio01", std),
- CAPRI_PIN_DESC(CAPRI_PIN_GPIO02, "gpio02", std),
- CAPRI_PIN_DESC(CAPRI_PIN_GPIO03, "gpio03", std),
- CAPRI_PIN_DESC(CAPRI_PIN_GPIO04, "gpio04", std),
- CAPRI_PIN_DESC(CAPRI_PIN_GPIO05, "gpio05", std),
- CAPRI_PIN_DESC(CAPRI_PIN_GPIO06, "gpio06", std),
- CAPRI_PIN_DESC(CAPRI_PIN_GPIO07, "gpio07", std),
- CAPRI_PIN_DESC(CAPRI_PIN_GPIO08, "gpio08", std),
- CAPRI_PIN_DESC(CAPRI_PIN_GPIO09, "gpio09", std),
- CAPRI_PIN_DESC(CAPRI_PIN_GPIO10, "gpio10", std),
- CAPRI_PIN_DESC(CAPRI_PIN_GPIO11, "gpio11", std),
- CAPRI_PIN_DESC(CAPRI_PIN_GPIO12, "gpio12", std),
- CAPRI_PIN_DESC(CAPRI_PIN_GPIO13, "gpio13", std),
- CAPRI_PIN_DESC(CAPRI_PIN_GPIO14, "gpio14", std),
- CAPRI_PIN_DESC(CAPRI_PIN_GPS_PABLANK, "gps_pablank", std),
- CAPRI_PIN_DESC(CAPRI_PIN_GPS_TMARK, "gps_tmark", std),
- CAPRI_PIN_DESC(CAPRI_PIN_HDMI_SCL, "hdmi_scl", hdmi),
- CAPRI_PIN_DESC(CAPRI_PIN_HDMI_SDA, "hdmi_sda", hdmi),
- CAPRI_PIN_DESC(CAPRI_PIN_IC_DM, "ic_dm", std),
- CAPRI_PIN_DESC(CAPRI_PIN_IC_DP, "ic_dp", std),
- CAPRI_PIN_DESC(CAPRI_PIN_KP_COL_IP_0, "kp_col_ip_0", std),
- CAPRI_PIN_DESC(CAPRI_PIN_KP_COL_IP_1, "kp_col_ip_1", std),
- CAPRI_PIN_DESC(CAPRI_PIN_KP_COL_IP_2, "kp_col_ip_2", std),
- CAPRI_PIN_DESC(CAPRI_PIN_KP_COL_IP_3, "kp_col_ip_3", std),
- CAPRI_PIN_DESC(CAPRI_PIN_KP_ROW_OP_0, "kp_row_op_0", std),
- CAPRI_PIN_DESC(CAPRI_PIN_KP_ROW_OP_1, "kp_row_op_1", std),
- CAPRI_PIN_DESC(CAPRI_PIN_KP_ROW_OP_2, "kp_row_op_2", std),
- CAPRI_PIN_DESC(CAPRI_PIN_KP_ROW_OP_3, "kp_row_op_3", std),
- CAPRI_PIN_DESC(CAPRI_PIN_LCD_B_0, "lcd_b_0", std),
- CAPRI_PIN_DESC(CAPRI_PIN_LCD_B_1, "lcd_b_1", std),
- CAPRI_PIN_DESC(CAPRI_PIN_LCD_B_2, "lcd_b_2", std),
- CAPRI_PIN_DESC(CAPRI_PIN_LCD_B_3, "lcd_b_3", std),
- CAPRI_PIN_DESC(CAPRI_PIN_LCD_B_4, "lcd_b_4", std),
- CAPRI_PIN_DESC(CAPRI_PIN_LCD_B_5, "lcd_b_5", std),
- CAPRI_PIN_DESC(CAPRI_PIN_LCD_B_6, "lcd_b_6", std),
- CAPRI_PIN_DESC(CAPRI_PIN_LCD_B_7, "lcd_b_7", std),
- CAPRI_PIN_DESC(CAPRI_PIN_LCD_G_0, "lcd_g_0", std),
- CAPRI_PIN_DESC(CAPRI_PIN_LCD_G_1, "lcd_g_1", std),
- CAPRI_PIN_DESC(CAPRI_PIN_LCD_G_2, "lcd_g_2", std),
- CAPRI_PIN_DESC(CAPRI_PIN_LCD_G_3, "lcd_g_3", std),
- CAPRI_PIN_DESC(CAPRI_PIN_LCD_G_4, "lcd_g_4", std),
- CAPRI_PIN_DESC(CAPRI_PIN_LCD_G_5, "lcd_g_5", std),
- CAPRI_PIN_DESC(CAPRI_PIN_LCD_G_6, "lcd_g_6", std),
- CAPRI_PIN_DESC(CAPRI_PIN_LCD_G_7, "lcd_g_7", std),
- CAPRI_PIN_DESC(CAPRI_PIN_LCD_HSYNC, "lcd_hsync", std),
- CAPRI_PIN_DESC(CAPRI_PIN_LCD_OE, "lcd_oe", std),
- CAPRI_PIN_DESC(CAPRI_PIN_LCD_PCLK, "lcd_pclk", std),
- CAPRI_PIN_DESC(CAPRI_PIN_LCD_R_0, "lcd_r_0", std),
- CAPRI_PIN_DESC(CAPRI_PIN_LCD_R_1, "lcd_r_1", std),
- CAPRI_PIN_DESC(CAPRI_PIN_LCD_R_2, "lcd_r_2", std),
- CAPRI_PIN_DESC(CAPRI_PIN_LCD_R_3, "lcd_r_3", std),
- CAPRI_PIN_DESC(CAPRI_PIN_LCD_R_4, "lcd_r_4", std),
- CAPRI_PIN_DESC(CAPRI_PIN_LCD_R_5, "lcd_r_5", std),
- CAPRI_PIN_DESC(CAPRI_PIN_LCD_R_6, "lcd_r_6", std),
- CAPRI_PIN_DESC(CAPRI_PIN_LCD_R_7, "lcd_r_7", std),
- CAPRI_PIN_DESC(CAPRI_PIN_LCD_VSYNC, "lcd_vsync", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MDMGPIO0, "mdmgpio0", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MDMGPIO1, "mdmgpio1", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MDMGPIO2, "mdmgpio2", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MDMGPIO3, "mdmgpio3", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MDMGPIO4, "mdmgpio4", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MDMGPIO5, "mdmgpio5", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MDMGPIO6, "mdmgpio6", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MDMGPIO7, "mdmgpio7", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MDMGPIO8, "mdmgpio8", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_0, "mphi_data_0", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_1, "mphi_data_1", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_2, "mphi_data_2", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_3, "mphi_data_3", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_4, "mphi_data_4", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_5, "mphi_data_5", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_6, "mphi_data_6", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_7, "mphi_data_7", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_8, "mphi_data_8", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_9, "mphi_data_9", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_10, "mphi_data_10", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_11, "mphi_data_11", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_12, "mphi_data_12", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_13, "mphi_data_13", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_14, "mphi_data_14", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MPHI_DATA_15, "mphi_data_15", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MPHI_HA0, "mphi_ha0", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MPHI_HAT0, "mphi_hat0", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MPHI_HAT1, "mphi_hat1", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MPHI_HCE0_N, "mphi_hce0_n", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MPHI_HCE1_N, "mphi_hce1_n", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MPHI_HRD_N, "mphi_hrd_n", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MPHI_HWR_N, "mphi_hwr_n", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MPHI_RUN0, "mphi_run0", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MPHI_RUN1, "mphi_run1", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MTX_SCAN_CLK, "mtx_scan_clk", std),
- CAPRI_PIN_DESC(CAPRI_PIN_MTX_SCAN_DATA, "mtx_scan_data", std),
- CAPRI_PIN_DESC(CAPRI_PIN_NAND_AD_0, "nand_ad_0", std),
- CAPRI_PIN_DESC(CAPRI_PIN_NAND_AD_1, "nand_ad_1", std),
- CAPRI_PIN_DESC(CAPRI_PIN_NAND_AD_2, "nand_ad_2", std),
- CAPRI_PIN_DESC(CAPRI_PIN_NAND_AD_3, "nand_ad_3", std),
- CAPRI_PIN_DESC(CAPRI_PIN_NAND_AD_4, "nand_ad_4", std),
- CAPRI_PIN_DESC(CAPRI_PIN_NAND_AD_5, "nand_ad_5", std),
- CAPRI_PIN_DESC(CAPRI_PIN_NAND_AD_6, "nand_ad_6", std),
- CAPRI_PIN_DESC(CAPRI_PIN_NAND_AD_7, "nand_ad_7", std),
- CAPRI_PIN_DESC(CAPRI_PIN_NAND_ALE, "nand_ale", std),
- CAPRI_PIN_DESC(CAPRI_PIN_NAND_CEN_0, "nand_cen_0", std),
- CAPRI_PIN_DESC(CAPRI_PIN_NAND_CEN_1, "nand_cen_1", std),
- CAPRI_PIN_DESC(CAPRI_PIN_NAND_CLE, "nand_cle", std),
- CAPRI_PIN_DESC(CAPRI_PIN_NAND_OEN, "nand_oen", std),
- CAPRI_PIN_DESC(CAPRI_PIN_NAND_RDY_0, "nand_rdy_0", std),
- CAPRI_PIN_DESC(CAPRI_PIN_NAND_RDY_1, "nand_rdy_1", std),
- CAPRI_PIN_DESC(CAPRI_PIN_NAND_WEN, "nand_wen", std),
- CAPRI_PIN_DESC(CAPRI_PIN_NAND_WP, "nand_wp", std),
- CAPRI_PIN_DESC(CAPRI_PIN_PC1, "pc1", std),
- CAPRI_PIN_DESC(CAPRI_PIN_PC2, "pc2", std),
- CAPRI_PIN_DESC(CAPRI_PIN_PMU_INT, "pmu_int", std),
- CAPRI_PIN_DESC(CAPRI_PIN_PMU_SCL, "pmu_scl", i2c),
- CAPRI_PIN_DESC(CAPRI_PIN_PMU_SDA, "pmu_sda", i2c),
- CAPRI_PIN_DESC(CAPRI_PIN_RFST2G_MTSLOTEN3G, "rfst2g_mtsloten3g", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RGMII_0_RX_CTL, "rgmii_0_rx_ctl", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RGMII_0_RXC, "rgmii_0_rxc", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RGMII_0_RXD_0, "rgmii_0_rxd_0", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RGMII_0_RXD_1, "rgmii_0_rxd_1", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RGMII_0_RXD_2, "rgmii_0_rxd_2", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RGMII_0_RXD_3, "rgmii_0_rxd_3", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RGMII_0_TX_CTL, "rgmii_0_tx_ctl", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RGMII_0_TXC, "rgmii_0_txc", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RGMII_0_TXD_0, "rgmii_0_txd_0", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RGMII_0_TXD_1, "rgmii_0_txd_1", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RGMII_0_TXD_2, "rgmii_0_txd_2", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RGMII_0_TXD_3, "rgmii_0_txd_3", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RGMII_1_RX_CTL, "rgmii_1_rx_ctl", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RGMII_1_RXC, "rgmii_1_rxc", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RGMII_1_RXD_0, "rgmii_1_rxd_0", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RGMII_1_RXD_1, "rgmii_1_rxd_1", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RGMII_1_RXD_2, "rgmii_1_rxd_2", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RGMII_1_RXD_3, "rgmii_1_rxd_3", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RGMII_1_TX_CTL, "rgmii_1_tx_ctl", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RGMII_1_TXC, "rgmii_1_txc", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RGMII_1_TXD_0, "rgmii_1_txd_0", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RGMII_1_TXD_1, "rgmii_1_txd_1", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RGMII_1_TXD_2, "rgmii_1_txd_2", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RGMII_1_TXD_3, "rgmii_1_txd_3", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RGMII_GPIO_0, "rgmii_gpio_0", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RGMII_GPIO_1, "rgmii_gpio_1", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RGMII_GPIO_2, "rgmii_gpio_2", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RGMII_GPIO_3, "rgmii_gpio_3", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RTXDATA2G_TXDATA3G1, "rtxdata2g_txdata3g1",
- std),
- CAPRI_PIN_DESC(CAPRI_PIN_RTXEN2G_TXDATA3G2, "rtxen2g_txdata3g2", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RXDATA3G0, "rxdata3g0", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RXDATA3G1, "rxdata3g1", std),
- CAPRI_PIN_DESC(CAPRI_PIN_RXDATA3G2, "rxdata3g2", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SDIO1_CLK, "sdio1_clk", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SDIO1_CMD, "sdio1_cmd", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SDIO1_DATA_0, "sdio1_data_0", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SDIO1_DATA_1, "sdio1_data_1", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SDIO1_DATA_2, "sdio1_data_2", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SDIO1_DATA_3, "sdio1_data_3", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SDIO4_CLK, "sdio4_clk", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SDIO4_CMD, "sdio4_cmd", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SDIO4_DATA_0, "sdio4_data_0", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SDIO4_DATA_1, "sdio4_data_1", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SDIO4_DATA_2, "sdio4_data_2", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SDIO4_DATA_3, "sdio4_data_3", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SIM_CLK, "sim_clk", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SIM_DATA, "sim_data", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SIM_DET, "sim_det", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SIM_RESETN, "sim_resetn", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SIM2_CLK, "sim2_clk", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SIM2_DATA, "sim2_data", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SIM2_DET, "sim2_det", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SIM2_RESETN, "sim2_resetn", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SRI_C, "sri_c", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SRI_D, "sri_d", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SRI_E, "sri_e", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP_EXTCLK, "ssp_extclk", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP0_CLK, "ssp0_clk", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP0_FS, "ssp0_fs", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP0_RXD, "ssp0_rxd", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP0_TXD, "ssp0_txd", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP2_CLK, "ssp2_clk", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP2_FS_0, "ssp2_fs_0", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP2_FS_1, "ssp2_fs_1", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP2_FS_2, "ssp2_fs_2", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP2_FS_3, "ssp2_fs_3", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP2_RXD_0, "ssp2_rxd_0", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP2_RXD_1, "ssp2_rxd_1", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP2_TXD_0, "ssp2_txd_0", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP2_TXD_1, "ssp2_txd_1", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP3_CLK, "ssp3_clk", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP3_FS, "ssp3_fs", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP3_RXD, "ssp3_rxd", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP3_TXD, "ssp3_txd", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP4_CLK, "ssp4_clk", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP4_FS, "ssp4_fs", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP4_RXD, "ssp4_rxd", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP4_TXD, "ssp4_txd", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP5_CLK, "ssp5_clk", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP5_FS, "ssp5_fs", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP5_RXD, "ssp5_rxd", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP5_TXD, "ssp5_txd", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP6_CLK, "ssp6_clk", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP6_FS, "ssp6_fs", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP6_RXD, "ssp6_rxd", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SSP6_TXD, "ssp6_txd", std),
- CAPRI_PIN_DESC(CAPRI_PIN_STAT_1, "stat_1", std),
- CAPRI_PIN_DESC(CAPRI_PIN_STAT_2, "stat_2", std),
- CAPRI_PIN_DESC(CAPRI_PIN_SYSCLKEN, "sysclken", std),
- CAPRI_PIN_DESC(CAPRI_PIN_TRACECLK, "traceclk", std),
- CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT00, "tracedt00", std),
- CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT01, "tracedt01", std),
- CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT02, "tracedt02", std),
- CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT03, "tracedt03", std),
- CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT04, "tracedt04", std),
- CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT05, "tracedt05", std),
- CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT06, "tracedt06", std),
- CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT07, "tracedt07", std),
- CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT08, "tracedt08", std),
- CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT09, "tracedt09", std),
- CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT10, "tracedt10", std),
- CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT11, "tracedt11", std),
- CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT12, "tracedt12", std),
- CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT13, "tracedt13", std),
- CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT14, "tracedt14", std),
- CAPRI_PIN_DESC(CAPRI_PIN_TRACEDT15, "tracedt15", std),
- CAPRI_PIN_DESC(CAPRI_PIN_TXDATA3G0, "txdata3g0", std),
- CAPRI_PIN_DESC(CAPRI_PIN_TXPWRIND, "txpwrind", std),
- CAPRI_PIN_DESC(CAPRI_PIN_UARTB1_UCTS, "uartb1_ucts", std),
- CAPRI_PIN_DESC(CAPRI_PIN_UARTB1_URTS, "uartb1_urts", std),
- CAPRI_PIN_DESC(CAPRI_PIN_UARTB1_URXD, "uartb1_urxd", std),
- CAPRI_PIN_DESC(CAPRI_PIN_UARTB1_UTXD, "uartb1_utxd", std),
- CAPRI_PIN_DESC(CAPRI_PIN_UARTB2_URXD, "uartb2_urxd", std),
- CAPRI_PIN_DESC(CAPRI_PIN_UARTB2_UTXD, "uartb2_utxd", std),
- CAPRI_PIN_DESC(CAPRI_PIN_UARTB3_UCTS, "uartb3_ucts", std),
- CAPRI_PIN_DESC(CAPRI_PIN_UARTB3_URTS, "uartb3_urts", std),
- CAPRI_PIN_DESC(CAPRI_PIN_UARTB3_URXD, "uartb3_urxd", std),
- CAPRI_PIN_DESC(CAPRI_PIN_UARTB3_UTXD, "uartb3_utxd", std),
- CAPRI_PIN_DESC(CAPRI_PIN_UARTB4_UCTS, "uartb4_ucts", std),
- CAPRI_PIN_DESC(CAPRI_PIN_UARTB4_URTS, "uartb4_urts", std),
- CAPRI_PIN_DESC(CAPRI_PIN_UARTB4_URXD, "uartb4_urxd", std),
- CAPRI_PIN_DESC(CAPRI_PIN_UARTB4_UTXD, "uartb4_utxd", std),
- CAPRI_PIN_DESC(CAPRI_PIN_VC_CAM1_SCL, "vc_cam1_scl", i2c),
- CAPRI_PIN_DESC(CAPRI_PIN_VC_CAM1_SDA, "vc_cam1_sda", i2c),
- CAPRI_PIN_DESC(CAPRI_PIN_VC_CAM2_SCL, "vc_cam2_scl", i2c),
- CAPRI_PIN_DESC(CAPRI_PIN_VC_CAM2_SDA, "vc_cam2_sda", i2c),
- CAPRI_PIN_DESC(CAPRI_PIN_VC_CAM3_SCL, "vc_cam3_scl", i2c),
- CAPRI_PIN_DESC(CAPRI_PIN_VC_CAM3_SDA, "vc_cam3_sda", i2c),
-};
-
-static const char * const capri_alt_groups[] = {
- "adcsync",
- "bat_rm",
- "bsc1_scl",
- "bsc1_sda",
- "bsc2_scl",
- "bsc2_sda",
- "classgpwr",
- "clk_cx8",
- "clkout_0",
- "clkout_1",
- "clkout_2",
- "clkout_3",
- "clkreq_in_0",
- "clkreq_in_1",
- "cws_sys_req1",
- "cws_sys_req2",
- "cws_sys_req3",
- "digmic1_clk",
- "digmic1_dq",
- "digmic2_clk",
- "digmic2_dq",
- "gpen13",
- "gpen14",
- "gpen15",
- "gpio00",
- "gpio01",
- "gpio02",
- "gpio03",
- "gpio04",
- "gpio05",
- "gpio06",
- "gpio07",
- "gpio08",
- "gpio09",
- "gpio10",
- "gpio11",
- "gpio12",
- "gpio13",
- "gpio14",
- "gps_pablank",
- "gps_tmark",
- "hdmi_scl",
- "hdmi_sda",
- "ic_dm",
- "ic_dp",
- "kp_col_ip_0",
- "kp_col_ip_1",
- "kp_col_ip_2",
- "kp_col_ip_3",
- "kp_row_op_0",
- "kp_row_op_1",
- "kp_row_op_2",
- "kp_row_op_3",
- "lcd_b_0",
- "lcd_b_1",
- "lcd_b_2",
- "lcd_b_3",
- "lcd_b_4",
- "lcd_b_5",
- "lcd_b_6",
- "lcd_b_7",
- "lcd_g_0",
- "lcd_g_1",
- "lcd_g_2",
- "lcd_g_3",
- "lcd_g_4",
- "lcd_g_5",
- "lcd_g_6",
- "lcd_g_7",
- "lcd_hsync",
- "lcd_oe",
- "lcd_pclk",
- "lcd_r_0",
- "lcd_r_1",
- "lcd_r_2",
- "lcd_r_3",
- "lcd_r_4",
- "lcd_r_5",
- "lcd_r_6",
- "lcd_r_7",
- "lcd_vsync",
- "mdmgpio0",
- "mdmgpio1",
- "mdmgpio2",
- "mdmgpio3",
- "mdmgpio4",
- "mdmgpio5",
- "mdmgpio6",
- "mdmgpio7",
- "mdmgpio8",
- "mphi_data_0",
- "mphi_data_1",
- "mphi_data_2",
- "mphi_data_3",
- "mphi_data_4",
- "mphi_data_5",
- "mphi_data_6",
- "mphi_data_7",
- "mphi_data_8",
- "mphi_data_9",
- "mphi_data_10",
- "mphi_data_11",
- "mphi_data_12",
- "mphi_data_13",
- "mphi_data_14",
- "mphi_data_15",
- "mphi_ha0",
- "mphi_hat0",
- "mphi_hat1",
- "mphi_hce0_n",
- "mphi_hce1_n",
- "mphi_hrd_n",
- "mphi_hwr_n",
- "mphi_run0",
- "mphi_run1",
- "mtx_scan_clk",
- "mtx_scan_data",
- "nand_ad_0",
- "nand_ad_1",
- "nand_ad_2",
- "nand_ad_3",
- "nand_ad_4",
- "nand_ad_5",
- "nand_ad_6",
- "nand_ad_7",
- "nand_ale",
- "nand_cen_0",
- "nand_cen_1",
- "nand_cle",
- "nand_oen",
- "nand_rdy_0",
- "nand_rdy_1",
- "nand_wen",
- "nand_wp",
- "pc1",
- "pc2",
- "pmu_int",
- "pmu_scl",
- "pmu_sda",
- "rfst2g_mtsloten3g",
- "rgmii_0_rx_ctl",
- "rgmii_0_rxc",
- "rgmii_0_rxd_0",
- "rgmii_0_rxd_1",
- "rgmii_0_rxd_2",
- "rgmii_0_rxd_3",
- "rgmii_0_tx_ctl",
- "rgmii_0_txc",
- "rgmii_0_txd_0",
- "rgmii_0_txd_1",
- "rgmii_0_txd_2",
- "rgmii_0_txd_3",
- "rgmii_1_rx_ctl",
- "rgmii_1_rxc",
- "rgmii_1_rxd_0",
- "rgmii_1_rxd_1",
- "rgmii_1_rxd_2",
- "rgmii_1_rxd_3",
- "rgmii_1_tx_ctl",
- "rgmii_1_txc",
- "rgmii_1_txd_0",
- "rgmii_1_txd_1",
- "rgmii_1_txd_2",
- "rgmii_1_txd_3",
- "rgmii_gpio_0",
- "rgmii_gpio_1",
- "rgmii_gpio_2",
- "rgmii_gpio_3",
- "rtxdata2g_txdata3g1",
- "rtxen2g_txdata3g2",
- "rxdata3g0",
- "rxdata3g1",
- "rxdata3g2",
- "sdio1_clk",
- "sdio1_cmd",
- "sdio1_data_0",
- "sdio1_data_1",
- "sdio1_data_2",
- "sdio1_data_3",
- "sdio4_clk",
- "sdio4_cmd",
- "sdio4_data_0",
- "sdio4_data_1",
- "sdio4_data_2",
- "sdio4_data_3",
- "sim_clk",
- "sim_data",
- "sim_det",
- "sim_resetn",
- "sim2_clk",
- "sim2_data",
- "sim2_det",
- "sim2_resetn",
- "sri_c",
- "sri_d",
- "sri_e",
- "ssp_extclk",
- "ssp0_clk",
- "ssp0_fs",
- "ssp0_rxd",
- "ssp0_txd",
- "ssp2_clk",
- "ssp2_fs_0",
- "ssp2_fs_1",
- "ssp2_fs_2",
- "ssp2_fs_3",
- "ssp2_rxd_0",
- "ssp2_rxd_1",
- "ssp2_txd_0",
- "ssp2_txd_1",
- "ssp3_clk",
- "ssp3_fs",
- "ssp3_rxd",
- "ssp3_txd",
- "ssp4_clk",
- "ssp4_fs",
- "ssp4_rxd",
- "ssp4_txd",
- "ssp5_clk",
- "ssp5_fs",
- "ssp5_rxd",
- "ssp5_txd",
- "ssp6_clk",
- "ssp6_fs",
- "ssp6_rxd",
- "ssp6_txd",
- "stat_1",
- "stat_2",
- "sysclken",
- "traceclk",
- "tracedt00",
- "tracedt01",
- "tracedt02",
- "tracedt03",
- "tracedt04",
- "tracedt05",
- "tracedt06",
- "tracedt07",
- "tracedt08",
- "tracedt09",
- "tracedt10",
- "tracedt11",
- "tracedt12",
- "tracedt13",
- "tracedt14",
- "tracedt15",
- "txdata3g0",
- "txpwrind",
- "uartb1_ucts",
- "uartb1_urts",
- "uartb1_urxd",
- "uartb1_utxd",
- "uartb2_urxd",
- "uartb2_utxd",
- "uartb3_ucts",
- "uartb3_urts",
- "uartb3_urxd",
- "uartb3_utxd",
- "uartb4_ucts",
- "uartb4_urts",
- "uartb4_urxd",
- "uartb4_utxd",
- "vc_cam1_scl",
- "vc_cam1_sda",
- "vc_cam2_scl",
- "vc_cam2_sda",
- "vc_cam3_scl",
- "vc_cam3_sda",
-};
-
-/* Every pin can implement all ALT1-ALT4 functions */
-#define CAPRI_PIN_FUNCTION(fcn_name) \
-{ \
- .name = #fcn_name, \
- .groups = capri_alt_groups, \
- .ngroups = ARRAY_SIZE(capri_alt_groups), \
-}
-
-static const struct capri_pin_function capri_functions[] = {
- CAPRI_PIN_FUNCTION(alt1),
- CAPRI_PIN_FUNCTION(alt2),
- CAPRI_PIN_FUNCTION(alt3),
- CAPRI_PIN_FUNCTION(alt4),
-};
-
-static struct capri_pinctrl_data capri_pinctrl = {
- .pins = capri_pinctrl_pins,
- .npins = ARRAY_SIZE(capri_pinctrl_pins),
- .functions = capri_functions,
- .nfunctions = ARRAY_SIZE(capri_functions),
-};
-
-static inline enum capri_pin_type pin_type_get(struct pinctrl_dev *pctldev,
- unsigned pin)
-{
- struct capri_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
-
- if (pin >= pdata->npins)
- return CAPRI_PIN_TYPE_UNKNOWN;
-
- return *(enum capri_pin_type *)(pdata->pins[pin].drv_data);
-}
-
-#define CAPRI_PIN_SHIFT(type, param) \
- (CAPRI_ ## type ## _PIN_REG_ ## param ## _SHIFT)
-
-#define CAPRI_PIN_MASK(type, param) \
- (CAPRI_ ## type ## _PIN_REG_ ## param ## _MASK)
-
-/*
- * This helper function is used to build up the value and mask used to write to
- * a pin register, but does not actually write to the register.
- */
-static inline void capri_pin_update(u32 *reg_val, u32 *reg_mask, u32 param_val,
- u32 param_shift, u32 param_mask)
-{
- *reg_val &= ~param_mask;
- *reg_val |= (param_val << param_shift) & param_mask;
- *reg_mask |= param_mask;
-}
-
-static struct regmap_config capri_pinctrl_regmap_config = {
- .reg_bits = 32,
- .reg_stride = 4,
- .val_bits = 32,
- .max_register = CAPRI_PIN_VC_CAM3_SDA,
-};
-
-static int capri_pinctrl_get_groups_count(struct pinctrl_dev *pctldev)
-{
- struct capri_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
-
- return pdata->npins;
-}
-
-static const char *capri_pinctrl_get_group_name(struct pinctrl_dev *pctldev,
- unsigned group)
-{
- struct capri_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
-
- return pdata->pins[group].name;
-}
-
-static int capri_pinctrl_get_group_pins(struct pinctrl_dev *pctldev,
- unsigned group,
- const unsigned **pins,
- unsigned *num_pins)
-{
- struct capri_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
-
- *pins = &pdata->pins[group].number;
- *num_pins = 1;
-
- return 0;
-}
-
-static void capri_pinctrl_pin_dbg_show(struct pinctrl_dev *pctldev,
- struct seq_file *s,
- unsigned offset)
-{
- seq_printf(s, " %s", dev_name(pctldev->dev));
-}
-
-static struct pinctrl_ops capri_pinctrl_ops = {
- .get_groups_count = capri_pinctrl_get_groups_count,
- .get_group_name = capri_pinctrl_get_group_name,
- .get_group_pins = capri_pinctrl_get_group_pins,
- .pin_dbg_show = capri_pinctrl_pin_dbg_show,
- .dt_node_to_map = pinconf_generic_dt_node_to_map_pin,
- .dt_free_map = pinctrl_utils_dt_free_map,
-};
-
-static int capri_pinctrl_get_fcns_count(struct pinctrl_dev *pctldev)
-{
- struct capri_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
-
- return pdata->nfunctions;
-}
-
-static const char *capri_pinctrl_get_fcn_name(struct pinctrl_dev *pctldev,
- unsigned function)
-{
- struct capri_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
-
- return pdata->functions[function].name;
-}
-
-static int capri_pinctrl_get_fcn_groups(struct pinctrl_dev *pctldev,
- unsigned function,
- const char * const **groups,
- unsigned * const num_groups)
-{
- struct capri_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
-
- *groups = pdata->functions[function].groups;
- *num_groups = pdata->functions[function].ngroups;
-
- return 0;
-}
-
-static int capri_pinmux_enable(struct pinctrl_dev *pctldev,
- unsigned function,
- unsigned group)
-{
- struct capri_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
- const struct capri_pin_function *f = &pdata->functions[function];
- u32 offset = 4 * pdata->pins[group].number;
- int rc = 0;
-
- dev_dbg(pctldev->dev,
- "%s(): Enable function %s (%d) of pin %s (%d) @offset 0x%x.\n",
- __func__, f->name, function, pdata->pins[group].name,
- pdata->pins[group].number, offset);
-
- rc = regmap_update_bits(pdata->regmap, offset, CAPRI_PIN_REG_F_SEL_MASK,
- function << CAPRI_PIN_REG_F_SEL_SHIFT);
- if (rc)
- dev_err(pctldev->dev,
- "Error updating register for pin %s (%d).\n",
- pdata->pins[group].name, pdata->pins[group].number);
-
- return rc;
-}
-
-static struct pinmux_ops capri_pinctrl_pinmux_ops = {
- .get_functions_count = capri_pinctrl_get_fcns_count,
- .get_function_name = capri_pinctrl_get_fcn_name,
- .get_function_groups = capri_pinctrl_get_fcn_groups,
- .enable = capri_pinmux_enable,
-};
-
-static int capri_pinctrl_pin_config_get(struct pinctrl_dev *pctldev,
- unsigned pin,
- unsigned long *config)
-{
- return -ENOTSUPP;
-}
-
-
-/* Goes through the configs and update register val/mask */
-static int capri_std_pin_update(struct pinctrl_dev *pctldev,
- unsigned pin,
- unsigned long *configs,
- unsigned num_configs,
- u32 *val,
- u32 *mask)
-{
- struct capri_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
- int i;
- enum pin_config_param param;
- u16 arg;
-
- for (i = 0; i < num_configs; i++) {
- param = pinconf_to_config_param(configs[i]);
- arg = pinconf_to_config_argument(configs[i]);
-
- switch (param) {
- case PIN_CONFIG_INPUT_SCHMITT_ENABLE:
- arg = (arg >= 1 ? 1 : 0);
- capri_pin_update(val, mask, arg,
- CAPRI_PIN_SHIFT(STD, HYST),
- CAPRI_PIN_MASK(STD, HYST));
- break;
- /*
- * The pin bias can only be one of pull-up, pull-down, or
- * disable. The user does not need to specify a value for the
- * property, and the default value from pinconf-generic is
- * ignored.
- */
- case PIN_CONFIG_BIAS_DISABLE:
- capri_pin_update(val, mask, 0,
- CAPRI_PIN_SHIFT(STD, PULL_UP),
- CAPRI_PIN_MASK(STD, PULL_UP));
- capri_pin_update(val, mask, 0,
- CAPRI_PIN_SHIFT(STD, PULL_DN),
- CAPRI_PIN_MASK(STD, PULL_DN));
- break;
-
- case PIN_CONFIG_BIAS_PULL_UP:
- capri_pin_update(val, mask, 1,
- CAPRI_PIN_SHIFT(STD, PULL_UP),
- CAPRI_PIN_MASK(STD, PULL_UP));
- capri_pin_update(val, mask, 0,
- CAPRI_PIN_SHIFT(STD, PULL_DN),
- CAPRI_PIN_MASK(STD, PULL_DN));
- break;
-
- case PIN_CONFIG_BIAS_PULL_DOWN:
- capri_pin_update(val, mask, 0,
- CAPRI_PIN_SHIFT(STD, PULL_UP),
- CAPRI_PIN_MASK(STD, PULL_UP));
- capri_pin_update(val, mask, 1,
- CAPRI_PIN_SHIFT(STD, PULL_DN),
- CAPRI_PIN_MASK(STD, PULL_DN));
- break;
-
- case PIN_CONFIG_SLEW_RATE:
- arg = (arg >= 1 ? 1 : 0);
- capri_pin_update(val, mask, arg,
- CAPRI_PIN_SHIFT(STD, SLEW),
- CAPRI_PIN_MASK(STD, SLEW));
- break;
-
- case PIN_CONFIG_INPUT_ENABLE:
- /* inversed since register is for input _disable_ */
- arg = (arg >= 1 ? 0 : 1);
- capri_pin_update(val, mask, arg,
- CAPRI_PIN_SHIFT(STD, INPUT_DIS),
- CAPRI_PIN_MASK(STD, INPUT_DIS));
- break;
-
- case PIN_CONFIG_DRIVE_STRENGTH:
- /* Valid range is 2-16 mA, even numbers only */
- if ((arg < 2) || (arg > 16) || (arg % 2)) {
- dev_err(pctldev->dev,
- "Invalid Drive Strength value (%d) for "
- "pin %s (%d). Valid values are "
- "(2..16) mA, even numbers only.\n",
- arg, pdata->pins[pin].name, pin);
- return -EINVAL;
- }
- capri_pin_update(val, mask, (arg/2)-1,
- CAPRI_PIN_SHIFT(STD, DRV_STR),
- CAPRI_PIN_MASK(STD, DRV_STR));
- break;
-
- default:
- dev_err(pctldev->dev,
- "Unrecognized pin config %d for pin %s (%d).\n",
- param, pdata->pins[pin].name, pin);
- return -EINVAL;
-
- } /* switch config */
- } /* for each config */
-
- return 0;
-}
-
-/*
- * The pull-up strength for an I2C pin is represented by bits 4-6 in the
- * register with the following mapping:
- * 0b000: No pull-up
- * 0b001: 1200 Ohm
- * 0b010: 1800 Ohm
- * 0b011: 720 Ohm
- * 0b100: 2700 Ohm
- * 0b101: 831 Ohm
- * 0b110: 1080 Ohm
- * 0b111: 568 Ohm
- * This array maps pull-up strength in Ohms to register values (1+index).
- */
-static const u16 capri_pullup_map[] = {1200, 1800, 720, 2700, 831, 1080, 568};
-
-/* Goes through the configs and update register val/mask */
-static int capri_i2c_pin_update(struct pinctrl_dev *pctldev,
- unsigned pin,
- unsigned long *configs,
- unsigned num_configs,
- u32 *val,
- u32 *mask)
-{
- struct capri_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
- int i, j;
- enum pin_config_param param;
- u16 arg;
-
- for (i = 0; i < num_configs; i++) {
- param = pinconf_to_config_param(configs[i]);
- arg = pinconf_to_config_argument(configs[i]);
-
- switch (param) {
- case PIN_CONFIG_BIAS_PULL_UP:
- for (j = 0; j < ARRAY_SIZE(capri_pullup_map); j++)
- if (capri_pullup_map[j] == arg)
- break;
-
- if (j == ARRAY_SIZE(capri_pullup_map)) {
- dev_err(pctldev->dev,
- "Invalid pull-up value (%d) for pin %s "
- "(%d). Valid values are 568, 720, 831, "
- "1080, 1200, 1800, 2700 Ohms.\n",
- arg, pdata->pins[pin].name, pin);
- return -EINVAL;
- }
-
- capri_pin_update(val, mask, j+1,
- CAPRI_PIN_SHIFT(I2C, PULL_UP_STR),
- CAPRI_PIN_MASK(I2C, PULL_UP_STR));
- break;
-
- case PIN_CONFIG_BIAS_DISABLE:
- capri_pin_update(val, mask, 0,
- CAPRI_PIN_SHIFT(I2C, PULL_UP_STR),
- CAPRI_PIN_MASK(I2C, PULL_UP_STR));
- break;
-
- case PIN_CONFIG_SLEW_RATE:
- arg = (arg >= 1 ? 1 : 0);
- capri_pin_update(val, mask, arg,
- CAPRI_PIN_SHIFT(I2C, SLEW),
- CAPRI_PIN_MASK(I2C, SLEW));
- break;
-
- case PIN_CONFIG_INPUT_ENABLE:
- /* inversed since register is for input _disable_ */
- arg = (arg >= 1 ? 0 : 1);
- capri_pin_update(val, mask, arg,
- CAPRI_PIN_SHIFT(I2C, INPUT_DIS),
- CAPRI_PIN_MASK(I2C, INPUT_DIS));
- break;
-
- default:
- dev_err(pctldev->dev,
- "Unrecognized pin config %d for pin %s (%d).\n",
- param, pdata->pins[pin].name, pin);
- return -EINVAL;
-
- } /* switch config */
- } /* for each config */
-
- return 0;
-}
-
-/* Goes through the configs and update register val/mask */
-static int capri_hdmi_pin_update(struct pinctrl_dev *pctldev,
- unsigned pin,
- unsigned long *configs,
- unsigned num_configs,
- u32 *val,
- u32 *mask)
-{
- struct capri_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
- int i;
- enum pin_config_param param;
- u16 arg;
-
- for (i = 0; i < num_configs; i++) {
- param = pinconf_to_config_param(configs[i]);
- arg = pinconf_to_config_argument(configs[i]);
-
- switch (param) {
- case PIN_CONFIG_SLEW_RATE:
- arg = (arg >= 1 ? 1 : 0);
- capri_pin_update(val, mask, arg,
- CAPRI_PIN_SHIFT(HDMI, MODE),
- CAPRI_PIN_MASK(HDMI, MODE));
- break;
-
- case PIN_CONFIG_INPUT_ENABLE:
- /* inversed since register is for input _disable_ */
- arg = (arg >= 1 ? 0 : 1);
- capri_pin_update(val, mask, arg,
- CAPRI_PIN_SHIFT(HDMI, INPUT_DIS),
- CAPRI_PIN_MASK(HDMI, INPUT_DIS));
- break;
-
- default:
- dev_err(pctldev->dev,
- "Unrecognized pin config %d for pin %s (%d).\n",
- param, pdata->pins[pin].name, pin);
- return -EINVAL;
-
- } /* switch config */
- } /* for each config */
-
- return 0;
-}
-
-static int capri_pinctrl_pin_config_set(struct pinctrl_dev *pctldev,
- unsigned pin,
- unsigned long *configs,
- unsigned num_configs)
-{
- struct capri_pinctrl_data *pdata = pinctrl_dev_get_drvdata(pctldev);
- enum capri_pin_type pin_type;
- u32 offset = 4 * pin;
- u32 cfg_val, cfg_mask;
- int rc;
-
- cfg_val = 0;
- cfg_mask = 0;
- pin_type = pin_type_get(pctldev, pin);
-
- /* Different pins have different configuration options */
- switch (pin_type) {
- case CAPRI_PIN_TYPE_STD:
- rc = capri_std_pin_update(pctldev, pin, configs, num_configs,
- &cfg_val, &cfg_mask);
- break;
-
- case CAPRI_PIN_TYPE_I2C:
- rc = capri_i2c_pin_update(pctldev, pin, configs, num_configs,
- &cfg_val, &cfg_mask);
- break;
-
- case CAPRI_PIN_TYPE_HDMI:
- rc = capri_hdmi_pin_update(pctldev, pin, configs, num_configs,
- &cfg_val, &cfg_mask);
- break;
-
- default:
- dev_err(pctldev->dev, "Unknown pin type for pin %s (%d).\n",
- pdata->pins[pin].name, pin);
- return -EINVAL;
-
- } /* switch pin type */
-
- if (rc)
- return rc;
-
- dev_dbg(pctldev->dev,
- "%s(): Set pin %s (%d) with config 0x%x, mask 0x%x\n",
- __func__, pdata->pins[pin].name, pin, cfg_val, cfg_mask);
-
- rc = regmap_update_bits(pdata->regmap, offset, cfg_mask, cfg_val);
- if (rc) {
- dev_err(pctldev->dev,
- "Error updating register for pin %s (%d).\n",
- pdata->pins[pin].name, pin);
- return rc;
- }
-
- return 0;
-}
-
-static struct pinconf_ops capri_pinctrl_pinconf_ops = {
- .pin_config_get = capri_pinctrl_pin_config_get,
- .pin_config_set = capri_pinctrl_pin_config_set,
-};
-
-static struct pinctrl_desc capri_pinctrl_desc = {
- /* name, pins, npins members initialized in probe function */
- .pctlops = &capri_pinctrl_ops,
- .pmxops = &capri_pinctrl_pinmux_ops,
- .confops = &capri_pinctrl_pinconf_ops,
- .owner = THIS_MODULE,
-};
-
-int __init capri_pinctrl_probe(struct platform_device *pdev)
-{
- struct capri_pinctrl_data *pdata = &capri_pinctrl;
- struct resource *res;
- struct pinctrl_dev *pctl;
-
- /* So far We can assume there is only 1 bank of registers */
- res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
- if (!res) {
- dev_err(&pdev->dev, "Missing MEM resource\n");
- return -ENODEV;
- }
-
- pdata->reg_base = devm_ioremap_resource(&pdev->dev, res);
- if (IS_ERR(pdata->reg_base)) {
- dev_err(&pdev->dev, "Failed to ioremap MEM resource\n");
- return -ENODEV;
- }
-
- /* Initialize the dynamic part of pinctrl_desc */
- pdata->regmap = devm_regmap_init_mmio(&pdev->dev, pdata->reg_base,
- &capri_pinctrl_regmap_config);
- if (IS_ERR(pdata->regmap)) {
- dev_err(&pdev->dev, "Regmap MMIO init failed.\n");
- return -ENODEV;
- }
-
- capri_pinctrl_desc.name = dev_name(&pdev->dev);
- capri_pinctrl_desc.pins = capri_pinctrl.pins;
- capri_pinctrl_desc.npins = capri_pinctrl.npins;
-
- pctl = pinctrl_register(&capri_pinctrl_desc,
- &pdev->dev,
- pdata);
- if (!pctl) {
- dev_err(&pdev->dev, "Failed to register pinctrl\n");
- return -ENODEV;
- }
-
- platform_set_drvdata(pdev, pdata);
-
- return 0;
-}
-
-static struct of_device_id capri_pinctrl_of_match[] = {
- { .compatible = "brcm,bcm11351-pinctrl", },
- { },
-};
-
-static struct platform_driver capri_pinctrl_driver = {
- .driver = {
- .name = "bcm-capri-pinctrl",
- .owner = THIS_MODULE,
- .of_match_table = capri_pinctrl_of_match,
- },
-};
-
-module_platform_driver_probe(capri_pinctrl_driver, capri_pinctrl_probe);
-
-MODULE_AUTHOR("Sherman Yin <syin@broadcom.com>");
-MODULE_DESCRIPTION("Broadcom Capri pinctrl driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/pinctrl/pinctrl-msm.c b/drivers/pinctrl/pinctrl-msm.c
index 38d579b..e43fbce 100644
--- a/drivers/pinctrl/pinctrl-msm.c
+++ b/drivers/pinctrl/pinctrl-msm.c
@@ -665,7 +665,10 @@ static void msm_gpio_irq_ack(struct irq_data *d)
spin_lock_irqsave(&pctrl->lock, flags);
val = readl(pctrl->regs + g->intr_status_reg);
- val &= ~BIT(g->intr_status_bit);
+ if (g->intr_ack_high)
+ val |= BIT(g->intr_status_bit);
+ else
+ val &= ~BIT(g->intr_status_bit);
writel(val, pctrl->regs + g->intr_status_reg);
if (test_bit(d->hwirq, pctrl->dual_edge_irqs))
@@ -744,6 +747,7 @@ static int msm_gpio_irq_set_type(struct irq_data *d, unsigned int type)
break;
case IRQ_TYPE_EDGE_BOTH:
val |= BIT(g->intr_detection_bit);
+ val |= BIT(g->intr_polarity_bit);
break;
case IRQ_TYPE_LEVEL_LOW:
break;
diff --git a/drivers/pinctrl/pinctrl-msm.h b/drivers/pinctrl/pinctrl-msm.h
index 8fbe9fb..6e26f1b 100644
--- a/drivers/pinctrl/pinctrl-msm.h
+++ b/drivers/pinctrl/pinctrl-msm.h
@@ -84,6 +84,7 @@ struct msm_pingroup {
unsigned intr_enable_bit:5;
unsigned intr_status_bit:5;
+ unsigned intr_ack_high:1;
unsigned intr_target_bit:5;
unsigned intr_raw_status_bit:5;
diff --git a/drivers/pinctrl/pinctrl-nomadik.c b/drivers/pinctrl/pinctrl-nomadik.c
index 208341f..8f6f16e 100644
--- a/drivers/pinctrl/pinctrl-nomadik.c
+++ b/drivers/pinctrl/pinctrl-nomadik.c
@@ -877,7 +877,6 @@ static void nmk_gpio_irq_handler(unsigned int irq, struct irq_desc *desc)
struct nmk_gpio_chip *nmk_chip = container_of(chip, struct nmk_gpio_chip, chip);
u32 status;
- pr_err("PLONK IRQ %d\n", irq);
clk_enable(nmk_chip->clk);
status = readl(nmk_chip->addr + NMK_GPIO_IS);
clk_disable(nmk_chip->clk);
diff --git a/drivers/pinctrl/pinctrl-rockchip.c b/drivers/pinctrl/pinctrl-rockchip.c
index 46dddc1..96c60d2 100644
--- a/drivers/pinctrl/pinctrl-rockchip.c
+++ b/drivers/pinctrl/pinctrl-rockchip.c
@@ -342,7 +342,7 @@ static const struct pinctrl_ops rockchip_pctrl_ops = {
* @pin: pin to change
* @mux: new mux function to set
*/
-static void rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
+static int rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
{
struct rockchip_pinctrl *info = bank->drvdata;
void __iomem *reg = info->reg_base + info->ctrl->mux_offset;
@@ -350,6 +350,20 @@ static void rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
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 (mux != RK_FUNC_GPIO) {
+ dev_err(info->dev,
+ "pin %d only supports a gpio mux\n", pin);
+ return -ENOTSUPP;
+ } else {
+ return 0;
+ }
+ }
+
dev_dbg(info->dev, "setting mux of GPIO%d-%d to %d\n",
bank->bank_num, pin, mux);
@@ -365,6 +379,8 @@ static void rockchip_set_mux(struct rockchip_pin_bank *bank, int pin, int mux)
writel(data, reg);
spin_unlock_irqrestore(&bank->slock, flags);
+
+ return 0;
}
#define RK2928_PULL_OFFSET 0x118
@@ -560,7 +576,7 @@ static int rockchip_pmx_enable(struct pinctrl_dev *pctldev, unsigned selector,
const unsigned int *pins = info->groups[group].pins;
const struct rockchip_pin_config *data = info->groups[group].data;
struct rockchip_pin_bank *bank;
- int cnt;
+ int cnt, ret = 0;
dev_dbg(info->dev, "enable function %s group %s\n",
info->functions[selector].name, info->groups[group].name);
@@ -571,8 +587,18 @@ static int rockchip_pmx_enable(struct pinctrl_dev *pctldev, unsigned selector,
*/
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,
- data[cnt].func);
+ ret = rockchip_set_mux(bank, pins[cnt] - bank->pin_base,
+ data[cnt].func);
+ if (ret)
+ break;
+ }
+
+ if (ret) {
+ /* revert the already done pin settings */
+ for (cnt--; cnt >= 0; cnt--)
+ rockchip_set_mux(bank, pins[cnt] - bank->pin_base, 0);
+
+ return ret;
}
return 0;
@@ -607,7 +633,7 @@ static int rockchip_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
struct rockchip_pinctrl *info = pinctrl_dev_get_drvdata(pctldev);
struct rockchip_pin_bank *bank;
struct gpio_chip *chip;
- int pin;
+ int pin, ret;
u32 data;
chip = range->gc;
@@ -617,7 +643,9 @@ static int rockchip_pmx_gpio_set_direction(struct pinctrl_dev *pctldev,
dev_dbg(info->dev, "gpio_direction for pin %u as %s-%d to %s\n",
offset, range->name, pin, input ? "input" : "output");
- rockchip_set_mux(bank, pin, RK_FUNC_GPIO);
+ ret = rockchip_set_mux(bank, pin, RK_FUNC_GPIO);
+ if (ret < 0)
+ return ret;
data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR);
/* set bit to 1 for output, 0 for input */
@@ -1144,9 +1172,13 @@ static int rockchip_irq_set_type(struct irq_data *d, unsigned int type)
u32 polarity;
u32 level;
u32 data;
+ int ret;
/* make sure the pin is configured as gpio input */
- rockchip_set_mux(bank, d->hwirq, RK_FUNC_GPIO);
+ ret = rockchip_set_mux(bank, d->hwirq, RK_FUNC_GPIO);
+ if (ret < 0)
+ return ret;
+
data = readl_relaxed(bank->reg_base + GPIO_SWPORT_DDR);
data &= ~mask;
writel_relaxed(data, bank->reg_base + GPIO_SWPORT_DDR);
@@ -1534,7 +1566,7 @@ static struct rockchip_pin_ctrl rk3188_pin_ctrl = {
.nr_banks = ARRAY_SIZE(rk3188_pin_banks),
.label = "RK3188-GPIO",
.type = RK3188,
- .mux_offset = 0x68,
+ .mux_offset = 0x60,
.pull_calc_reg = rk3188_calc_pull_reg_and_bit,
};
diff --git a/drivers/ptp/ptp_clock.c b/drivers/ptp/ptp_clock.c
index e25d2bc..296b0ec 100644
--- a/drivers/ptp/ptp_clock.c
+++ b/drivers/ptp/ptp_clock.c
@@ -142,7 +142,10 @@ static int ptp_clock_adjtime(struct posix_clock *pc, struct timex *tx)
delta = ktime_to_ns(kt);
err = ops->adjtime(ops, delta);
} else if (tx->modes & ADJ_FREQUENCY) {
- err = ops->adjfreq(ops, scaled_ppm_to_ppb(tx->freq));
+ s32 ppb = scaled_ppm_to_ppb(tx->freq);
+ if (ppb > ops->max_adj || ppb < -ops->max_adj)
+ return -ERANGE;
+ err = ops->adjfreq(ops, ppb);
ptp->dialed_frequency = tx->freq;
} else if (tx->modes == 0) {
tx->freq = ptp->dialed_frequency;
diff --git a/drivers/pwm/pwm-spear.c b/drivers/pwm/pwm-spear.c
index 8ad26b8..cb2d4f0 100644
--- a/drivers/pwm/pwm-spear.c
+++ b/drivers/pwm/pwm-spear.c
@@ -2,7 +2,7 @@
* ST Microelectronics SPEAr Pulse Width Modulator driver
*
* Copyright (C) 2012 ST Microelectronics
- * Shiraz Hashim <shiraz.hashim@st.com>
+ * Shiraz Hashim <shiraz.linux.kernel@gmail.com>
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
@@ -264,6 +264,6 @@ static struct platform_driver spear_pwm_driver = {
module_platform_driver(spear_pwm_driver);
MODULE_LICENSE("GPL");
-MODULE_AUTHOR("Shiraz Hashim <shiraz.hashim@st.com>");
+MODULE_AUTHOR("Shiraz Hashim <shiraz.linux.kernel@gmail.com>");
MODULE_AUTHOR("Viresh Kumar <viresh.kumar@linaro.com>");
MODULE_ALIAS("platform:spear-pwm");
diff --git a/drivers/s390/char/sclp.c b/drivers/s390/char/sclp.c
index 1990285..c316051 100644
--- a/drivers/s390/char/sclp.c
+++ b/drivers/s390/char/sclp.c
@@ -1252,7 +1252,7 @@ static __init int sclp_initcall(void)
return rc;
sclp_pdev = platform_device_register_simple("sclp", -1, NULL, 0);
- rc = PTR_RET(sclp_pdev);
+ rc = PTR_ERR_OR_ZERO(sclp_pdev);
if (rc)
goto fail_platform_driver_unregister;
diff --git a/drivers/s390/char/sclp_cmd.c b/drivers/s390/char/sclp_cmd.c
index 6e8f90f..6e14999 100644
--- a/drivers/s390/char/sclp_cmd.c
+++ b/drivers/s390/char/sclp_cmd.c
@@ -515,7 +515,7 @@ static int __init sclp_detect_standby_memory(void)
if (rc)
goto out;
sclp_pdev = platform_device_register_simple("sclp_mem", -1, NULL, 0);
- rc = PTR_RET(sclp_pdev);
+ rc = PTR_ERR_OR_ZERO(sclp_pdev);
if (rc)
goto out_driver;
sclp_add_standby_memory();
diff --git a/drivers/s390/char/sclp_vt220.c b/drivers/s390/char/sclp_vt220.c
index 4eed38c..cd9c919 100644
--- a/drivers/s390/char/sclp_vt220.c
+++ b/drivers/s390/char/sclp_vt220.c
@@ -97,13 +97,16 @@ static void sclp_vt220_pm_event_fn(struct sclp_register *reg,
static int __sclp_vt220_emit(struct sclp_vt220_request *request);
static void sclp_vt220_emit_current(void);
-/* Registration structure for our interest in SCLP event buffers */
+/* Registration structure for SCLP output event buffers */
static struct sclp_register sclp_vt220_register = {
.send_mask = EVTYP_VT220MSG_MASK,
+ .pm_event_fn = sclp_vt220_pm_event_fn,
+};
+
+/* Registration structure for SCLP input event buffers */
+static struct sclp_register sclp_vt220_register_input = {
.receive_mask = EVTYP_VT220MSG_MASK,
- .state_change_fn = NULL,
.receiver_fn = sclp_vt220_receiver_fn,
- .pm_event_fn = sclp_vt220_pm_event_fn,
};
@@ -715,9 +718,14 @@ static int __init sclp_vt220_tty_init(void)
rc = tty_register_driver(driver);
if (rc)
goto out_init;
+ rc = sclp_register(&sclp_vt220_register_input);
+ if (rc)
+ goto out_reg;
sclp_vt220_driver = driver;
return 0;
+out_reg:
+ tty_unregister_driver(driver);
out_init:
__sclp_vt220_cleanup();
out_driver:
diff --git a/drivers/s390/net/claw.c b/drivers/s390/net/claw.c
index fd7b3bd..d837c3c 100644
--- a/drivers/s390/net/claw.c
+++ b/drivers/s390/net/claw.c
@@ -3348,7 +3348,7 @@ static int __init claw_init(void)
}
CLAW_DBF_TEXT(2, setup, "init_mod");
claw_root_dev = root_device_register("claw");
- ret = PTR_RET(claw_root_dev);
+ ret = PTR_ERR_OR_ZERO(claw_root_dev);
if (ret)
goto register_err;
ret = ccw_driver_register(&claw_ccw_driver);
diff --git a/drivers/s390/net/ctcm_main.c b/drivers/s390/net/ctcm_main.c
index 70b3a02..03b6ad0 100644
--- a/drivers/s390/net/ctcm_main.c
+++ b/drivers/s390/net/ctcm_main.c
@@ -1837,7 +1837,7 @@ static int __init ctcm_init(void)
if (ret)
goto out_err;
ctcm_root_dev = root_device_register("ctcm");
- ret = PTR_RET(ctcm_root_dev);
+ ret = PTR_ERR_OR_ZERO(ctcm_root_dev);
if (ret)
goto register_err;
ret = ccw_driver_register(&ctcm_ccw_driver);
diff --git a/drivers/s390/net/lcs.c b/drivers/s390/net/lcs.c
index c461f2a..8d5d969 100644
--- a/drivers/s390/net/lcs.c
+++ b/drivers/s390/net/lcs.c
@@ -2442,7 +2442,7 @@ __init lcs_init_module(void)
if (rc)
goto out_err;
lcs_root_dev = root_device_register("lcs");
- rc = PTR_RET(lcs_root_dev);
+ rc = PTR_ERR_OR_ZERO(lcs_root_dev);
if (rc)
goto register_err;
rc = ccw_driver_register(&lcs_ccw_driver);
diff --git a/drivers/s390/net/qeth_core.h b/drivers/s390/net/qeth_core.h
index 5333b2c..a2088af 100644
--- a/drivers/s390/net/qeth_core.h
+++ b/drivers/s390/net/qeth_core.h
@@ -268,10 +268,8 @@ static inline int qeth_is_ipa_enabled(struct qeth_ipa_info *ipa,
#define QETH_NO_PRIO_QUEUEING 0
#define QETH_PRIO_Q_ING_PREC 1
#define QETH_PRIO_Q_ING_TOS 2
-#define IP_TOS_LOWDELAY 0x10
-#define IP_TOS_HIGHTHROUGHPUT 0x08
-#define IP_TOS_HIGHRELIABILITY 0x04
-#define IP_TOS_NOTIMPORTANT 0x02
+#define QETH_PRIO_Q_ING_SKB 3
+#define QETH_PRIO_Q_ING_VLAN 4
/* Packing */
#define QETH_LOW_WATERMARK_PACK 2
diff --git a/drivers/s390/net/qeth_core_main.c b/drivers/s390/net/qeth_core_main.c
index 22470a3..34993009 100644
--- a/drivers/s390/net/qeth_core_main.c
+++ b/drivers/s390/net/qeth_core_main.c
@@ -20,6 +20,7 @@
#include <linux/kthread.h>
#include <linux/slab.h>
#include <net/iucv/af_iucv.h>
+#include <net/dsfield.h>
#include <asm/ebcdic.h>
#include <asm/io.h>
@@ -3670,42 +3671,56 @@ void qeth_qdio_output_handler(struct ccw_device *ccwdev,
}
EXPORT_SYMBOL_GPL(qeth_qdio_output_handler);
+/**
+ * Note: Function assumes that we have 4 outbound queues.
+ */
int qeth_get_priority_queue(struct qeth_card *card, struct sk_buff *skb,
int ipv, int cast_type)
{
- if (!ipv && (card->info.type == QETH_CARD_TYPE_OSD ||
- card->info.type == QETH_CARD_TYPE_OSX))
- return card->qdio.default_out_queue;
- switch (card->qdio.no_out_queues) {
- case 4:
- if (cast_type && card->info.is_multicast_different)
- return card->info.is_multicast_different &
- (card->qdio.no_out_queues - 1);
- if (card->qdio.do_prio_queueing && (ipv == 4)) {
- const u8 tos = ip_hdr(skb)->tos;
-
- if (card->qdio.do_prio_queueing ==
- QETH_PRIO_Q_ING_TOS) {
- if (tos & IP_TOS_NOTIMPORTANT)
- return 3;
- if (tos & IP_TOS_HIGHRELIABILITY)
- return 2;
- if (tos & IP_TOS_HIGHTHROUGHPUT)
- return 1;
- if (tos & IP_TOS_LOWDELAY)
- return 0;
- }
- if (card->qdio.do_prio_queueing ==
- QETH_PRIO_Q_ING_PREC)
- return 3 - (tos >> 6);
- } else if (card->qdio.do_prio_queueing && (ipv == 6)) {
- /* TODO: IPv6!!! */
+ __be16 *tci;
+ u8 tos;
+
+ if (cast_type && card->info.is_multicast_different)
+ return card->info.is_multicast_different &
+ (card->qdio.no_out_queues - 1);
+
+ switch (card->qdio.do_prio_queueing) {
+ case QETH_PRIO_Q_ING_TOS:
+ case QETH_PRIO_Q_ING_PREC:
+ switch (ipv) {
+ case 4:
+ tos = ipv4_get_dsfield(ip_hdr(skb));
+ break;
+ case 6:
+ tos = ipv6_get_dsfield(ipv6_hdr(skb));
+ break;
+ default:
+ return card->qdio.default_out_queue;
}
- return card->qdio.default_out_queue;
- case 1: /* fallthrough for single-out-queue 1920-device */
+ if (card->qdio.do_prio_queueing == QETH_PRIO_Q_ING_PREC)
+ return ~tos >> 6 & 3;
+ if (tos & IPTOS_MINCOST)
+ return 3;
+ if (tos & IPTOS_RELIABILITY)
+ return 2;
+ if (tos & IPTOS_THROUGHPUT)
+ return 1;
+ if (tos & IPTOS_LOWDELAY)
+ return 0;
+ break;
+ case QETH_PRIO_Q_ING_SKB:
+ if (skb->priority > 5)
+ return 0;
+ return ~skb->priority >> 1 & 3;
+ case QETH_PRIO_Q_ING_VLAN:
+ tci = &((struct ethhdr *)skb->data)->h_proto;
+ if (*tci == ETH_P_8021Q)
+ return ~*(tci + 1) >> (VLAN_PRIO_SHIFT + 1) & 3;
+ break;
default:
- return card->qdio.default_out_queue;
+ break;
}
+ return card->qdio.default_out_queue;
}
EXPORT_SYMBOL_GPL(qeth_get_priority_queue);
@@ -5824,7 +5839,7 @@ static int __init qeth_core_init(void)
if (rc)
goto out_err;
qeth_core_root_dev = root_device_register("qeth");
- rc = PTR_RET(qeth_core_root_dev);
+ rc = PTR_ERR_OR_ZERO(qeth_core_root_dev);
if (rc)
goto register_err;
qeth_core_header_cache = kmem_cache_create("qeth_hdr",
diff --git a/drivers/s390/net/qeth_core_sys.c b/drivers/s390/net/qeth_core_sys.c
index 425c0ec..8a25a2b 100644
--- a/drivers/s390/net/qeth_core_sys.c
+++ b/drivers/s390/net/qeth_core_sys.c
@@ -217,6 +217,10 @@ static ssize_t qeth_dev_prioqing_show(struct device *dev,
return sprintf(buf, "%s\n", "by precedence");
case QETH_PRIO_Q_ING_TOS:
return sprintf(buf, "%s\n", "by type of service");
+ case QETH_PRIO_Q_ING_SKB:
+ return sprintf(buf, "%s\n", "by skb-priority");
+ case QETH_PRIO_Q_ING_VLAN:
+ return sprintf(buf, "%s\n", "by VLAN headers");
default:
return sprintf(buf, "always queue %i\n",
card->qdio.default_out_queue);
@@ -250,11 +254,23 @@ static ssize_t qeth_dev_prioqing_store(struct device *dev,
}
tmp = strsep((char **) &buf, "\n");
- if (!strcmp(tmp, "prio_queueing_prec"))
+ if (!strcmp(tmp, "prio_queueing_prec")) {
card->qdio.do_prio_queueing = QETH_PRIO_Q_ING_PREC;
- else if (!strcmp(tmp, "prio_queueing_tos"))
+ card->qdio.default_out_queue = QETH_DEFAULT_QUEUE;
+ } else if (!strcmp(tmp, "prio_queueing_skb")) {
+ card->qdio.do_prio_queueing = QETH_PRIO_Q_ING_SKB;
+ card->qdio.default_out_queue = QETH_DEFAULT_QUEUE;
+ } else if (!strcmp(tmp, "prio_queueing_tos")) {
card->qdio.do_prio_queueing = QETH_PRIO_Q_ING_TOS;
- else if (!strcmp(tmp, "no_prio_queueing:0")) {
+ card->qdio.default_out_queue = QETH_DEFAULT_QUEUE;
+ } else if (!strcmp(tmp, "prio_queueing_vlan")) {
+ if (!card->options.layer2) {
+ rc = -ENOTSUPP;
+ goto out;
+ }
+ card->qdio.do_prio_queueing = QETH_PRIO_Q_ING_VLAN;
+ card->qdio.default_out_queue = QETH_DEFAULT_QUEUE;
+ } else if (!strcmp(tmp, "no_prio_queueing:0")) {
card->qdio.do_prio_queueing = QETH_NO_PRIO_QUEUEING;
card->qdio.default_out_queue = 0;
} else if (!strcmp(tmp, "no_prio_queueing:1")) {
diff --git a/drivers/s390/net/qeth_l2_main.c b/drivers/s390/net/qeth_l2_main.c
index 8dea3f1..e232cec 100644
--- a/drivers/s390/net/qeth_l2_main.c
+++ b/drivers/s390/net/qeth_l2_main.c
@@ -725,15 +725,20 @@ static int qeth_l2_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
int elements = 0;
struct qeth_card *card = dev->ml_priv;
struct sk_buff *new_skb = skb;
- int ipv = qeth_get_ip_version(skb);
int cast_type = qeth_l2_get_cast_type(card, skb);
- struct qeth_qdio_out_q *queue = card->qdio.out_qs
- [qeth_get_priority_queue(card, skb, ipv, cast_type)];
+ struct qeth_qdio_out_q *queue;
int tx_bytes = skb->len;
int data_offset = -1;
int elements_needed = 0;
int hd_len = 0;
+ if (card->qdio.do_prio_queueing || (cast_type &&
+ card->info.is_multicast_different))
+ queue = card->qdio.out_qs[qeth_get_priority_queue(card, skb,
+ qeth_get_ip_version(skb), cast_type)];
+ else
+ queue = card->qdio.out_qs[card->qdio.default_out_queue];
+
if ((card->state != CARD_STATE_UP) || !card->lan_online) {
card->stats.tx_carrier_errors++;
goto tx_drop;
diff --git a/drivers/s390/net/qeth_l3_main.c b/drivers/s390/net/qeth_l3_main.c
index 3524d34..c8d91d7 100644
--- a/drivers/s390/net/qeth_l3_main.c
+++ b/drivers/s390/net/qeth_l3_main.c
@@ -2926,8 +2926,11 @@ static int qeth_l3_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
struct sk_buff *new_skb = NULL;
int ipv = qeth_get_ip_version(skb);
int cast_type = qeth_l3_get_cast_type(card, skb);
- struct qeth_qdio_out_q *queue = card->qdio.out_qs
- [qeth_get_priority_queue(card, skb, ipv, cast_type)];
+ struct qeth_qdio_out_q *queue =
+ card->qdio.out_qs[card->qdio.do_prio_queueing
+ || (cast_type && card->info.is_multicast_different) ?
+ qeth_get_priority_queue(card, skb, ipv, cast_type) :
+ card->qdio.default_out_queue];
int tx_bytes = skb->len;
bool large_send;
int data_offset = -1;
diff --git a/drivers/staging/Kconfig b/drivers/staging/Kconfig
index ea5efb4..22365f1 100644
--- a/drivers/staging/Kconfig
+++ b/drivers/staging/Kconfig
@@ -40,8 +40,6 @@ source "drivers/staging/olpc_dcon/Kconfig"
source "drivers/staging/panel/Kconfig"
-source "drivers/staging/rtl8187se/Kconfig"
-
source "drivers/staging/rtl8192u/Kconfig"
source "drivers/staging/rtl8192e/Kconfig"
diff --git a/drivers/staging/Makefile b/drivers/staging/Makefile
index 86e020c..fbe84ed 100644
--- a/drivers/staging/Makefile
+++ b/drivers/staging/Makefile
@@ -12,7 +12,6 @@ obj-$(CONFIG_PRISM2_USB) += wlan-ng/
obj-$(CONFIG_COMEDI) += comedi/
obj-$(CONFIG_FB_OLPC_DCON) += olpc_dcon/
obj-$(CONFIG_PANEL) += panel/
-obj-$(CONFIG_R8187SE) += rtl8187se/
obj-$(CONFIG_RTL8192U) += rtl8192u/
obj-$(CONFIG_RTL8192E) += rtl8192e/
obj-$(CONFIG_R8712U) += rtl8712/
diff --git a/drivers/staging/comedi/comedi_buf.c b/drivers/staging/comedi/comedi_buf.c
index 924fce9..2575950 100644
--- a/drivers/staging/comedi/comedi_buf.c
+++ b/drivers/staging/comedi/comedi_buf.c
@@ -61,6 +61,8 @@ static void __comedi_buf_free(struct comedi_device *dev,
struct comedi_subdevice *s)
{
struct comedi_async *async = s->async;
+ struct comedi_buf_map *bm;
+ unsigned long flags;
if (async->prealloc_buf) {
vunmap(async->prealloc_buf);
@@ -68,8 +70,11 @@ static void __comedi_buf_free(struct comedi_device *dev,
async->prealloc_bufsz = 0;
}
- comedi_buf_map_put(async->buf_map);
+ spin_lock_irqsave(&s->spin_lock, flags);
+ bm = async->buf_map;
async->buf_map = NULL;
+ spin_unlock_irqrestore(&s->spin_lock, flags);
+ comedi_buf_map_put(bm);
}
static void __comedi_buf_alloc(struct comedi_device *dev,
@@ -80,6 +85,7 @@ static void __comedi_buf_alloc(struct comedi_device *dev,
struct page **pages = NULL;
struct comedi_buf_map *bm;
struct comedi_buf_page *buf;
+ unsigned long flags;
unsigned i;
if (!IS_ENABLED(CONFIG_HAS_DMA) && s->async_dma_dir != DMA_NONE) {
@@ -92,8 +98,10 @@ static void __comedi_buf_alloc(struct comedi_device *dev,
if (!bm)
return;
- async->buf_map = bm;
kref_init(&bm->refcount);
+ spin_lock_irqsave(&s->spin_lock, flags);
+ async->buf_map = bm;
+ spin_unlock_irqrestore(&s->spin_lock, flags);
bm->dma_dir = s->async_dma_dir;
if (bm->dma_dir != DMA_NONE)
/* Need ref to hardware device to free buffer later. */
@@ -127,7 +135,9 @@ static void __comedi_buf_alloc(struct comedi_device *dev,
pages[i] = virt_to_page(buf->virt_addr);
}
+ spin_lock_irqsave(&s->spin_lock, flags);
bm->n_pages = i;
+ spin_unlock_irqrestore(&s->spin_lock, flags);
/* vmap the prealloc_buf if all the pages were allocated */
if (i == n_pages)
@@ -150,6 +160,29 @@ int comedi_buf_map_put(struct comedi_buf_map *bm)
return 1;
}
+/* returns s->async->buf_map and increments its kref refcount */
+struct comedi_buf_map *
+comedi_buf_map_from_subdev_get(struct comedi_subdevice *s)
+{
+ struct comedi_async *async = s->async;
+ struct comedi_buf_map *bm = NULL;
+ unsigned long flags;
+
+ if (!async)
+ return NULL;
+
+ spin_lock_irqsave(&s->spin_lock, flags);
+ bm = async->buf_map;
+ /* only want it if buffer pages allocated */
+ if (bm && bm->n_pages)
+ comedi_buf_map_get(bm);
+ else
+ bm = NULL;
+ spin_unlock_irqrestore(&s->spin_lock, flags);
+
+ return bm;
+}
+
bool comedi_buf_is_mmapped(struct comedi_async *async)
{
struct comedi_buf_map *bm = async->buf_map;
diff --git a/drivers/staging/comedi/comedi_fops.c b/drivers/staging/comedi/comedi_fops.c
index ea6dc36..acc8019 100644
--- a/drivers/staging/comedi/comedi_fops.c
+++ b/drivers/staging/comedi/comedi_fops.c
@@ -1926,14 +1926,21 @@ static int comedi_mmap(struct file *file, struct vm_area_struct *vma)
struct comedi_device *dev = file->private_data;
struct comedi_subdevice *s;
struct comedi_async *async;
- struct comedi_buf_map *bm;
+ struct comedi_buf_map *bm = NULL;
unsigned long start = vma->vm_start;
unsigned long size;
int n_pages;
int i;
int retval;
- mutex_lock(&dev->mutex);
+ /*
+ * 'trylock' avoids circular dependency with current->mm->mmap_sem
+ * and down-reading &dev->attach_lock should normally succeed without
+ * contention unless the device is in the process of being attached
+ * or detached.
+ */
+ if (!down_read_trylock(&dev->attach_lock))
+ return -EAGAIN;
if (!dev->attached) {
dev_dbg(dev->class_dev, "no driver attached\n");
@@ -1973,7 +1980,9 @@ static int comedi_mmap(struct file *file, struct vm_area_struct *vma)
}
n_pages = size >> PAGE_SHIFT;
- bm = async->buf_map;
+
+ /* get reference to current buf map (if any) */
+ bm = comedi_buf_map_from_subdev_get(s);
if (!bm || n_pages > bm->n_pages) {
retval = -EINVAL;
goto done;
@@ -1997,7 +2006,8 @@ static int comedi_mmap(struct file *file, struct vm_area_struct *vma)
retval = 0;
done:
- mutex_unlock(&dev->mutex);
+ up_read(&dev->attach_lock);
+ comedi_buf_map_put(bm); /* put reference to buf map - okay if NULL */
return retval;
}
diff --git a/drivers/staging/comedi/comedi_internal.h b/drivers/staging/comedi/comedi_internal.h
index 9a74657..a492f2d 100644
--- a/drivers/staging/comedi/comedi_internal.h
+++ b/drivers/staging/comedi/comedi_internal.h
@@ -19,6 +19,8 @@ void comedi_buf_reset(struct comedi_async *async);
bool comedi_buf_is_mmapped(struct comedi_async *async);
void comedi_buf_map_get(struct comedi_buf_map *bm);
int comedi_buf_map_put(struct comedi_buf_map *bm);
+struct comedi_buf_map *comedi_buf_map_from_subdev_get(
+ struct comedi_subdevice *s);
unsigned int comedi_buf_write_n_allocated(struct comedi_async *async);
void comedi_device_cancel_all(struct comedi_device *dev);
diff --git a/drivers/staging/goldfish/goldfish_audio.c b/drivers/staging/goldfish/goldfish_audio.c
index f96dcec..7ac2602 100644
--- a/drivers/staging/goldfish/goldfish_audio.c
+++ b/drivers/staging/goldfish/goldfish_audio.c
@@ -334,6 +334,7 @@ static int goldfish_audio_probe(struct platform_device *pdev)
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);
diff --git a/drivers/staging/gs_fpgaboot/Makefile b/drivers/staging/gs_fpgaboot/Makefile
index 34cb606..d2f0211 100644
--- a/drivers/staging/gs_fpgaboot/Makefile
+++ b/drivers/staging/gs_fpgaboot/Makefile
@@ -1,4 +1,2 @@
gs_fpga-y += gs_fpgaboot.o io.o
obj-$(CONFIG_GS_FPGABOOT) += gs_fpga.o
-
-ccflags-$(CONFIG_GS_FPGA_DEBUG) := -DDEBUG
diff --git a/drivers/staging/gs_fpgaboot/gs_fpgaboot.c b/drivers/staging/gs_fpgaboot/gs_fpgaboot.c
index 89bc84d..7506900 100644
--- a/drivers/staging/gs_fpgaboot/gs_fpgaboot.c
+++ b/drivers/staging/gs_fpgaboot/gs_fpgaboot.c
@@ -373,7 +373,6 @@ static int __init gs_fpgaboot_init(void)
r = -1;
pr_info("FPGA DOWNLOAD --->\n");
- pr_info("built at %s UTC\n", __TIMESTAMP__);
pr_info("FPGA image file name: %s\n", file);
diff --git a/drivers/staging/rtl8187se/Kconfig b/drivers/staging/rtl8187se/Kconfig
deleted file mode 100644
index ff8d41e..0000000
--- a/drivers/staging/rtl8187se/Kconfig
+++ /dev/null
@@ -1,10 +0,0 @@
-config R8187SE
- tristate "RealTek RTL8187SE Wireless LAN NIC driver"
- depends on PCI && WLAN
- depends on m
- select WIRELESS_EXT
- select WEXT_PRIV
- select EEPROM_93CX6
- select CRYPTO
- ---help---
- If built as a module, it will be called r8187se.ko.
diff --git a/drivers/staging/rtl8187se/Makefile b/drivers/staging/rtl8187se/Makefile
deleted file mode 100644
index 91d1aa2..0000000
--- a/drivers/staging/rtl8187se/Makefile
+++ /dev/null
@@ -1,38 +0,0 @@
-
-#ccflags-y += -DCONFIG_IEEE80211_NOWEP=y
-#ccflags-y += -std=gnu89
-#ccflags-y += -O2
-#CC = gcc
-
-ccflags-y := -DSW_ANTE
-ccflags-y += -DTX_TRACK
-ccflags-y += -DHIGH_POWER
-ccflags-y += -DSW_DIG
-ccflags-y += -DRATE_ADAPT
-
-#enable it for legacy power save, disable it for leisure power save
-ccflags-y += -DENABLE_LPS
-
-
-#ccflags-y := -mhard-float -DCONFIG_FORCE_HARD_FLOAT=y
-
-r8187se-y := \
- r8180_core.o \
- r8180_wx.o \
- r8180_rtl8225z2.o \
- r8185b_init.o \
- r8180_dm.o \
- ieee80211/dot11d.o \
- ieee80211/ieee80211_softmac.o \
- ieee80211/ieee80211_rx.o \
- ieee80211/ieee80211_tx.o \
- ieee80211/ieee80211_wx.o \
- ieee80211/ieee80211_module.o \
- ieee80211/ieee80211_softmac_wx.o \
- ieee80211/ieee80211_crypt.o \
- ieee80211/ieee80211_crypt_tkip.o \
- ieee80211/ieee80211_crypt_ccmp.o \
- ieee80211/ieee80211_crypt_wep.o
-
-obj-$(CONFIG_R8187SE) += r8187se.o
-
diff --git a/drivers/staging/rtl8187se/Module.symvers b/drivers/staging/rtl8187se/Module.symvers
deleted file mode 100644
index e69de29..0000000
--- a/drivers/staging/rtl8187se/Module.symvers
+++ /dev/null
diff --git a/drivers/staging/rtl8187se/TODO b/drivers/staging/rtl8187se/TODO
deleted file mode 100644
index 704949a..0000000
--- a/drivers/staging/rtl8187se/TODO
+++ /dev/null
@@ -1,13 +0,0 @@
-TODO:
-- prepare private ieee80211 stack for merge with rtl8192su's version:
- - add hwsec_active flag to struct ieee80211_device
- - add bHwSec flag to cb_desc structure
-- switch to use shared "librtl" instead of private ieee80211 stack
-- switch to use LIB80211
-- switch to use MAC80211
-- use kernel coding style
-- checkpatch.pl fixes
-- sparse fixes
-- integrate with drivers/net/wireless/rtl818x
-
-Please send any patches to Greg Kroah-Hartman <greg@kroah.com>.
diff --git a/drivers/staging/rtl8187se/ieee80211/dot11d.c b/drivers/staging/rtl8187se/ieee80211/dot11d.c
deleted file mode 100644
index 4483c2c..0000000
--- a/drivers/staging/rtl8187se/ieee80211/dot11d.c
+++ /dev/null
@@ -1,189 +0,0 @@
-#include "dot11d.h"
-
-void Dot11d_Init(struct ieee80211_device *ieee)
-{
- PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(ieee);
-
- pDot11dInfo->bEnabled = 0;
-
- pDot11dInfo->State = DOT11D_STATE_NONE;
- pDot11dInfo->CountryIeLen = 0;
- memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
- memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
- RESET_CIE_WATCHDOG(ieee);
-
- netdev_info(ieee->dev, "Dot11d_Init()\n");
-}
-
-/* Reset to the state as we are just entering a regulatory domain. */
-void Dot11d_Reset(struct ieee80211_device *ieee)
-{
- u32 i;
- PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(ieee);
-
- /* Clear old channel map */
- memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
- memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
- /* Set new channel map */
- for (i = 1; i <= 11; i++)
- (pDot11dInfo->channel_map)[i] = 1;
-
- for (i = 12; i <= 14; i++)
- (pDot11dInfo->channel_map)[i] = 2;
-
- pDot11dInfo->State = DOT11D_STATE_NONE;
- pDot11dInfo->CountryIeLen = 0;
- RESET_CIE_WATCHDOG(ieee);
-}
-
-/*
- * Description:
- * Update country IE from Beacon or Probe Response and configure PHY for
- * operation in the regulatory domain.
- *
- * TODO:
- * Configure Tx power.
- *
- * Assumption:
- * 1. IS_DOT11D_ENABLE() is TRUE.
- * 2. Input IE is an valid one.
- */
-void Dot11d_UpdateCountryIe(struct ieee80211_device *dev, u8 *pTaddr,
- u16 CoutryIeLen, u8 *pCoutryIe)
-{
- PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
- u8 i, j, NumTriples, MaxChnlNum;
- u8 index, MaxTxPowerInDbm;
- PCHNL_TXPOWER_TRIPLE pTriple;
-
- if ((CoutryIeLen - 3)%3 != 0) {
- netdev_info(dev->dev, "Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n");
- Dot11d_Reset(dev);
- return;
- }
-
- memset(pDot11dInfo->channel_map, 0, MAX_CHANNEL_NUMBER+1);
- memset(pDot11dInfo->MaxTxPwrDbmList, 0xFF, MAX_CHANNEL_NUMBER+1);
- MaxChnlNum = 0;
- NumTriples = (CoutryIeLen - 3) / 3; /* skip 3-byte country string. */
- pTriple = (PCHNL_TXPOWER_TRIPLE)(pCoutryIe + 3);
- for (i = 0; i < NumTriples; i++) {
- if (MaxChnlNum >= pTriple->FirstChnl) {
- /*
- * It is not in a monotonically increasing order,
- * so stop processing.
- */
- netdev_info(dev->dev,
- "Dot11d_UpdateCountryIe(): Invalid country IE, skip it........1\n");
- Dot11d_Reset(dev);
- return;
- }
- if (MAX_CHANNEL_NUMBER <
- (pTriple->FirstChnl + pTriple->NumChnls)) {
- /*
- * It is not a valid set of channel id,
- * so stop processing
- */
- netdev_info(dev->dev,
- "Dot11d_UpdateCountryIe(): Invalid country IE, skip it........2\n");
- Dot11d_Reset(dev);
- return;
- }
-
- for (j = 0; j < pTriple->NumChnls; j++) {
- index = pTriple->FirstChnl + j;
- pDot11dInfo->channel_map[index] = 1;
- MaxTxPowerInDbm = pTriple->MaxTxPowerInDbm;
- pDot11dInfo->MaxTxPwrDbmList[index] = MaxTxPowerInDbm;
- MaxChnlNum = pTriple->FirstChnl + j;
- }
-
- pTriple = (PCHNL_TXPOWER_TRIPLE)((u8 *)pTriple + 3);
- }
-#if 1
- netdev_info(dev->dev, "Channel List:");
- for (i = 1; i <= MAX_CHANNEL_NUMBER; i++)
- if (pDot11dInfo->channel_map[i] > 0)
- netdev_info(dev->dev, " %d", i);
- netdev_info(dev->dev, "\n");
-#endif
-
- UPDATE_CIE_SRC(dev, pTaddr);
-
- pDot11dInfo->CountryIeLen = CoutryIeLen;
- memcpy(pDot11dInfo->CountryIeBuf, pCoutryIe, CoutryIeLen);
- pDot11dInfo->State = DOT11D_STATE_LEARNED;
-}
-
-u8 DOT11D_GetMaxTxPwrInDbm(struct ieee80211_device *dev, u8 Channel)
-{
- PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
- u8 MaxTxPwrInDbm = 255;
-
- if (MAX_CHANNEL_NUMBER < Channel) {
- netdev_info(dev->dev, "DOT11D_GetMaxTxPwrInDbm(): Invalid Channel\n");
- return MaxTxPwrInDbm;
- }
- if (pDot11dInfo->channel_map[Channel])
- MaxTxPwrInDbm = pDot11dInfo->MaxTxPwrDbmList[Channel];
-
- return MaxTxPwrInDbm;
-}
-
-
-void DOT11D_ScanComplete(struct ieee80211_device *dev)
-{
- PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
-
- switch (pDot11dInfo->State) {
- case DOT11D_STATE_LEARNED:
- pDot11dInfo->State = DOT11D_STATE_DONE;
- break;
-
- case DOT11D_STATE_DONE:
- if (GET_CIE_WATCHDOG(dev) == 0) {
- /* Reset country IE if previous one is gone. */
- Dot11d_Reset(dev);
- }
- break;
- case DOT11D_STATE_NONE:
- break;
- }
-}
-
-int IsLegalChannel(struct ieee80211_device *dev, u8 channel)
-{
- PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
-
- if (MAX_CHANNEL_NUMBER < channel) {
- netdev_info(dev->dev, "IsLegalChannel(): Invalid Channel\n");
- return 0;
- }
- if (pDot11dInfo->channel_map[channel] > 0)
- return 1;
- return 0;
-}
-
-int ToLegalChannel(struct ieee80211_device *dev, u8 channel)
-{
- PRT_DOT11D_INFO pDot11dInfo = GET_DOT11D_INFO(dev);
- u8 default_chn = 0;
- u32 i = 0;
-
- for (i = 1; i <= MAX_CHANNEL_NUMBER; i++) {
- if (pDot11dInfo->channel_map[i] > 0) {
- default_chn = i;
- break;
- }
- }
-
- if (MAX_CHANNEL_NUMBER < channel) {
- netdev_info(dev->dev, "IsLegalChannel(): Invalid Channel\n");
- return default_chn;
- }
-
- if (pDot11dInfo->channel_map[channel] > 0)
- return channel;
-
- return default_chn;
-}
diff --git a/drivers/staging/rtl8187se/ieee80211/dot11d.h b/drivers/staging/rtl8187se/ieee80211/dot11d.h
deleted file mode 100644
index f996691..0000000
--- a/drivers/staging/rtl8187se/ieee80211/dot11d.h
+++ /dev/null
@@ -1,71 +0,0 @@
-#ifndef __INC_DOT11D_H
-#define __INC_DOT11D_H
-
-#include "ieee80211.h"
-
-/* #define ENABLE_DOT11D */
-
-/* #define DOT11D_MAX_CHNL_NUM 83 */
-
-typedef struct _CHNL_TXPOWER_TRIPLE {
- u8 FirstChnl;
- u8 NumChnls;
- u8 MaxTxPowerInDbm;
-} CHNL_TXPOWER_TRIPLE, *PCHNL_TXPOWER_TRIPLE;
-
-typedef enum _DOT11D_STATE {
- DOT11D_STATE_NONE = 0,
- DOT11D_STATE_LEARNED,
- DOT11D_STATE_DONE,
-} DOT11D_STATE;
-
-typedef struct _RT_DOT11D_INFO {
- /* DECLARE_RT_OBJECT(RT_DOT12D_INFO); */
-
- bool bEnabled; /* dot11MultiDomainCapabilityEnabled */
-
- u16 CountryIeLen; /* > 0 if CountryIeBuf[] contains valid country information element. */
- u8 CountryIeBuf[MAX_IE_LEN];
- u8 CountryIeSrcAddr[6]; /* Source AP of the country IE. */
- u8 CountryIeWatchdog;
-
- u8 channel_map[MAX_CHANNEL_NUMBER+1]; /* !!!Value 0: Invalid, 1: Valid (active scan), 2: Valid (passive scan) */
- /* u8 ChnlListLen; // #Bytes valid in ChnlList[]. */
- /* u8 ChnlList[DOT11D_MAX_CHNL_NUM]; */
- u8 MaxTxPwrDbmList[MAX_CHANNEL_NUMBER+1];
-
- DOT11D_STATE State;
-} RT_DOT11D_INFO, *PRT_DOT11D_INFO;
-
-#define eqMacAddr(a, b) (((a)[0] == (b)[0] && (a)[1] == (b)[1] && (a)[2] == (b)[2] && (a)[3] == (b)[3] && (a)[4] == (b)[4] && (a)[5] == (b)[5]) ? 1:0)
-#define cpMacAddr(des, src) ((des)[0] = (src)[0], (des)[1] = (src)[1], (des)[2] = (src)[2], (des)[3] = (src)[3], (des)[4] = (src)[4], (des)[5] = (src)[5])
-#define GET_DOT11D_INFO(__pIeeeDev) ((PRT_DOT11D_INFO)((__pIeeeDev)->pDot11dInfo))
-
-#define IS_DOT11D_ENABLE(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->bEnabled
-#define IS_COUNTRY_IE_VALID(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen > 0)
-
-#define IS_EQUAL_CIE_SRC(__pIeeeDev, __pTa) eqMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
-#define UPDATE_CIE_SRC(__pIeeeDev, __pTa) cpMacAddr(GET_DOT11D_INFO(__pIeeeDev)->CountryIeSrcAddr, __pTa)
-
-#define IS_COUNTRY_IE_CHANGED(__pIeeeDev, __Ie) \
- (((__Ie).Length == 0 || (__Ie).Length != GET_DOT11D_INFO(__pIeeeDev)->CountryIeLen) ? \
- FALSE : \
- (!memcmp(GET_DOT11D_INFO(__pIeeeDev)->CountryIeBuf, (__Ie).Octet, (__Ie).Length)))
-
-#define CIE_WATCHDOG_TH 1
-#define GET_CIE_WATCHDOG(__pIeeeDev) GET_DOT11D_INFO(__pIeeeDev)->CountryIeWatchdog
-#define RESET_CIE_WATCHDOG(__pIeeeDev) GET_CIE_WATCHDOG(__pIeeeDev) = 0
-#define UPDATE_CIE_WATCHDOG(__pIeeeDev) ++GET_CIE_WATCHDOG(__pIeeeDev)
-
-#define IS_DOT11D_STATE_DONE(__pIeeeDev) (GET_DOT11D_INFO(__pIeeeDev)->State == DOT11D_STATE_DONE)
-
-void Dot11d_Init(struct ieee80211_device *dev);
-void Dot11d_Reset(struct ieee80211_device *dev);
-void Dot11d_UpdateCountryIe(struct ieee80211_device *dev, u8 *pTaddr,
- u16 CoutryIeLen, u8 *pCoutryIe);
-u8 DOT11D_GetMaxTxPwrInDbm(struct ieee80211_device *dev, u8 Channel);
-void DOT11D_ScanComplete(struct ieee80211_device *dev);
-int IsLegalChannel(struct ieee80211_device *dev, u8 channel);
-int ToLegalChannel(struct ieee80211_device *dev, u8 channel);
-
-#endif /* #ifndef __INC_DOT11D_H */
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211.h b/drivers/staging/rtl8187se/ieee80211/ieee80211.h
deleted file mode 100644
index d1763b7..0000000
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211.h
+++ /dev/null
@@ -1,1496 +0,0 @@
-/*
- * Merged with mainline ieee80211.h in Aug 2004. Original ieee802_11
- * remains copyright by the original authors
- *
- * Portions of the merged code are based on Host AP (software wireless
- * LAN access point) driver for Intersil Prism2/2.5/3.
- *
- * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
- * <jkmaline@cc.hut.fi>
- * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
- *
- * Adaption to a generic IEEE 802.11 stack by James Ketrenos
- * <jketreno@linux.intel.com>
- * Copyright (c) 2004, Intel Corporation
- *
- * Modified for Realtek's wi-fi cards by Andrea Merello
- * <andrea.merello@gmail.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. See README and COPYING for
- * more details.
- */
-#ifndef IEEE80211_H
-#define IEEE80211_H
-#include <linux/if_ether.h> /* ETH_ALEN */
-#include <linux/kernel.h> /* ARRAY_SIZE */
-#include <linux/jiffies.h>
-#include <linux/timer.h>
-#include <linux/sched.h>
-#include <linux/semaphore.h>
-#include <linux/wireless.h>
-#include <linux/ieee80211.h>
-#include <linux/interrupt.h>
-
-#define KEY_TYPE_NA 0x0
-#define KEY_TYPE_WEP40 0x1
-#define KEY_TYPE_TKIP 0x2
-#define KEY_TYPE_CCMP 0x4
-#define KEY_TYPE_WEP104 0x5
-
-#define aSifsTime 10
-
-#define MGMT_QUEUE_NUM 5
-
-
-#define IEEE_CMD_SET_WPA_PARAM 1
-#define IEEE_CMD_SET_WPA_IE 2
-#define IEEE_CMD_SET_ENCRYPTION 3
-#define IEEE_CMD_MLME 4
-
-#define IEEE_PARAM_WPA_ENABLED 1
-#define IEEE_PARAM_TKIP_COUNTERMEASURES 2
-#define IEEE_PARAM_DROP_UNENCRYPTED 3
-#define IEEE_PARAM_PRIVACY_INVOKED 4
-#define IEEE_PARAM_AUTH_ALGS 5
-#define IEEE_PARAM_IEEE_802_1X 6
-//It should consistent with the driver_XXX.c
-// David, 2006.9.26
-#define IEEE_PARAM_WPAX_SELECT 7
-//Added for notify the encryption type selection
-// David, 2006.9.26
-#define IEEE_PROTO_WPA 1
-#define IEEE_PROTO_RSN 2
-//Added for notify the encryption type selection
-// David, 2006.9.26
-#define IEEE_WPAX_USEGROUP 0
-#define IEEE_WPAX_WEP40 1
-#define IEEE_WPAX_TKIP 2
-#define IEEE_WPAX_WRAP 3
-#define IEEE_WPAX_CCMP 4
-#define IEEE_WPAX_WEP104 5
-
-#define IEEE_KEY_MGMT_IEEE8021X 1
-#define IEEE_KEY_MGMT_PSK 2
-
-
-
-#define IEEE_MLME_STA_DEAUTH 1
-#define IEEE_MLME_STA_DISASSOC 2
-
-
-#define IEEE_CRYPT_ERR_UNKNOWN_ALG 2
-#define IEEE_CRYPT_ERR_UNKNOWN_ADDR 3
-#define IEEE_CRYPT_ERR_CRYPT_INIT_FAILED 4
-#define IEEE_CRYPT_ERR_KEY_SET_FAILED 5
-#define IEEE_CRYPT_ERR_TX_KEY_SET_FAILED 6
-#define IEEE_CRYPT_ERR_CARD_CONF_FAILED 7
-
-
-#define IEEE_CRYPT_ALG_NAME_LEN 16
-
-extern int ieee80211_crypto_tkip_init(void);
-extern void ieee80211_crypto_tkip_exit(void);
-
-//by amy for ps
-typedef 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;
-
- } u;
-}ieee_param;
-
-
-#define MSECS(t) msecs_to_jiffies(t)
-#define msleep_interruptible_rtl msleep_interruptible
-
-#define IEEE80211_DATA_LEN 2304
-/* Maximum size for the MA-UNITDATA primitive, 802.11 standard section
- 6.2.1.1.2.
-
- The figure in section 7.1.2 suggests a body size of up to 2312
- bytes is allowed, which is a bit confusing, I suspect this
- represents the 2304 bytes of real data, plus a possible 8 bytes of
- WEP IV and ICV. (this interpretation suggested by Ramiro Barreiro) */
-
-#define IEEE80211_3ADDR_LEN 24
-#define IEEE80211_4ADDR_LEN 30
-#define IEEE80211_FCS_LEN 4
-#define IEEE80211_HLEN IEEE80211_4ADDR_LEN
-#define IEEE80211_FRAME_LEN (IEEE80211_DATA_LEN + IEEE80211_HLEN)
-#define IEEE80211_MGMT_HDR_LEN 24
-#define IEEE80211_DATA_HDR3_LEN 24
-#define IEEE80211_DATA_HDR4_LEN 30
-
-#define MIN_FRAG_THRESHOLD 256U
-#define MAX_FRAG_THRESHOLD 2346U
-
-/* Frame control field constants */
-#define IEEE80211_FCTL_DSTODS 0x0300 //added by david
-#define IEEE80211_FCTL_WEP 0x4000
-
-/* debug macros */
-
-#ifdef CONFIG_IEEE80211_DEBUG
-extern u32 ieee80211_debug_level;
-#define IEEE80211_DEBUG(level, fmt, args...) \
-do { if (ieee80211_debug_level & (level)) \
- printk(KERN_DEBUG "ieee80211: %c %s " fmt, \
- in_interrupt() ? 'I' : 'U', __func__ , ## args); } while (0)
-#else
-#define IEEE80211_DEBUG(level, fmt, args...) do {} while (0)
-#endif /* CONFIG_IEEE80211_DEBUG */
-
-/*
- * To use the debug system;
- *
- * If you are defining a new debug classification, simply add it to the #define
- * list here in the form of:
- *
- * #define IEEE80211_DL_xxxx VALUE
- *
- * shifting value to the left one bit from the previous entry. xxxx should be
- * the name of the classification (for example, WEP)
- *
- * You then need to either add a IEEE80211_xxxx_DEBUG() macro definition for your
- * classification, or use IEEE80211_DEBUG(IEEE80211_DL_xxxx, ...) whenever you want
- * to send output to that classification.
- *
- * To add your debug level to the list of levels seen when you perform
- *
- * % cat /proc/net/ipw/debug_level
- *
- * you simply need to add your entry to the ipw_debug_levels array.
- *
- * If you do not see debug_level in /proc/net/ipw then you do not have
- * CONFIG_IEEE80211_DEBUG defined in your kernel configuration
- *
- */
-
-#define IEEE80211_DL_INFO (1<<0)
-#define IEEE80211_DL_WX (1<<1)
-#define IEEE80211_DL_SCAN (1<<2)
-#define IEEE80211_DL_STATE (1<<3)
-#define IEEE80211_DL_MGMT (1<<4)
-#define IEEE80211_DL_FRAG (1<<5)
-#define IEEE80211_DL_EAP (1<<6)
-#define IEEE80211_DL_DROP (1<<7)
-
-#define IEEE80211_DL_TX (1<<8)
-#define IEEE80211_DL_RX (1<<9)
-
-#define IEEE80211_ERROR(f, a...) printk(KERN_ERR "ieee80211: " f, ## a)
-#define IEEE80211_WARNING(f, a...) printk(KERN_WARNING "ieee80211: " f, ## a)
-#define IEEE80211_DEBUG_INFO(f, a...) IEEE80211_DEBUG(IEEE80211_DL_INFO, f, ## a)
-
-#define IEEE80211_DEBUG_WX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_WX, f, ## a)
-#define IEEE80211_DEBUG_SCAN(f, a...) IEEE80211_DEBUG(IEEE80211_DL_SCAN, f, ## a)
-//#define IEEE_DEBUG_SCAN IEEE80211_WARNING
-#define IEEE80211_DEBUG_STATE(f, a...) IEEE80211_DEBUG(IEEE80211_DL_STATE, f, ## a)
-#define IEEE80211_DEBUG_MGMT(f, a...) IEEE80211_DEBUG(IEEE80211_DL_MGMT, f, ## a)
-#define IEEE80211_DEBUG_FRAG(f, a...) IEEE80211_DEBUG(IEEE80211_DL_FRAG, f, ## a)
-#define IEEE80211_DEBUG_EAP(f, a...) IEEE80211_DEBUG(IEEE80211_DL_EAP, f, ## a)
-#define IEEE80211_DEBUG_DROP(f, a...) IEEE80211_DEBUG(IEEE80211_DL_DROP, f, ## a)
-#define IEEE80211_DEBUG_TX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_TX, f, ## a)
-#define IEEE80211_DEBUG_RX(f, a...) IEEE80211_DEBUG(IEEE80211_DL_RX, f, ## a)
-#include <linux/netdevice.h>
-#include <linux/if_arp.h> /* ARPHRD_ETHER */
-
-#ifndef WIRELESS_SPY
-#define WIRELESS_SPY // enable iwspy support
-#endif
-#include <net/iw_handler.h> // new driver API
-
-#ifndef ETH_P_PAE
-#define ETH_P_PAE 0x888E /* Port Access Entity (IEEE 802.1X) */
-#endif /* ETH_P_PAE */
-
-#define ETH_P_PREAUTH 0x88C7 /* IEEE 802.11i pre-authentication */
-
-#ifndef ETH_P_80211_RAW
-#define ETH_P_80211_RAW (ETH_P_ECONET + 1)
-#endif
-
-/* IEEE 802.11 defines */
-
-#define P80211_OUI_LEN 3
-
-struct ieee80211_snap_hdr {
-
- u8 dsap; /* always 0xAA */
- u8 ssap; /* always 0xAA */
- u8 ctrl; /* always 0x03 */
- u8 oui[P80211_OUI_LEN]; /* organizational universal id */
-
-} __attribute__ ((packed));
-
-#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_GET_SEQ_FRAG(seq) ((seq) & IEEE80211_SCTL_FRAG)
-#define WLAN_GET_SEQ_SEQ(seq) ((seq) & IEEE80211_SCTL_SEQ)
-
-#define WLAN_CAPABILITY_BSS (1<<0)
-#define WLAN_CAPABILITY_SHORT_SLOT (1<<10)
-
-#define IEEE80211_STATMASK_SIGNAL (1<<0)
-#define IEEE80211_STATMASK_RSSI (1<<1)
-#define IEEE80211_STATMASK_NOISE (1<<2)
-#define IEEE80211_STATMASK_RATE (1<<3)
-#define IEEE80211_STATMASK_WEMASK 0x7
-
-
-#define IEEE80211_CCK_MODULATION (1<<0)
-#define IEEE80211_OFDM_MODULATION (1<<1)
-
-#define IEEE80211_24GHZ_BAND (1<<0)
-#define IEEE80211_52GHZ_BAND (1<<1)
-
-#define IEEE80211_CCK_RATE_LEN 4
-#define IEEE80211_CCK_RATE_1MB 0x02
-#define IEEE80211_CCK_RATE_2MB 0x04
-#define IEEE80211_CCK_RATE_5MB 0x0B
-#define IEEE80211_CCK_RATE_11MB 0x16
-#define IEEE80211_OFDM_RATE_LEN 8
-#define IEEE80211_OFDM_RATE_6MB 0x0C
-#define IEEE80211_OFDM_RATE_9MB 0x12
-#define IEEE80211_OFDM_RATE_12MB 0x18
-#define IEEE80211_OFDM_RATE_18MB 0x24
-#define IEEE80211_OFDM_RATE_24MB 0x30
-#define IEEE80211_OFDM_RATE_36MB 0x48
-#define IEEE80211_OFDM_RATE_48MB 0x60
-#define IEEE80211_OFDM_RATE_54MB 0x6C
-#define IEEE80211_BASIC_RATE_MASK 0x80
-
-#define IEEE80211_CCK_RATE_1MB_MASK (1<<0)
-#define IEEE80211_CCK_RATE_2MB_MASK (1<<1)
-#define IEEE80211_CCK_RATE_5MB_MASK (1<<2)
-#define IEEE80211_CCK_RATE_11MB_MASK (1<<3)
-#define IEEE80211_OFDM_RATE_6MB_MASK (1<<4)
-#define IEEE80211_OFDM_RATE_9MB_MASK (1<<5)
-#define IEEE80211_OFDM_RATE_12MB_MASK (1<<6)
-#define IEEE80211_OFDM_RATE_18MB_MASK (1<<7)
-#define IEEE80211_OFDM_RATE_24MB_MASK (1<<8)
-#define IEEE80211_OFDM_RATE_36MB_MASK (1<<9)
-#define IEEE80211_OFDM_RATE_48MB_MASK (1<<10)
-#define IEEE80211_OFDM_RATE_54MB_MASK (1<<11)
-
-#define IEEE80211_CCK_RATES_MASK 0x0000000F
-#define IEEE80211_CCK_BASIC_RATES_MASK (IEEE80211_CCK_RATE_1MB_MASK | \
- IEEE80211_CCK_RATE_2MB_MASK)
-#define IEEE80211_CCK_DEFAULT_RATES_MASK (IEEE80211_CCK_BASIC_RATES_MASK | \
- IEEE80211_CCK_RATE_5MB_MASK | \
- IEEE80211_CCK_RATE_11MB_MASK)
-
-#define IEEE80211_OFDM_RATES_MASK 0x00000FF0
-#define IEEE80211_OFDM_BASIC_RATES_MASK (IEEE80211_OFDM_RATE_6MB_MASK | \
- IEEE80211_OFDM_RATE_12MB_MASK | \
- IEEE80211_OFDM_RATE_24MB_MASK)
-#define IEEE80211_OFDM_DEFAULT_RATES_MASK (IEEE80211_OFDM_BASIC_RATES_MASK | \
- IEEE80211_OFDM_RATE_9MB_MASK | \
- IEEE80211_OFDM_RATE_18MB_MASK | \
- IEEE80211_OFDM_RATE_36MB_MASK | \
- IEEE80211_OFDM_RATE_48MB_MASK | \
- IEEE80211_OFDM_RATE_54MB_MASK)
-#define IEEE80211_DEFAULT_RATES_MASK (IEEE80211_OFDM_DEFAULT_RATES_MASK | \
- IEEE80211_CCK_DEFAULT_RATES_MASK)
-
-#define IEEE80211_NUM_OFDM_RATES 8
-#define IEEE80211_NUM_CCK_RATES 4
-#define IEEE80211_OFDM_SHIFT_MASK_A 4
-
-/* this is stolen and modified from the madwifi driver*/
-#define IEEE80211_FC0_TYPE_MASK 0x0c
-#define IEEE80211_FC0_TYPE_DATA 0x08
-#define IEEE80211_FC0_SUBTYPE_MASK 0xB0
-#define IEEE80211_FC0_SUBTYPE_QOS 0x80
-
-#define IEEE80211_QOS_HAS_SEQ(fc) \
- (((fc) & (IEEE80211_FC0_TYPE_MASK | IEEE80211_FC0_SUBTYPE_MASK)) == \
- (IEEE80211_FC0_TYPE_DATA | IEEE80211_FC0_SUBTYPE_QOS))
-
-/* this is stolen from ipw2200 driver */
-#define IEEE_IBSS_MAC_HASH_SIZE 31
-struct ieee_ibss_seq {
- u8 mac[ETH_ALEN];
- u16 seq_num[17];
- u16 frag_num[17];
- unsigned long packet_time[17];
- struct list_head list;
-};
-
-/* NOTE: This data is for statistical purposes; not all hardware provides this
- * information for frames received. Not setting these will not cause
- * any adverse affects. */
-struct ieee80211_rx_stats {
- u32 mac_time[2];
- u8 signalstrength;
- s8 rssi;
- u8 signal;
- u8 noise;
- u16 rate; /* in 100 kbps */
- u8 received_channel;
- u8 control;
- u8 mask;
- u8 freq;
- u16 len;
- u8 nic_type;
-};
-
-/* IEEE 802.11 requires that STA supports concurrent reception of at least
- * three fragmented frames. This define can be increased to support more
- * concurrent frames, but it should be noted that each entry can consume about
- * 2 kB of RAM and increasing cache size will slow down frame reassembly. */
-#define IEEE80211_FRAG_CACHE_LEN 4
-
-struct ieee80211_frag_entry {
- unsigned long first_frag_time;
- unsigned int seq;
- unsigned int last_frag;
- struct sk_buff *skb;
- u8 src_addr[ETH_ALEN];
- u8 dst_addr[ETH_ALEN];
-};
-
-struct ieee80211_stats {
- unsigned int tx_unicast_frames;
- unsigned int tx_multicast_frames;
- unsigned int tx_fragments;
- unsigned int tx_unicast_octets;
- unsigned int tx_multicast_octets;
- unsigned int tx_deferred_transmissions;
- unsigned int tx_single_retry_frames;
- unsigned int tx_multiple_retry_frames;
- unsigned int tx_retry_limit_exceeded;
- unsigned int tx_discards;
- unsigned int rx_unicast_frames;
- unsigned int rx_multicast_frames;
- unsigned int rx_fragments;
- unsigned int rx_unicast_octets;
- unsigned int rx_multicast_octets;
- unsigned int rx_fcs_errors;
- unsigned int rx_discards_no_buffer;
- unsigned int tx_discards_wrong_sa;
- unsigned int rx_discards_undecryptable;
- unsigned int rx_message_in_msg_fragments;
- unsigned int rx_message_in_bad_msg_fragments;
-};
-
-struct ieee80211_device;
-
-#include "ieee80211_crypt.h"
-
-#define SEC_KEY_1 (1<<0)
-#define SEC_KEY_2 (1<<1)
-#define SEC_KEY_3 (1<<2)
-#define SEC_KEY_4 (1<<3)
-#define SEC_ACTIVE_KEY (1<<4)
-#define SEC_AUTH_MODE (1<<5)
-#define SEC_UNICAST_GROUP (1<<6)
-#define SEC_LEVEL (1<<7)
-#define SEC_ENABLED (1<<8)
-
-#define SEC_LEVEL_0 0 /* None */
-#define SEC_LEVEL_1 1 /* WEP 40 and 104 bit */
-#define SEC_LEVEL_2 2 /* Level 1 + TKIP */
-#define SEC_LEVEL_2_CKIP 3 /* Level 1 + CKIP */
-#define SEC_LEVEL_3 4 /* Level 2 + CCMP */
-
-#define WEP_KEYS 4
-#define WEP_KEY_LEN 13
-
-#define WEP_KEY_LEN_MODIF 32
-
-struct ieee80211_security {
- u16 active_key:2,
- enabled:1,
- auth_mode:2,
- auth_algo:4,
- unicast_uses_group:1;
- u8 key_sizes[WEP_KEYS];
- u8 keys[WEP_KEYS][WEP_KEY_LEN_MODIF];
- u8 level;
- u16 flags;
-} __attribute__ ((packed));
-
-
-/*
-
- 802.11 data frame from AP
-
- ,-------------------------------------------------------------------.
-Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 |
- |------|------|---------|---------|---------|------|---------|------|
-Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | frame | fcs |
- | | tion | (BSSID) | | | ence | data | |
- `-------------------------------------------------------------------'
-
-Total: 28-2340 bytes
-
-*/
-
-/* Management Frame Information Element Types */
-enum {
- MFIE_TYPE_SSID = 0,
- MFIE_TYPE_RATES = 1,
- MFIE_TYPE_FH_SET = 2,
- MFIE_TYPE_DS_SET = 3,
- MFIE_TYPE_CF_SET = 4,
- MFIE_TYPE_TIM = 5,
- MFIE_TYPE_IBSS_SET = 6,
- MFIE_TYPE_COUNTRY = 7,
- MFIE_TYPE_CHALLENGE = 16,
- MFIE_TYPE_ERP = 42,
- MFIE_TYPE_RSN = 48,
- MFIE_TYPE_RATES_EX = 50,
- MFIE_TYPE_GENERIC = 221,
-};
-
-struct ieee80211_header_data {
- __le16 frame_ctl;
- u16 duration_id;
- u8 addr1[6];
- u8 addr2[6];
- u8 addr3[6];
- u16 seq_ctrl;
-};
-
-struct ieee80211_hdr_4addr {
- __le16 frame_ctl;
- u16 duration_id;
- u8 addr1[ETH_ALEN];
- u8 addr2[ETH_ALEN];
- u8 addr3[ETH_ALEN];
- u16 seq_ctl;
- u8 addr4[ETH_ALEN];
-} __attribute__ ((packed));
-
-struct ieee80211_hdr_3addrqos {
- u16 frame_ctl;
- u16 duration_id;
- u8 addr1[ETH_ALEN];
- u8 addr2[ETH_ALEN];
- u8 addr3[ETH_ALEN];
- u16 seq_ctl;
- u16 qos_ctl;
-} __attribute__ ((packed));
-
-struct ieee80211_hdr_4addrqos {
- u16 frame_ctl;
- u16 duration_id;
- u8 addr1[ETH_ALEN];
- u8 addr2[ETH_ALEN];
- u8 addr3[ETH_ALEN];
- u16 seq_ctl;
- u8 addr4[ETH_ALEN];
- u16 qos_ctl;
-} __attribute__ ((packed));
-
-struct ieee80211_info_element_hdr {
- u8 id;
- u8 len;
-} __attribute__ ((packed));
-
-struct ieee80211_info_element {
- u8 id;
- u8 len;
- u8 data[0];
-} __attribute__ ((packed));
-
-struct ieee80211_authentication {
- struct ieee80211_header_data header;
- u16 algorithm;
- u16 transaction;
- u16 status;
- //struct ieee80211_info_element_hdr info_element;
-} __attribute__ ((packed));
-
-struct ieee80211_disassoc_frame {
- struct ieee80211_hdr_3addr header;
- u16 reasoncode;
-} __attribute__ ((packed));
-
-struct ieee80211_probe_request {
- struct ieee80211_header_data header;
- /* struct ieee80211_info_element info_element; */
-} __attribute__ ((packed));
-
-struct ieee80211_probe_response {
- struct ieee80211_header_data header;
- u32 time_stamp[2];
- u16 beacon_interval;
- u16 capability;
- struct ieee80211_info_element info_element;
-} __attribute__ ((packed));
-
-struct ieee80211_assoc_request_frame {
- struct ieee80211_hdr_3addr header;
- u16 capability;
- u16 listen_interval;
- //u8 current_ap[ETH_ALEN];
- struct ieee80211_info_element_hdr info_element;
-} __attribute__ ((packed));
-
-struct ieee80211_assoc_response_frame {
- struct ieee80211_hdr_3addr header;
- u16 capability;
- u16 status;
- u16 aid;
- struct ieee80211_info_element info_element; /* supported rates */
-} __attribute__ ((packed));
-
-struct ieee80211_txb {
- u8 nr_frags;
- u8 encrypted;
- u16 reserved;
- u16 frag_size;
- u16 payload_size;
- struct sk_buff *fragments[0];
-};
-
-/* SWEEP TABLE ENTRIES NUMBER */
-#define MAX_SWEEP_TAB_ENTRIES 42
-#define MAX_SWEEP_TAB_ENTRIES_PER_PACKET 7
-
-/* MAX_RATES_LENGTH needs to be 12. The spec says 8, and many APs
- * only use 8, and then use extended rates for the remaining supported
- * rates. Other APs, however, stick all of their supported rates on the
- * main rates information element... */
-#define MAX_RATES_LENGTH ((u8)12)
-#define MAX_RATES_EX_LENGTH ((u8)16)
-
-#define MAX_NETWORK_COUNT 128
-
-#define MAX_CHANNEL_NUMBER 165
-
-#define IEEE80211_SOFTMAC_SCAN_TIME 100 /* (HZ / 2) */
-#define IEEE80211_SOFTMAC_ASSOC_RETRY_TIME (HZ * 2)
-
-#define CRC_LENGTH 4U
-
-#define MAX_WPA_IE_LEN 64
-
-#define NETWORK_EMPTY_ESSID (1 << 0)
-#define NETWORK_HAS_OFDM (1 << 1)
-#define NETWORK_HAS_CCK (1 << 2)
-
-struct ieee80211_wmm_ac_param {
- u8 ac_aci_acm_aifsn;
- u8 ac_ecwmin_ecwmax;
- u16 ac_txop_limit;
-};
-
-struct ieee80211_wmm_ts_info {
- u8 ac_dir_tid;
- u8 ac_up_psb;
- u8 reserved;
-} __attribute__ ((packed));
-
-struct ieee80211_wmm_tspec_elem {
- struct ieee80211_wmm_ts_info ts_info;
- u16 norm_msdu_size;
- u16 max_msdu_size;
- u32 min_serv_inter;
- u32 max_serv_inter;
- u32 inact_inter;
- u32 suspen_inter;
- u32 serv_start_time;
- u32 min_data_rate;
- u32 mean_data_rate;
- u32 peak_data_rate;
- u32 max_burst_size;
- u32 delay_bound;
- u32 min_phy_rate;
- u16 surp_band_allow;
- u16 medium_time;
-}__attribute__((packed));
-
-enum eap_type {
- EAP_PACKET = 0,
- EAPOL_START,
- EAPOL_LOGOFF,
- EAPOL_KEY,
- EAPOL_ENCAP_ASF_ALERT
-};
-
-static const char *eap_types[] = {
- [EAP_PACKET] = "EAP-Packet",
- [EAPOL_START] = "EAPOL-Start",
- [EAPOL_LOGOFF] = "EAPOL-Logoff",
- [EAPOL_KEY] = "EAPOL-Key",
- [EAPOL_ENCAP_ASF_ALERT] = "EAPOL-Encap-ASF-Alert"
-};
-
-static inline const char *eap_get_type(int type)
-{
- return (type >= ARRAY_SIZE(eap_types)) ? "Unknown" : eap_types[type];
-}
-
-struct eapol {
- u8 snap[6];
- u16 ethertype;
- u8 version;
- u8 type;
- u16 length;
-} __attribute__ ((packed));
-
-struct ieee80211_softmac_stats {
- unsigned int rx_ass_ok;
- unsigned int rx_ass_err;
- unsigned int rx_probe_rq;
- unsigned int tx_probe_rs;
- unsigned int tx_beacons;
- unsigned int rx_auth_rq;
- unsigned int rx_auth_rs_ok;
- unsigned int rx_auth_rs_err;
- unsigned int tx_auth_rq;
- unsigned int no_auth_rs;
- unsigned int no_ass_rs;
- unsigned int tx_ass_rq;
- unsigned int rx_ass_rq;
- unsigned int tx_probe_rq;
- unsigned int reassoc;
- unsigned int swtxstop;
- unsigned int swtxawake;
-};
-
-#define BEACON_PROBE_SSID_ID_POSITION 12
-
-/*
- * These are the data types that can make up management packets
- *
- u16 auth_algorithm;
- u16 auth_sequence;
- u16 beacon_interval;
- u16 capability;
- u8 current_ap[ETH_ALEN];
- u16 listen_interval;
- struct {
- u16 association_id:14, reserved:2;
- } __attribute__ ((packed));
- u32 time_stamp[2];
- u16 reason;
- u16 status;
-*/
-
-#define IEEE80211_DEFAULT_TX_ESSID "Penguin"
-#define IEEE80211_DEFAULT_BASIC_RATE 10
-
-enum {WMM_all_frame, WMM_two_frame, WMM_four_frame, WMM_six_frame};
-#define MAX_SP_Len (WMM_all_frame << 4)
-#define IEEE80211_QOS_TID 0x0f
-#define QOS_CTL_NOTCONTAIN_ACK (0x01 << 5)
-
-#define MAX_IE_LEN 0xFF //+YJ,080625
-
-struct rtl8187se_channel_list {
- u8 channel[MAX_CHANNEL_NUMBER + 1];
- u8 len;
-};
-
-//by amy for ps
-#define IEEE80211_WATCH_DOG_TIME 2000
-//by amy for ps
-//by amy for antenna
-#define ANTENNA_DIVERSITY_TIMER_PERIOD 1000 // 1000 m
-//by amy for antenna
-
-#define IEEE80211_DTIM_MBCAST 4
-#define IEEE80211_DTIM_UCAST 2
-#define IEEE80211_DTIM_VALID 1
-#define IEEE80211_DTIM_INVALID 0
-
-#define IEEE80211_PS_DISABLED 0
-#define IEEE80211_PS_UNICAST IEEE80211_DTIM_UCAST
-#define IEEE80211_PS_MBCAST IEEE80211_DTIM_MBCAST
-#define IEEE80211_PS_ENABLE IEEE80211_DTIM_VALID
-//added by David for QoS 2006/6/30
-//#define WMM_Hang_8187
-#ifdef WMM_Hang_8187
-#undef WMM_Hang_8187
-#endif
-
-#define WME_AC_BE 0x00
-#define WME_AC_BK 0x01
-#define WME_AC_VI 0x02
-#define WME_AC_VO 0x03
-#define WME_ACI_MASK 0x03
-#define WME_AIFSN_MASK 0x03
-#define WME_AC_PRAM_LEN 16
-
-//UP Mapping to AC, using in MgntQuery_SequenceNumber() and maybe for DSCP
-//#define UP2AC(up) ((up<3) ? ((up==0)?1:0) : (up>>1))
-#define UP2AC(up) ( \
- ((up) < 1) ? WME_AC_BE : \
- ((up) < 3) ? WME_AC_BK : \
- ((up) < 4) ? WME_AC_BE : \
- ((up) < 6) ? WME_AC_VI : \
- WME_AC_VO)
-//AC Mapping to UP, using in Tx part for selecting the corresponding TX queue
-#define AC2UP(_ac) ( \
- ((_ac) == WME_AC_VO) ? 6 : \
- ((_ac) == WME_AC_VI) ? 5 : \
- ((_ac) == WME_AC_BK) ? 1 : \
- 0)
-
-#define ETHER_ADDR_LEN 6 /* length of an Ethernet address */
-struct ether_header {
- u8 ether_dhost[ETHER_ADDR_LEN];
- u8 ether_shost[ETHER_ADDR_LEN];
- u16 ether_type;
-} __attribute__((packed));
-
-#ifndef ETHERTYPE_PAE
-#define ETHERTYPE_PAE 0x888e /* EAPOL PAE/802.1x */
-#endif
-#ifndef ETHERTYPE_IP
-#define ETHERTYPE_IP 0x0800 /* IP protocol */
-#endif
-
-struct ieee80211_network {
- /* These entries are used to identify a unique network */
- u8 bssid[ETH_ALEN];
- u8 channel;
- /* Ensure null-terminated for any debug msgs */
- u8 ssid[IW_ESSID_MAX_SIZE + 1];
- u8 ssid_len;
-
- /* These are network statistics */
- struct ieee80211_rx_stats stats;
- u16 capability;
- u8 rates[MAX_RATES_LENGTH];
- u8 rates_len;
- u8 rates_ex[MAX_RATES_EX_LENGTH];
- u8 rates_ex_len;
- unsigned long last_scanned;
- u8 mode;
- u8 flags;
- u32 last_associate;
- u32 time_stamp[2];
- u16 beacon_interval;
- u16 listen_interval;
- u16 atim_window;
- u8 wpa_ie[MAX_WPA_IE_LEN];
- size_t wpa_ie_len;
- u8 rsn_ie[MAX_WPA_IE_LEN];
- size_t rsn_ie_len;
- u8 dtim_period;
- u8 dtim_data;
- u32 last_dtim_sta_time[2];
- struct list_head list;
- //appeded for QoS
- u8 wmm_info;
- struct ieee80211_wmm_ac_param wmm_param[4];
- u8 QoS_Enable;
- u8 SignalStrength;
-//by amy 080312
- u8 HighestOperaRate;
-//by amy 080312
- u8 Turbo_Enable;//enable turbo mode, added by thomas
- u16 CountryIeLen;
- u8 CountryIeBuf[MAX_IE_LEN];
-};
-
-enum ieee80211_state {
-
- /* the card is not linked at all */
- IEEE80211_NOLINK = 0,
-
- /* IEEE80211_ASSOCIATING* are for BSS client mode
- * the driver shall not perform RX filtering unless
- * the state is LINKED.
- * The driver shall just check for the state LINKED and
- * defaults to NOLINK for ALL the other states (including
- * LINKED_SCANNING)
- */
-
- /* the association procedure will start (wq scheduling)*/
- IEEE80211_ASSOCIATING,
- IEEE80211_ASSOCIATING_RETRY,
-
- /* the association procedure is sending AUTH request*/
- IEEE80211_ASSOCIATING_AUTHENTICATING,
-
- /* the association procedure has successfully authenticated
- * and is sending association request
- */
- IEEE80211_ASSOCIATING_AUTHENTICATED,
-
- /* the link is ok. the card associated to a BSS or linked
- * to a ibss cell or acting as an AP and creating the bss
- */
- IEEE80211_LINKED,
-
- /* same as LINKED, but the driver shall apply RX filter
- * rules as we are in NO_LINK mode. As the card is still
- * logically linked, but it is doing a syncro site survey
- * then it will be back to LINKED state.
- */
- IEEE80211_LINKED_SCANNING,
-
-};
-
-#define DEFAULT_MAX_SCAN_AGE (15 * HZ)
-#define DEFAULT_FTS 2346
-
-#define CFG_IEEE80211_RESERVE_FCS (1<<0)
-#define CFG_IEEE80211_COMPUTE_FCS (1<<1)
-
-typedef struct tx_pending_t{
- int frag;
- struct ieee80211_txb *txb;
-}tx_pending_t;
-
-enum {
- COUNTRY_CODE_FCC = 0,
- COUNTRY_CODE_IC = 1,
- COUNTRY_CODE_ETSI = 2,
- COUNTRY_CODE_SPAIN = 3,
- COUNTRY_CODE_FRANCE = 4,
- COUNTRY_CODE_MKK = 5,
- COUNTRY_CODE_MKK1 = 6,
- COUNTRY_CODE_ISRAEL = 7,
- COUNTRY_CODE_TELEC = 8,
- COUNTRY_CODE_GLOBAL_DOMAIN = 9,
- COUNTRY_CODE_WORLD_WIDE_13_INDEX = 10
-};
-
-struct ieee80211_device {
- struct net_device *dev;
-
- /* Bookkeeping structures */
- struct net_device_stats stats;
- struct ieee80211_stats ieee_stats;
- struct ieee80211_softmac_stats softmac_stats;
-
- /* Probe / Beacon management */
- struct list_head network_free_list;
- struct list_head network_list;
- struct ieee80211_network *networks;
- int scans;
- int scan_age;
-
- int iw_mode; /* operating mode (IW_MODE_*) */
-
- spinlock_t lock;
- spinlock_t wpax_suitlist_lock;
-
- int tx_headroom; /* Set to size of any additional room needed at front
- * of allocated Tx SKBs */
- u32 config;
-
- /* WEP and other encryption related settings at the device level */
- int open_wep; /* Set to 1 to allow unencrypted frames */
-
- int reset_on_keychange; /* Set to 1 if the HW needs to be reset on
- * WEP key changes */
-
- /* If the host performs {en,de}cryption, then set to 1 */
- int host_encrypt;
- int host_decrypt;
- int ieee802_1x; /* is IEEE 802.1X used */
-
- /* WPA data */
- int wpa_enabled;
- int drop_unencrypted;
- int tkip_countermeasures;
- int privacy_invoked;
- size_t wpa_ie_len;
- u8 *wpa_ie;
-
- u8 ap_mac_addr[6];
- u16 pairwise_key_type;
- u16 broadcast_key_type;
-
- struct list_head crypt_deinit_list;
- struct ieee80211_crypt_data *crypt[WEP_KEYS];
- int tx_keyidx; /* default TX key index (crypt[tx_keyidx]) */
- struct timer_list crypt_deinit_timer;
-
- int bcrx_sta_key; /* use individual keys to override default keys even
- * with RX of broad/multicast frames */
-
- /* Fragmentation structures */
- /* each stream contains an entry */
- struct ieee80211_frag_entry frag_cache[17][IEEE80211_FRAG_CACHE_LEN];
- unsigned int frag_next_idx[17];
- u16 fts; /* Fragmentation Threshold */
-
- /* This stores infos for the current network.
- * Either the network we are associated in INFRASTRUCTURE
- * or the network that we are creating in MASTER mode.
- * ad-hoc is a mixture ;-).
- * Note that in infrastructure mode, even when not associated,
- * fields bssid and essid may be valid (if wpa_set and essid_set
- * are true) as thy carry the value set by the user via iwconfig
- */
- struct ieee80211_network current_network;
-
-
- enum ieee80211_state state;
-
- int short_slot;
- int mode; /* A, B, G */
- int modulation; /* CCK, OFDM */
- int freq_band; /* 2.4Ghz, 5.2Ghz, Mixed */
- int abg_true; /* ABG flag */
-
- /* used for forcing the ibss workqueue to terminate
- * without wait for the syncro scan to terminate
- */
- short sync_scan_hurryup;
-
- void * pDot11dInfo;
- bool bGlobalDomain;
-
- // For Liteon Ch12~13 passive scan
- u8 MinPassiveChnlNum;
- u8 IbssStartChnl;
-
- int rate; /* current rate */
- int basic_rate;
- //FIXME: please callback, see if redundant with softmac_features
- short active_scan;
-
- /* this contains flags for selectively enable softmac support */
- u16 softmac_features;
-
- /* if the sequence control field is not filled by HW */
- u16 seq_ctrl[5];
-
- /* association procedure transaction sequence number */
- u16 associate_seq;
-
- /* AID for RTXed association responses */
- u16 assoc_id;
-
- /* power save mode related*/
- short ps;
- short sta_sleep;
- int ps_timeout;
- struct tasklet_struct ps_task;
- u32 ps_th;
- u32 ps_tl;
-
- short raw_tx;
- /* used if IEEE_SOFTMAC_TX_QUEUE is set */
- short queue_stop;
- short scanning;
- short proto_started;
-
- struct semaphore wx_sem;
- struct semaphore scan_sem;
-
- spinlock_t mgmt_tx_lock;
- spinlock_t beacon_lock;
-
- short beacon_txing;
-
- short wap_set;
- short ssid_set;
-
- u8 wpax_type_set; //{added by David, 2006.9.28}
- u32 wpax_type_notify; //{added by David, 2006.9.26}
-
- /* QoS related flag */
- char init_wmmparam_flag;
-
- /* for discarding duplicated packets in IBSS */
- struct list_head ibss_mac_hash[IEEE_IBSS_MAC_HASH_SIZE];
-
- /* for discarding duplicated packets in BSS */
- u16 last_rxseq_num[17]; /* rx seq previous per-tid */
- u16 last_rxfrag_num[17];/* tx frag previous per-tid */
- unsigned long last_packet_time[17];
-
- /* for PS mode */
- unsigned long last_rx_ps_time;
-
- /* used if IEEE_SOFTMAC_SINGLE_QUEUE is set */
- struct sk_buff *mgmt_queue_ring[MGMT_QUEUE_NUM];
- int mgmt_queue_head;
- int mgmt_queue_tail;
-
-
- /* used if IEEE_SOFTMAC_TX_QUEUE is set */
- struct tx_pending_t tx_pending;
-
- /* used if IEEE_SOFTMAC_ASSOCIATE is set */
- struct timer_list associate_timer;
-
- /* used if IEEE_SOFTMAC_BEACONS is set */
- struct timer_list beacon_timer;
-
- struct work_struct associate_complete_wq;
-// struct work_struct associate_retry_wq;
- struct work_struct associate_procedure_wq;
-// struct work_struct softmac_scan_wq;
- struct work_struct wx_sync_scan_wq;
- struct work_struct wmm_param_update_wq;
- struct work_struct ps_request_tx_ack_wq;//for ps
-// struct work_struct hw_wakeup_wq;
-// struct work_struct hw_sleep_wq;
-// struct work_struct watch_dog_wq;
- bool bInactivePs;
- bool actscanning;
- bool beinretry;
- u16 ListenInterval;
- unsigned long NumRxDataInPeriod; //YJ,add,080828
- unsigned long NumRxBcnInPeriod; //YJ,add,080828
- unsigned long NumRxOkTotal;
- unsigned long NumRxUnicast;//YJ,add,080828,for keep alive
- bool bHwRadioOff;
- struct delayed_work softmac_scan_wq;
- struct delayed_work associate_retry_wq;
- struct delayed_work hw_wakeup_wq;
- struct delayed_work hw_sleep_wq;//+by amy 080324
- struct delayed_work watch_dog_wq;
- struct delayed_work sw_antenna_wq;
- struct delayed_work start_ibss_wq;
-//by amy for rate adaptive 080312
- struct delayed_work rate_adapter_wq;
-//by amy for rate adaptive
- struct delayed_work hw_dig_wq;
- struct delayed_work tx_pw_wq;
-
-//Added for RF power on power off by lizhaoming 080512
- struct delayed_work GPIOChangeRFWorkItem;
-
- struct workqueue_struct *wq;
-
- /* Callback functions */
- void (*set_security)(struct net_device *dev,
- struct ieee80211_security *sec);
-
- /* Used to TX data frame by using txb structs.
- * this is not used if in the softmac_features
- * is set the flag IEEE_SOFTMAC_TX_QUEUE
- */
- int (*hard_start_xmit)(struct ieee80211_txb *txb,
- struct net_device *dev);
-
- int (*reset_port)(struct net_device *dev);
-
- /* Softmac-generated frames (management) are TXed via this
- * callback if the flag IEEE_SOFTMAC_SINGLE_QUEUE is
- * not set. As some cards may have different HW queues that
- * one might want to use for data and management frames
- * the option to have two callbacks might be useful.
- * This function can't sleep.
- */
- int (*softmac_hard_start_xmit)(struct sk_buff *skb,
- struct net_device *dev);
-
- /* used instead of hard_start_xmit (not softmac_hard_start_xmit)
- * if the IEEE_SOFTMAC_TX_QUEUE feature is used to TX data
- * frames. If the option IEEE_SOFTMAC_SINGLE_QUEUE is also set
- * then also management frames are sent via this callback.
- * This function can't sleep.
- */
- void (*softmac_data_hard_start_xmit)(struct sk_buff *skb,
- struct net_device *dev,int rate);
-
- /* stops the HW queue for DATA frames. Useful to avoid
- * waste time to TX data frame when we are reassociating
- * This function can sleep.
- */
- void (*data_hard_stop)(struct net_device *dev);
-
- /* OK this is complementar to data_poll_hard_stop */
- void (*data_hard_resume)(struct net_device *dev);
-
- /* ask to the driver to retune the radio .
- * This function can sleep. the driver should ensure
- * the radio has been switched before return.
- */
- void (*set_chan)(struct net_device *dev,short ch);
-
- /* These are not used if the ieee stack takes care of
- * scanning (IEEE_SOFTMAC_SCAN feature set).
- * In this case only the set_chan is used.
- *
- * The syncro version is similar to the start_scan but
- * does not return until all channels has been scanned.
- * this is called in user context and should sleep,
- * it is called in a work_queue when switching to ad-hoc mode
- * or in behalf of iwlist scan when the card is associated
- * and root user ask for a scan.
- * the function stop_scan should stop both the syncro and
- * background scanning and can sleep.
- * The function start_scan should initiate the background
- * scanning and can't sleep.
- */
- void (*scan_syncro)(struct net_device *dev);
- void (*start_scan)(struct net_device *dev);
- void (*stop_scan)(struct net_device *dev);
-
- /* indicate the driver that the link state is changed
- * for example it may indicate the card is associated now.
- * Driver might be interested in this to apply RX filter
- * rules or simply light the LINK led
- */
- void (*link_change)(struct net_device *dev);
-
- /* these two function indicates to the HW when to start
- * and stop to send beacons. This is used when the
- * IEEE_SOFTMAC_BEACONS is not set. For now the
- * stop_send_bacons is NOT guaranteed to be called only
- * after start_send_beacons.
- */
- void (*start_send_beacons) (struct net_device *dev);
- void (*stop_send_beacons) (struct net_device *dev);
-
- /* power save mode related */
- void (*sta_wake_up) (struct net_device *dev);
- void (*ps_request_tx_ack) (struct net_device *dev);
- void (*enter_sleep_state) (struct net_device *dev, u32 th, u32 tl);
- short (*ps_is_queue_empty) (struct net_device *dev);
-
- /* QoS related */
- //void (*wmm_param_update) (struct net_device *dev, u8 *ac_param);
- //void (*wmm_param_update) (struct ieee80211_device *ieee);
-
- /* This must be the last item so that it points to the data
- * allocated beyond this structure by alloc_ieee80211 */
- u8 priv[0];
-};
-
-#define IEEE_A (1<<0)
-#define IEEE_B (1<<1)
-#define IEEE_G (1<<2)
-#define IEEE_MODE_MASK (IEEE_A|IEEE_B|IEEE_G)
-
-/* Generate a 802.11 header */
-
-/* Uses the channel change callback directly
- * instead of [start/stop] scan callbacks
- */
-#define IEEE_SOFTMAC_SCAN (1<<2)
-
-/* Perform authentication and association handshake */
-#define IEEE_SOFTMAC_ASSOCIATE (1<<3)
-
-/* Generate probe requests */
-#define IEEE_SOFTMAC_PROBERQ (1<<4)
-
-/* Generate response to probe requests */
-#define IEEE_SOFTMAC_PROBERS (1<<5)
-
-/* The ieee802.11 stack will manages the netif queue
- * wake/stop for the driver, taking care of 802.11
- * fragmentation. See softmac.c for details. */
-#define IEEE_SOFTMAC_TX_QUEUE (1<<7)
-
-/* Uses only the softmac_data_hard_start_xmit
- * even for TX management frames.
- */
-#define IEEE_SOFTMAC_SINGLE_QUEUE (1<<8)
-
-/* Generate beacons. The stack will enqueue beacons
- * to the card
- */
-#define IEEE_SOFTMAC_BEACONS (1<<6)
-
-
-
-static inline void *ieee80211_priv(struct net_device *dev)
-{
- return ((struct ieee80211_device *)netdev_priv(dev))->priv;
-}
-
-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] == ' ')
- return 1;
-
- /* Otherwise, if the entire essid is 0, we assume it is hidden */
- while (essid_len) {
- essid_len--;
- if (essid[essid_len] != '\0')
- return 0;
- }
-
- return 1;
-}
-
-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
- * combinations of modes, so as long as there is one valid combination
- * of ap/device supported modes, then return success
- *
- */
- if ((mode & IEEE_A) &&
- (ieee->modulation & IEEE80211_OFDM_MODULATION) &&
- (ieee->freq_band & IEEE80211_52GHZ_BAND))
- return 1;
-
- if ((mode & IEEE_G) &&
- (ieee->modulation & IEEE80211_OFDM_MODULATION) &&
- (ieee->freq_band & IEEE80211_24GHZ_BAND))
- return 1;
-
- if ((mode & IEEE_B) &&
- (ieee->modulation & IEEE80211_CCK_MODULATION) &&
- (ieee->freq_band & IEEE80211_24GHZ_BAND))
- return 1;
-
- return 0;
-}
-
-static inline int ieee80211_get_hdrlen(u16 fc)
-{
- int hdrlen = 24;
-
- switch (WLAN_FC_GET_TYPE(fc)) {
- case IEEE80211_FTYPE_DATA:
- if ((fc & IEEE80211_FCTL_FROMDS) && (fc & IEEE80211_FCTL_TODS))
- hdrlen = 30; /* Addr4 */
- if(IEEE80211_QOS_HAS_SEQ(fc))
- hdrlen += 2; /* QOS ctrl*/
- break;
- case IEEE80211_FTYPE_CTL:
- switch (WLAN_FC_GET_STYPE(fc)) {
- case IEEE80211_STYPE_CTS:
- case IEEE80211_STYPE_ACK:
- hdrlen = 10;
- break;
- default:
- hdrlen = 16;
- break;
- }
- break;
- }
-
- return hdrlen;
-}
-
-
-
-/* ieee80211.c */
-extern void free_ieee80211(struct net_device *dev);
-extern struct net_device *alloc_ieee80211(int sizeof_priv);
-
-extern int ieee80211_set_encryption(struct ieee80211_device *ieee);
-
-/* ieee80211_tx.c */
-
-extern int ieee80211_encrypt_fragment(struct ieee80211_device *ieee,
- struct sk_buff *frag, int hdr_len);
-
-extern int ieee80211_rtl_xmit(struct sk_buff *skb, struct net_device *dev);
-extern void ieee80211_txb_free(struct ieee80211_txb *);
-
-
-/* ieee80211_rx.c */
-extern int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
- struct ieee80211_rx_stats *rx_stats);
-extern void ieee80211_rx_mgt(struct ieee80211_device *ieee,
- struct ieee80211_hdr_4addr *header,
- struct ieee80211_rx_stats *stats);
-
-/* ieee80211_wx.c */
-extern int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *key);
-extern int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *key);
-extern int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *key);
-extern int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- struct iw_param *data, char *extra);
-int ieee80211_wx_set_mlme(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len);
-/* ieee80211_softmac.c */
-extern short ieee80211_is_54g(const struct ieee80211_network *net);
-extern short ieee80211_is_shortslot(const struct ieee80211_network *net);
-extern int ieee80211_rx_frame_softmac(struct ieee80211_device *ieee,
- struct sk_buff *skb,
- struct ieee80211_rx_stats *rx_stats,
- u16 type, u16 stype);
-extern void ieee80211_softmac_new_net(struct ieee80211_device *ieee,
- struct ieee80211_network *net);
-
-extern void ieee80211_softmac_xmit(struct ieee80211_txb *txb,
- struct ieee80211_device *ieee);
-extern void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee);
-extern void ieee80211_start_bss(struct ieee80211_device *ieee);
-extern void ieee80211_start_master_bss(struct ieee80211_device *ieee);
-extern void ieee80211_start_ibss(struct ieee80211_device *ieee);
-extern void ieee80211_softmac_init(struct ieee80211_device *ieee);
-extern void ieee80211_softmac_free(struct ieee80211_device *ieee);
-extern void ieee80211_associate_abort(struct ieee80211_device *ieee);
-extern void ieee80211_disassociate(struct ieee80211_device *ieee);
-extern void ieee80211_stop_scan(struct ieee80211_device *ieee);
-extern void ieee80211_start_scan_syncro(struct ieee80211_device *ieee);
-extern void ieee80211_check_all_nets(struct ieee80211_device *ieee);
-extern void ieee80211_start_protocol(struct ieee80211_device *ieee);
-extern void ieee80211_stop_protocol(struct ieee80211_device *ieee);
-extern void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee);
-extern void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee);
-extern void ieee80211_reset_queue(struct ieee80211_device *ieee);
-extern void ieee80211_rtl_wake_queue(struct ieee80211_device *ieee);
-extern void ieee80211_rtl_stop_queue(struct ieee80211_device *ieee);
-extern struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee);
-extern void ieee80211_start_send_beacons(struct ieee80211_device *ieee);
-extern void ieee80211_stop_send_beacons(struct ieee80211_device *ieee);
-extern int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee,
- struct iw_point *p);
-extern void notify_wx_assoc_event(struct ieee80211_device *ieee);
-extern void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success);
-extern void SendDisassociation(struct ieee80211_device *ieee, u8 *asSta,
- u8 asRsn);
-extern void ieee80211_rtl_start_scan(struct ieee80211_device *ieee);
-
-//Add for RF power on power off by lizhaoming 080512
-extern void SendDisassociation(struct ieee80211_device *ieee, u8 *asSta,
- u8 asRsn);
-
-/* ieee80211_crypt_ccmp&tkip&wep.c */
-extern void ieee80211_tkip_null(void);
-extern void ieee80211_wep_null(void);
-extern void ieee80211_ccmp_null(void);
-/* ieee80211_softmac_wx.c */
-
-extern int ieee80211_wx_get_wap(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *ext);
-
-extern int ieee80211_wx_set_wap(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *awrq,
- char *extra);
-
-extern int ieee80211_wx_get_essid(struct ieee80211_device *ieee,
- struct iw_request_info *a,
- union iwreq_data *wrqu, char *b);
-
-extern int ieee80211_wx_set_rate(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-extern int ieee80211_wx_get_rate(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-extern int ieee80211_wx_set_mode(struct ieee80211_device *ieee,
- struct iw_request_info *a,
- union iwreq_data *wrqu, char *b);
-
-extern int ieee80211_wx_set_scan(struct ieee80211_device *ieee,
- struct iw_request_info *a,
- union iwreq_data *wrqu, char *b);
-
-extern int ieee80211_wx_set_essid(struct ieee80211_device *ieee,
- struct iw_request_info *a,
- union iwreq_data *wrqu, char *extra);
-
-extern int ieee80211_wx_get_mode(struct ieee80211_device *ieee,
- struct iw_request_info *a,
- union iwreq_data *wrqu, char *b);
-
-extern int ieee80211_wx_set_freq(struct ieee80211_device *ieee,
- struct iw_request_info *a,
- union iwreq_data *wrqu, char *b);
-
-extern int ieee80211_wx_get_freq(struct ieee80211_device *ieee,
- struct iw_request_info *a,
- union iwreq_data *wrqu, char *b);
-
-extern void ieee80211_wx_sync_scan_wq(struct work_struct *work);
-
-extern int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-extern int ieee80211_wx_get_name(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-extern int ieee80211_wx_set_power(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-extern int ieee80211_wx_get_power(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra);
-
-extern void ieee80211_softmac_ips_scan_syncro(struct ieee80211_device *ieee);
-
-extern void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee,
- short pwr);
-
-extern const long ieee80211_wlan_frequencies[];
-
-extern inline void ieee80211_increment_scans(struct ieee80211_device *ieee)
-{
- ieee->scans++;
-}
-
-extern inline int ieee80211_get_scans(struct ieee80211_device *ieee)
-{
- return ieee->scans;
-}
-
-static inline const char *escape_essid(const char *essid, u8 essid_len) {
- static char escaped[IW_ESSID_MAX_SIZE * 2 + 1];
- const char *s = essid;
- char *d = escaped;
-
- if (ieee80211_is_empty_essid(essid, essid_len)) {
- memcpy(escaped, "<hidden>", sizeof("<hidden>"));
- return escaped;
- }
-
- essid_len = min(essid_len, (u8)IW_ESSID_MAX_SIZE);
- while (essid_len--) {
- if (*s == '\0') {
- *d++ = '\\';
- *d++ = '0';
- s++;
- } else {
- *d++ = *s++;
- }
- }
- *d = '\0';
- return escaped;
-}
-#endif /* IEEE80211_H */
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c
deleted file mode 100644
index 101f0c0..0000000
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.c
+++ /dev/null
@@ -1,240 +0,0 @@
-/*
- * Host AP crypto routines
- *
- * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
- * Portions Copyright (C) 2004, Intel Corporation <jketreno@linux.intel.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. See README and COPYING for
- * more details.
- *
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-//#include <linux/config.h>
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/string.h>
-#include <linux/errno.h>
-
-#include "ieee80211.h"
-
-MODULE_AUTHOR("Jouni Malinen");
-MODULE_DESCRIPTION("HostAP crypto");
-MODULE_LICENSE("GPL");
-
-struct ieee80211_crypto_alg {
- struct list_head list;
- struct ieee80211_crypto_ops *ops;
-};
-
-
-struct ieee80211_crypto {
- struct list_head algs;
- spinlock_t lock;
-};
-
-static struct ieee80211_crypto *hcrypt;
-
-void ieee80211_crypt_deinit_entries(struct ieee80211_device *ieee, int force)
-{
- struct list_head *ptr, *n;
- struct ieee80211_crypt_data *entry;
-
- for (ptr = ieee->crypt_deinit_list.next, n = ptr->next;
- ptr != &ieee->crypt_deinit_list; ptr = n, n = ptr->next) {
- entry = list_entry(ptr, struct ieee80211_crypt_data, list);
-
- if (atomic_read(&entry->refcnt) != 0 && !force)
- continue;
-
- list_del(ptr);
-
- if (entry->ops)
- entry->ops->deinit(entry->priv);
- kfree(entry);
- }
-}
-
-void ieee80211_crypt_deinit_handler(unsigned long data)
-{
- struct ieee80211_device *ieee = (struct ieee80211_device *)data;
- unsigned long flags;
-
- spin_lock_irqsave(&ieee->lock, flags);
- ieee80211_crypt_deinit_entries(ieee, 0);
- if (!list_empty(&ieee->crypt_deinit_list)) {
- pr_debug("entries remaining in delayed crypt deletion list\n");
- ieee->crypt_deinit_timer.expires = jiffies + HZ;
- add_timer(&ieee->crypt_deinit_timer);
- }
- spin_unlock_irqrestore(&ieee->lock, flags);
-
-}
-
-void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
- struct ieee80211_crypt_data **crypt)
-{
- struct ieee80211_crypt_data *tmp;
- unsigned long flags;
-
- if (*crypt == NULL)
- return;
-
- tmp = *crypt;
- *crypt = NULL;
-
- /* must not run ops->deinit() while there may be pending encrypt or
- * decrypt operations. Use a list of delayed deinits to avoid needing
- * locking. */
-
- spin_lock_irqsave(&ieee->lock, flags);
- list_add(&tmp->list, &ieee->crypt_deinit_list);
- if (!timer_pending(&ieee->crypt_deinit_timer)) {
- ieee->crypt_deinit_timer.expires = jiffies + HZ;
- add_timer(&ieee->crypt_deinit_timer);
- }
- spin_unlock_irqrestore(&ieee->lock, flags);
-}
-
-int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops)
-{
- unsigned long flags;
- struct ieee80211_crypto_alg *alg;
-
- if (hcrypt == NULL)
- return -1;
-
- alg = kzalloc(sizeof(*alg), GFP_KERNEL);
- if (alg == NULL)
- return -ENOMEM;
-
- alg->ops = ops;
-
- spin_lock_irqsave(&hcrypt->lock, flags);
- list_add(&alg->list, &hcrypt->algs);
- spin_unlock_irqrestore(&hcrypt->lock, flags);
-
- pr_debug("registered algorithm '%s'\n", ops->name);
-
- return 0;
-}
-
-int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops)
-{
- unsigned long flags;
- struct list_head *ptr;
- struct ieee80211_crypto_alg *del_alg = NULL;
-
- if (hcrypt == NULL)
- return -1;
-
- spin_lock_irqsave(&hcrypt->lock, flags);
- for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) {
- struct ieee80211_crypto_alg *alg =
- (struct ieee80211_crypto_alg *) ptr;
- if (alg->ops == ops) {
- list_del(&alg->list);
- del_alg = alg;
- break;
- }
- }
- spin_unlock_irqrestore(&hcrypt->lock, flags);
-
- if (del_alg) {
- pr_debug("unregistered algorithm '%s'\n", ops->name);
- kfree(del_alg);
- }
-
- return del_alg ? 0 : -1;
-}
-
-
-struct ieee80211_crypto_ops *ieee80211_get_crypto_ops(const char *name)
-{
- unsigned long flags;
- struct list_head *ptr;
- struct ieee80211_crypto_alg *found_alg = NULL;
-
- if (hcrypt == NULL)
- return NULL;
-
- spin_lock_irqsave(&hcrypt->lock, flags);
- for (ptr = hcrypt->algs.next; ptr != &hcrypt->algs; ptr = ptr->next) {
- struct ieee80211_crypto_alg *alg =
- (struct ieee80211_crypto_alg *) ptr;
- if (strcmp(alg->ops->name, name) == 0) {
- found_alg = alg;
- break;
- }
- }
- spin_unlock_irqrestore(&hcrypt->lock, flags);
-
- if (found_alg)
- return found_alg->ops;
- else
- return NULL;
-}
-
-
-static void *ieee80211_crypt_null_init(int keyidx) { return (void *) 1; }
-static void ieee80211_crypt_null_deinit(void *priv) {}
-
-static struct ieee80211_crypto_ops ieee80211_crypt_null = {
- .name = "NULL",
- .init = ieee80211_crypt_null_init,
- .deinit = ieee80211_crypt_null_deinit,
- .encrypt_mpdu = NULL,
- .decrypt_mpdu = NULL,
- .encrypt_msdu = NULL,
- .decrypt_msdu = NULL,
- .set_key = NULL,
- .get_key = NULL,
- .extra_prefix_len = 0,
- .extra_postfix_len = 0,
- .owner = THIS_MODULE,
-};
-
-
-int ieee80211_crypto_init(void)
-{
- int ret = -ENOMEM;
-
- hcrypt = kzalloc(sizeof(*hcrypt), GFP_KERNEL);
- if (!hcrypt)
- goto out;
-
- INIT_LIST_HEAD(&hcrypt->algs);
- spin_lock_init(&hcrypt->lock);
-
- ret = ieee80211_register_crypto_ops(&ieee80211_crypt_null);
- if (ret < 0) {
- kfree(hcrypt);
- hcrypt = NULL;
- }
-out:
- return ret;
-}
-
-
-void ieee80211_crypto_deinit(void)
-{
- struct list_head *ptr, *n;
- struct ieee80211_crypto_alg *alg = NULL;
-
- if (hcrypt == NULL)
- return;
-
- list_for_each_safe(ptr, n, &hcrypt->algs) {
- alg = list_entry(ptr, struct ieee80211_crypto_alg, list);
- if (alg) {
- list_del(ptr);
- pr_debug("unregistered algorithm '%s' (deinit)\n",
- alg->ops->name);
- kfree(alg);
- }
- }
- kfree(hcrypt);
-}
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.h b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.h
deleted file mode 100644
index 0b4ea43..0000000
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt.h
+++ /dev/null
@@ -1,86 +0,0 @@
-/*
- * Original code based on Host AP (software wireless LAN access point) driver
- * for Intersil Prism2/2.5/3.
- *
- * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
- * <jkmaline@cc.hut.fi>
- * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
- *
- * Adaption to a generic IEEE 802.11 stack by James Ketrenos
- * <jketreno@linux.intel.com>
- *
- * Copyright (c) 2004, 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. See README and COPYING for
- * more details.
- */
-
-/*
- * This file defines the interface to the ieee80211 crypto module.
- */
-#ifndef IEEE80211_CRYPT_H
-#define IEEE80211_CRYPT_H
-
-#include <linux/skbuff.h>
-
-struct ieee80211_crypto_ops {
- const char *name;
-
- /* init new crypto context (e.g., allocate private data space,
- * select IV, etc.); returns NULL on failure or pointer to allocated
- * private data on success */
- void * (*init)(int keyidx);
-
- /* deinitialize crypto context and free allocated private data */
- void (*deinit)(void *priv);
-
- /* encrypt/decrypt return < 0 on error or >= 0 on success. The return
- * value from decrypt_mpdu is passed as the keyidx value for
- * decrypt_msdu. skb must have enough head and tail room for the
- * encryption; if not, error will be returned; these functions are
- * called for all MPDUs (i.e., fragments).
- */
- int (*encrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
- int (*decrypt_mpdu)(struct sk_buff *skb, int hdr_len, void *priv);
-
- /* These functions are called for full MSDUs, i.e. full frames.
- * These can be NULL if full MSDU operations are not needed. */
- int (*encrypt_msdu)(struct sk_buff *skb, int hdr_len, void *priv);
- int (*decrypt_msdu)(struct sk_buff *skb, int keyidx, int hdr_len,
- void *priv);
-
- int (*set_key)(void *key, int len, u8 *seq, void *priv);
- int (*get_key)(void *key, int len, u8 *seq, void *priv);
-
- /* procfs handler for printing out key information and possible
- * statistics */
- char * (*print_stats)(char *p, void *priv);
-
- /* maximum number of bytes added by encryption; encrypt buf is
- * allocated with extra_prefix_len bytes, copy of in_buf, and
- * extra_postfix_len; encrypt need not use all this space, but
- * the result must start at the beginning of the buffer and correct
- * length must be returned */
- int extra_prefix_len, extra_postfix_len;
-
- struct module *owner;
-};
-
-struct ieee80211_crypt_data {
- struct list_head list; /* delayed deletion list */
- struct ieee80211_crypto_ops *ops;
- void *priv;
- atomic_t refcnt;
-};
-
-int ieee80211_register_crypto_ops(struct ieee80211_crypto_ops *ops);
-int ieee80211_unregister_crypto_ops(struct ieee80211_crypto_ops *ops);
-struct ieee80211_crypto_ops *ieee80211_get_crypto_ops(const char *name);
-void ieee80211_crypt_deinit_entries(struct ieee80211_device *, int);
-void ieee80211_crypt_deinit_handler(unsigned long);
-void ieee80211_crypt_delayed_deinit(struct ieee80211_device *ieee,
- struct ieee80211_crypt_data **crypt);
-
-#endif
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c
deleted file mode 100644
index 4fe2538..0000000
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_ccmp.c
+++ /dev/null
@@ -1,455 +0,0 @@
-/*
- * Host AP crypt: host-based CCMP encryption implementation for Host AP driver
- *
- * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi>
- *
- * 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. See README and COPYING for
- * more details.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/random.h>
-#include <linux/skbuff.h>
-#include <linux/netdevice.h>
-#include <linux/if_ether.h>
-#include <linux/if_arp.h>
-#include <linux/string.h>
-#include <linux/wireless.h>
-
-#include "ieee80211.h"
-
-#include <linux/crypto.h>
-#include <linux/scatterlist.h>
-
-MODULE_AUTHOR("Jouni Malinen");
-MODULE_DESCRIPTION("Host AP crypt: CCMP");
-MODULE_LICENSE("GPL");
-
-
-#define AES_BLOCK_LEN 16
-#define CCMP_HDR_LEN 8
-#define CCMP_MIC_LEN 8
-#define CCMP_TK_LEN 16
-#define CCMP_PN_LEN 6
-
-struct ieee80211_ccmp_data {
- u8 key[CCMP_TK_LEN];
- int key_set;
-
- u8 tx_pn[CCMP_PN_LEN];
- u8 rx_pn[CCMP_PN_LEN];
-
- u32 dot11RSNAStatsCCMPFormatErrors;
- u32 dot11RSNAStatsCCMPReplays;
- u32 dot11RSNAStatsCCMPDecryptErrors;
-
- int key_idx;
-
- struct crypto_tfm *tfm;
-
- /* scratch buffers for virt_to_page() (crypto API) */
- u8 tx_b0[AES_BLOCK_LEN], tx_b[AES_BLOCK_LEN],
- tx_e[AES_BLOCK_LEN], tx_s0[AES_BLOCK_LEN];
- u8 rx_b0[AES_BLOCK_LEN], rx_b[AES_BLOCK_LEN], rx_a[AES_BLOCK_LEN];
-};
-
-static void ieee80211_ccmp_aes_encrypt(struct crypto_tfm *tfm,
- const u8 pt[16], u8 ct[16])
-{
- crypto_cipher_encrypt_one((void *)tfm, ct, pt);
-}
-
-static void *ieee80211_ccmp_init(int key_idx)
-{
- struct ieee80211_ccmp_data *priv;
-
- priv = kzalloc(sizeof(*priv), GFP_ATOMIC);
- if (priv == NULL)
- goto fail;
- priv->key_idx = key_idx;
-
- priv->tfm = (void *)crypto_alloc_cipher("aes", 0, CRYPTO_ALG_ASYNC);
- if (IS_ERR(priv->tfm)) {
- pr_debug("could not allocate crypto API aes\n");
- priv->tfm = NULL;
- goto fail;
- }
-
- return priv;
-
-fail:
- if (priv) {
- if (priv->tfm)
- crypto_free_cipher((void *)priv->tfm);
- kfree(priv);
- }
-
- return NULL;
-}
-
-
-static void ieee80211_ccmp_deinit(void *priv)
-{
- struct ieee80211_ccmp_data *_priv = priv;
-
- if (_priv && _priv->tfm)
- crypto_free_cipher((void *)_priv->tfm);
- kfree(priv);
-}
-
-
-static inline void xor_block(u8 *b, u8 *a, size_t len)
-{
- int i;
- for (i = 0; i < len; i++)
- b[i] ^= a[i];
-}
-
-static void ccmp_init_blocks(struct crypto_tfm *tfm,
- struct ieee80211_hdr_4addr *hdr,
- u8 *pn, size_t dlen, u8 *b0, u8 *auth,
- u8 *s0)
-{
- u8 *pos, qc = 0;
- size_t aad_len;
- u16 fc;
- int a4_included, qc_included;
- u8 aad[2 * AES_BLOCK_LEN];
-
- fc = le16_to_cpu(hdr->frame_ctl);
- a4_included = ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
- (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS));
- /*
- qc_included = ((WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) &&
- (WLAN_FC_GET_STYPE(fc) & 0x08));
- */
- qc_included = ((WLAN_FC_GET_TYPE(fc) == IEEE80211_FTYPE_DATA) &&
- (WLAN_FC_GET_STYPE(fc) & 0x80));
- aad_len = 22;
- if (a4_included)
- aad_len += 6;
- if (qc_included) {
- pos = (u8 *) &hdr->addr4;
- if (a4_included)
- pos += 6;
- qc = *pos & 0x0f;
- aad_len += 2;
- }
- /* CCM Initial Block:
- * Flag (Include authentication header, M=3 (8-octet MIC),
- * L=1 (2-octet Dlen))
- * Nonce: 0x00 | A2 | PN
- * Dlen */
- b0[0] = 0x59;
- b0[1] = qc;
- memcpy(b0 + 2, hdr->addr2, ETH_ALEN);
- memcpy(b0 + 8, pn, CCMP_PN_LEN);
- b0[14] = (dlen >> 8) & 0xff;
- b0[15] = dlen & 0xff;
-
- /* AAD:
- * FC with bits 4..6 and 11..13 masked to zero; 14 is always one
- * A1 | A2 | A3
- * SC with bits 4..15 (seq#) masked to zero
- * A4 (if present)
- * QC (if present)
- */
- pos = (u8 *) hdr;
- aad[0] = 0; /* aad_len >> 8 */
- aad[1] = aad_len & 0xff;
- aad[2] = pos[0] & 0x8f;
- aad[3] = pos[1] & 0xc7;
- memcpy(aad + 4, hdr->addr1, 3 * ETH_ALEN);
- pos = (u8 *) &hdr->seq_ctl;
- aad[22] = pos[0] & 0x0f;
- aad[23] = 0; /* all bits masked */
- memset(aad + 24, 0, 8);
- if (a4_included)
- memcpy(aad + 24, hdr->addr4, ETH_ALEN);
- if (qc_included) {
- aad[a4_included ? 30 : 24] = qc;
- /* rest of QC masked */
- }
-
- /* Start with the first block and AAD */
- ieee80211_ccmp_aes_encrypt(tfm, b0, auth);
- xor_block(auth, aad, AES_BLOCK_LEN);
- ieee80211_ccmp_aes_encrypt(tfm, auth, auth);
- xor_block(auth, &aad[AES_BLOCK_LEN], AES_BLOCK_LEN);
- ieee80211_ccmp_aes_encrypt(tfm, auth, auth);
- b0[0] &= 0x07;
- b0[14] = b0[15] = 0;
- ieee80211_ccmp_aes_encrypt(tfm, b0, s0);
-}
-
-static int ieee80211_ccmp_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
-{
- struct ieee80211_ccmp_data *key = priv;
- int data_len, i;
- u8 *pos;
- struct ieee80211_hdr_4addr *hdr;
- int blocks, last, len;
- u8 *mic;
- u8 *b0 = key->tx_b0;
- u8 *b = key->tx_b;
- u8 *e = key->tx_e;
- u8 *s0 = key->tx_s0;
-
- if (skb_headroom(skb) < CCMP_HDR_LEN ||
- skb_tailroom(skb) < CCMP_MIC_LEN ||
- skb->len < hdr_len)
- return -1;
-
- data_len = skb->len - hdr_len;
- pos = skb_push(skb, CCMP_HDR_LEN);
- memmove(pos, pos + CCMP_HDR_LEN, hdr_len);
- pos += hdr_len;
-
- i = CCMP_PN_LEN - 1;
- while (i >= 0) {
- key->tx_pn[i]++;
- if (key->tx_pn[i] != 0)
- break;
- i--;
- }
-
- *pos++ = key->tx_pn[5];
- *pos++ = key->tx_pn[4];
- *pos++ = 0;
- *pos++ = (key->key_idx << 6) | (1 << 5) /* Ext IV included */;
- *pos++ = key->tx_pn[3];
- *pos++ = key->tx_pn[2];
- *pos++ = key->tx_pn[1];
- *pos++ = key->tx_pn[0];
-
- hdr = (struct ieee80211_hdr_4addr *)skb->data;
- mic = skb_put(skb, CCMP_MIC_LEN);
-
- ccmp_init_blocks(key->tfm, hdr, key->tx_pn, data_len, b0, b, s0);
-
- blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN;
- last = data_len % AES_BLOCK_LEN;
-
- for (i = 1; i <= blocks; i++) {
- len = (i == blocks && last) ? last : AES_BLOCK_LEN;
- /* Authentication */
- xor_block(b, pos, len);
- ieee80211_ccmp_aes_encrypt(key->tfm, b, b);
- /* Encryption, with counter */
- b0[14] = (i >> 8) & 0xff;
- b0[15] = i & 0xff;
- ieee80211_ccmp_aes_encrypt(key->tfm, b0, e);
- xor_block(pos, e, len);
- pos += len;
- }
-
- for (i = 0; i < CCMP_MIC_LEN; i++)
- mic[i] = b[i] ^ s0[i];
-
- return 0;
-}
-
-
-static int ieee80211_ccmp_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
-{
- struct ieee80211_ccmp_data *key = priv;
- u8 keyidx, *pos;
- struct ieee80211_hdr_4addr *hdr;
- u8 pn[6];
- size_t data_len = skb->len - hdr_len - CCMP_HDR_LEN - CCMP_MIC_LEN;
- u8 *mic = skb->data + skb->len - CCMP_MIC_LEN;
- u8 *b0 = key->rx_b0;
- u8 *b = key->rx_b;
- u8 *a = key->rx_a;
- int i, blocks, last, len;
-
- if (skb->len < hdr_len + CCMP_HDR_LEN + CCMP_MIC_LEN) {
- key->dot11RSNAStatsCCMPFormatErrors++;
- return -1;
- }
-
- hdr = (struct ieee80211_hdr_4addr *)skb->data;
- pos = skb->data + hdr_len;
- keyidx = pos[3];
- if (!(keyidx & (1 << 5))) {
- if (net_ratelimit()) {
- pr_debug("received packet without ExtIV flag from %pM\n",
- hdr->addr2);
- }
- key->dot11RSNAStatsCCMPFormatErrors++;
- return -2;
- }
- keyidx >>= 6;
- if (key->key_idx != keyidx) {
- pr_debug("RX tkey->key_idx=%d frame keyidx=%d priv=%p\n",
- key->key_idx, keyidx, priv);
- return -6;
- }
- if (!key->key_set) {
- if (net_ratelimit()) {
- pr_debug("received packet from %pM with keyid=%d that does not have a configured key\n",
- hdr->addr2, keyidx);
- }
- return -3;
- }
-
- pn[0] = pos[7];
- pn[1] = pos[6];
- pn[2] = pos[5];
- pn[3] = pos[4];
- pn[4] = pos[1];
- pn[5] = pos[0];
- pos += 8;
-
- if (memcmp(pn, key->rx_pn, CCMP_PN_LEN) <= 0) {
- if (net_ratelimit()) {
- pr_debug("replay detected: STA=%pM previous PN %pm received PN %pm\n",
- hdr->addr2, key->rx_pn, pn);
- }
- key->dot11RSNAStatsCCMPReplays++;
- return -4;
- }
-
- ccmp_init_blocks(key->tfm, hdr, pn, data_len, b0, a, b);
- xor_block(mic, b, CCMP_MIC_LEN);
-
- blocks = (data_len + AES_BLOCK_LEN - 1) / AES_BLOCK_LEN;
- last = data_len % AES_BLOCK_LEN;
-
- for (i = 1; i <= blocks; i++) {
- len = (i == blocks && last) ? last : AES_BLOCK_LEN;
- /* Decrypt, with counter */
- b0[14] = (i >> 8) & 0xff;
- b0[15] = i & 0xff;
- ieee80211_ccmp_aes_encrypt(key->tfm, b0, b);
- xor_block(pos, b, len);
- /* Authentication */
- xor_block(a, pos, len);
- ieee80211_ccmp_aes_encrypt(key->tfm, a, a);
- pos += len;
- }
-
- if (memcmp(mic, a, CCMP_MIC_LEN) != 0) {
- if (net_ratelimit())
- pr_debug("decrypt failed: STA=%pM\n", hdr->addr2);
-
- key->dot11RSNAStatsCCMPDecryptErrors++;
- return -5;
- }
-
- memcpy(key->rx_pn, pn, CCMP_PN_LEN);
-
- /* Remove hdr and MIC */
- memmove(skb->data + CCMP_HDR_LEN, skb->data, hdr_len);
- skb_pull(skb, CCMP_HDR_LEN);
- skb_trim(skb, skb->len - CCMP_MIC_LEN);
-
- return keyidx;
-}
-
-
-static int ieee80211_ccmp_set_key(void *key, int len, u8 *seq, void *priv)
-{
- struct ieee80211_ccmp_data *data = priv;
- int keyidx;
- struct crypto_tfm *tfm = data->tfm;
-
- keyidx = data->key_idx;
- memset(data, 0, sizeof(*data));
- data->key_idx = keyidx;
- data->tfm = tfm;
- if (len == CCMP_TK_LEN) {
- memcpy(data->key, key, CCMP_TK_LEN);
- data->key_set = 1;
- if (seq) {
- data->rx_pn[0] = seq[5];
- data->rx_pn[1] = seq[4];
- data->rx_pn[2] = seq[3];
- data->rx_pn[3] = seq[2];
- data->rx_pn[4] = seq[1];
- data->rx_pn[5] = seq[0];
- }
- crypto_cipher_setkey((void *)data->tfm, data->key, CCMP_TK_LEN);
- } else if (len == 0)
- data->key_set = 0;
- else
- return -1;
-
- return 0;
-}
-
-
-static int ieee80211_ccmp_get_key(void *key, int len, u8 *seq, void *priv)
-{
- struct ieee80211_ccmp_data *data = priv;
-
- if (len < CCMP_TK_LEN)
- return -1;
-
- if (!data->key_set)
- return 0;
- memcpy(key, data->key, CCMP_TK_LEN);
-
- if (seq) {
- seq[0] = data->tx_pn[5];
- seq[1] = data->tx_pn[4];
- seq[2] = data->tx_pn[3];
- seq[3] = data->tx_pn[2];
- seq[4] = data->tx_pn[1];
- seq[5] = data->tx_pn[0];
- }
-
- return CCMP_TK_LEN;
-}
-
-
-static char *ieee80211_ccmp_print_stats(char *p, void *priv)
-{
- struct ieee80211_ccmp_data *ccmp = priv;
- p += sprintf(p,
- "key[%d] alg=CCMP key_set=%d tx_pn=%pm rx_pn=%pm format_errors=%d replays=%d decrypt_errors=%d\n",
- ccmp->key_idx, ccmp->key_set,
- ccmp->tx_pn, ccmp->rx_pn,
- ccmp->dot11RSNAStatsCCMPFormatErrors,
- ccmp->dot11RSNAStatsCCMPReplays,
- ccmp->dot11RSNAStatsCCMPDecryptErrors);
-
- return p;
-}
-
-void ieee80211_ccmp_null(void)
-{
- return;
-}
-static struct ieee80211_crypto_ops ieee80211_crypt_ccmp = {
- .name = "CCMP",
- .init = ieee80211_ccmp_init,
- .deinit = ieee80211_ccmp_deinit,
- .encrypt_mpdu = ieee80211_ccmp_encrypt,
- .decrypt_mpdu = ieee80211_ccmp_decrypt,
- .encrypt_msdu = NULL,
- .decrypt_msdu = NULL,
- .set_key = ieee80211_ccmp_set_key,
- .get_key = ieee80211_ccmp_get_key,
- .print_stats = ieee80211_ccmp_print_stats,
- .extra_prefix_len = CCMP_HDR_LEN,
- .extra_postfix_len = CCMP_MIC_LEN,
- .owner = THIS_MODULE,
-};
-
-
-int ieee80211_crypto_ccmp_init(void)
-{
- return ieee80211_register_crypto_ops(&ieee80211_crypt_ccmp);
-}
-
-
-void ieee80211_crypto_ccmp_exit(void)
-{
- ieee80211_unregister_crypto_ops(&ieee80211_crypt_ccmp);
-}
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_tkip.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_tkip.c
deleted file mode 100644
index 6c1acc5..0000000
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_tkip.c
+++ /dev/null
@@ -1,740 +0,0 @@
-/*
- * Host AP crypt: host-based TKIP encryption implementation for Host AP driver
- *
- * Copyright (c) 2003-2004, Jouni Malinen <jkmaline@cc.hut.fi>
- *
- * 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. See README and COPYING for
- * more details.
- */
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/random.h>
-#include <linux/skbuff.h>
-#include <linux/netdevice.h>
-#include <linux/if_ether.h>
-#include <linux/if_arp.h>
-#include <asm/string.h>
-
-#include "ieee80211.h"
-
-#include <linux/crypto.h>
-#include <linux/scatterlist.h>
-#include <linux/crc32.h>
-
-MODULE_AUTHOR("Jouni Malinen");
-MODULE_DESCRIPTION("Host AP crypt: TKIP");
-MODULE_LICENSE("GPL");
-
-
-struct ieee80211_tkip_data {
-#define TKIP_KEY_LEN 32
- u8 key[TKIP_KEY_LEN];
- int key_set;
-
- u32 tx_iv32;
- u16 tx_iv16;
- u16 tx_ttak[5];
- int tx_phase1_done;
-
- u32 rx_iv32;
- u16 rx_iv16;
- u16 rx_ttak[5];
- int rx_phase1_done;
- u32 rx_iv32_new;
- u16 rx_iv16_new;
-
- u32 dot11RSNAStatsTKIPReplays;
- u32 dot11RSNAStatsTKIPICVErrors;
- u32 dot11RSNAStatsTKIPLocalMICFailures;
-
- int key_idx;
-
- struct crypto_blkcipher *rx_tfm_arc4;
- struct crypto_hash *rx_tfm_michael;
- struct crypto_blkcipher *tx_tfm_arc4;
- struct crypto_hash *tx_tfm_michael;
- struct crypto_tfm *tfm_arc4;
- struct crypto_tfm *tfm_michael;
-
- /* scratch buffers for virt_to_page() (crypto API) */
- u8 rx_hdr[16], tx_hdr[16];
-};
-
-static void *ieee80211_tkip_init(int key_idx)
-{
- struct ieee80211_tkip_data *priv;
-
- priv = kzalloc(sizeof(*priv), GFP_ATOMIC);
- if (priv == NULL)
- goto fail;
- priv->key_idx = key_idx;
-
- priv->tx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0,
- CRYPTO_ALG_ASYNC);
- if (IS_ERR(priv->tx_tfm_arc4)) {
- printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
- "crypto API arc4\n");
- priv->tx_tfm_arc4 = NULL;
- goto fail;
- }
-
- priv->tx_tfm_michael = crypto_alloc_hash("michael_mic", 0,
- CRYPTO_ALG_ASYNC);
- if (IS_ERR(priv->tx_tfm_michael)) {
- printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
- "crypto API michael_mic\n");
- priv->tx_tfm_michael = NULL;
- goto fail;
- }
-
- priv->rx_tfm_arc4 = crypto_alloc_blkcipher("ecb(arc4)", 0,
- CRYPTO_ALG_ASYNC);
- if (IS_ERR(priv->rx_tfm_arc4)) {
- printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
- "crypto API arc4\n");
- priv->rx_tfm_arc4 = NULL;
- goto fail;
- }
-
- priv->rx_tfm_michael = crypto_alloc_hash("michael_mic", 0,
- CRYPTO_ALG_ASYNC);
- if (IS_ERR(priv->rx_tfm_michael)) {
- printk(KERN_DEBUG "ieee80211_crypt_tkip: could not allocate "
- "crypto API michael_mic\n");
- priv->rx_tfm_michael = NULL;
- goto fail;
- }
-
- return priv;
-
-fail:
- if (priv) {
- if (priv->tx_tfm_michael)
- crypto_free_hash(priv->tx_tfm_michael);
- if (priv->tx_tfm_arc4)
- crypto_free_blkcipher(priv->tx_tfm_arc4);
- if (priv->rx_tfm_michael)
- crypto_free_hash(priv->rx_tfm_michael);
- if (priv->rx_tfm_arc4)
- crypto_free_blkcipher(priv->rx_tfm_arc4);
- kfree(priv);
- }
-
- return NULL;
-}
-
-
-static void ieee80211_tkip_deinit(void *priv)
-{
- struct ieee80211_tkip_data *_priv = priv;
-
- if (_priv) {
- if (_priv->tx_tfm_michael)
- crypto_free_hash(_priv->tx_tfm_michael);
- if (_priv->tx_tfm_arc4)
- crypto_free_blkcipher(_priv->tx_tfm_arc4);
- if (_priv->rx_tfm_michael)
- crypto_free_hash(_priv->rx_tfm_michael);
- if (_priv->rx_tfm_arc4)
- crypto_free_blkcipher(_priv->rx_tfm_arc4);
- }
- kfree(priv);
-}
-
-
-static inline u16 RotR1(u16 val)
-{
- return (val >> 1) | (val << 15);
-}
-
-
-static inline u8 Lo8(u16 val)
-{
- return val & 0xff;
-}
-
-
-static inline u8 Hi8(u16 val)
-{
- return val >> 8;
-}
-
-
-static inline u16 Lo16(u32 val)
-{
- return val & 0xffff;
-}
-
-
-static inline u16 Hi16(u32 val)
-{
- return val >> 16;
-}
-
-
-static inline u16 Mk16(u8 hi, u8 lo)
-{
- return lo | (((u16) hi) << 8);
-}
-
-
-static inline u16 Mk16_le(u16 *v)
-{
- return le16_to_cpu(*v);
-}
-
-
-static const u16 Sbox[256] = {
- 0xC6A5, 0xF884, 0xEE99, 0xF68D, 0xFF0D, 0xD6BD, 0xDEB1, 0x9154,
- 0x6050, 0x0203, 0xCEA9, 0x567D, 0xE719, 0xB562, 0x4DE6, 0xEC9A,
- 0x8F45, 0x1F9D, 0x8940, 0xFA87, 0xEF15, 0xB2EB, 0x8EC9, 0xFB0B,
- 0x41EC, 0xB367, 0x5FFD, 0x45EA, 0x23BF, 0x53F7, 0xE496, 0x9B5B,
- 0x75C2, 0xE11C, 0x3DAE, 0x4C6A, 0x6C5A, 0x7E41, 0xF502, 0x834F,
- 0x685C, 0x51F4, 0xD134, 0xF908, 0xE293, 0xAB73, 0x6253, 0x2A3F,
- 0x080C, 0x9552, 0x4665, 0x9D5E, 0x3028, 0x37A1, 0x0A0F, 0x2FB5,
- 0x0E09, 0x2436, 0x1B9B, 0xDF3D, 0xCD26, 0x4E69, 0x7FCD, 0xEA9F,
- 0x121B, 0x1D9E, 0x5874, 0x342E, 0x362D, 0xDCB2, 0xB4EE, 0x5BFB,
- 0xA4F6, 0x764D, 0xB761, 0x7DCE, 0x527B, 0xDD3E, 0x5E71, 0x1397,
- 0xA6F5, 0xB968, 0x0000, 0xC12C, 0x4060, 0xE31F, 0x79C8, 0xB6ED,
- 0xD4BE, 0x8D46, 0x67D9, 0x724B, 0x94DE, 0x98D4, 0xB0E8, 0x854A,
- 0xBB6B, 0xC52A, 0x4FE5, 0xED16, 0x86C5, 0x9AD7, 0x6655, 0x1194,
- 0x8ACF, 0xE910, 0x0406, 0xFE81, 0xA0F0, 0x7844, 0x25BA, 0x4BE3,
- 0xA2F3, 0x5DFE, 0x80C0, 0x058A, 0x3FAD, 0x21BC, 0x7048, 0xF104,
- 0x63DF, 0x77C1, 0xAF75, 0x4263, 0x2030, 0xE51A, 0xFD0E, 0xBF6D,
- 0x814C, 0x1814, 0x2635, 0xC32F, 0xBEE1, 0x35A2, 0x88CC, 0x2E39,
- 0x9357, 0x55F2, 0xFC82, 0x7A47, 0xC8AC, 0xBAE7, 0x322B, 0xE695,
- 0xC0A0, 0x1998, 0x9ED1, 0xA37F, 0x4466, 0x547E, 0x3BAB, 0x0B83,
- 0x8CCA, 0xC729, 0x6BD3, 0x283C, 0xA779, 0xBCE2, 0x161D, 0xAD76,
- 0xDB3B, 0x6456, 0x744E, 0x141E, 0x92DB, 0x0C0A, 0x486C, 0xB8E4,
- 0x9F5D, 0xBD6E, 0x43EF, 0xC4A6, 0x39A8, 0x31A4, 0xD337, 0xF28B,
- 0xD532, 0x8B43, 0x6E59, 0xDAB7, 0x018C, 0xB164, 0x9CD2, 0x49E0,
- 0xD8B4, 0xACFA, 0xF307, 0xCF25, 0xCAAF, 0xF48E, 0x47E9, 0x1018,
- 0x6FD5, 0xF088, 0x4A6F, 0x5C72, 0x3824, 0x57F1, 0x73C7, 0x9751,
- 0xCB23, 0xA17C, 0xE89C, 0x3E21, 0x96DD, 0x61DC, 0x0D86, 0x0F85,
- 0xE090, 0x7C42, 0x71C4, 0xCCAA, 0x90D8, 0x0605, 0xF701, 0x1C12,
- 0xC2A3, 0x6A5F, 0xAEF9, 0x69D0, 0x1791, 0x9958, 0x3A27, 0x27B9,
- 0xD938, 0xEB13, 0x2BB3, 0x2233, 0xD2BB, 0xA970, 0x0789, 0x33A7,
- 0x2DB6, 0x3C22, 0x1592, 0xC920, 0x8749, 0xAAFF, 0x5078, 0xA57A,
- 0x038F, 0x59F8, 0x0980, 0x1A17, 0x65DA, 0xD731, 0x84C6, 0xD0B8,
- 0x82C3, 0x29B0, 0x5A77, 0x1E11, 0x7BCB, 0xA8FC, 0x6DD6, 0x2C3A,
-};
-
-
-static inline u16 _S_(u16 v)
-{
- u16 t = Sbox[Hi8(v)];
- return Sbox[Lo8(v)] ^ ((t << 8) | (t >> 8));
-}
-
-#define PHASE1_LOOP_COUNT 8
-
-static void tkip_mixing_phase1(u16 *TTAK, const u8 *TK, const u8 *TA, u32 IV32)
-{
- int i, j;
-
- /* Initialize the 80-bit TTAK from TSC (IV32) and TA[0..5] */
- TTAK[0] = Lo16(IV32);
- TTAK[1] = Hi16(IV32);
- TTAK[2] = Mk16(TA[1], TA[0]);
- TTAK[3] = Mk16(TA[3], TA[2]);
- TTAK[4] = Mk16(TA[5], TA[4]);
-
- for (i = 0; i < PHASE1_LOOP_COUNT; i++) {
- j = 2 * (i & 1);
- TTAK[0] += _S_(TTAK[4] ^ Mk16(TK[1 + j], TK[0 + j]));
- TTAK[1] += _S_(TTAK[0] ^ Mk16(TK[5 + j], TK[4 + j]));
- TTAK[2] += _S_(TTAK[1] ^ Mk16(TK[9 + j], TK[8 + j]));
- TTAK[3] += _S_(TTAK[2] ^ Mk16(TK[13 + j], TK[12 + j]));
- TTAK[4] += _S_(TTAK[3] ^ Mk16(TK[1 + j], TK[0 + j])) + i;
- }
-}
-
-
-static void tkip_mixing_phase2(u8 *WEPSeed, const u8 *TK, const u16 *TTAK,
- u16 IV16)
-{
- /* Make temporary area overlap WEP seed so that the final copy can be
- * avoided on little endian hosts. */
- u16 *PPK = (u16 *) &WEPSeed[4];
-
- /* Step 1 - make copy of TTAK and bring in TSC */
- PPK[0] = TTAK[0];
- PPK[1] = TTAK[1];
- PPK[2] = TTAK[2];
- PPK[3] = TTAK[3];
- PPK[4] = TTAK[4];
- PPK[5] = TTAK[4] + IV16;
-
- /* Step 2 - 96-bit bijective mixing using S-box */
- PPK[0] += _S_(PPK[5] ^ Mk16_le((u16 *) &TK[0]));
- PPK[1] += _S_(PPK[0] ^ Mk16_le((u16 *) &TK[2]));
- PPK[2] += _S_(PPK[1] ^ Mk16_le((u16 *) &TK[4]));
- PPK[3] += _S_(PPK[2] ^ Mk16_le((u16 *) &TK[6]));
- PPK[4] += _S_(PPK[3] ^ Mk16_le((u16 *) &TK[8]));
- PPK[5] += _S_(PPK[4] ^ Mk16_le((u16 *) &TK[10]));
-
- PPK[0] += RotR1(PPK[5] ^ Mk16_le((u16 *) &TK[12]));
- PPK[1] += RotR1(PPK[0] ^ Mk16_le((u16 *) &TK[14]));
- PPK[2] += RotR1(PPK[1]);
- PPK[3] += RotR1(PPK[2]);
- PPK[4] += RotR1(PPK[3]);
- PPK[5] += RotR1(PPK[4]);
-
- /* Step 3 - bring in last of TK bits, assign 24-bit WEP IV value
- * WEPSeed[0..2] is transmitted as WEP IV */
- WEPSeed[0] = Hi8(IV16);
- WEPSeed[1] = (Hi8(IV16) | 0x20) & 0x7F;
- WEPSeed[2] = Lo8(IV16);
- WEPSeed[3] = Lo8((PPK[5] ^ Mk16_le((u16 *) &TK[0])) >> 1);
-
-#ifdef __BIG_ENDIAN
- {
- int i;
- for (i = 0; i < 6; i++)
- PPK[i] = (PPK[i] << 8) | (PPK[i] >> 8);
- }
-#endif
-}
-
-static int ieee80211_tkip_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
-{
- struct ieee80211_tkip_data *tkey = priv;
- struct blkcipher_desc desc = {.tfm = tkey->tx_tfm_arc4};
- int len;
- u8 *pos;
- struct ieee80211_hdr_4addr *hdr;
- u8 rc4key[16], *icv;
- u32 crc;
- struct scatterlist sg;
- int ret;
-
- ret = 0;
- if (skb_headroom(skb) < 8 || skb_tailroom(skb) < 4 ||
- skb->len < hdr_len)
- return -1;
-
- hdr = (struct ieee80211_hdr_4addr *)skb->data;
-
- if (!tkey->tx_phase1_done) {
- tkip_mixing_phase1(tkey->tx_ttak, tkey->key, hdr->addr2,
- tkey->tx_iv32);
- tkey->tx_phase1_done = 1;
- }
- tkip_mixing_phase2(rc4key, tkey->key, tkey->tx_ttak, tkey->tx_iv16);
-
- len = skb->len - hdr_len;
- pos = skb_push(skb, 8);
- memmove(pos, pos + 8, hdr_len);
- pos += hdr_len;
-
- *pos++ = rc4key[0];
- *pos++ = rc4key[1];
- *pos++ = rc4key[2];
- *pos++ = (tkey->key_idx << 6) | (1 << 5) /* Ext IV included */;
- *pos++ = tkey->tx_iv32 & 0xff;
- *pos++ = (tkey->tx_iv32 >> 8) & 0xff;
- *pos++ = (tkey->tx_iv32 >> 16) & 0xff;
- *pos++ = (tkey->tx_iv32 >> 24) & 0xff;
-
- icv = skb_put(skb, 4);
- crc = ~crc32_le(~0, pos, len);
- icv[0] = crc;
- icv[1] = crc >> 8;
- icv[2] = crc >> 16;
- icv[3] = crc >> 24;
- crypto_blkcipher_setkey(tkey->tx_tfm_arc4, rc4key, 16);
- sg_init_one(&sg, pos, len + 4);
- ret = crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
-
- tkey->tx_iv16++;
- if (tkey->tx_iv16 == 0) {
- tkey->tx_phase1_done = 0;
- tkey->tx_iv32++;
- }
- return ret;
-}
-
-static int ieee80211_tkip_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
-{
- struct ieee80211_tkip_data *tkey = priv;
- struct blkcipher_desc desc = { .tfm = tkey->rx_tfm_arc4 };
- u8 keyidx, *pos;
- u32 iv32;
- u16 iv16;
- struct ieee80211_hdr_4addr *hdr;
- u8 icv[4];
- u32 crc;
- struct scatterlist sg;
- u8 rc4key[16];
- int plen;
-
- if (skb->len < hdr_len + 8 + 4)
- return -1;
-
- hdr = (struct ieee80211_hdr_4addr *)skb->data;
- pos = skb->data + hdr_len;
- keyidx = pos[3];
- if (!(keyidx & (1 << 5))) {
- if (net_ratelimit()) {
- printk(KERN_DEBUG "TKIP: received packet without ExtIV"
- " flag from %pM\n", hdr->addr2);
- }
- return -2;
- }
- keyidx >>= 6;
- if (tkey->key_idx != keyidx) {
- printk(KERN_DEBUG "TKIP: RX tkey->key_idx=%d frame "
- "keyidx=%d priv=%p\n", tkey->key_idx, keyidx, priv);
- return -6;
- }
- if (!tkey->key_set) {
- if (net_ratelimit()) {
- printk(KERN_DEBUG "TKIP: received packet from %pM"
- " with keyid=%d that does not have a configured"
- " key\n", hdr->addr2, keyidx);
- }
- return -3;
- }
- iv16 = (pos[0] << 8) | pos[2];
- iv32 = pos[4] | (pos[5] << 8) | (pos[6] << 16) | (pos[7] << 24);
- pos += 8;
-
- if (iv32 < tkey->rx_iv32 ||
- (iv32 == tkey->rx_iv32 && iv16 <= tkey->rx_iv16)) {
- if (net_ratelimit()) {
- printk(KERN_DEBUG "TKIP: replay detected: STA=%pM"
- " previous TSC %08x%04x received TSC "
- "%08x%04x\n", hdr->addr2,
- tkey->rx_iv32, tkey->rx_iv16, iv32, iv16);
- }
- tkey->dot11RSNAStatsTKIPReplays++;
- return -4;
- }
-
- if (iv32 != tkey->rx_iv32 || !tkey->rx_phase1_done) {
- tkip_mixing_phase1(tkey->rx_ttak, tkey->key, hdr->addr2, iv32);
- tkey->rx_phase1_done = 1;
- }
- tkip_mixing_phase2(rc4key, tkey->key, tkey->rx_ttak, iv16);
-
- plen = skb->len - hdr_len - 12;
- crypto_blkcipher_setkey(tkey->rx_tfm_arc4, rc4key, 16);
- sg_init_one(&sg, pos, plen + 4);
- if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4)) {
- if (net_ratelimit()) {
- printk(KERN_DEBUG ": TKIP: failed to decrypt "
- "received packet from %pM\n",
- hdr->addr2);
- }
- return -7;
- }
-
- crc = ~crc32_le(~0, pos, plen);
- icv[0] = crc;
- icv[1] = crc >> 8;
- icv[2] = crc >> 16;
- icv[3] = crc >> 24;
- if (memcmp(icv, pos + plen, 4) != 0) {
- if (iv32 != tkey->rx_iv32) {
- /* Previously cached Phase1 result was already lost, so
- * it needs to be recalculated for the next packet. */
- tkey->rx_phase1_done = 0;
- }
- if (net_ratelimit()) {
- printk(KERN_DEBUG "TKIP: ICV error detected: STA="
- "%pM\n", hdr->addr2);
- }
- tkey->dot11RSNAStatsTKIPICVErrors++;
- return -5;
- }
-
- /* Update real counters only after Michael MIC verification has
- * completed */
- tkey->rx_iv32_new = iv32;
- tkey->rx_iv16_new = iv16;
-
- /* Remove IV and ICV */
- memmove(skb->data + 8, skb->data, hdr_len);
- skb_pull(skb, 8);
- skb_trim(skb, skb->len - 4);
-
- return keyidx;
-}
-
-static int michael_mic(struct crypto_hash *tfm_michael, u8 *key, u8 *hdr,
- u8 *data, size_t data_len, u8 *mic)
-{
- struct hash_desc desc;
- struct scatterlist sg[2];
-
- if (tfm_michael == NULL) {
- printk(KERN_WARNING "michael_mic: tfm_michael == NULL\n");
- return -1;
- }
-
- sg_init_table(sg, 2);
- sg_set_buf(&sg[0], hdr, 16);
- sg_set_buf(&sg[1], data, data_len);
-
- if (crypto_hash_setkey(tfm_michael, key, 8))
- return -1;
-
- desc.tfm = tfm_michael;
- desc.flags = 0;
- return crypto_hash_digest(&desc, sg, data_len + 16, mic);
-}
-
-static void michael_mic_hdr(struct sk_buff *skb, u8 *hdr)
-{
- struct ieee80211_hdr_4addr *hdr11;
-
- hdr11 = (struct ieee80211_hdr_4addr *)skb->data;
- switch (le16_to_cpu(hdr11->frame_ctl) &
- (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
- case IEEE80211_FCTL_TODS:
- memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
- memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
- break;
- case IEEE80211_FCTL_FROMDS:
- memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
- memcpy(hdr + ETH_ALEN, hdr11->addr3, ETH_ALEN); /* SA */
- break;
- case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
- memcpy(hdr, hdr11->addr3, ETH_ALEN); /* DA */
- memcpy(hdr + ETH_ALEN, hdr11->addr4, ETH_ALEN); /* SA */
- break;
- case 0:
- memcpy(hdr, hdr11->addr1, ETH_ALEN); /* DA */
- memcpy(hdr + ETH_ALEN, hdr11->addr2, ETH_ALEN); /* SA */
- break;
- }
-
- hdr[12] = 0; /* priority */
-
- hdr[13] = hdr[14] = hdr[15] = 0; /* reserved */
-}
-
-
-static int ieee80211_michael_mic_add(struct sk_buff *skb, int hdr_len,
- void *priv)
-{
- struct ieee80211_tkip_data *tkey = priv;
- u8 *pos;
- struct ieee80211_hdr_4addr *hdr;
-
- hdr = (struct ieee80211_hdr_4addr *)skb->data;
-
- if (skb_tailroom(skb) < 8 || skb->len < hdr_len) {
- printk(KERN_DEBUG "Invalid packet for Michael MIC add "
- "(tailroom=%d hdr_len=%d skb->len=%d)\n",
- skb_tailroom(skb), hdr_len, skb->len);
- return -1;
- }
-
- michael_mic_hdr(skb, tkey->tx_hdr);
-
- if (IEEE80211_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_ctl)))
- tkey->tx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07;
-
- pos = skb_put(skb, 8);
-
- if (michael_mic(tkey->tx_tfm_michael, &tkey->key[16], tkey->tx_hdr,
- skb->data + hdr_len, skb->len - 8 - hdr_len, pos))
- return -1;
-
- return 0;
-}
-
-static void ieee80211_michael_mic_failure(struct net_device *dev,
- struct ieee80211_hdr_4addr *hdr,
- int keyidx)
-{
- union iwreq_data wrqu;
- struct iw_michaelmicfailure ev;
-
- /* TODO: needed parameters: count, keyid, key type, TSC */
- memset(&ev, 0, sizeof(ev));
- ev.flags = keyidx & IW_MICFAILURE_KEY_ID;
- if (hdr->addr1[0] & 0x01)
- ev.flags |= IW_MICFAILURE_GROUP;
- else
- ev.flags |= IW_MICFAILURE_PAIRWISE;
- ev.src_addr.sa_family = ARPHRD_ETHER;
- memcpy(ev.src_addr.sa_data, hdr->addr2, ETH_ALEN);
- memset(&wrqu, 0, sizeof(wrqu));
- wrqu.data.length = sizeof(ev);
- wireless_send_event(dev, IWEVMICHAELMICFAILURE, &wrqu, (char *) &ev);
-}
-
-static int ieee80211_michael_mic_verify(struct sk_buff *skb, int keyidx,
- int hdr_len, void *priv)
-{
- struct ieee80211_tkip_data *tkey = priv;
- u8 mic[8];
- struct ieee80211_hdr_4addr *hdr;
-
- hdr = (struct ieee80211_hdr_4addr *)skb->data;
-
- if (!tkey->key_set)
- return -1;
-
- michael_mic_hdr(skb, tkey->rx_hdr);
- if (IEEE80211_QOS_HAS_SEQ(le16_to_cpu(hdr->frame_ctl)))
- tkey->rx_hdr[12] = *(skb->data + hdr_len - 2) & 0x07;
-
- if (michael_mic(tkey->rx_tfm_michael, &tkey->key[24], tkey->rx_hdr,
- skb->data + hdr_len, skb->len - 8 - hdr_len, mic))
- return -1;
-
- if (memcmp(mic, skb->data + skb->len - 8, 8) != 0) {
- struct ieee80211_hdr_4addr *hdr;
- hdr = (struct ieee80211_hdr_4addr *)skb->data;
- printk(KERN_DEBUG "%s: Michael MIC verification failed for "
- "MSDU from %pM keyidx=%d\n",
- skb->dev ? skb->dev->name : "N/A", hdr->addr2,
- keyidx);
- if (skb->dev)
- ieee80211_michael_mic_failure(skb->dev, hdr, keyidx);
- tkey->dot11RSNAStatsTKIPLocalMICFailures++;
- return -1;
- }
-
- /* Update TSC counters for RX now that the packet verification has
- * completed. */
- tkey->rx_iv32 = tkey->rx_iv32_new;
- tkey->rx_iv16 = tkey->rx_iv16_new;
-
- skb_trim(skb, skb->len - 8);
-
- return 0;
-}
-
-
-static int ieee80211_tkip_set_key(void *key, int len, u8 *seq, void *priv)
-{
- struct ieee80211_tkip_data *tkey = priv;
- int keyidx;
- struct crypto_hash *tfm = tkey->tx_tfm_michael;
- struct crypto_blkcipher *tfm2 = tkey->tx_tfm_arc4;
- struct crypto_hash *tfm3 = tkey->rx_tfm_michael;
- struct crypto_blkcipher *tfm4 = tkey->rx_tfm_arc4;
-
- keyidx = tkey->key_idx;
- memset(tkey, 0, sizeof(*tkey));
- tkey->key_idx = keyidx;
-
- tkey->tx_tfm_michael = tfm;
- tkey->tx_tfm_arc4 = tfm2;
- tkey->rx_tfm_michael = tfm3;
- tkey->rx_tfm_arc4 = tfm4;
-
- if (len == TKIP_KEY_LEN) {
- memcpy(tkey->key, key, TKIP_KEY_LEN);
- tkey->key_set = 1;
- tkey->tx_iv16 = 1; /* TSC is initialized to 1 */
- if (seq) {
- tkey->rx_iv32 = (seq[5] << 24) | (seq[4] << 16) |
- (seq[3] << 8) | seq[2];
- tkey->rx_iv16 = (seq[1] << 8) | seq[0];
- }
- } else if (len == 0)
- tkey->key_set = 0;
- else
- return -1;
-
- return 0;
-}
-
-
-static int ieee80211_tkip_get_key(void *key, int len, u8 *seq, void *priv)
-{
- struct ieee80211_tkip_data *tkey = priv;
-
- if (len < TKIP_KEY_LEN)
- return -1;
-
- if (!tkey->key_set)
- return 0;
- memcpy(key, tkey->key, TKIP_KEY_LEN);
-
- if (seq) {
- /* Return the sequence number of the last transmitted frame. */
- u16 iv16 = tkey->tx_iv16;
- u32 iv32 = tkey->tx_iv32;
- if (iv16 == 0)
- iv32--;
- iv16--;
- seq[0] = tkey->tx_iv16;
- seq[1] = tkey->tx_iv16 >> 8;
- seq[2] = tkey->tx_iv32;
- seq[3] = tkey->tx_iv32 >> 8;
- seq[4] = tkey->tx_iv32 >> 16;
- seq[5] = tkey->tx_iv32 >> 24;
- }
-
- return TKIP_KEY_LEN;
-}
-
-
-static char *ieee80211_tkip_print_stats(char *p, void *priv)
-{
- struct ieee80211_tkip_data *tkip = priv;
- p += sprintf(p, "key[%d] alg=TKIP key_set=%d "
- "tx_pn=%02x%02x%02x%02x%02x%02x "
- "rx_pn=%02x%02x%02x%02x%02x%02x "
- "replays=%d icv_errors=%d local_mic_failures=%d\n",
- tkip->key_idx, tkip->key_set,
- (tkip->tx_iv32 >> 24) & 0xff,
- (tkip->tx_iv32 >> 16) & 0xff,
- (tkip->tx_iv32 >> 8) & 0xff,
- tkip->tx_iv32 & 0xff,
- (tkip->tx_iv16 >> 8) & 0xff,
- tkip->tx_iv16 & 0xff,
- (tkip->rx_iv32 >> 24) & 0xff,
- (tkip->rx_iv32 >> 16) & 0xff,
- (tkip->rx_iv32 >> 8) & 0xff,
- tkip->rx_iv32 & 0xff,
- (tkip->rx_iv16 >> 8) & 0xff,
- tkip->rx_iv16 & 0xff,
- tkip->dot11RSNAStatsTKIPReplays,
- tkip->dot11RSNAStatsTKIPICVErrors,
- tkip->dot11RSNAStatsTKIPLocalMICFailures);
- return p;
-}
-
-
-static struct ieee80211_crypto_ops ieee80211_crypt_tkip = {
- .name = "TKIP",
- .init = ieee80211_tkip_init,
- .deinit = ieee80211_tkip_deinit,
- .encrypt_mpdu = ieee80211_tkip_encrypt,
- .decrypt_mpdu = ieee80211_tkip_decrypt,
- .encrypt_msdu = ieee80211_michael_mic_add,
- .decrypt_msdu = ieee80211_michael_mic_verify,
- .set_key = ieee80211_tkip_set_key,
- .get_key = ieee80211_tkip_get_key,
- .print_stats = ieee80211_tkip_print_stats,
- .extra_prefix_len = 4 + 4, /* IV + ExtIV */
- .extra_postfix_len = 8 + 4, /* MIC + ICV */
- .owner = THIS_MODULE,
-};
-
-
-int ieee80211_crypto_tkip_init(void)
-{
- return ieee80211_register_crypto_ops(&ieee80211_crypt_tkip);
-}
-
-
-void ieee80211_crypto_tkip_exit(void)
-{
- ieee80211_unregister_crypto_ops(&ieee80211_crypt_tkip);
-}
-
-
-void ieee80211_tkip_null(void)
-{
-}
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_wep.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_wep.c
deleted file mode 100644
index f253672..0000000
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_crypt_wep.c
+++ /dev/null
@@ -1,277 +0,0 @@
-/*
- * Host AP crypt: host-based WEP encryption implementation for Host AP driver
- *
- * Copyright (c) 2002-2004, Jouni Malinen <jkmaline@cc.hut.fi>
- *
- * 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. See README and COPYING for
- * more details.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#include <linux/module.h>
-#include <linux/slab.h>
-#include <linux/random.h>
-#include <linux/skbuff.h>
-#include <linux/string.h>
-
-#include "ieee80211.h"
-
-#include <linux/crypto.h>
-#include <linux/scatterlist.h>
-#include <linux/crc32.h>
-
-MODULE_AUTHOR("Jouni Malinen");
-MODULE_DESCRIPTION("Host AP crypt: WEP");
-MODULE_LICENSE("GPL");
-
-struct prism2_wep_data {
- u32 iv;
-#define WEP_KEY_LEN 13
- u8 key[WEP_KEY_LEN + 1];
- u8 key_len;
- u8 key_idx;
- struct crypto_blkcipher *tx_tfm;
- struct crypto_blkcipher *rx_tfm;
-};
-
-static void *prism2_wep_init(int keyidx)
-{
- struct prism2_wep_data *priv;
-
- priv = kzalloc(sizeof(*priv), GFP_ATOMIC);
- if (priv == NULL)
- goto fail;
- priv->key_idx = keyidx;
- priv->tx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
- if (IS_ERR(priv->tx_tfm)) {
- pr_debug("could not allocate crypto API arc4\n");
- priv->tx_tfm = NULL;
- goto fail;
- }
- priv->rx_tfm = crypto_alloc_blkcipher("ecb(arc4)", 0, CRYPTO_ALG_ASYNC);
- if (IS_ERR(priv->rx_tfm)) {
- pr_debug("could not allocate crypto API arc4\n");
- priv->rx_tfm = NULL;
- goto fail;
- }
-
- /* start WEP IV from a random value */
- get_random_bytes(&priv->iv, 4);
-
- return priv;
-
-fail:
- if (priv) {
- if (priv->tx_tfm)
- crypto_free_blkcipher(priv->tx_tfm);
- if (priv->rx_tfm)
- crypto_free_blkcipher(priv->rx_tfm);
- kfree(priv);
- }
-
- return NULL;
-}
-
-static void prism2_wep_deinit(void *priv)
-{
- struct prism2_wep_data *_priv = priv;
-
- if (_priv) {
- if (_priv->tx_tfm)
- crypto_free_blkcipher(_priv->tx_tfm);
- if (_priv->rx_tfm)
- crypto_free_blkcipher(_priv->rx_tfm);
- }
-
- kfree(priv);
-}
-
-/* Perform WEP encryption on given skb that has at least 4 bytes of headroom
- * for IV and 4 bytes of tailroom for ICV. Both IV and ICV will be transmitted,
- * so the payload length increases with 8 bytes.
- *
- * WEP frame payload: IV + TX key idx, RC4(data), ICV = RC4(CRC32(data))
- */
-static int prism2_wep_encrypt(struct sk_buff *skb, int hdr_len, void *priv)
-{
- struct prism2_wep_data *wep = priv;
- struct blkcipher_desc desc = { .tfm = wep->tx_tfm };
- u32 klen, len;
- u8 key[WEP_KEY_LEN + 3];
- u8 *pos;
- u32 crc;
- u8 *icv;
- struct scatterlist sg;
-
- if (skb_headroom(skb) < 4 || skb_tailroom(skb) < 4 ||
- skb->len < hdr_len)
- return -1;
-
- len = skb->len - hdr_len;
- pos = skb_push(skb, 4);
- memmove(pos, pos + 4, hdr_len);
- pos += hdr_len;
-
- klen = 3 + wep->key_len;
-
- wep->iv++;
-
- /* Fluhrer, Mantin, and Shamir have reported weaknesses in the key
- * scheduling algorithm of RC4. At least IVs (KeyByte + 3, 0xff, N)
- * can be used to speedup attacks, so avoid using them. */
- if ((wep->iv & 0xff00) == 0xff00) {
- u8 B = (wep->iv >> 16) & 0xff;
- if (B >= 3 && B < klen)
- wep->iv += 0x0100;
- }
-
- /* Prepend 24-bit IV to RC4 key and TX frame */
- *pos++ = key[0] = (wep->iv >> 16) & 0xff;
- *pos++ = key[1] = (wep->iv >> 8) & 0xff;
- *pos++ = key[2] = wep->iv & 0xff;
- *pos++ = wep->key_idx << 6;
-
- /* Copy rest of the WEP key (the secret part) */
- memcpy(key + 3, wep->key, wep->key_len);
-
- /* Append little-endian CRC32 and encrypt it to produce ICV */
- crc = ~crc32_le(~0, pos, len);
- icv = skb_put(skb, 4);
- icv[0] = crc;
- icv[1] = crc >> 8;
- icv[2] = crc >> 16;
- icv[3] = crc >> 24;
-
- crypto_blkcipher_setkey(wep->tx_tfm, key, klen);
- sg_init_one(&sg, pos, len + 4);
-
- return crypto_blkcipher_encrypt(&desc, &sg, &sg, len + 4);
-}
-
-/* Perform WEP decryption on given buffer. Buffer includes whole WEP part of
- * the frame: IV (4 bytes), encrypted payload (including SNAP header),
- * ICV (4 bytes). len includes both IV and ICV.
- *
- * Returns 0 if frame was decrypted successfully and ICV was correct and -1 on
- * failure. If frame is OK, IV and ICV will be removed.
- */
-static int prism2_wep_decrypt(struct sk_buff *skb, int hdr_len, void *priv)
-{
- struct prism2_wep_data *wep = priv;
- struct blkcipher_desc desc = { .tfm = wep->rx_tfm };
- u32 klen, plen;
- u8 key[WEP_KEY_LEN + 3];
- u8 keyidx, *pos;
- u32 crc;
- u8 icv[4];
- struct scatterlist sg;
-
- if (skb->len < hdr_len + 8)
- return -1;
-
- pos = skb->data + hdr_len;
- key[0] = *pos++;
- key[1] = *pos++;
- key[2] = *pos++;
- keyidx = *pos++ >> 6;
- if (keyidx != wep->key_idx)
- return -1;
-
- klen = 3 + wep->key_len;
-
- /* Copy rest of the WEP key (the secret part) */
- memcpy(key + 3, wep->key, wep->key_len);
-
- /* Apply RC4 to data and compute CRC32 over decrypted data */
- plen = skb->len - hdr_len - 8;
-
- crypto_blkcipher_setkey(wep->rx_tfm, key, klen);
- sg_init_one(&sg, pos, plen + 4);
-
- if (crypto_blkcipher_decrypt(&desc, &sg, &sg, plen + 4))
- return -7;
-
- crc = ~crc32_le(~0, pos, plen);
- icv[0] = crc;
- icv[1] = crc >> 8;
- icv[2] = crc >> 16;
- icv[3] = crc >> 24;
-
- if (memcmp(icv, pos + plen, 4) != 0) {
- /* ICV mismatch - drop frame */
- return -2;
- }
-
- /* Remove IV and ICV */
- memmove(skb->data + 4, skb->data, hdr_len);
- skb_pull(skb, 4);
- skb_trim(skb, skb->len - 4);
- return 0;
-}
-
-static int prism2_wep_set_key(void *key, int len, u8 *seq, void *priv)
-{
- struct prism2_wep_data *wep = priv;
-
- if (len < 0 || len > WEP_KEY_LEN)
- return -1;
-
- memcpy(wep->key, key, len);
- wep->key_len = len;
-
- return 0;
-}
-
-static int prism2_wep_get_key(void *key, int len, u8 *seq, void *priv)
-{
- struct prism2_wep_data *wep = priv;
-
- if (len < wep->key_len)
- return -1;
-
- memcpy(key, wep->key, wep->key_len);
-
- return wep->key_len;
-}
-
-static char *prism2_wep_print_stats(char *p, void *priv)
-{
- struct prism2_wep_data *wep = priv;
- p += sprintf(p, "key[%d] alg=WEP len=%d\n",
- wep->key_idx, wep->key_len);
- return p;
-}
-
-static struct ieee80211_crypto_ops ieee80211_crypt_wep = {
- .name = "WEP",
- .init = prism2_wep_init,
- .deinit = prism2_wep_deinit,
- .encrypt_mpdu = prism2_wep_encrypt,
- .decrypt_mpdu = prism2_wep_decrypt,
- .encrypt_msdu = NULL,
- .decrypt_msdu = NULL,
- .set_key = prism2_wep_set_key,
- .get_key = prism2_wep_get_key,
- .print_stats = prism2_wep_print_stats,
- .extra_prefix_len = 4, /* IV */
- .extra_postfix_len = 4, /* ICV */
- .owner = THIS_MODULE,
-};
-
-int ieee80211_crypto_wep_init(void)
-{
- return ieee80211_register_crypto_ops(&ieee80211_crypt_wep);
-}
-
-void ieee80211_crypto_wep_exit(void)
-{
- ieee80211_unregister_crypto_ops(&ieee80211_crypt_wep);
-}
-
-void ieee80211_wep_null(void)
-{
- return;
-}
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_module.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_module.c
deleted file mode 100644
index 07a1fbb..0000000
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_module.c
+++ /dev/null
@@ -1,203 +0,0 @@
-/*******************************************************************************
-
- Copyright(c) 2004 Intel Corporation. All rights reserved.
-
- Portions of this file are based on the WEP enablement code provided by the
- Host AP project hostap-drivers v0.1.3
- Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
- <jkmaline@cc.hut.fi>
- Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
-
- 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., 59
- Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
- The full GNU General Public License is included in this distribution in the
- file called LICENSE.
-
- Contact Information:
- James P. Ketrenos <ipw2100-admin@linux.intel.com>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-*******************************************************************************/
-
-#include <linux/compiler.h>
-//#include <linux/config.h>
-#include <linux/errno.h>
-#include <linux/if_arp.h>
-#include <linux/in6.h>
-#include <linux/in.h>
-#include <linux/ip.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/netdevice.h>
-#include <linux/pci.h>
-#include <linux/proc_fs.h>
-#include <linux/skbuff.h>
-#include <linux/slab.h>
-#include <linux/tcp.h>
-#include <linux/types.h>
-#include <linux/wireless.h>
-#include <linux/etherdevice.h>
-#include <linux/uaccess.h>
-#include <net/arp.h>
-#include <net/net_namespace.h>
-
-#include "ieee80211.h"
-
-MODULE_DESCRIPTION("802.11 data/management/control stack");
-MODULE_AUTHOR("Copyright (C) 2004 Intel Corporation <jketreno@linux.intel.com>");
-MODULE_LICENSE("GPL");
-
-#define DRV_NAME "ieee80211"
-
-static inline int ieee80211_networks_allocate(struct ieee80211_device *ieee)
-{
- if (ieee->networks)
- return 0;
-
- ieee->networks = kcalloc(
- MAX_NETWORK_COUNT, sizeof(struct ieee80211_network),
- GFP_KERNEL);
- if (!ieee->networks)
- return -ENOMEM;
-
- return 0;
-}
-
-static inline void ieee80211_networks_free(struct ieee80211_device *ieee)
-{
- if (!ieee->networks)
- return;
- kfree(ieee->networks);
- ieee->networks = NULL;
-}
-
-static inline void ieee80211_networks_initialize(struct ieee80211_device *ieee)
-{
- int i;
-
- INIT_LIST_HEAD(&ieee->network_free_list);
- INIT_LIST_HEAD(&ieee->network_list);
- for (i = 0; i < MAX_NETWORK_COUNT; i++)
- list_add_tail(&ieee->networks[i].list, &ieee->network_free_list);
-}
-
-
-struct net_device *alloc_ieee80211(int sizeof_priv)
-{
- struct ieee80211_device *ieee;
- struct net_device *dev;
- int i, err;
-
- IEEE80211_DEBUG_INFO("Initializing...\n");
-
- dev = alloc_etherdev(sizeof(struct ieee80211_device) + sizeof_priv);
- if (!dev) {
- IEEE80211_ERROR("Unable to network device.\n");
- goto failed;
- }
- ieee = netdev_priv(dev);
-
- ieee->dev = dev;
-
- err = ieee80211_networks_allocate(ieee);
- if (err) {
- IEEE80211_ERROR("Unable to allocate beacon storage: %d\n",
- err);
- goto failed;
- }
- ieee80211_networks_initialize(ieee);
-
- /* Default fragmentation threshold is maximum payload size */
- ieee->fts = DEFAULT_FTS;
- ieee->scan_age = DEFAULT_MAX_SCAN_AGE;
- ieee->open_wep = 1;
-
- /* Default to enabling full open WEP with host based encrypt/decrypt */
- ieee->host_encrypt = 1;
- ieee->host_decrypt = 1;
- ieee->ieee802_1x = 1; /* Default to supporting 802.1x */
-
- INIT_LIST_HEAD(&ieee->crypt_deinit_list);
- init_timer(&ieee->crypt_deinit_timer);
- ieee->crypt_deinit_timer.data = (unsigned long)ieee;
- ieee->crypt_deinit_timer.function = ieee80211_crypt_deinit_handler;
-
- spin_lock_init(&ieee->lock);
- spin_lock_init(&ieee->wpax_suitlist_lock);
-
- ieee->wpax_type_set = 0;
- ieee->wpa_enabled = 0;
- ieee->tkip_countermeasures = 0;
- ieee->drop_unencrypted = 0;
- ieee->privacy_invoked = 0;
- ieee->ieee802_1x = 1;
- ieee->raw_tx = 0;
-
- ieee80211_softmac_init(ieee);
-
- for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++)
- INIT_LIST_HEAD(&ieee->ibss_mac_hash[i]);
-
- for (i = 0; i < 17; i++) {
- ieee->last_rxseq_num[i] = -1;
- ieee->last_rxfrag_num[i] = -1;
- ieee->last_packet_time[i] = 0;
- }
-//These function were added to load crypte module autoly
- ieee80211_tkip_null();
- ieee80211_wep_null();
- ieee80211_ccmp_null();
- return dev;
-
- failed:
- if (dev)
- free_netdev(dev);
- return NULL;
-}
-
-
-void free_ieee80211(struct net_device *dev)
-{
- struct ieee80211_device *ieee = netdev_priv(dev);
-
- int i;
- struct list_head *p, *q;
-
-
- ieee80211_softmac_free(ieee);
- del_timer_sync(&ieee->crypt_deinit_timer);
- ieee80211_crypt_deinit_entries(ieee, 1);
-
- for (i = 0; i < WEP_KEYS; i++) {
- struct ieee80211_crypt_data *crypt = ieee->crypt[i];
- if (crypt) {
- if (crypt->ops)
- crypt->ops->deinit(crypt->priv);
- kfree(crypt);
- ieee->crypt[i] = NULL;
- }
- }
-
- ieee80211_networks_free(ieee);
-
- for (i = 0; i < IEEE_IBSS_MAC_HASH_SIZE; i++) {
- list_for_each_safe(p, q, &ieee->ibss_mac_hash[i]) {
- kfree(list_entry(p, struct ieee_ibss_seq, list));
- list_del(p);
- }
- }
-
-
- free_netdev(dev);
-}
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c
deleted file mode 100644
index b522b57..0000000
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_rx.c
+++ /dev/null
@@ -1,1486 +0,0 @@
-/*
- * Original code based Host AP (software wireless LAN access point) driver
- * for Intersil Prism2/2.5/3 - hostap.o module, common routines
- *
- * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
- * <jkmaline@cc.hut.fi>
- * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
- * Copyright (c) 2004, 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. See README and COPYING for
- * more details.
- ******************************************************************************
-
- Few modifications for Realtek's Wi-Fi drivers by
- Andrea Merello <andrea.merello@gmail.com>
-
- A special thanks goes to Realtek for their support !
-
-******************************************************************************/
-
-
-#include <linux/compiler.h>
-//#include <linux/config.h>
-#include <linux/errno.h>
-#include <linux/if_arp.h>
-#include <linux/in6.h>
-#include <linux/in.h>
-#include <linux/ip.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/netdevice.h>
-#include <linux/pci.h>
-#include <linux/proc_fs.h>
-#include <linux/skbuff.h>
-#include <linux/slab.h>
-#include <linux/tcp.h>
-#include <linux/types.h>
-#include <linux/wireless.h>
-#include <linux/etherdevice.h>
-#include <linux/uaccess.h>
-#include <linux/ctype.h>
-
-#include "ieee80211.h"
-#include "dot11d.h"
-static inline void ieee80211_monitor_rx(struct ieee80211_device *ieee,
- struct sk_buff *skb,
- struct ieee80211_rx_stats *rx_stats)
-{
- struct ieee80211_hdr_4addr *hdr =
- (struct ieee80211_hdr_4addr *)skb->data;
- u16 fc = le16_to_cpu(hdr->frame_ctl);
-
- skb->dev = ieee->dev;
- skb_reset_mac_header(skb);
- skb_pull(skb, ieee80211_get_hdrlen(fc));
- skb->pkt_type = PACKET_OTHERHOST;
- skb->protocol = __constant_htons(ETH_P_80211_RAW);
- memset(skb->cb, 0, sizeof(skb->cb));
- netif_rx(skb);
-}
-
-
-/* Called only as a tasklet (software IRQ) */
-static struct ieee80211_frag_entry *
-ieee80211_frag_cache_find(struct ieee80211_device *ieee, unsigned int seq,
- unsigned int frag, u8 tid, u8 *src, u8 *dst)
-{
- struct ieee80211_frag_entry *entry;
- int i;
-
- for (i = 0; i < IEEE80211_FRAG_CACHE_LEN; i++) {
- entry = &ieee->frag_cache[tid][i];
- if (entry->skb != NULL &&
- time_after(jiffies, entry->first_frag_time + 2 * HZ)) {
- IEEE80211_DEBUG_FRAG(
- "expiring fragment cache entry "
- "seq=%u last_frag=%u\n",
- entry->seq, entry->last_frag);
- dev_kfree_skb_any(entry->skb);
- entry->skb = NULL;
- }
-
- if (entry->skb != NULL && entry->seq == seq &&
- (entry->last_frag + 1 == frag || frag == -1) &&
- memcmp(entry->src_addr, src, ETH_ALEN) == 0 &&
- memcmp(entry->dst_addr, dst, ETH_ALEN) == 0)
- return entry;
- }
-
- return NULL;
-}
-
-/* Called only as a tasklet (software IRQ) */
-static struct sk_buff *
-ieee80211_frag_cache_get(struct ieee80211_device *ieee,
- struct ieee80211_hdr_4addr *hdr)
-{
- struct sk_buff *skb = NULL;
- u16 fc = le16_to_cpu(hdr->frame_ctl);
- u16 sc = le16_to_cpu(hdr->seq_ctl);
- unsigned int frag = WLAN_GET_SEQ_FRAG(sc);
- unsigned int seq = WLAN_GET_SEQ_SEQ(sc);
- struct ieee80211_frag_entry *entry;
- struct ieee80211_hdr_3addrqos *hdr_3addrqos;
- struct ieee80211_hdr_4addrqos *hdr_4addrqos;
- u8 tid;
-
- if (((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS) && IEEE80211_QOS_HAS_SEQ(fc)) {
- hdr_4addrqos = (struct ieee80211_hdr_4addrqos *)hdr;
- tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & IEEE80211_QOS_TID;
- tid = UP2AC(tid);
- tid++;
- } else if (IEEE80211_QOS_HAS_SEQ(fc)) {
- hdr_3addrqos = (struct ieee80211_hdr_3addrqos *)hdr;
- tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & IEEE80211_QOS_TID;
- tid = UP2AC(tid);
- tid++;
- } else {
- tid = 0;
- }
-
- if (frag == 0) {
- /* Reserve enough space to fit maximum frame length */
- skb = dev_alloc_skb(ieee->dev->mtu +
- sizeof(struct ieee80211_hdr_4addr) +
- 8 /* LLC */ +
- 2 /* alignment */ +
- 8 /* WEP */ +
- ETH_ALEN /* WDS */ +
- (IEEE80211_QOS_HAS_SEQ(fc) ? 2 : 0) /* QOS Control */);
- if (skb == NULL)
- return NULL;
-
- entry = &ieee->frag_cache[tid][ieee->frag_next_idx[tid]];
- ieee->frag_next_idx[tid]++;
- if (ieee->frag_next_idx[tid] >= IEEE80211_FRAG_CACHE_LEN)
- ieee->frag_next_idx[tid] = 0;
-
- if (entry->skb != NULL)
- dev_kfree_skb_any(entry->skb);
-
- entry->first_frag_time = jiffies;
- entry->seq = seq;
- entry->last_frag = frag;
- entry->skb = skb;
- memcpy(entry->src_addr, hdr->addr2, ETH_ALEN);
- memcpy(entry->dst_addr, hdr->addr1, ETH_ALEN);
- } else {
- /* received a fragment of a frame for which the head fragment
- * should have already been received */
- entry = ieee80211_frag_cache_find(ieee, seq, frag, tid, hdr->addr2,
- hdr->addr1);
- if (entry != NULL) {
- entry->last_frag = frag;
- skb = entry->skb;
- }
- }
-
- return skb;
-}
-
-
-/* Called only as a tasklet (software IRQ) */
-static int ieee80211_frag_cache_invalidate(struct ieee80211_device *ieee,
- struct ieee80211_hdr_4addr *hdr)
-{
- u16 fc = le16_to_cpu(hdr->frame_ctl);
- u16 sc = le16_to_cpu(hdr->seq_ctl);
- unsigned int seq = WLAN_GET_SEQ_SEQ(sc);
- struct ieee80211_frag_entry *entry;
- struct ieee80211_hdr_3addrqos *hdr_3addrqos;
- struct ieee80211_hdr_4addrqos *hdr_4addrqos;
- u8 tid;
-
- if (((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS) && IEEE80211_QOS_HAS_SEQ(fc)) {
- hdr_4addrqos = (struct ieee80211_hdr_4addrqos *)hdr;
- tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & IEEE80211_QOS_TID;
- tid = UP2AC(tid);
- tid++;
- } else if (IEEE80211_QOS_HAS_SEQ(fc)) {
- hdr_3addrqos = (struct ieee80211_hdr_3addrqos *)hdr;
- tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & IEEE80211_QOS_TID;
- tid = UP2AC(tid);
- tid++;
- } else {
- tid = 0;
- }
-
- entry = ieee80211_frag_cache_find(ieee, seq, -1, tid, hdr->addr2,
- hdr->addr1);
-
- if (entry == NULL) {
- IEEE80211_DEBUG_FRAG(
- "could not invalidate fragment cache "
- "entry (seq=%u)\n", seq);
- return -1;
- }
-
- entry->skb = NULL;
- return 0;
-}
-
-
-
-/* ieee80211_rx_frame_mgtmt
- *
- * Responsible for handling management control frames
- *
- * Called by ieee80211_rx */
-static inline int
-ieee80211_rx_frame_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb,
- struct ieee80211_rx_stats *rx_stats, u16 type,
- u16 stype)
-{
- struct ieee80211_hdr_4addr *hdr;
-
- // cheat the the hdr type
- hdr = (struct ieee80211_hdr_4addr *)skb->data;
-
- /* On the struct stats definition there is written that
- * this is not mandatory.... but seems that the probe
- * response parser uses it
- */
- rx_stats->len = skb->len;
- ieee80211_rx_mgt(ieee, (struct ieee80211_hdr_4addr *)skb->data,
- rx_stats);
-
- if ((ieee->state == IEEE80211_LINKED) && (memcmp(hdr->addr3, ieee->current_network.bssid, ETH_ALEN))) {
- dev_kfree_skb_any(skb);
- return 0;
- }
-
- ieee80211_rx_frame_softmac(ieee, skb, rx_stats, type, stype);
-
- dev_kfree_skb_any(skb);
-
- return 0;
-
-}
-
-
-
-/* See IEEE 802.1H for LLC/SNAP encapsulation/decapsulation */
-/* Ethernet-II snap header (RFC1042 for most EtherTypes) */
-static unsigned char rfc1042_header[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0x00 };
-/* Bridge-Tunnel header (for EtherTypes ETH_P_AARP and ETH_P_IPX) */
-static unsigned char bridge_tunnel_header[] = { 0xaa, 0xaa, 0x03, 0x00, 0x00, 0xf8 };
-/* No encapsulation header if EtherType < 0x600 (=length) */
-
-/* Called by ieee80211_rx_frame_decrypt */
-static int ieee80211_is_eapol_frame(struct ieee80211_device *ieee,
- struct sk_buff *skb, size_t hdrlen)
-{
- struct net_device *dev = ieee->dev;
- u16 fc, ethertype;
- struct ieee80211_hdr_4addr *hdr;
- u8 *pos;
-
- if (skb->len < 24)
- return 0;
-
- hdr = (struct ieee80211_hdr_4addr *)skb->data;
- fc = le16_to_cpu(hdr->frame_ctl);
-
- /* check that the frame is unicast frame to us */
- if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
- IEEE80211_FCTL_TODS &&
- memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0 &&
- memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN) == 0) {
- /* ToDS frame with own addr BSSID and DA */
- } else if ((fc & (IEEE80211_FCTL_TODS | IEEE80211_FCTL_FROMDS)) ==
- IEEE80211_FCTL_FROMDS &&
- memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN) == 0) {
- /* FromDS frame with own addr as DA */
- } else
- return 0;
-
- if (skb->len < 24 + 8)
- return 0;
-
- /* check for port access entity Ethernet type */
-// pos = skb->data + 24;
- pos = skb->data + hdrlen;
- ethertype = (pos[6] << 8) | pos[7];
- if (ethertype == ETH_P_PAE)
- return 1;
-
- return 0;
-}
-
-/* Called only as a tasklet (software IRQ), by ieee80211_rx */
-static inline int
-ieee80211_rx_frame_decrypt(struct ieee80211_device *ieee, struct sk_buff *skb,
- struct ieee80211_crypt_data *crypt)
-{
- struct ieee80211_hdr_4addr *hdr;
- int res, hdrlen;
-
- if (crypt == NULL || crypt->ops->decrypt_mpdu == NULL)
- return 0;
-
- 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()) {
- netdev_dbg(ieee->dev,
- "TKIP countermeasures: dropped received packet from %pM\n",
- ieee->dev->name, hdr->addr2);
- }
- return -1;
- }
-#endif
-
- atomic_inc(&crypt->refcnt);
- res = crypt->ops->decrypt_mpdu(skb, hdrlen, crypt->priv);
- atomic_dec(&crypt->refcnt);
- if (res < 0) {
- IEEE80211_DEBUG_DROP(
- "decryption failed (SA=%pM"
- ") res=%d\n", hdr->addr2, res);
- if (res == -2)
- IEEE80211_DEBUG_DROP("Decryption failed ICV "
- "mismatch (key %d)\n",
- skb->data[hdrlen + 3] >> 6);
- ieee->ieee_stats.rx_discards_undecryptable++;
- return -1;
- }
-
- return res;
-}
-
-
-/* Called only as a tasklet (software IRQ), by ieee80211_rx */
-static inline int
-ieee80211_rx_frame_decrypt_msdu(struct ieee80211_device *ieee,
- struct sk_buff *skb, int keyidx,
- struct ieee80211_crypt_data *crypt)
-{
- struct ieee80211_hdr_4addr *hdr;
- int res, hdrlen;
-
- if (crypt == NULL || crypt->ops->decrypt_msdu == NULL)
- return 0;
-
- hdr = (struct ieee80211_hdr_4addr *)skb->data;
- hdrlen = ieee80211_get_hdrlen(le16_to_cpu(hdr->frame_ctl));
-
- atomic_inc(&crypt->refcnt);
- res = crypt->ops->decrypt_msdu(skb, keyidx, hdrlen, crypt->priv);
- atomic_dec(&crypt->refcnt);
- if (res < 0) {
- netdev_dbg(ieee->dev,
- "MSDU decryption/MIC verification failed (SA=%pM keyidx=%d)\n",
- hdr->addr2, keyidx);
- return -1;
- }
-
- return 0;
-}
-
-
-/* this function is stolen from ipw2200 driver*/
-#define IEEE_PACKET_RETRY_TIME (5*HZ)
-static int is_duplicate_packet(struct ieee80211_device *ieee,
- struct ieee80211_hdr_4addr *header)
-{
- u16 fc = le16_to_cpu(header->frame_ctl);
- u16 sc = le16_to_cpu(header->seq_ctl);
- u16 seq = WLAN_GET_SEQ_SEQ(sc);
- u16 frag = WLAN_GET_SEQ_FRAG(sc);
- u16 *last_seq, *last_frag;
- unsigned long *last_time;
- struct ieee80211_hdr_3addrqos *hdr_3addrqos;
- struct ieee80211_hdr_4addrqos *hdr_4addrqos;
- u8 tid;
-
- //TO2DS and QoS
- if (((fc & IEEE80211_FCTL_DSTODS) == IEEE80211_FCTL_DSTODS) && IEEE80211_QOS_HAS_SEQ(fc)) {
- hdr_4addrqos = (struct ieee80211_hdr_4addrqos *)header;
- tid = le16_to_cpu(hdr_4addrqos->qos_ctl) & IEEE80211_QOS_TID;
- tid = UP2AC(tid);
- tid++;
- } else if (IEEE80211_QOS_HAS_SEQ(fc)) { //QoS
- hdr_3addrqos = (struct ieee80211_hdr_3addrqos *)header;
- tid = le16_to_cpu(hdr_3addrqos->qos_ctl) & IEEE80211_QOS_TID;
- tid = UP2AC(tid);
- tid++;
- } else { // no QoS
- tid = 0;
- }
- switch (ieee->iw_mode) {
- case IW_MODE_ADHOC:
- {
- struct list_head *p;
- struct ieee_ibss_seq *entry = NULL;
- u8 *mac = header->addr2;
- int index = mac[5] % IEEE_IBSS_MAC_HASH_SIZE;
-
- list_for_each(p, &ieee->ibss_mac_hash[index]) {
- entry = list_entry(p, struct ieee_ibss_seq, list);
- if (!memcmp(entry->mac, mac, ETH_ALEN))
- break;
- }
- // if (memcmp(entry->mac, mac, ETH_ALEN)){
- if (p == &ieee->ibss_mac_hash[index]) {
- entry = kmalloc(sizeof(struct ieee_ibss_seq), GFP_ATOMIC);
- if (!entry)
- return 0;
-
- memcpy(entry->mac, mac, ETH_ALEN);
- entry->seq_num[tid] = seq;
- entry->frag_num[tid] = frag;
- entry->packet_time[tid] = jiffies;
- list_add(&entry->list, &ieee->ibss_mac_hash[index]);
- return 0;
- }
- last_seq = &entry->seq_num[tid];
- last_frag = &entry->frag_num[tid];
- last_time = &entry->packet_time[tid];
- break;
- }
-
- case IW_MODE_INFRA:
- last_seq = &ieee->last_rxseq_num[tid];
- last_frag = &ieee->last_rxfrag_num[tid];
- last_time = &ieee->last_packet_time[tid];
-
- break;
- default:
- return 0;
- }
-
-// if(tid != 0) {
-// printk(KERN_WARNING ":)))))))))))%x %x %x, fc(%x)\n", tid, *last_seq, seq, header->frame_ctl);
-// }
- if ((*last_seq == seq) &&
- time_after(*last_time + IEEE_PACKET_RETRY_TIME, jiffies)) {
- if (*last_frag == frag) {
- //printk(KERN_WARNING "[1] go drop!\n");
- goto drop;
-
- }
- if (*last_frag + 1 != frag)
- /* out-of-order fragment */
- //printk(KERN_WARNING "[2] go drop!\n");
- goto drop;
- } else
- *last_seq = seq;
-
- *last_frag = frag;
- *last_time = jiffies;
- return 0;
-
-drop:
-// BUG_ON(!(fc & IEEE80211_FCTL_RETRY));
-// printk("DUP\n");
-
- return 1;
-}
-
-
-/* All received frames are sent to this function. @skb contains the frame in
- * IEEE 802.11 format, i.e., in the format it was sent over air.
- * This function is called only as a tasklet (software IRQ). */
-int ieee80211_rtl_rx(struct ieee80211_device *ieee, struct sk_buff *skb,
- struct ieee80211_rx_stats *rx_stats)
-{
- struct net_device *dev = ieee->dev;
- //struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- struct ieee80211_hdr_4addr *hdr;
-
- size_t hdrlen;
- u16 fc, type, stype, sc;
- struct net_device_stats *stats;
- unsigned int frag;
- u8 *payload;
- u16 ethertype;
- u8 dst[ETH_ALEN];
- u8 src[ETH_ALEN];
- u8 bssid[ETH_ALEN];
- struct ieee80211_crypt_data *crypt = NULL;
- int keyidx = 0;
-
- // cheat the the hdr type
- hdr = (struct ieee80211_hdr_4addr *)skb->data;
- stats = &ieee->stats;
-
- if (skb->len < 10) {
- netdev_info(ieee->dev, "SKB length < 10\n");
- goto rx_dropped;
- }
-
- fc = le16_to_cpu(hdr->frame_ctl);
- type = WLAN_FC_GET_TYPE(fc);
- stype = WLAN_FC_GET_STYPE(fc);
- sc = le16_to_cpu(hdr->seq_ctl);
-
- frag = WLAN_GET_SEQ_FRAG(sc);
-
-//YJ,add,080828,for keep alive
- if ((fc & IEEE80211_FCTL_TODS) != IEEE80211_FCTL_TODS) {
- if (!memcmp(hdr->addr1, dev->dev_addr, ETH_ALEN))
- ieee->NumRxUnicast++;
- } else {
- if (!memcmp(hdr->addr3, dev->dev_addr, ETH_ALEN))
- ieee->NumRxUnicast++;
- }
-//YJ,add,080828,for keep alive,end
-
- hdrlen = ieee80211_get_hdrlen(fc);
-
-
- if (ieee->iw_mode == IW_MODE_MONITOR) {
- ieee80211_monitor_rx(ieee, skb, rx_stats);
- stats->rx_packets++;
- stats->rx_bytes += skb->len;
- return 1;
- }
-
- if (ieee->host_decrypt) {
- int idx = 0;
- if (skb->len >= hdrlen + 3)
- idx = skb->data[hdrlen + 3] >> 6;
- crypt = ieee->crypt[idx];
-
- /* allow NULL decrypt to indicate an station specific override
- * for default encryption */
- if (crypt && (crypt->ops == NULL ||
- crypt->ops->decrypt_mpdu == NULL))
- crypt = NULL;
-
- if (!crypt && (fc & IEEE80211_FCTL_WEP)) {
- /* This seems to be triggered by some (multicast?)
- * frames from other than current BSS, so just drop the
- * frames silently instead of filling system log with
- * these reports. */
- IEEE80211_DEBUG_DROP("Decryption failed (not set)"
- " (SA=%pM)\n",
- hdr->addr2);
- ieee->ieee_stats.rx_discards_undecryptable++;
- goto rx_dropped;
- }
- }
-
- if (skb->len < IEEE80211_DATA_HDR3_LEN)
- goto rx_dropped;
-
- // if QoS enabled, should check the sequence for each of the AC
- if (is_duplicate_packet(ieee, hdr))
- goto rx_dropped;
-
-
- if (type == IEEE80211_FTYPE_MGMT) {
- if (ieee80211_rx_frame_mgmt(ieee, skb, rx_stats, type, stype))
- goto rx_dropped;
- else
- goto rx_exit;
- }
-
- /* Data frame - extract src/dst addresses */
- switch (fc & (IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS)) {
- case IEEE80211_FCTL_FROMDS:
- memcpy(dst, hdr->addr1, ETH_ALEN);
- memcpy(src, hdr->addr3, ETH_ALEN);
- memcpy(bssid, hdr->addr2, ETH_ALEN);
- break;
- case IEEE80211_FCTL_TODS:
- memcpy(dst, hdr->addr3, ETH_ALEN);
- memcpy(src, hdr->addr2, ETH_ALEN);
- memcpy(bssid, hdr->addr1, ETH_ALEN);
- break;
- case IEEE80211_FCTL_FROMDS | IEEE80211_FCTL_TODS:
- if (skb->len < IEEE80211_DATA_HDR4_LEN)
- goto rx_dropped;
- memcpy(dst, hdr->addr3, ETH_ALEN);
- memcpy(src, hdr->addr4, ETH_ALEN);
- memcpy(bssid, ieee->current_network.bssid, ETH_ALEN);
- break;
- case 0:
- memcpy(dst, hdr->addr1, ETH_ALEN);
- memcpy(src, hdr->addr2, ETH_ALEN);
- memcpy(bssid, hdr->addr3, ETH_ALEN);
- break;
- }
-
-
- dev->last_rx = jiffies;
-
-
- /* Nullfunc frames may have PS-bit set, so they must be passed to
- * hostap_handle_sta_rx() before being dropped here. */
- if (stype != IEEE80211_STYPE_DATA &&
- stype != IEEE80211_STYPE_DATA_CFACK &&
- stype != IEEE80211_STYPE_DATA_CFPOLL &&
- stype != IEEE80211_STYPE_DATA_CFACKPOLL &&
- stype != IEEE80211_STYPE_QOS_DATA//add by David,2006.8.4
- ) {
- if (stype != IEEE80211_STYPE_NULLFUNC)
- IEEE80211_DEBUG_DROP(
- "RX: dropped data frame "
- "with no data (type=0x%02x, "
- "subtype=0x%02x, len=%d)\n",
- type, stype, skb->len);
- goto rx_dropped;
- }
- if (memcmp(bssid, ieee->current_network.bssid, ETH_ALEN))
- goto rx_dropped;
-
- ieee->NumRxDataInPeriod++;
- ieee->NumRxOkTotal++;
- /* skb: hdr + (possibly fragmented, possibly encrypted) payload */
-
- if (ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) &&
- (keyidx = ieee80211_rx_frame_decrypt(ieee, skb, crypt)) < 0)
- goto rx_dropped;
-
- hdr = (struct ieee80211_hdr_4addr *)skb->data;
-
- /* skb: hdr + (possibly fragmented) plaintext payload */
- // PR: FIXME: hostap has additional conditions in the "if" below:
- // ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) &&
- if ((frag != 0 || (fc & IEEE80211_FCTL_MOREFRAGS))) {
- int flen;
- struct sk_buff *frag_skb = ieee80211_frag_cache_get(ieee, hdr);
- IEEE80211_DEBUG_FRAG("Rx Fragment received (%u)\n", frag);
-
- if (!frag_skb) {
- IEEE80211_DEBUG(IEEE80211_DL_RX | IEEE80211_DL_FRAG,
- "Rx cannot get skb from fragment "
- "cache (morefrag=%d seq=%u frag=%u)\n",
- (fc & IEEE80211_FCTL_MOREFRAGS) != 0,
- WLAN_GET_SEQ_SEQ(sc), frag);
- goto rx_dropped;
- }
- flen = skb->len;
- if (frag != 0)
- flen -= hdrlen;
-
- if (frag_skb->tail + flen > frag_skb->end) {
- netdev_warn(ieee->dev,
- "host decrypted and reassembled frame did not fit skb\n");
- ieee80211_frag_cache_invalidate(ieee, hdr);
- goto rx_dropped;
- }
-
- if (frag == 0) {
- /* copy first fragment (including full headers) into
- * beginning of the fragment cache skb */
- memcpy(skb_put(frag_skb, flen), skb->data, flen);
- } else {
- /* append frame payload to the end of the fragment
- * cache skb */
- memcpy(skb_put(frag_skb, flen), skb->data + hdrlen,
- flen);
- }
- dev_kfree_skb_any(skb);
- skb = NULL;
-
- if (fc & IEEE80211_FCTL_MOREFRAGS) {
- /* more fragments expected - leave the skb in fragment
- * cache for now; it will be delivered to upper layers
- * after all fragments have been received */
- goto rx_exit;
- }
-
- /* this was the last fragment and the frame will be
- * delivered, so remove skb from fragment cache */
- skb = frag_skb;
- hdr = (struct ieee80211_hdr_4addr *)skb->data;
- ieee80211_frag_cache_invalidate(ieee, hdr);
- }
-
- /* skb: hdr + (possible reassembled) full MSDU payload; possibly still
- * encrypted/authenticated */
- if (ieee->host_decrypt && (fc & IEEE80211_FCTL_WEP) &&
- ieee80211_rx_frame_decrypt_msdu(ieee, skb, keyidx, crypt))
- goto rx_dropped;
-
- hdr = (struct ieee80211_hdr_4addr *)skb->data;
- if (crypt && !(fc & IEEE80211_FCTL_WEP) && !ieee->open_wep) {
- if (/*ieee->ieee802_1x &&*/
- ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
-
-#ifdef CONFIG_IEEE80211_DEBUG
- /* pass unencrypted EAPOL frames even if encryption is
- * configured */
- struct eapol *eap = (struct eapol *)(skb->data +
- 24);
- IEEE80211_DEBUG_EAP("RX: IEEE 802.1X EAPOL frame: %s\n",
- eap_get_type(eap->type));
-#endif
- } else {
- IEEE80211_DEBUG_DROP(
- "encryption configured, but RX "
- "frame not encrypted (SA=%pM)\n",
- hdr->addr2);
- goto rx_dropped;
- }
- }
-
-#ifdef CONFIG_IEEE80211_DEBUG
- if (crypt && !(fc & IEEE80211_FCTL_WEP) &&
- ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
- struct eapol *eap = (struct eapol *)(skb->data +
- 24);
- IEEE80211_DEBUG_EAP("RX: IEEE 802.1X EAPOL frame: %s\n",
- eap_get_type(eap->type));
- }
-#endif
-
- if (crypt && !(fc & IEEE80211_FCTL_WEP) && !ieee->open_wep &&
- !ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
- IEEE80211_DEBUG_DROP(
- "dropped unencrypted RX data "
- "frame from %pM"
- " (drop_unencrypted=1)\n",
- hdr->addr2);
- goto rx_dropped;
- }
-/*
- if(ieee80211_is_eapol_frame(ieee, skb, hdrlen)) {
- printk(KERN_WARNING "RX: IEEE802.1X EPAOL frame!\n");
- }
-*/
- /* skb: hdr + (possible reassembled) full plaintext payload */
- payload = skb->data + hdrlen;
- ethertype = (payload[6] << 8) | payload[7];
-
-
- /* convert hdr + possible LLC headers into Ethernet header */
- if (skb->len - hdrlen >= 8 &&
- ((memcmp(payload, rfc1042_header, SNAP_SIZE) == 0 &&
- ethertype != ETH_P_AARP && ethertype != ETH_P_IPX) ||
- memcmp(payload, bridge_tunnel_header, SNAP_SIZE) == 0)) {
- /* remove RFC1042 or Bridge-Tunnel encapsulation and
- * replace EtherType */
- skb_pull(skb, hdrlen + SNAP_SIZE);
- memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
- memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
- } else {
- u16 len;
- /* Leave Ethernet header part of hdr and full payload */
- skb_pull(skb, hdrlen);
- len = htons(skb->len);
- memcpy(skb_push(skb, 2), &len, 2);
- memcpy(skb_push(skb, ETH_ALEN), src, ETH_ALEN);
- memcpy(skb_push(skb, ETH_ALEN), dst, ETH_ALEN);
- }
-
-
- stats->rx_packets++;
- stats->rx_bytes += skb->len;
-
- if (skb) {
- skb->protocol = eth_type_trans(skb, dev);
- memset(skb->cb, 0, sizeof(skb->cb));
- skb->dev = dev;
- skb->ip_summed = CHECKSUM_NONE; /* 802.11 crc not sufficient */
- ieee->last_rx_ps_time = jiffies;
- netif_rx(skb);
- }
-
- rx_exit:
- return 1;
-
- rx_dropped:
- stats->rx_dropped++;
-
- /* Returning 0 indicates to caller that we have not handled the SKB--
- * so it is still allocated and can be used again by underlying
- * hardware as a DMA target */
- return 0;
-}
-
-#define MGMT_FRAME_FIXED_PART_LENGTH 0x24
-
-static inline int ieee80211_is_ofdm_rate(u8 rate)
-{
- switch (rate & ~IEEE80211_BASIC_RATE_MASK) {
- case IEEE80211_OFDM_RATE_6MB:
- case IEEE80211_OFDM_RATE_9MB:
- case IEEE80211_OFDM_RATE_12MB:
- case IEEE80211_OFDM_RATE_18MB:
- case IEEE80211_OFDM_RATE_24MB:
- case IEEE80211_OFDM_RATE_36MB:
- case IEEE80211_OFDM_RATE_48MB:
- case IEEE80211_OFDM_RATE_54MB:
- return 1;
- }
- return 0;
-}
-
-static inline int ieee80211_SignalStrengthTranslate(int CurrSS)
-{
- int RetSS;
-
- // Step 1. Scale mapping.
- if (CurrSS >= 71 && CurrSS <= 100)
- RetSS = 90 + ((CurrSS - 70) / 3);
- else if (CurrSS >= 41 && CurrSS <= 70)
- RetSS = 78 + ((CurrSS - 40) / 3);
- else if (CurrSS >= 31 && CurrSS <= 40)
- RetSS = 66 + (CurrSS - 30);
- else if (CurrSS >= 21 && CurrSS <= 30)
- RetSS = 54 + (CurrSS - 20);
- else if (CurrSS >= 5 && CurrSS <= 20)
- RetSS = 42 + (((CurrSS - 5) * 2) / 3);
- else if (CurrSS == 4)
- RetSS = 36;
- else if (CurrSS == 3)
- RetSS = 27;
- else if (CurrSS == 2)
- RetSS = 18;
- else if (CurrSS == 1)
- RetSS = 9;
- else
- RetSS = CurrSS;
-
- //RT_TRACE(COMP_DBG, DBG_LOUD, ("##### After Mapping: LastSS: %d, CurrSS: %d, RetSS: %d\n", LastSS, CurrSS, RetSS));
-
- // Step 2. Smoothing.
-
- //RT_TRACE(COMP_DBG, DBG_LOUD, ("$$$$$ After Smoothing: LastSS: %d, CurrSS: %d, RetSS: %d\n", LastSS, CurrSS, RetSS));
-
- return RetSS;
-}
-
-static inline void
-ieee80211_extract_country_ie(struct ieee80211_device *ieee,
- struct ieee80211_info_element *info_element,
- struct ieee80211_network *network, u8 *addr2)
-{
- if (IS_DOT11D_ENABLE(ieee)) {
- if (info_element->len != 0) {
- memcpy(network->CountryIeBuf, info_element->data, info_element->len);
- network->CountryIeLen = info_element->len;
-
- if (!IS_COUNTRY_IE_VALID(ieee))
- Dot11d_UpdateCountryIe(ieee, addr2, info_element->len, info_element->data);
- }
-
- //
- // 070305, rcnjko: I update country IE watch dog here because
- // some AP (e.g. Cisco 1242) don't include country IE in their
- // probe response frame.
- //
- if (IS_EQUAL_CIE_SRC(ieee, addr2))
- UPDATE_CIE_WATCHDOG(ieee);
- }
-
-}
-
-/* SignalStrengthIndex is 0-100 */
-static int ieee80211_TranslateToDbm(unsigned char SignalStrengthIndex)
-{
- unsigned char SignalPower; // in dBm.
-
- // Translate to dBm (x=0.5y-95).
- SignalPower = (int)SignalStrengthIndex * 7 / 10;
- SignalPower -= 95;
-
- return SignalPower;
-}
-inline int ieee80211_network_init(
- struct ieee80211_device *ieee,
- struct ieee80211_probe_response *beacon,
- struct ieee80211_network *network,
- struct ieee80211_rx_stats *stats)
-{
-#ifdef CONFIG_IEEE80211_DEBUG
- char rates_str[64];
- char *p;
-#endif
- struct ieee80211_info_element *info_element;
- u16 left;
- u8 i;
- short offset;
- u8 curRate = 0, hOpRate = 0, curRate_ex = 0;
-
- /* Pull out fixed field data */
- memcpy(network->bssid, beacon->header.addr3, ETH_ALEN);
- network->capability = beacon->capability;
- network->last_scanned = jiffies;
- network->time_stamp[0] = beacon->time_stamp[0];
- network->time_stamp[1] = beacon->time_stamp[1];
- network->beacon_interval = beacon->beacon_interval;
- /* Where to pull this? beacon->listen_interval;*/
- network->listen_interval = 0x0A;
- network->rates_len = network->rates_ex_len = 0;
- network->last_associate = 0;
- network->ssid_len = 0;
- network->flags = 0;
- network->atim_window = 0;
- network->QoS_Enable = 0;
-//by amy 080312
- network->HighestOperaRate = 0;
-//by amy 080312
- network->Turbo_Enable = 0;
- network->CountryIeLen = 0;
- memset(network->CountryIeBuf, 0, MAX_IE_LEN);
-
- if (stats->freq == IEEE80211_52GHZ_BAND) {
- /* for A band (No DS info) */
- network->channel = stats->received_channel;
- } else
- network->flags |= NETWORK_HAS_CCK;
-
- network->wpa_ie_len = 0;
- network->rsn_ie_len = 0;
-
- info_element = &beacon->info_element;
- left = stats->len - ((void *)info_element - (void *)beacon);
- while (left >= sizeof(struct ieee80211_info_element_hdr)) {
- if (sizeof(struct ieee80211_info_element_hdr) + info_element->len > left) {
- IEEE80211_DEBUG_SCAN("SCAN: parse failed: info_element->len + 2 > left : info_element->len+2=%d left=%d.\n",
- info_element->len + sizeof(struct ieee80211_info_element),
- left);
- return 1;
- }
-
- switch (info_element->id) {
- case MFIE_TYPE_SSID:
- if (ieee80211_is_empty_essid(info_element->data,
- info_element->len)) {
- network->flags |= NETWORK_EMPTY_ESSID;
- break;
- }
-
- network->ssid_len = min(info_element->len,
- (u8)IW_ESSID_MAX_SIZE);
- memcpy(network->ssid, info_element->data, network->ssid_len);
- if (network->ssid_len < IW_ESSID_MAX_SIZE)
- memset(network->ssid + network->ssid_len, 0,
- IW_ESSID_MAX_SIZE - network->ssid_len);
-
- IEEE80211_DEBUG_SCAN("MFIE_TYPE_SSID: '%s' len=%d.\n",
- network->ssid, network->ssid_len);
- break;
-
- case MFIE_TYPE_RATES:
-#ifdef CONFIG_IEEE80211_DEBUG
- p = rates_str;
-#endif
- network->rates_len = min(info_element->len, MAX_RATES_LENGTH);
- for (i = 0; i < network->rates_len; i++) {
- network->rates[i] = info_element->data[i];
- curRate = network->rates[i] & 0x7f;
- if (hOpRate < curRate)
- hOpRate = curRate;
-#ifdef CONFIG_IEEE80211_DEBUG
- p += snprintf(p, sizeof(rates_str) - (p - rates_str), "%02X ", network->rates[i]);
-#endif
- if (ieee80211_is_ofdm_rate(info_element->data[i])) {
- network->flags |= NETWORK_HAS_OFDM;
- if (info_element->data[i] &
- IEEE80211_BASIC_RATE_MASK)
- network->flags &=
- ~NETWORK_HAS_CCK;
- }
- }
-
- IEEE80211_DEBUG_SCAN("MFIE_TYPE_RATES: '%s' (%d)\n",
- rates_str, network->rates_len);
- break;
-
- case MFIE_TYPE_RATES_EX:
-#ifdef CONFIG_IEEE80211_DEBUG
- p = rates_str;
-#endif
- network->rates_ex_len = min(info_element->len, MAX_RATES_EX_LENGTH);
- for (i = 0; i < network->rates_ex_len; i++) {
- network->rates_ex[i] = info_element->data[i];
- curRate_ex = network->rates_ex[i] & 0x7f;
- if (hOpRate < curRate_ex)
- hOpRate = curRate_ex;
-#ifdef CONFIG_IEEE80211_DEBUG
- p += snprintf(p, sizeof(rates_str) - (p - rates_str), "%02X ", network->rates[i]);
-#endif
- if (ieee80211_is_ofdm_rate(info_element->data[i])) {
- network->flags |= NETWORK_HAS_OFDM;
- if (info_element->data[i] &
- IEEE80211_BASIC_RATE_MASK)
- network->flags &=
- ~NETWORK_HAS_CCK;
- }
- }
-
- IEEE80211_DEBUG_SCAN("MFIE_TYPE_RATES_EX: '%s' (%d)\n",
- rates_str, network->rates_ex_len);
- break;
-
- case MFIE_TYPE_DS_SET:
- IEEE80211_DEBUG_SCAN("MFIE_TYPE_DS_SET: %d\n",
- info_element->data[0]);
- if (stats->freq == IEEE80211_24GHZ_BAND)
- network->channel = info_element->data[0];
- break;
-
- case MFIE_TYPE_FH_SET:
- IEEE80211_DEBUG_SCAN("MFIE_TYPE_FH_SET: ignored\n");
- break;
-
- case MFIE_TYPE_CF_SET:
- IEEE80211_DEBUG_SCAN("MFIE_TYPE_CF_SET: ignored\n");
- break;
-
- case MFIE_TYPE_TIM:
-
- if (info_element->len < 4)
- break;
-
- network->dtim_period = info_element->data[1];
-
- if (ieee->state != IEEE80211_LINKED)
- break;
-
- network->last_dtim_sta_time[0] = jiffies;
- network->last_dtim_sta_time[1] = stats->mac_time[1];
-
- network->dtim_data = IEEE80211_DTIM_VALID;
-
- if (info_element->data[0] != 0)
- break;
-
- if (info_element->data[2] & 1)
- network->dtim_data |= IEEE80211_DTIM_MBCAST;
-
- offset = (info_element->data[2] >> 1)*2;
-
- //printk("offset1:%x aid:%x\n",offset, ieee->assoc_id);
-
- /* add and modified for ps 2008.1.22 */
- if (ieee->assoc_id < 8*offset ||
- ieee->assoc_id > 8*(offset + info_element->len - 3)) {
- break;
- }
-
- offset = (ieee->assoc_id/8) - offset;// + ((aid % 8)? 0 : 1) ;
-
- // printk("offset:%x data:%x, ucast:%d\n", offset,
- // info_element->data[3+offset] ,
- // info_element->data[3+offset] & (1<<(ieee->assoc_id%8)));
-
- if (info_element->data[3+offset] & (1<<(ieee->assoc_id%8)))
- network->dtim_data |= IEEE80211_DTIM_UCAST;
-
- break;
-
- case MFIE_TYPE_IBSS_SET:
- IEEE80211_DEBUG_SCAN("MFIE_TYPE_IBSS_SET: ignored\n");
- break;
-
- case MFIE_TYPE_CHALLENGE:
- IEEE80211_DEBUG_SCAN("MFIE_TYPE_CHALLENGE: ignored\n");
- break;
-
- case MFIE_TYPE_GENERIC:
- //nic is 87B
- IEEE80211_DEBUG_SCAN("MFIE_TYPE_GENERIC: %d bytes\n",
- info_element->len);
- if (info_element->len >= 4 &&
- info_element->data[0] == 0x00 &&
- info_element->data[1] == 0x50 &&
- info_element->data[2] == 0xf2 &&
- info_element->data[3] == 0x01) {
- network->wpa_ie_len = min(info_element->len + 2,
- MAX_WPA_IE_LEN);
- memcpy(network->wpa_ie, info_element,
- network->wpa_ie_len);
- }
-
- if (info_element->len == 7 &&
- info_element->data[0] == 0x00 &&
- info_element->data[1] == 0xe0 &&
- info_element->data[2] == 0x4c &&
- info_element->data[3] == 0x01 &&
- info_element->data[4] == 0x02) {
- network->Turbo_Enable = 1;
- }
- if (1 == stats->nic_type) //nic 87
- break;
-
- if (info_element->len >= 5 &&
- info_element->data[0] == 0x00 &&
- info_element->data[1] == 0x50 &&
- info_element->data[2] == 0xf2 &&
- info_element->data[3] == 0x02 &&
- info_element->data[4] == 0x00) {
- //printk(KERN_WARNING "wmm info updated: %x\n", info_element->data[6]);
- //WMM Information Element
- network->wmm_info = info_element->data[6];
- network->QoS_Enable = 1;
- }
-
- if (info_element->len >= 8 &&
- info_element->data[0] == 0x00 &&
- info_element->data[1] == 0x50 &&
- info_element->data[2] == 0xf2 &&
- info_element->data[3] == 0x02 &&
- info_element->data[4] == 0x01) {
- // Not care about version at present.
- //WMM Information Element
- //printk(KERN_WARNING "wmm info&param updated: %x\n", info_element->data[6]);
- network->wmm_info = info_element->data[6];
- //WMM Parameter Element
- memcpy(network->wmm_param, (u8 *)(info_element->data + 8), (info_element->len - 8));
- network->QoS_Enable = 1;
- }
- break;
-
- case MFIE_TYPE_RSN:
- IEEE80211_DEBUG_SCAN("MFIE_TYPE_RSN: %d bytes\n",
- info_element->len);
- network->rsn_ie_len = min(info_element->len + 2,
- MAX_WPA_IE_LEN);
- memcpy(network->rsn_ie, info_element,
- network->rsn_ie_len);
- break;
- case MFIE_TYPE_COUNTRY:
- IEEE80211_DEBUG_SCAN("MFIE_TYPE_COUNTRY: %d bytes\n",
- info_element->len);
-// printk("=====>Receive <%s> Country IE\n",network->ssid);
- ieee80211_extract_country_ie(ieee, info_element, network, beacon->header.addr2);
- break;
- default:
- IEEE80211_DEBUG_SCAN("unsupported IE %d\n",
- info_element->id);
- break;
- }
-
- left -= sizeof(struct ieee80211_info_element_hdr) +
- info_element->len;
- info_element = (struct ieee80211_info_element *)
- &info_element->data[info_element->len];
- }
-//by amy 080312
- network->HighestOperaRate = hOpRate;
-//by amy 080312
- network->mode = 0;
- if (stats->freq == IEEE80211_52GHZ_BAND)
- network->mode = IEEE_A;
- else {
- if (network->flags & NETWORK_HAS_OFDM)
- network->mode |= IEEE_G;
- if (network->flags & NETWORK_HAS_CCK)
- network->mode |= IEEE_B;
- }
-
- if (network->mode == 0) {
- IEEE80211_DEBUG_SCAN("Filtered out '%s (%pM)' "
- "network.\n",
- escape_essid(network->ssid,
- network->ssid_len),
- network->bssid);
- return 1;
- }
-
- if (ieee80211_is_empty_essid(network->ssid, network->ssid_len))
- network->flags |= NETWORK_EMPTY_ESSID;
-
- stats->signal = ieee80211_TranslateToDbm(stats->signalstrength);
- //stats->noise = stats->signal - stats->noise;
- stats->noise = ieee80211_TranslateToDbm(100 - stats->signalstrength) - 25;
- memcpy(&network->stats, stats, sizeof(network->stats));
-
- return 0;
-}
-
-static inline int is_same_network(struct ieee80211_network *src,
- struct ieee80211_network *dst,
- struct ieee80211_device *ieee)
-{
- /* A network is only a duplicate if the channel, BSSID, ESSID
- * and the capability field (in particular IBSS and BSS) all match.
- * We treat all <hidden> with the same BSSID and channel
- * as one network */
- return (((src->ssid_len == dst->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) && //YJ,mod,080819,for hidden ap
- //((src->ssid_len == dst->ssid_len) &&
- (src->channel == dst->channel) &&
- !memcmp(src->bssid, dst->bssid, ETH_ALEN) &&
- (!memcmp(src->ssid, dst->ssid, src->ssid_len) || (ieee->iw_mode == IW_MODE_INFRA)) && //YJ,mod,080819,for hidden ap
- //!memcmp(src->ssid, dst->ssid, src->ssid_len) &&
- ((src->capability & WLAN_CAPABILITY_IBSS) ==
- (dst->capability & WLAN_CAPABILITY_IBSS)) &&
- ((src->capability & WLAN_CAPABILITY_BSS) ==
- (dst->capability & WLAN_CAPABILITY_BSS)));
-}
-
-inline void update_network(struct ieee80211_network *dst,
- struct ieee80211_network *src)
-{
- unsigned char quality = src->stats.signalstrength;
- unsigned char signal = 0;
- unsigned char noise = 0;
- if (dst->stats.signalstrength > 0)
- quality = (dst->stats.signalstrength * 5 + src->stats.signalstrength + 5)/6;
- signal = ieee80211_TranslateToDbm(quality);
- //noise = signal - src->stats.noise;
- if (dst->stats.noise > 0)
- noise = (dst->stats.noise * 5 + src->stats.noise)/6;
- //if(strcmp(dst->ssid, "linksys_lzm000") == 0)
-// printk("ssid:%s, quality:%d, signal:%d\n", dst->ssid, quality, signal);
- memcpy(&dst->stats, &src->stats, sizeof(struct ieee80211_rx_stats));
- dst->stats.signalstrength = quality;
- dst->stats.signal = signal;
-// printk("==================>stats.signal is %d\n",dst->stats.signal);
- dst->stats.noise = noise;
-
-
- dst->capability = src->capability;
- memcpy(dst->rates, src->rates, src->rates_len);
- dst->rates_len = src->rates_len;
- memcpy(dst->rates_ex, src->rates_ex, src->rates_ex_len);
- dst->rates_ex_len = src->rates_ex_len;
- dst->HighestOperaRate = src->HighestOperaRate;
- //printk("==========>in %s: src->ssid is %s,chan is %d\n",__func__,src->ssid,src->channel);
-
- //YJ,add,080819,for hidden ap
- if (src->ssid_len > 0) {
- //if(src->ssid_len == 13)
- // printk("=====================>>>>>>>> Dst ssid: %s Src ssid: %s\n", dst->ssid, src->ssid);
- memset(dst->ssid, 0, dst->ssid_len);
- dst->ssid_len = src->ssid_len;
- memcpy(dst->ssid, src->ssid, src->ssid_len);
- }
- //YJ,add,080819,for hidden ap,end
-
- dst->channel = src->channel;
- dst->mode = src->mode;
- dst->flags = src->flags;
- dst->time_stamp[0] = src->time_stamp[0];
- dst->time_stamp[1] = src->time_stamp[1];
-
- dst->beacon_interval = src->beacon_interval;
- dst->listen_interval = src->listen_interval;
- dst->atim_window = src->atim_window;
- dst->dtim_period = src->dtim_period;
- dst->dtim_data = src->dtim_data;
- dst->last_dtim_sta_time[0] = src->last_dtim_sta_time[0];
- dst->last_dtim_sta_time[1] = src->last_dtim_sta_time[1];
-// printk("update:%s, dtim_period:%x, dtim_data:%x\n", src->ssid, src->dtim_period, src->dtim_data);
- memcpy(dst->wpa_ie, src->wpa_ie, src->wpa_ie_len);
- dst->wpa_ie_len = src->wpa_ie_len;
- memcpy(dst->rsn_ie, src->rsn_ie, src->rsn_ie_len);
- dst->rsn_ie_len = src->rsn_ie_len;
-
- dst->last_scanned = jiffies;
- /* dst->last_associate is not overwritten */
-// disable QoS process now, added by David 2006/7/25
-#if 1
- dst->wmm_info = src->wmm_info; //sure to exist in beacon or probe response frame.
-/*
- if((dst->wmm_info^src->wmm_info)&0x0f) {//Param Set Count change, update Parameter
- memcpy(dst->wmm_param, src->wmm_param, IEEE80211_AC_PRAM_LEN);
- }
-*/
- if (src->wmm_param[0].ac_aci_acm_aifsn || \
- src->wmm_param[1].ac_aci_acm_aifsn || \
- src->wmm_param[2].ac_aci_acm_aifsn || \
- src->wmm_param[3].ac_aci_acm_aifsn) {
- memcpy(dst->wmm_param, src->wmm_param, WME_AC_PRAM_LEN);
- }
- dst->QoS_Enable = src->QoS_Enable;
-#else
- dst->QoS_Enable = 1;//for Rtl8187 simulation
-#endif
- dst->SignalStrength = src->SignalStrength;
- dst->Turbo_Enable = src->Turbo_Enable;
- dst->CountryIeLen = src->CountryIeLen;
- memcpy(dst->CountryIeBuf, src->CountryIeBuf, src->CountryIeLen);
-}
-
-
-inline void
-ieee80211_process_probe_response(struct ieee80211_device *ieee,
- struct ieee80211_probe_response *beacon,
- struct ieee80211_rx_stats *stats)
-{
- struct ieee80211_network network;
- struct ieee80211_network *target;
- struct ieee80211_network *oldest = NULL;
-#ifdef CONFIG_IEEE80211_DEBUG
- struct ieee80211_info_element *info_element = &beacon->info_element;
-#endif
- unsigned long flags;
- short renew;
- u8 wmm_info;
- u8 is_beacon = (WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == IEEE80211_STYPE_BEACON) ? 1 : 0; //YJ,add,080819,for hidden ap
-
- memset(&network, 0, sizeof(struct ieee80211_network));
-
- IEEE80211_DEBUG_SCAN(
- "'%s' (%pM): %c%c%c%c %c%c%c%c-%c%c%c%c %c%c%c%c\n",
- escape_essid(info_element->data, info_element->len),
- beacon->header.addr3,
- (beacon->capability & (1<<0xf)) ? '1' : '0',
- (beacon->capability & (1<<0xe)) ? '1' : '0',
- (beacon->capability & (1<<0xd)) ? '1' : '0',
- (beacon->capability & (1<<0xc)) ? '1' : '0',
- (beacon->capability & (1<<0xb)) ? '1' : '0',
- (beacon->capability & (1<<0xa)) ? '1' : '0',
- (beacon->capability & (1<<0x9)) ? '1' : '0',
- (beacon->capability & (1<<0x8)) ? '1' : '0',
- (beacon->capability & (1<<0x7)) ? '1' : '0',
- (beacon->capability & (1<<0x6)) ? '1' : '0',
- (beacon->capability & (1<<0x5)) ? '1' : '0',
- (beacon->capability & (1<<0x4)) ? '1' : '0',
- (beacon->capability & (1<<0x3)) ? '1' : '0',
- (beacon->capability & (1<<0x2)) ? '1' : '0',
- (beacon->capability & (1<<0x1)) ? '1' : '0',
- (beacon->capability & (1<<0x0)) ? '1' : '0');
-
- if (ieee80211_network_init(ieee, beacon, &network, stats)) {
- IEEE80211_DEBUG_SCAN("Dropped '%s' (%pM) via %s.\n",
- escape_essid(info_element->data,
- info_element->len),
- beacon->header.addr3,
- WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
- IEEE80211_STYPE_PROBE_RESP ?
- "PROBE RESPONSE" : "BEACON");
- return;
- }
-
- // For Asus EeePc request,
- // (1) if wireless adapter receive get any 802.11d country code in AP beacon,
- // wireless adapter should follow the country code.
- // (2) If there is no any country code in beacon,
- // then wireless adapter should do active scan from ch1~11 and
- // passive scan from ch12~14
- if (ieee->bGlobalDomain) {
- if (WLAN_FC_GET_STYPE(beacon->header.frame_ctl) == IEEE80211_STYPE_PROBE_RESP) {
- // Case 1: Country code
- if (IS_COUNTRY_IE_VALID(ieee)) {
- if (!IsLegalChannel(ieee, network.channel)) {
- printk("GetScanInfo(): For Country code, filter probe response at channel(%d).\n", network.channel);
- return;
- }
- }
- // Case 2: No any country code.
- else {
- // Filter over channel ch12~14
- if (network.channel > 11) {
- printk("GetScanInfo(): For Global Domain, filter probe response at channel(%d).\n", network.channel);
- return;
- }
- }
- } else {
- // Case 1: Country code
- if (IS_COUNTRY_IE_VALID(ieee)) {
- if (!IsLegalChannel(ieee, network.channel)) {
- printk("GetScanInfo(): For Country code, filter beacon at channel(%d).\n", network.channel);
- return;
- }
- }
- // Case 2: No any country code.
- else {
- // Filter over channel ch12~14
- if (network.channel > 14) {
- printk("GetScanInfo(): For Global Domain, filter beacon at channel(%d).\n", network.channel);
- return;
- }
- }
- }
- }
- /* The network parsed correctly -- so now we scan our known networks
- * to see if we can find it in our list.
- *
- * NOTE: This search is definitely not optimized. Once its doing
- * the "right thing" we'll optimize it for efficiency if
- * necessary */
-
- /* Search for this entry in the list and update it if it is
- * already there. */
-
- spin_lock_irqsave(&ieee->lock, flags);
-
- if (is_same_network(&ieee->current_network, &network, ieee)) {
- wmm_info = ieee->current_network.wmm_info;
- //YJ,add,080819,for hidden ap
- if (is_beacon == 0)
- network.flags = (~NETWORK_EMPTY_ESSID & network.flags)|(NETWORK_EMPTY_ESSID & ieee->current_network.flags);
- else if (ieee->state == IEEE80211_LINKED)
- ieee->NumRxBcnInPeriod++;
- //YJ,add,080819,for hidden ap,end
- //printk("====>network.ssid=%s cur_ssid=%s\n", network.ssid, ieee->current_network.ssid);
- update_network(&ieee->current_network, &network);
- }
-
- list_for_each_entry(target, &ieee->network_list, list) {
- if (is_same_network(target, &network, ieee))
- break;
- if ((oldest == NULL) ||
- (target->last_scanned < oldest->last_scanned))
- oldest = target;
- }
-
- /* If we didn't find a match, then get a new network slot to initialize
- * with this beacon's information */
- if (&target->list == &ieee->network_list) {
- if (list_empty(&ieee->network_free_list)) {
- /* If there are no more slots, expire the oldest */
- list_del(&oldest->list);
- target = oldest;
- IEEE80211_DEBUG_SCAN("Expired '%s' (%pM) from "
- "network list.\n",
- escape_essid(target->ssid,
- target->ssid_len),
- target->bssid);
- } else {
- /* Otherwise just pull from the free list */
- target = list_entry(ieee->network_free_list.next,
- struct ieee80211_network, list);
- list_del(ieee->network_free_list.next);
- }
-
-
-#ifdef CONFIG_IEEE80211_DEBUG
- IEEE80211_DEBUG_SCAN("Adding '%s' (%pM) via %s.\n",
- escape_essid(network.ssid,
- network.ssid_len),
- network.bssid,
- WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
- IEEE80211_STYPE_PROBE_RESP ?
- "PROBE RESPONSE" : "BEACON");
-#endif
-
- memcpy(target, &network, sizeof(*target));
- list_add_tail(&target->list, &ieee->network_list);
- } else {
- IEEE80211_DEBUG_SCAN("Updating '%s' (%pM) via %s.\n",
- escape_essid(target->ssid,
- target->ssid_len),
- target->bssid,
- WLAN_FC_GET_STYPE(beacon->header.frame_ctl) ==
- IEEE80211_STYPE_PROBE_RESP ?
- "PROBE RESPONSE" : "BEACON");
-
- /* we have an entry and we are going to update it. But this entry may
- * be already expired. In this case we do the same as we found a new
- * net and call the new_net handler
- */
- renew = !time_after(target->last_scanned + ieee->scan_age, jiffies);
- //YJ,add,080819,for hidden ap
- if (is_beacon == 0)
- network.flags = (~NETWORK_EMPTY_ESSID & network.flags)|(NETWORK_EMPTY_ESSID & target->flags);
- //if(strncmp(network.ssid, "linksys-c",9) == 0)
- // printk("====>2 network.ssid=%s FLAG=%d target.ssid=%s FLAG=%d\n", network.ssid, network.flags, target->ssid, target->flags);
- if (((network.flags & NETWORK_EMPTY_ESSID) == NETWORK_EMPTY_ESSID) \
- && (((network.ssid_len > 0) && (strncmp(target->ssid, network.ssid, network.ssid_len)))\
- || ((ieee->current_network.ssid_len == network.ssid_len) && (strncmp(ieee->current_network.ssid, network.ssid, network.ssid_len) == 0) && (ieee->state == IEEE80211_NOLINK))))
- renew = 1;
- //YJ,add,080819,for hidden ap,end
- update_network(target, &network);
- }
-
- spin_unlock_irqrestore(&ieee->lock, flags);
-}
-
-void ieee80211_rx_mgt(struct ieee80211_device *ieee,
- struct ieee80211_hdr_4addr *header,
- struct ieee80211_rx_stats *stats)
-{
- switch (WLAN_FC_GET_STYPE(header->frame_ctl)) {
-
- case IEEE80211_STYPE_BEACON:
- IEEE80211_DEBUG_MGMT("received BEACON (%d)\n",
- WLAN_FC_GET_STYPE(header->frame_ctl));
- IEEE80211_DEBUG_SCAN("Beacon\n");
- ieee80211_process_probe_response(
- ieee, (struct ieee80211_probe_response *)header, stats);
- break;
-
- case IEEE80211_STYPE_PROBE_RESP:
- IEEE80211_DEBUG_MGMT("received PROBE RESPONSE (%d)\n",
- WLAN_FC_GET_STYPE(header->frame_ctl));
- IEEE80211_DEBUG_SCAN("Probe response\n");
- ieee80211_process_probe_response(
- ieee, (struct ieee80211_probe_response *)header, stats);
- break;
- }
-}
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c
deleted file mode 100644
index 03eb164..0000000
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac.c
+++ /dev/null
@@ -1,2711 +0,0 @@
-/* IEEE 802.11 SoftMAC layer
- * Copyright (c) 2005 Andrea Merello <andrea.merello@gmail.com>
- *
- * Mostly extracted from the rtl8180-sa2400 driver for the
- * in-kernel generic ieee802.11 stack.
- *
- * Few lines might be stolen from other part of the ieee80211
- * stack. Copyright who own it's copyright
- *
- * WPA code stolen from the ipw2200 driver.
- * Copyright who own it's copyright.
- *
- * released under the GPL
- */
-
-#include "ieee80211.h"
-
-#include <linux/random.h>
-#include <linux/delay.h>
-#include <linux/slab.h>
-#include <linux/interrupt.h>
-#include <linux/uaccess.h>
-#include <linux/etherdevice.h>
-
-#include "dot11d.h"
-
-short ieee80211_is_54g(const struct ieee80211_network *net)
-{
- return (net->rates_ex_len > 0) || (net->rates_len > 4);
-}
-
-short ieee80211_is_shortslot(const struct ieee80211_network *net)
-{
- return net->capability & WLAN_CAPABILITY_SHORT_SLOT;
-}
-
-/* returns the total length needed for placing the RATE MFIE
- * tag and the EXTENDED RATE MFIE tag if needed.
- * It encludes two bytes per tag for the tag itself and its len
- */
-static unsigned int ieee80211_MFIE_rate_len(struct ieee80211_device *ieee)
-{
- unsigned int rate_len = 0;
-
- if (ieee->modulation & IEEE80211_CCK_MODULATION)
- rate_len = IEEE80211_CCK_RATE_LEN + 2;
-
- if (ieee->modulation & IEEE80211_OFDM_MODULATION)
-
- rate_len += IEEE80211_OFDM_RATE_LEN + 2;
-
- return rate_len;
-}
-
-/* place the MFIE rate, tag to the memory (double) poised.
- * Then it updates the pointer so that it points after the new MFIE tag added.
- */
-static void ieee80211_MFIE_Brate(struct ieee80211_device *ieee, u8 **tag_p)
-{
- u8 *tag = *tag_p;
-
- if (ieee->modulation & IEEE80211_CCK_MODULATION) {
- *tag++ = MFIE_TYPE_RATES;
- *tag++ = 4;
- *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
- *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
- *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
- *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
- }
-
- /* We may add an option for custom rates that specific HW might support */
- *tag_p = tag;
-}
-
-static void ieee80211_MFIE_Grate(struct ieee80211_device *ieee, u8 **tag_p)
-{
- u8 *tag = *tag_p;
-
- if (ieee->modulation & IEEE80211_OFDM_MODULATION) {
- *tag++ = MFIE_TYPE_RATES_EX;
- *tag++ = 8;
- *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB;
- *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB;
- *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB;
- *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB;
- *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB;
- *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB;
- *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB;
- *tag++ = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB;
-
- }
- /* We may add an option for custom rates that specific HW might support */
- *tag_p = tag;
-}
-
-static void ieee80211_WMM_Info(struct ieee80211_device *ieee, u8 **tag_p)
-{
- u8 *tag = *tag_p;
-
- *tag++ = MFIE_TYPE_GENERIC; /* 0 */
- *tag++ = 7;
- *tag++ = 0x00;
- *tag++ = 0x50;
- *tag++ = 0xf2;
- *tag++ = 0x02; /* 5 */
- *tag++ = 0x00;
- *tag++ = 0x01;
-#ifdef SUPPORT_USPD
- if (ieee->current_network.wmm_info & 0x80)
- *tag++ = 0x0f|MAX_SP_Len;
- else
- *tag++ = MAX_SP_Len;
-#else
- *tag++ = MAX_SP_Len;
-#endif
- *tag_p = tag;
-}
-
-static void ieee80211_TURBO_Info(struct ieee80211_device *ieee, u8 **tag_p)
-{
- u8 *tag = *tag_p;
- *tag++ = MFIE_TYPE_GENERIC; /* 0 */
- *tag++ = 7;
- *tag++ = 0x00;
- *tag++ = 0xe0;
- *tag++ = 0x4c;
- *tag++ = 0x01; /* 5 */
- *tag++ = 0x02;
- *tag++ = 0x11;
- *tag++ = 0x00;
- *tag_p = tag;
- printk(KERN_ALERT "This is enable turbo mode IE process\n");
-}
-
-static void enqueue_mgmt(struct ieee80211_device *ieee, struct sk_buff *skb)
-{
- int nh;
- nh = (ieee->mgmt_queue_head + 1) % MGMT_QUEUE_NUM;
-
- ieee->mgmt_queue_head = nh;
- ieee->mgmt_queue_ring[nh] = skb;
-}
-
-static struct sk_buff *dequeue_mgmt(struct ieee80211_device *ieee)
-{
- struct sk_buff *ret;
-
- if (ieee->mgmt_queue_tail == ieee->mgmt_queue_head)
- return NULL;
-
- ret = ieee->mgmt_queue_ring[ieee->mgmt_queue_tail];
-
- ieee->mgmt_queue_tail =
- (ieee->mgmt_queue_tail + 1) % MGMT_QUEUE_NUM;
-
- return ret;
-}
-
-static void init_mgmt_queue(struct ieee80211_device *ieee)
-{
- ieee->mgmt_queue_tail = ieee->mgmt_queue_head = 0;
-}
-
-void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl);
-
-inline void softmac_mgmt_xmit(struct sk_buff *skb,
- struct ieee80211_device *ieee)
-{
- unsigned long flags;
- short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
- struct ieee80211_hdr_3addr *header =
- (struct ieee80211_hdr_3addr *) skb->data;
-
- spin_lock_irqsave(&ieee->lock, flags);
-
- /* called with 2nd param 0, no mgmt lock required */
- ieee80211_sta_wakeup(ieee, 0);
-
- if (single) {
- if (ieee->queue_stop) {
- enqueue_mgmt(ieee, skb);
- } else {
- header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0]<<4);
-
- if (ieee->seq_ctrl[0] == 0xFFF)
- ieee->seq_ctrl[0] = 0;
- else
- ieee->seq_ctrl[0]++;
-
- /* avoid watchdog triggers */
- ieee->dev->trans_start = jiffies;
- ieee->softmac_data_hard_start_xmit(skb, ieee->dev, ieee->basic_rate);
- }
-
- spin_unlock_irqrestore(&ieee->lock, flags);
- } else {
- spin_unlock_irqrestore(&ieee->lock, flags);
- spin_lock_irqsave(&ieee->mgmt_tx_lock, flags);
-
- header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
-
- if (ieee->seq_ctrl[0] == 0xFFF)
- ieee->seq_ctrl[0] = 0;
- else
- ieee->seq_ctrl[0]++;
-
- /* avoid watchdog triggers */
- ieee->dev->trans_start = jiffies;
- ieee->softmac_hard_start_xmit(skb, ieee->dev);
-
- spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags);
- }
-}
-
-inline void softmac_ps_mgmt_xmit(struct sk_buff *skb,
- struct ieee80211_device *ieee)
-{
- short single = ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE;
- struct ieee80211_hdr_3addr *header =
- (struct ieee80211_hdr_3addr *) skb->data;
-
- if (single) {
- header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
-
- if (ieee->seq_ctrl[0] == 0xFFF)
- ieee->seq_ctrl[0] = 0;
- else
- ieee->seq_ctrl[0]++;
-
- /* avoid watchdog triggers */
- ieee->dev->trans_start = jiffies;
- ieee->softmac_data_hard_start_xmit(skb, ieee->dev, ieee->basic_rate);
- } else {
- header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
-
- if (ieee->seq_ctrl[0] == 0xFFF)
- ieee->seq_ctrl[0] = 0;
- else
- ieee->seq_ctrl[0]++;
-
- /* avoid watchdog triggers */
- ieee->dev->trans_start = jiffies;
- ieee->softmac_hard_start_xmit(skb, ieee->dev);
- }
-}
-
-inline struct sk_buff *
-ieee80211_disassociate_skb(struct ieee80211_network *beacon,
- struct ieee80211_device *ieee, u8 asRsn)
-{
- struct sk_buff *skb;
- struct ieee80211_disassoc_frame *disass;
-
- skb = dev_alloc_skb(sizeof(struct ieee80211_disassoc_frame));
- if (!skb)
- return NULL;
-
- disass = (struct ieee80211_disassoc_frame *) skb_put(skb, sizeof(struct ieee80211_disassoc_frame));
- disass->header.frame_control = cpu_to_le16(IEEE80211_STYPE_DISASSOC);
- disass->header.duration_id = 0;
-
- memcpy(disass->header.addr1, beacon->bssid, ETH_ALEN);
- memcpy(disass->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
- memcpy(disass->header.addr3, beacon->bssid, ETH_ALEN);
-
- disass->reasoncode = asRsn;
- return skb;
-}
-
-void SendDisassociation(struct ieee80211_device *ieee, u8 *asSta, u8 asRsn)
-{
- struct ieee80211_network *beacon = &ieee->current_network;
- struct sk_buff *skb;
- skb = ieee80211_disassociate_skb(beacon, ieee, asRsn);
- if (skb)
- softmac_mgmt_xmit(skb, ieee);
-}
-
-inline struct sk_buff *ieee80211_probe_req(struct ieee80211_device *ieee)
-{
- unsigned int len, rate_len;
- u8 *tag;
- struct sk_buff *skb;
- struct ieee80211_probe_request *req;
-
- len = ieee->current_network.ssid_len;
-
- rate_len = ieee80211_MFIE_rate_len(ieee);
-
- skb = dev_alloc_skb(sizeof(struct ieee80211_probe_request) +
- 2 + len + rate_len);
- if (!skb)
- return NULL;
-
- req = (struct ieee80211_probe_request *) skb_put(skb, sizeof(struct ieee80211_probe_request));
- req->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_REQ);
- req->header.duration_id = 0; /* FIXME: is this OK ? */
-
- memset(req->header.addr1, 0xff, ETH_ALEN);
- memcpy(req->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
- memset(req->header.addr3, 0xff, ETH_ALEN);
-
- tag = (u8 *) skb_put(skb, len + 2 + rate_len);
-
- *tag++ = MFIE_TYPE_SSID;
- *tag++ = len;
- memcpy(tag, ieee->current_network.ssid, len);
- tag += len;
- ieee80211_MFIE_Brate(ieee, &tag);
- ieee80211_MFIE_Grate(ieee, &tag);
-
- return skb;
-}
-
-struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee);
-
-static void ieee80211_send_beacon(struct ieee80211_device *ieee)
-{
- struct sk_buff *skb;
-
- skb = ieee80211_get_beacon_(ieee);
-
- if (skb) {
- softmac_mgmt_xmit(skb, ieee);
- ieee->softmac_stats.tx_beacons++;
- dev_kfree_skb_any(skb);
- }
-
- ieee->beacon_timer.expires = jiffies +
- (MSECS(ieee->current_network.beacon_interval - 5));
-
- if (ieee->beacon_txing)
- add_timer(&ieee->beacon_timer);
-}
-
-
-static void ieee80211_send_beacon_cb(unsigned long _ieee)
-{
- struct ieee80211_device *ieee =
- (struct ieee80211_device *) _ieee;
- unsigned long flags;
-
- spin_lock_irqsave(&ieee->beacon_lock, flags);
- ieee80211_send_beacon(ieee);
- spin_unlock_irqrestore(&ieee->beacon_lock, flags);
-}
-
-static void ieee80211_send_probe(struct ieee80211_device *ieee)
-{
- struct sk_buff *skb;
-
- skb = ieee80211_probe_req(ieee);
- if (skb) {
- softmac_mgmt_xmit(skb, ieee);
- ieee->softmac_stats.tx_probe_rq++;
- }
-}
-
-static void ieee80211_send_probe_requests(struct ieee80211_device *ieee)
-{
- if (ieee->active_scan && (ieee->softmac_features & IEEE_SOFTMAC_PROBERQ)) {
- ieee80211_send_probe(ieee);
- ieee80211_send_probe(ieee);
- }
-}
-
-/* this performs syncro scan blocking the caller until all channels
- * in the allowed channel map has been checked.
- */
-static void ieee80211_softmac_scan_syncro(struct ieee80211_device *ieee)
-{
- short ch = 0;
- u8 channel_map[MAX_CHANNEL_NUMBER+1];
- memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
- down(&ieee->scan_sem);
-
- while (1) {
- do {
- ch++;
- if (ch > MAX_CHANNEL_NUMBER)
- goto out; /* scan completed */
-
- } while (!channel_map[ch]);
- /* this function can be called in two situations
- * 1- We have switched to ad-hoc mode and we are
- * performing a complete syncro scan before conclude
- * there are no interesting cell and to create a
- * new one. In this case the link state is
- * IEEE80211_NOLINK until we found an interesting cell.
- * If so the ieee8021_new_net, called by the RX path
- * will set the state to IEEE80211_LINKED, so we stop
- * scanning
- * 2- We are linked and the root uses run iwlist scan.
- * So we switch to IEEE80211_LINKED_SCANNING to remember
- * that we are still logically linked (not interested in
- * new network events, despite for updating the net list,
- * but we are temporarily 'unlinked' as the driver shall
- * not filter RX frames and the channel is changing.
- * So the only situation in witch are interested is to check
- * if the state become LINKED because of the #1 situation
- */
-
- if (ieee->state == IEEE80211_LINKED)
- goto out;
-
- ieee->set_chan(ieee->dev, ch);
- if (channel_map[ch] == 1)
- ieee80211_send_probe_requests(ieee);
-
- /* this prevent excessive time wait when we
- * need to wait for a syncro scan to end..
- */
- if (ieee->sync_scan_hurryup)
- goto out;
-
- msleep_interruptible_rtl(IEEE80211_SOFTMAC_SCAN_TIME);
- }
-out:
- ieee->sync_scan_hurryup = 0;
- up(&ieee->scan_sem);
- if (IS_DOT11D_ENABLE(ieee))
- DOT11D_ScanComplete(ieee);
-}
-
-void ieee80211_softmac_ips_scan_syncro(struct ieee80211_device *ieee)
-{
- int ch;
- unsigned int watch_dog = 0;
- u8 channel_map[MAX_CHANNEL_NUMBER+1];
- memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
- down(&ieee->scan_sem);
- ch = ieee->current_network.channel;
-
- while (1) {
- /* this function can be called in two situations
- * 1- We have switched to ad-hoc mode and we are
- * performing a complete syncro scan before conclude
- * there are no interesting cell and to create a
- * new one. In this case the link state is
- * IEEE80211_NOLINK until we found an interesting cell.
- * If so the ieee8021_new_net, called by the RX path
- * will set the state to IEEE80211_LINKED, so we stop
- * scanning
- * 2- We are linked and the root uses run iwlist scan.
- * So we switch to IEEE80211_LINKED_SCANNING to remember
- * that we are still logically linked (not interested in
- * new network events, despite for updating the net list,
- * but we are temporarily 'unlinked' as the driver shall
- * not filter RX frames and the channel is changing.
- * So the only situation in witch are interested is to check
- * if the state become LINKED because of the #1 situation
- */
- if (ieee->state == IEEE80211_LINKED)
- goto out;
-
- if (channel_map[ieee->current_network.channel] > 0)
- ieee->set_chan(ieee->dev, ieee->current_network.channel);
-
- if (channel_map[ieee->current_network.channel] == 1)
- ieee80211_send_probe_requests(ieee);
-
- msleep_interruptible_rtl(IEEE80211_SOFTMAC_SCAN_TIME);
-
- do {
- if (watch_dog++ >= MAX_CHANNEL_NUMBER)
- goto out; /* scan completed */
-
- ieee->current_network.channel = (ieee->current_network.channel + 1)%MAX_CHANNEL_NUMBER;
- } while (!channel_map[ieee->current_network.channel]);
- }
-out:
- ieee->actscanning = false;
- up(&ieee->scan_sem);
- if (IS_DOT11D_ENABLE(ieee))
- DOT11D_ScanComplete(ieee);
-}
-
-static void ieee80211_softmac_scan_wq(struct work_struct *work)
-{
- struct delayed_work *dwork = to_delayed_work(work);
- struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, softmac_scan_wq);
- static short watchdog;
- u8 channel_map[MAX_CHANNEL_NUMBER+1];
- memcpy(channel_map, GET_DOT11D_INFO(ieee)->channel_map, MAX_CHANNEL_NUMBER+1);
- down(&ieee->scan_sem);
-
- do {
- ieee->current_network.channel =
- (ieee->current_network.channel + 1) % MAX_CHANNEL_NUMBER;
- if (watchdog++ > MAX_CHANNEL_NUMBER)
- goto out; /* no good chans */
- } while (!channel_map[ieee->current_network.channel]);
-
- if (ieee->scanning == 0) {
- printk("error out, scanning = 0\n");
- goto out;
- }
- ieee->set_chan(ieee->dev, ieee->current_network.channel);
- if (channel_map[ieee->current_network.channel] == 1)
- ieee80211_send_probe_requests(ieee);
-
- queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, IEEE80211_SOFTMAC_SCAN_TIME);
- up(&ieee->scan_sem);
- return;
-out:
- ieee->actscanning = false;
- watchdog = 0;
- ieee->scanning = 0;
- up(&ieee->scan_sem);
-
- if (IS_DOT11D_ENABLE(ieee))
- DOT11D_ScanComplete(ieee);
- return;
-}
-
-static void ieee80211_beacons_start(struct ieee80211_device *ieee)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&ieee->beacon_lock, flags);
-
- ieee->beacon_txing = 1;
- ieee80211_send_beacon(ieee);
-
- spin_unlock_irqrestore(&ieee->beacon_lock, flags);
-}
-
-static void ieee80211_beacons_stop(struct ieee80211_device *ieee)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&ieee->beacon_lock, flags);
-
- ieee->beacon_txing = 0;
- del_timer_sync(&ieee->beacon_timer);
-
- spin_unlock_irqrestore(&ieee->beacon_lock, flags);
-}
-
-void ieee80211_stop_send_beacons(struct ieee80211_device *ieee)
-{
- if (ieee->stop_send_beacons)
- ieee->stop_send_beacons(ieee->dev);
- if (ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
- ieee80211_beacons_stop(ieee);
-}
-
-void ieee80211_start_send_beacons(struct ieee80211_device *ieee)
-{
- if (ieee->start_send_beacons)
- ieee->start_send_beacons(ieee->dev);
- if (ieee->softmac_features & IEEE_SOFTMAC_BEACONS)
- ieee80211_beacons_start(ieee);
-}
-
-static void ieee80211_softmac_stop_scan(struct ieee80211_device *ieee)
-{
- down(&ieee->scan_sem);
-
- if (ieee->scanning == 1) {
- ieee->scanning = 0;
- cancel_delayed_work(&ieee->softmac_scan_wq);
- }
-
- up(&ieee->scan_sem);
-}
-
-void ieee80211_stop_scan(struct ieee80211_device *ieee)
-{
- if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
- ieee80211_softmac_stop_scan(ieee);
- else
- ieee->stop_scan(ieee->dev);
-}
-
-/* called with ieee->lock held */
-void ieee80211_rtl_start_scan(struct ieee80211_device *ieee)
-{
- if (IS_DOT11D_ENABLE(ieee)) {
- if (IS_COUNTRY_IE_VALID(ieee))
- RESET_CIE_WATCHDOG(ieee);
- }
-
- if (ieee->softmac_features & IEEE_SOFTMAC_SCAN) {
- if (ieee->scanning == 0) {
- ieee->scanning = 1;
-#if 1
- queue_delayed_work(ieee->wq, &ieee->softmac_scan_wq, 0);
-#endif
- }
- }else
- ieee->start_scan(ieee->dev);
-}
-
-/* called with wx_sem held */
-void ieee80211_start_scan_syncro(struct ieee80211_device *ieee)
-{
- if (IS_DOT11D_ENABLE(ieee)) {
- if (IS_COUNTRY_IE_VALID(ieee))
- RESET_CIE_WATCHDOG(ieee);
- }
- ieee->sync_scan_hurryup = 0;
-
- if (ieee->softmac_features & IEEE_SOFTMAC_SCAN)
- ieee80211_softmac_scan_syncro(ieee);
- else
- ieee->scan_syncro(ieee->dev);
-}
-
-inline struct sk_buff *
-ieee80211_authentication_req(struct ieee80211_network *beacon,
- struct ieee80211_device *ieee, int challengelen)
-{
- struct sk_buff *skb;
- struct ieee80211_authentication *auth;
-
- skb = dev_alloc_skb(sizeof(struct ieee80211_authentication) + challengelen);
-
- if (!skb)
- return NULL;
-
- auth = (struct ieee80211_authentication *)
- skb_put(skb, sizeof(struct ieee80211_authentication));
-
- auth->header.frame_ctl = IEEE80211_STYPE_AUTH;
- if (challengelen)
- auth->header.frame_ctl |= IEEE80211_FCTL_WEP;
-
- auth->header.duration_id = 0x013a; /* FIXME */
-
- memcpy(auth->header.addr1, beacon->bssid, ETH_ALEN);
- memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
- memcpy(auth->header.addr3, beacon->bssid, ETH_ALEN);
-
- auth->algorithm = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
-
- auth->transaction = cpu_to_le16(ieee->associate_seq);
- ieee->associate_seq++;
-
- auth->status = cpu_to_le16(WLAN_STATUS_SUCCESS);
-
- return skb;
-}
-
-static struct sk_buff *ieee80211_probe_resp(struct ieee80211_device *ieee,
- u8 *dest)
-{
- u8 *tag;
- int beacon_size;
- struct ieee80211_probe_response *beacon_buf;
- struct sk_buff *skb;
- int encrypt;
- int atim_len, erp_len;
- struct ieee80211_crypt_data *crypt;
-
- char *ssid = ieee->current_network.ssid;
- int ssid_len = ieee->current_network.ssid_len;
- int rate_len = ieee->current_network.rates_len+2;
- int rate_ex_len = ieee->current_network.rates_ex_len;
- int wpa_ie_len = ieee->wpa_ie_len;
- if (rate_ex_len > 0)
- rate_ex_len += 2;
-
- if (ieee->current_network.capability & WLAN_CAPABILITY_IBSS)
- atim_len = 4;
- else
- atim_len = 0;
-
- if (ieee80211_is_54g(&ieee->current_network))
- erp_len = 3;
- else
- erp_len = 0;
-
- beacon_size = sizeof(struct ieee80211_probe_response)+
- ssid_len
- +3 /* channel */
- +rate_len
- +rate_ex_len
- +atim_len
- +wpa_ie_len
- +erp_len;
-
- skb = dev_alloc_skb(beacon_size);
-
- if (!skb)
- return NULL;
-
- beacon_buf = (struct ieee80211_probe_response *) skb_put(skb, beacon_size);
-
- memcpy(beacon_buf->header.addr1, dest, ETH_ALEN);
- memcpy(beacon_buf->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
- memcpy(beacon_buf->header.addr3, ieee->current_network.bssid, ETH_ALEN);
-
- beacon_buf->header.duration_id = 0; /* FIXME */
- beacon_buf->beacon_interval =
- cpu_to_le16(ieee->current_network.beacon_interval);
- beacon_buf->capability =
- cpu_to_le16(ieee->current_network.capability & WLAN_CAPABILITY_IBSS);
-
- if (ieee->short_slot && (ieee->current_network.capability & WLAN_CAPABILITY_SHORT_SLOT))
- beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
-
- crypt = ieee->crypt[ieee->tx_keyidx];
-
- encrypt = ieee->host_encrypt && crypt && crypt->ops &&
- ((0 == strcmp(crypt->ops->name, "WEP")) || wpa_ie_len);
-
- if (encrypt)
- beacon_buf->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
-
-
- beacon_buf->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_PROBE_RESP);
-
- beacon_buf->info_element.id = MFIE_TYPE_SSID;
- beacon_buf->info_element.len = ssid_len;
-
- tag = (u8 *) beacon_buf->info_element.data;
-
- memcpy(tag, ssid, ssid_len);
-
- tag += ssid_len;
-
- *(tag++) = MFIE_TYPE_RATES;
- *(tag++) = rate_len - 2;
- memcpy(tag, ieee->current_network.rates, rate_len-2);
- tag += rate_len - 2;
-
- *(tag++) = MFIE_TYPE_DS_SET;
- *(tag++) = 1;
- *(tag++) = ieee->current_network.channel;
-
- if (atim_len) {
- *(tag++) = MFIE_TYPE_IBSS_SET;
- *(tag++) = 2;
- *((u16 *)(tag)) = cpu_to_le16(ieee->current_network.atim_window);
- tag += 2;
- }
-
- if (erp_len) {
- *(tag++) = MFIE_TYPE_ERP;
- *(tag++) = 1;
- *(tag++) = 0;
- }
-
- if (rate_ex_len) {
- *(tag++) = MFIE_TYPE_RATES_EX;
- *(tag++) = rate_ex_len-2;
- memcpy(tag, ieee->current_network.rates_ex, rate_ex_len-2);
- tag += rate_ex_len - 2;
- }
-
- if (wpa_ie_len) {
- if (ieee->iw_mode == IW_MODE_ADHOC) {
- /* as Windows will set pairwise key same as the group
- * key which is not allowed in Linux, so set this for
- * IOT issue.
- */
- memcpy(&ieee->wpa_ie[14], &ieee->wpa_ie[8], 4);
- }
-
- memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
- }
- skb->dev = ieee->dev;
- return skb;
-}
-
-static struct sk_buff *ieee80211_assoc_resp(struct ieee80211_device *ieee,
- u8 *dest)
-{
- struct sk_buff *skb;
- u8 *tag;
-
- struct ieee80211_crypt_data *crypt;
- struct ieee80211_assoc_response_frame *assoc;
- short encrypt;
-
- unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
- int len = sizeof(struct ieee80211_assoc_response_frame) + rate_len;
-
- skb = dev_alloc_skb(len);
-
- if (!skb)
- return NULL;
-
- assoc = (struct ieee80211_assoc_response_frame *)
- skb_put(skb, sizeof(struct ieee80211_assoc_response_frame));
-
- assoc->header.frame_control = cpu_to_le16(IEEE80211_STYPE_ASSOC_RESP);
- memcpy(assoc->header.addr1, dest, ETH_ALEN);
- memcpy(assoc->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
- memcpy(assoc->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
- assoc->capability = cpu_to_le16(ieee->iw_mode == IW_MODE_MASTER ?
- WLAN_CAPABILITY_BSS : WLAN_CAPABILITY_IBSS);
-
- if (ieee->short_slot)
- assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
-
- if (ieee->host_encrypt)
- crypt = ieee->crypt[ieee->tx_keyidx];
- else
- crypt = NULL;
-
- encrypt = (crypt && crypt->ops);
-
- if (encrypt)
- assoc->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
-
- assoc->status = 0;
- assoc->aid = cpu_to_le16(ieee->assoc_id);
- if (ieee->assoc_id == 0x2007)
- ieee->assoc_id = 0;
- else
- ieee->assoc_id++;
-
- tag = (u8 *) skb_put(skb, rate_len);
-
- ieee80211_MFIE_Brate(ieee, &tag);
- ieee80211_MFIE_Grate(ieee, &tag);
-
- return skb;
-}
-
-static struct sk_buff *ieee80211_auth_resp(struct ieee80211_device *ieee,
- int status, u8 *dest)
-{
- struct sk_buff *skb;
- struct ieee80211_authentication *auth;
-
- skb = dev_alloc_skb(sizeof(struct ieee80211_authentication)+1);
-
- if (!skb)
- return NULL;
-
- skb->len = sizeof(struct ieee80211_authentication);
-
- auth = (struct ieee80211_authentication *)skb->data;
-
- auth->status = cpu_to_le16(status);
- auth->transaction = cpu_to_le16(2);
- auth->algorithm = cpu_to_le16(WLAN_AUTH_OPEN);
-
- memcpy(auth->header.addr3, ieee->dev->dev_addr, ETH_ALEN);
- memcpy(auth->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
- memcpy(auth->header.addr1, dest, ETH_ALEN);
- auth->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_AUTH);
- return skb;
-}
-
-static struct sk_buff *ieee80211_null_func(struct ieee80211_device *ieee, short pwr)
-{
- struct sk_buff *skb;
- struct ieee80211_hdr_3addr *hdr;
-
- skb = dev_alloc_skb(sizeof(struct ieee80211_hdr_3addr));
-
- if (!skb)
- return NULL;
-
- hdr = (struct ieee80211_hdr_3addr *)skb_put(skb, sizeof(struct ieee80211_hdr_3addr));
-
- memcpy(hdr->addr1, ieee->current_network.bssid, ETH_ALEN);
- memcpy(hdr->addr2, ieee->dev->dev_addr, ETH_ALEN);
- memcpy(hdr->addr3, ieee->current_network.bssid, ETH_ALEN);
-
- hdr->frame_control = cpu_to_le16(IEEE80211_FTYPE_DATA |
- IEEE80211_STYPE_NULLFUNC | IEEE80211_FCTL_TODS |
- (pwr ? IEEE80211_FCTL_PM:0));
-
- return skb;
-}
-
-static void ieee80211_resp_to_assoc_rq(struct ieee80211_device *ieee, u8 *dest)
-{
- struct sk_buff *buf = ieee80211_assoc_resp(ieee, dest);
-
- if (buf) {
- softmac_mgmt_xmit(buf, ieee);
- dev_kfree_skb_any(buf);
- }
-}
-
-static void ieee80211_resp_to_auth(struct ieee80211_device *ieee, int s, u8 *dest)
-{
- struct sk_buff *buf = ieee80211_auth_resp(ieee, s, dest);
-
- if (buf) {
- softmac_mgmt_xmit(buf, ieee);
- dev_kfree_skb_any(buf);
- }
-}
-
-static void ieee80211_resp_to_probe(struct ieee80211_device *ieee, u8 *dest)
-{
- struct sk_buff *buf = ieee80211_probe_resp(ieee, dest);
-
- if (buf) {
- softmac_mgmt_xmit(buf, ieee);
- dev_kfree_skb_any(buf);
- }
-}
-
-inline struct sk_buff *
-ieee80211_association_req(struct ieee80211_network *beacon,
- struct ieee80211_device *ieee)
-{
- struct sk_buff *skb;
-
- struct ieee80211_assoc_request_frame *hdr;
- u8 *tag;
- unsigned int wpa_len = beacon->wpa_ie_len;
-#if 1
- /* for testing purpose */
- unsigned int rsn_len = beacon->rsn_ie_len;
-#endif
- unsigned int rate_len = ieee80211_MFIE_rate_len(ieee);
- unsigned int wmm_info_len = beacon->QoS_Enable?9:0;
- unsigned int turbo_info_len = beacon->Turbo_Enable?9:0;
-
- u8 encry_proto = ieee->wpax_type_notify & 0xff;
-
- int len = 0;
-
- /* [0] Notify type of encryption: WPA/WPA2
- * [1] pair wise type
- * [2] authen type
- */
- if (ieee->wpax_type_set) {
- if (IEEE_PROTO_WPA == encry_proto) {
- rsn_len = 0;
- } else if (IEEE_PROTO_RSN == encry_proto) {
- wpa_len = 0;
- }
- }
- len = sizeof(struct ieee80211_assoc_request_frame)+
- + beacon->ssid_len /* essid tagged val */
- + rate_len /* rates tagged val */
- + wpa_len
- + rsn_len
- + wmm_info_len
- + turbo_info_len;
-
- skb = dev_alloc_skb(len);
-
- if (!skb)
- return NULL;
-
- hdr = (struct ieee80211_assoc_request_frame *)
- skb_put(skb, sizeof(struct ieee80211_assoc_request_frame));
-
- hdr->header.frame_control = IEEE80211_STYPE_ASSOC_REQ;
- hdr->header.duration_id = 37; /* FIXME */
- memcpy(hdr->header.addr1, beacon->bssid, ETH_ALEN);
- memcpy(hdr->header.addr2, ieee->dev->dev_addr, ETH_ALEN);
- memcpy(hdr->header.addr3, beacon->bssid, ETH_ALEN);
- memcpy(ieee->ap_mac_addr, beacon->bssid, ETH_ALEN); /* for HW security */
-
- hdr->capability = cpu_to_le16(WLAN_CAPABILITY_BSS);
- if (beacon->capability & WLAN_CAPABILITY_PRIVACY)
- hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_PRIVACY);
- if (beacon->capability & WLAN_CAPABILITY_SHORT_PREAMBLE)
- hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_PREAMBLE);
-
- if (ieee->short_slot)
- hdr->capability |= cpu_to_le16(WLAN_CAPABILITY_SHORT_SLOT);
-
- hdr->listen_interval = 0xa; /* FIXME */
-
- hdr->info_element.id = MFIE_TYPE_SSID;
-
- hdr->info_element.len = beacon->ssid_len;
- tag = skb_put(skb, beacon->ssid_len);
- memcpy(tag, beacon->ssid, beacon->ssid_len);
-
- tag = skb_put(skb, rate_len);
-
- ieee80211_MFIE_Brate(ieee, &tag);
- ieee80211_MFIE_Grate(ieee, &tag);
-
- /* add rsn==0 condition for ap's mix security mode(wpa+wpa2)
- * choose AES encryption as default algorithm while using mixed mode.
- */
-
- tag = skb_put(skb, ieee->wpa_ie_len);
- memcpy(tag, ieee->wpa_ie, ieee->wpa_ie_len);
-
- tag = skb_put(skb, wmm_info_len);
- if (wmm_info_len)
- ieee80211_WMM_Info(ieee, &tag);
-
- tag = skb_put(skb, turbo_info_len);
- if (turbo_info_len)
- ieee80211_TURBO_Info(ieee, &tag);
-
- return skb;
-}
-
-void ieee80211_associate_abort(struct ieee80211_device *ieee)
-{
- unsigned long flags;
- spin_lock_irqsave(&ieee->lock, flags);
-
- ieee->associate_seq++;
-
- /* don't scan, and avoid to have the RX path possibly
- * try again to associate. Even do not react to AUTH or
- * ASSOC response. Just wait for the retry wq to be scheduled.
- * Here we will check if there are good nets to associate
- * with, so we retry or just get back to NO_LINK and scanning
- */
- if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING) {
- IEEE80211_DEBUG_MGMT("Authentication failed\n");
- ieee->softmac_stats.no_auth_rs++;
- } else {
- IEEE80211_DEBUG_MGMT("Association failed\n");
- ieee->softmac_stats.no_ass_rs++;
- }
-
- ieee->state = IEEE80211_ASSOCIATING_RETRY;
-
- queue_delayed_work(ieee->wq, &ieee->associate_retry_wq, IEEE80211_SOFTMAC_ASSOC_RETRY_TIME);
-
- spin_unlock_irqrestore(&ieee->lock, flags);
-}
-
-static void ieee80211_associate_abort_cb(unsigned long dev)
-{
- ieee80211_associate_abort((struct ieee80211_device *) dev);
-}
-
-static void ieee80211_associate_step1(struct ieee80211_device *ieee)
-{
- struct ieee80211_network *beacon = &ieee->current_network;
- struct sk_buff *skb;
-
- IEEE80211_DEBUG_MGMT("Stopping scan\n");
- ieee->softmac_stats.tx_auth_rq++;
- skb = ieee80211_authentication_req(beacon, ieee, 0);
- if (!skb) {
- ieee80211_associate_abort(ieee);
- } else {
- ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATING;
- IEEE80211_DEBUG_MGMT("Sending authentication request\n");
- softmac_mgmt_xmit(skb, ieee);
- /* BUGON when you try to add_timer twice, using mod_timer may
- * be better.
- */
- if (!timer_pending(&ieee->associate_timer)) {
- ieee->associate_timer.expires = jiffies + (HZ / 2);
- add_timer(&ieee->associate_timer);
- }
- /* If call dev_kfree_skb_any,a warning will ocur....
- * KERNEL: assertion (!atomic_read(&skb->users)) failed at
- * net/core/dev.c (1708)
- */
- }
-}
-
-static void ieee80211_rtl_auth_challenge(struct ieee80211_device *ieee, u8 *challenge,
- int chlen)
-{
- u8 *c;
- struct sk_buff *skb;
- struct ieee80211_network *beacon = &ieee->current_network;
- del_timer_sync(&ieee->associate_timer);
- ieee->associate_seq++;
- ieee->softmac_stats.tx_auth_rq++;
-
- skb = ieee80211_authentication_req(beacon, ieee, chlen+2);
- if (!skb)
- ieee80211_associate_abort(ieee);
- else {
- c = skb_put(skb, chlen+2);
- *(c++) = MFIE_TYPE_CHALLENGE;
- *(c++) = chlen;
- memcpy(c, challenge, chlen);
-
- IEEE80211_DEBUG_MGMT("Sending authentication challenge response\n");
-
- ieee80211_encrypt_fragment(ieee, skb, sizeof(struct ieee80211_hdr_3addr));
-
- softmac_mgmt_xmit(skb, ieee);
- if (!timer_pending(&ieee->associate_timer)) {
- ieee->associate_timer.expires = jiffies + (HZ / 2);
- add_timer(&ieee->associate_timer);
- }
- dev_kfree_skb_any(skb);
- }
- kfree(challenge);
-}
-
-static void ieee80211_associate_step2(struct ieee80211_device *ieee)
-{
- struct sk_buff *skb;
- struct ieee80211_network *beacon = &ieee->current_network;
-
- del_timer_sync(&ieee->associate_timer);
-
- IEEE80211_DEBUG_MGMT("Sending association request\n");
- ieee->softmac_stats.tx_ass_rq++;
- skb = ieee80211_association_req(beacon, ieee);
- if (!skb)
- ieee80211_associate_abort(ieee);
- else {
- softmac_mgmt_xmit(skb, ieee);
- if (!timer_pending(&ieee->associate_timer)) {
- ieee->associate_timer.expires = jiffies + (HZ / 2);
- add_timer(&ieee->associate_timer);
- }
- }
-}
-
-static void ieee80211_associate_complete_wq(struct work_struct *work)
-{
- struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_complete_wq);
-
- printk(KERN_INFO "Associated successfully\n");
- if (ieee80211_is_54g(&ieee->current_network) &&
- (ieee->modulation & IEEE80211_OFDM_MODULATION)) {
- ieee->rate = 540;
- printk(KERN_INFO"Using G rates\n");
- } else {
- ieee->rate = 110;
- printk(KERN_INFO"Using B rates\n");
- }
- ieee->link_change(ieee->dev);
- notify_wx_assoc_event(ieee);
- if (ieee->data_hard_resume)
- ieee->data_hard_resume(ieee->dev);
- netif_carrier_on(ieee->dev);
-}
-
-static void ieee80211_associate_complete(struct ieee80211_device *ieee)
-{
- del_timer_sync(&ieee->associate_timer);
-
- ieee->state = IEEE80211_LINKED;
- IEEE80211_DEBUG_MGMT("Successfully associated\n");
-
- queue_work(ieee->wq, &ieee->associate_complete_wq);
-}
-
-static void ieee80211_associate_procedure_wq(struct work_struct *work)
-{
- struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, associate_procedure_wq);
-
- ieee->sync_scan_hurryup = 1;
- down(&ieee->wx_sem);
-
- if (ieee->data_hard_stop)
- ieee->data_hard_stop(ieee->dev);
-
- ieee80211_stop_scan(ieee);
- ieee->set_chan(ieee->dev, ieee->current_network.channel);
-
- ieee->associate_seq = 1;
- ieee80211_associate_step1(ieee);
-
- up(&ieee->wx_sem);
-}
-
-inline void ieee80211_softmac_new_net(struct ieee80211_device *ieee,
- struct ieee80211_network *net)
-{
- u8 tmp_ssid[IW_ESSID_MAX_SIZE+1];
- int tmp_ssid_len = 0;
-
- short apset, ssidset, ssidbroad, apmatch, ssidmatch;
-
- /* we are interested in new new only if we are not associated
- * and we are not associating / authenticating
- */
- if (ieee->state != IEEE80211_NOLINK)
- return;
-
- if ((ieee->iw_mode == IW_MODE_INFRA) && !(net->capability & WLAN_CAPABILITY_BSS))
- return;
-
- if ((ieee->iw_mode == IW_MODE_ADHOC) && !(net->capability & WLAN_CAPABILITY_IBSS))
- return;
-
- if (ieee->iw_mode == IW_MODE_INFRA || ieee->iw_mode == IW_MODE_ADHOC) {
- /* if the user specified the AP MAC, we need also the essid
- * This could be obtained by beacons or, if the network does not
- * broadcast it, it can be put manually.
- */
- apset = ieee->wap_set;
- ssidset = ieee->ssid_set;
- ssidbroad = !(net->ssid_len == 0 || net->ssid[0] == '\0');
- apmatch = (memcmp(ieee->current_network.bssid, net->bssid, ETH_ALEN) == 0);
-
- if (ieee->current_network.ssid_len != net->ssid_len)
- ssidmatch = 0;
- else
- ssidmatch = (0 == strncmp(ieee->current_network.ssid, net->ssid, net->ssid_len));
-
- /* if the user set the AP check if match.
- * if the network does not broadcast essid we check the user
- * supplied ANY essid
- * if the network does broadcast and the user does not set essid
- * it is OK
- * if the network does broadcast and the user did set essid
- * chech if essid match
- * (apset && apmatch && ((ssidset && ssidbroad && ssidmatch) ||
- * (ssidbroad && !ssidset) || (!ssidbroad && ssidset))) ||
- * if the ap is not set, check that the user set the bssid and
- * the network does broadcast and that those two bssid matches
- * (!apset && ssidset && ssidbroad && ssidmatch)
- */
- if ((apset && apmatch && ((ssidset && ssidbroad && ssidmatch) ||
- (ssidbroad && !ssidset) || (!ssidbroad && ssidset))) ||
- (!apset && ssidset && ssidbroad && ssidmatch)) {
- /* if the essid is hidden replace it with the
- * essid provided by the user.
- */
- if (!ssidbroad) {
- strncpy(tmp_ssid, ieee->current_network.ssid, IW_ESSID_MAX_SIZE);
- tmp_ssid_len = ieee->current_network.ssid_len;
- }
- memcpy(&ieee->current_network, net, sizeof(struct ieee80211_network));
-
- if (!ssidbroad) {
- strncpy(ieee->current_network.ssid, tmp_ssid, IW_ESSID_MAX_SIZE);
- ieee->current_network.ssid_len = tmp_ssid_len;
- }
- printk(KERN_INFO"Linking with %s: channel is %d\n", ieee->current_network.ssid, ieee->current_network.channel);
-
- if (ieee->iw_mode == IW_MODE_INFRA) {
- ieee->state = IEEE80211_ASSOCIATING;
- ieee->beinretry = false;
- queue_work(ieee->wq, &ieee->associate_procedure_wq);
- } else {
- if (ieee80211_is_54g(&ieee->current_network) &&
- (ieee->modulation & IEEE80211_OFDM_MODULATION)) {
- ieee->rate = 540;
- printk(KERN_INFO"Using G rates\n");
- } else {
- ieee->rate = 110;
- printk(KERN_INFO"Using B rates\n");
- }
- ieee->state = IEEE80211_LINKED;
- ieee->beinretry = false;
- }
- }
- }
-}
-
-void ieee80211_softmac_check_all_nets(struct ieee80211_device *ieee)
-{
- unsigned long flags;
- struct ieee80211_network *target;
-
- spin_lock_irqsave(&ieee->lock, flags);
- list_for_each_entry(target, &ieee->network_list, list) {
- /* if the state become different that NOLINK means
- * we had found what we are searching for
- */
- if (ieee->state != IEEE80211_NOLINK)
- break;
-
- if (ieee->scan_age == 0 || time_after(target->last_scanned + ieee->scan_age, jiffies))
- ieee80211_softmac_new_net(ieee, target);
- }
- spin_unlock_irqrestore(&ieee->lock, flags);
-}
-
-static inline u16 auth_parse(struct sk_buff *skb, u8 **challenge, int *chlen)
-{
- struct ieee80211_authentication *a;
- u8 *t;
- if (skb->len < (sizeof(struct ieee80211_authentication) - sizeof(struct ieee80211_info_element))) {
- IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n", skb->len);
- return 0xcafe;
- }
- *challenge = NULL;
- a = (struct ieee80211_authentication *) skb->data;
- if (skb->len > (sizeof(struct ieee80211_authentication) + 3)) {
- t = skb->data + sizeof(struct ieee80211_authentication);
-
- if (*(t++) == MFIE_TYPE_CHALLENGE) {
- *chlen = *(t++);
- *challenge = kmemdup(t, *chlen, GFP_ATOMIC);
- if (!*challenge)
- return -ENOMEM;
- }
- }
- return cpu_to_le16(a->status);
-}
-
-static int auth_rq_parse(struct sk_buff *skb, u8 *dest)
-{
- struct ieee80211_authentication *a;
-
- if (skb->len < (sizeof(struct ieee80211_authentication) - sizeof(struct ieee80211_info_element))) {
- IEEE80211_DEBUG_MGMT("invalid len in auth request: %d\n", skb->len);
- return -1;
- }
- a = (struct ieee80211_authentication *) skb->data;
-
- memcpy(dest, a->header.addr2, ETH_ALEN);
-
- if (le16_to_cpu(a->algorithm) != WLAN_AUTH_OPEN)
- return WLAN_STATUS_NOT_SUPPORTED_AUTH_ALG;
-
- return WLAN_STATUS_SUCCESS;
-}
-
-static short probe_rq_parse(struct ieee80211_device *ieee, struct sk_buff *skb,
- u8 *src)
-{
- u8 *tag;
- u8 *skbend;
- u8 *ssid = NULL;
- u8 ssidlen = 0;
-
- struct ieee80211_hdr_3addr *header =
- (struct ieee80211_hdr_3addr *) skb->data;
-
- if (skb->len < sizeof(struct ieee80211_hdr_3addr))
- return -1; /* corrupted */
-
- memcpy(src, header->addr2, ETH_ALEN);
-
- skbend = (u8 *)skb->data + skb->len;
-
- tag = skb->data + sizeof(struct ieee80211_hdr_3addr);
-
- while (tag+1 < skbend) {
- if (*tag == 0) {
- ssid = tag+2;
- ssidlen = *(tag+1);
- break;
- }
- tag++; /* point to the len field */
- tag = tag + *(tag); /* point to the last data byte of the tag */
- tag++; /* point to the next tag */
- }
-
- if (ssidlen == 0)
- return 1;
-
- if (!ssid)
- return 1; /* ssid not found in tagged param */
-
- return (!strncmp(ssid, ieee->current_network.ssid, ssidlen));
-
-}
-
-static int assoc_rq_parse(struct sk_buff *skb, u8 *dest)
-{
- struct ieee80211_assoc_request_frame *a;
-
- if (skb->len < (sizeof(struct ieee80211_assoc_request_frame) -
- sizeof(struct ieee80211_info_element))) {
-
- IEEE80211_DEBUG_MGMT("invalid len in auth request:%d\n", skb->len);
- return -1;
- }
-
- a = (struct ieee80211_assoc_request_frame *) skb->data;
-
- memcpy(dest, a->header.addr2, ETH_ALEN);
-
- return 0;
-}
-
-static inline u16 assoc_parse(struct sk_buff *skb, int *aid)
-{
- struct ieee80211_assoc_response_frame *a;
- if (skb->len < sizeof(struct ieee80211_assoc_response_frame)) {
- IEEE80211_DEBUG_MGMT("invalid len in auth resp: %d\n", skb->len);
- return 0xcafe;
- }
-
- a = (struct ieee80211_assoc_response_frame *) skb->data;
- *aid = le16_to_cpu(a->aid) & 0x3fff;
- return le16_to_cpu(a->status);
-}
-
-static inline void ieee80211_rx_probe_rq(struct ieee80211_device *ieee,
- struct sk_buff *skb)
-{
- u8 dest[ETH_ALEN];
-
- ieee->softmac_stats.rx_probe_rq++;
- if (probe_rq_parse(ieee, skb, dest)) {
- ieee->softmac_stats.tx_probe_rs++;
- ieee80211_resp_to_probe(ieee, dest);
- }
-}
-
-inline void ieee80211_rx_auth_rq(struct ieee80211_device *ieee,
- struct sk_buff *skb)
-{
- u8 dest[ETH_ALEN];
- int status;
- ieee->softmac_stats.rx_auth_rq++;
-
- status = auth_rq_parse(skb, dest);
- if (status != -1)
- ieee80211_resp_to_auth(ieee, status, dest);
-}
-
-inline void
-ieee80211_rx_assoc_rq(struct ieee80211_device *ieee, struct sk_buff *skb)
-{
-
- u8 dest[ETH_ALEN];
-
- ieee->softmac_stats.rx_ass_rq++;
- if (assoc_rq_parse(skb, dest) != -1)
- ieee80211_resp_to_assoc_rq(ieee, dest);
-
-
- printk(KERN_INFO"New client associated: %pM\n", dest);
-}
-
-void ieee80211_sta_ps_send_null_frame(struct ieee80211_device *ieee, short pwr)
-{
- struct sk_buff *buf = ieee80211_null_func(ieee, pwr);
-
- if (buf)
- softmac_ps_mgmt_xmit(buf, ieee);
-}
-
-static short ieee80211_sta_ps_sleep(struct ieee80211_device *ieee, u32 *time_h,
- u32 *time_l)
-{
- int timeout = 0;
-
- u8 dtim;
- dtim = ieee->current_network.dtim_data;
-
- if (!(dtim & IEEE80211_DTIM_VALID))
- return 0;
- else
- timeout = ieee->current_network.beacon_interval;
-
- ieee->current_network.dtim_data = IEEE80211_DTIM_INVALID;
-
- if (dtim & ((IEEE80211_DTIM_UCAST | IEEE80211_DTIM_MBCAST) & ieee->ps))
- return 2;
-
- if (!time_after(jiffies, ieee->dev->trans_start + MSECS(timeout)))
- return 0;
-
- if (!time_after(jiffies, ieee->last_rx_ps_time + MSECS(timeout)))
- return 0;
-
- if ((ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE) &&
- (ieee->mgmt_queue_tail != ieee->mgmt_queue_head))
- return 0;
-
- if (time_l) {
- *time_l = ieee->current_network.last_dtim_sta_time[0]
- + MSECS((ieee->current_network.beacon_interval));
- }
-
- if (time_h) {
- *time_h = ieee->current_network.last_dtim_sta_time[1];
- if (time_l && *time_l < ieee->current_network.last_dtim_sta_time[0])
- *time_h += 1;
- }
-
- return 1;
-}
-
-static inline void ieee80211_sta_ps(struct ieee80211_device *ieee)
-{
-
- u32 th, tl;
- short sleep;
-
- unsigned long flags, flags2;
-
- spin_lock_irqsave(&ieee->lock, flags);
-
- if ((ieee->ps == IEEE80211_PS_DISABLED ||
- ieee->iw_mode != IW_MODE_INFRA ||
- ieee->state != IEEE80211_LINKED)) {
-
- /* #warning CHECK_LOCK_HERE */
- spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
-
- ieee80211_sta_wakeup(ieee, 1);
-
- spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
- }
-
- sleep = ieee80211_sta_ps_sleep(ieee, &th, &tl);
- /* 2 wake, 1 sleep, 0 do nothing */
- if (sleep == 0)
- goto out;
-
- if (sleep == 1) {
- if (ieee->sta_sleep == 1)
- ieee->enter_sleep_state(ieee->dev, th, tl);
-
- else if (ieee->sta_sleep == 0) {
- spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
- if (ieee->ps_is_queue_empty(ieee->dev)) {
- ieee->sta_sleep = 2;
-
- ieee->ps_request_tx_ack(ieee->dev);
-
- ieee80211_sta_ps_send_null_frame(ieee, 1);
-
- ieee->ps_th = th;
- ieee->ps_tl = tl;
- }
- spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
- }
- } else if (sleep == 2) {
- /* #warning CHECK_LOCK_HERE */
- spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
-
- ieee80211_sta_wakeup(ieee, 1);
-
- spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
- }
-out:
- spin_unlock_irqrestore(&ieee->lock, flags);
-}
-
-void ieee80211_sta_wakeup(struct ieee80211_device *ieee, short nl)
-{
- if (ieee->sta_sleep == 0) {
- if (nl) {
- ieee->ps_request_tx_ack(ieee->dev);
- ieee80211_sta_ps_send_null_frame(ieee, 0);
- }
- return;
- }
-
- if (ieee->sta_sleep == 1)
- ieee->sta_wake_up(ieee->dev);
-
- ieee->sta_sleep = 0;
-
- if (nl) {
- ieee->ps_request_tx_ack(ieee->dev);
- ieee80211_sta_ps_send_null_frame(ieee, 0);
- }
-}
-
-void ieee80211_ps_tx_ack(struct ieee80211_device *ieee, short success)
-{
- unsigned long flags, flags2;
-
- spin_lock_irqsave(&ieee->lock, flags);
- if (ieee->sta_sleep == 2) {
- /* Null frame with PS bit set */
- if (success) {
- ieee->sta_sleep = 1;
- ieee->enter_sleep_state(ieee->dev, ieee->ps_th, ieee->ps_tl);
- }
- /* if the card report not success we can't be sure the AP
- * has not RXed so we can't assume the AP believe us awake
- */
- } else {
- if ((ieee->sta_sleep == 0) && !success) {
- spin_lock_irqsave(&ieee->mgmt_tx_lock, flags2);
- ieee80211_sta_ps_send_null_frame(ieee, 0);
- spin_unlock_irqrestore(&ieee->mgmt_tx_lock, flags2);
- }
- }
- spin_unlock_irqrestore(&ieee->lock, flags);
-}
-
-inline int ieee80211_rx_frame_softmac(struct ieee80211_device *ieee,
- struct sk_buff *skb,
- struct ieee80211_rx_stats *rx_stats,
- u16 type, u16 stype)
-{
- struct ieee80211_hdr_3addr *header = (struct ieee80211_hdr_3addr *) skb->data;
- u16 errcode;
- u8 *challenge = NULL;
- int chlen = 0;
- int aid = 0;
- struct ieee80211_assoc_response_frame *assoc_resp;
- struct ieee80211_info_element *info_element;
-
- if (!ieee->proto_started)
- return 0;
-
- if (ieee->sta_sleep || (ieee->ps != IEEE80211_PS_DISABLED &&
- ieee->iw_mode == IW_MODE_INFRA &&
- ieee->state == IEEE80211_LINKED))
-
- tasklet_schedule(&ieee->ps_task);
-
- if (WLAN_FC_GET_STYPE(header->frame_control) != IEEE80211_STYPE_PROBE_RESP &&
- WLAN_FC_GET_STYPE(header->frame_control) != IEEE80211_STYPE_BEACON)
- ieee->last_rx_ps_time = jiffies;
-
- switch (WLAN_FC_GET_STYPE(header->frame_control)) {
- case IEEE80211_STYPE_ASSOC_RESP:
- case IEEE80211_STYPE_REASSOC_RESP:
- IEEE80211_DEBUG_MGMT("received [RE]ASSOCIATION RESPONSE (%d)\n",
- WLAN_FC_GET_STYPE(header->frame_ctl));
- if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
- ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATED &&
- ieee->iw_mode == IW_MODE_INFRA) {
- errcode = assoc_parse(skb, &aid);
- if (0 == errcode) {
- u16 left;
-
- ieee->state = IEEE80211_LINKED;
- ieee->assoc_id = aid;
- ieee->softmac_stats.rx_ass_ok++;
- /* card type is 8187 */
- if (1 == rx_stats->nic_type)
- goto associate_complete;
-
- assoc_resp = (struct ieee80211_assoc_response_frame *)skb->data;
- info_element = &assoc_resp->info_element;
- left = skb->len - ((void *)info_element - (void *)assoc_resp);
-
- while (left >= sizeof(struct ieee80211_info_element_hdr)) {
- if (sizeof(struct ieee80211_info_element_hdr) + info_element->len > left) {
- printk(KERN_WARNING "[re]associate response error!");
- return 1;
- }
- switch (info_element->id) {
- case MFIE_TYPE_GENERIC:
- IEEE80211_DEBUG_SCAN("MFIE_TYPE_GENERIC: %d bytes\n", info_element->len);
- if (info_element->len >= 8 &&
- info_element->data[0] == 0x00 &&
- info_element->data[1] == 0x50 &&
- info_element->data[2] == 0xf2 &&
- info_element->data[3] == 0x02 &&
- info_element->data[4] == 0x01) {
- /* Not care about version at present.
- * WMM Parameter Element.
- */
- memcpy(ieee->current_network.wmm_param, (u8 *)(info_element->data\
- + 8), (info_element->len - 8));
-
- if (((ieee->current_network.wmm_info^info_element->data[6])& \
- 0x0f) || (!ieee->init_wmmparam_flag)) {
- /* refresh parameter element for current network
- * update the register parameter for hardware.
- */
- ieee->init_wmmparam_flag = 1;
- queue_work(ieee->wq, &ieee->wmm_param_update_wq);
- }
- /* update info_element for current network */
- ieee->current_network.wmm_info = info_element->data[6];
- }
- break;
- default:
- /* nothing to do at present!!! */
- break;
- }
-
- left -= sizeof(struct ieee80211_info_element_hdr) +
- info_element->len;
- info_element = (struct ieee80211_info_element *)
- &info_element->data[info_element->len];
- }
- /* legacy AP, reset the AC_xx_param register */
- if (!ieee->init_wmmparam_flag) {
- queue_work(ieee->wq, &ieee->wmm_param_update_wq);
- ieee->init_wmmparam_flag = 1; /* indicate AC_xx_param upated since last associate */
- }
-associate_complete:
- ieee80211_associate_complete(ieee);
- } else {
- ieee->softmac_stats.rx_ass_err++;
- IEEE80211_DEBUG_MGMT(
- "Association response status code 0x%x\n",
- errcode);
- ieee80211_associate_abort(ieee);
- }
- }
- break;
- case IEEE80211_STYPE_ASSOC_REQ:
- case IEEE80211_STYPE_REASSOC_REQ:
- if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
- ieee->iw_mode == IW_MODE_MASTER)
-
- ieee80211_rx_assoc_rq(ieee, skb);
- break;
- case IEEE80211_STYPE_AUTH:
- if (ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) {
- if (ieee->state == IEEE80211_ASSOCIATING_AUTHENTICATING &&
- ieee->iw_mode == IW_MODE_INFRA){
- IEEE80211_DEBUG_MGMT("Received authentication response");
-
- errcode = auth_parse(skb, &challenge, &chlen);
- if (0 == errcode) {
- if (ieee->open_wep || !challenge) {
- ieee->state = IEEE80211_ASSOCIATING_AUTHENTICATED;
- ieee->softmac_stats.rx_auth_rs_ok++;
-
- ieee80211_associate_step2(ieee);
- } else {
- ieee80211_rtl_auth_challenge(ieee, challenge, chlen);
- }
- } else {
- ieee->softmac_stats.rx_auth_rs_err++;
- IEEE80211_DEBUG_MGMT("Authentication response status code 0x%x", errcode);
- ieee80211_associate_abort(ieee);
- }
-
- } else if (ieee->iw_mode == IW_MODE_MASTER) {
- ieee80211_rx_auth_rq(ieee, skb);
- }
- }
- break;
- case IEEE80211_STYPE_PROBE_REQ:
- if ((ieee->softmac_features & IEEE_SOFTMAC_PROBERS) &&
- ((ieee->iw_mode == IW_MODE_ADHOC ||
- ieee->iw_mode == IW_MODE_MASTER) &&
- ieee->state == IEEE80211_LINKED))
-
- ieee80211_rx_probe_rq(ieee, skb);
- break;
- case IEEE80211_STYPE_DISASSOC:
- case IEEE80211_STYPE_DEAUTH:
- /* FIXME for now repeat all the association procedure
- * both for disassociation and deauthentication
- */
- if ((ieee->softmac_features & IEEE_SOFTMAC_ASSOCIATE) &&
- (ieee->state == IEEE80211_LINKED) &&
- (ieee->iw_mode == IW_MODE_INFRA) &&
- (!memcmp(header->addr2, ieee->current_network.bssid, ETH_ALEN))) {
- ieee->state = IEEE80211_ASSOCIATING;
- ieee->softmac_stats.reassoc++;
-
- queue_work(ieee->wq, &ieee->associate_procedure_wq);
- }
- break;
- default:
- return -1;
- break;
- }
- return 0;
-}
-
-/* following are for a simpler TX queue management.
- * Instead of using netif_[stop/wake]_queue the driver
- * will uses these two function (plus a reset one), that
- * will internally uses the kernel netif_* and takes
- * care of the ieee802.11 fragmentation.
- * So the driver receives a fragment per time and might
- * call the stop function when it want without take care
- * to have enough room to TX an entire packet.
- * This might be useful if each fragment need it's own
- * descriptor, thus just keep a total free memory > than
- * the max fragmentation threshold is not enough.. If the
- * ieee802.11 stack passed a TXB struct then you needed
- * to keep N free descriptors where
- * N = MAX_PACKET_SIZE / MIN_FRAG_TRESHOLD
- * In this way you need just one and the 802.11 stack
- * will take care of buffering fragments and pass them to
- * to the driver later, when it wakes the queue.
- */
-
-void ieee80211_softmac_xmit(struct ieee80211_txb *txb,
- struct ieee80211_device *ieee)
-{
- unsigned long flags;
- int i;
-
- spin_lock_irqsave(&ieee->lock, flags);
-
- /* called with 2nd parm 0, no tx mgmt lock required */
- ieee80211_sta_wakeup(ieee, 0);
-
- for (i = 0; i < txb->nr_frags; i++) {
- if (ieee->queue_stop) {
- ieee->tx_pending.txb = txb;
- ieee->tx_pending.frag = i;
- goto exit;
- } else {
- ieee->softmac_data_hard_start_xmit(
- txb->fragments[i],
- ieee->dev, ieee->rate);
- ieee->stats.tx_packets++;
- ieee->stats.tx_bytes += txb->fragments[i]->len;
- ieee->dev->trans_start = jiffies;
- }
- }
-
- ieee80211_txb_free(txb);
-
- exit:
- spin_unlock_irqrestore(&ieee->lock, flags);
-}
-
-/* called with ieee->lock acquired */
-static void ieee80211_resume_tx(struct ieee80211_device *ieee)
-{
- int i;
- for (i = ieee->tx_pending.frag; i < ieee->tx_pending.txb->nr_frags; i++) {
-
- if (ieee->queue_stop) {
- ieee->tx_pending.frag = i;
- return;
- } else {
- ieee->softmac_data_hard_start_xmit(
- ieee->tx_pending.txb->fragments[i],
- ieee->dev, ieee->rate);
- ieee->stats.tx_packets++;
- ieee->dev->trans_start = jiffies;
- }
- }
-
- ieee80211_txb_free(ieee->tx_pending.txb);
- ieee->tx_pending.txb = NULL;
-}
-
-void ieee80211_reset_queue(struct ieee80211_device *ieee)
-{
- unsigned long flags;
-
- spin_lock_irqsave(&ieee->lock, flags);
- init_mgmt_queue(ieee);
- if (ieee->tx_pending.txb) {
- ieee80211_txb_free(ieee->tx_pending.txb);
- ieee->tx_pending.txb = NULL;
- }
- ieee->queue_stop = 0;
- spin_unlock_irqrestore(&ieee->lock, flags);
-}
-
-void ieee80211_rtl_wake_queue(struct ieee80211_device *ieee)
-{
- unsigned long flags;
- struct sk_buff *skb;
- struct ieee80211_hdr_3addr *header;
-
- spin_lock_irqsave(&ieee->lock, flags);
- if (!ieee->queue_stop)
- goto exit;
-
- ieee->queue_stop = 0;
-
- if (ieee->softmac_features & IEEE_SOFTMAC_SINGLE_QUEUE) {
- while (!ieee->queue_stop && (skb = dequeue_mgmt(ieee))) {
- header = (struct ieee80211_hdr_3addr *) skb->data;
-
- header->seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
-
- if (ieee->seq_ctrl[0] == 0xFFF)
- ieee->seq_ctrl[0] = 0;
- else
- ieee->seq_ctrl[0]++;
-
- ieee->softmac_data_hard_start_xmit(skb, ieee->dev, ieee->basic_rate);
- dev_kfree_skb_any(skb);
- }
- }
- if (!ieee->queue_stop && ieee->tx_pending.txb)
- ieee80211_resume_tx(ieee);
-
- if (!ieee->queue_stop && netif_queue_stopped(ieee->dev)) {
- ieee->softmac_stats.swtxawake++;
- netif_wake_queue(ieee->dev);
- }
-exit:
- spin_unlock_irqrestore(&ieee->lock, flags);
-}
-
-void ieee80211_rtl_stop_queue(struct ieee80211_device *ieee)
-{
- if (!netif_queue_stopped(ieee->dev)) {
- netif_stop_queue(ieee->dev);
- ieee->softmac_stats.swtxstop++;
- }
- ieee->queue_stop = 1;
-}
-
-inline void ieee80211_randomize_cell(struct ieee80211_device *ieee)
-{
- random_ether_addr(ieee->current_network.bssid);
-}
-
-/* called in user context only */
-void ieee80211_start_master_bss(struct ieee80211_device *ieee)
-{
- ieee->assoc_id = 1;
-
- if (ieee->current_network.ssid_len == 0) {
- strncpy(ieee->current_network.ssid,
- IEEE80211_DEFAULT_TX_ESSID,
- IW_ESSID_MAX_SIZE);
-
- ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID);
- ieee->ssid_set = 1;
- }
-
- memcpy(ieee->current_network.bssid, ieee->dev->dev_addr, ETH_ALEN);
-
- ieee->set_chan(ieee->dev, ieee->current_network.channel);
- ieee->state = IEEE80211_LINKED;
- ieee->link_change(ieee->dev);
- notify_wx_assoc_event(ieee);
-
- if (ieee->data_hard_resume)
- ieee->data_hard_resume(ieee->dev);
-
- netif_carrier_on(ieee->dev);
-}
-
-static void ieee80211_start_monitor_mode(struct ieee80211_device *ieee)
-{
- if (ieee->raw_tx) {
-
- if (ieee->data_hard_resume)
- ieee->data_hard_resume(ieee->dev);
-
- netif_carrier_on(ieee->dev);
- }
-}
-
-static void ieee80211_start_ibss_wq(struct work_struct *work)
-{
- struct delayed_work *dwork = to_delayed_work(work);
- struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, start_ibss_wq);
-
- /* iwconfig mode ad-hoc will schedule this and return
- * on the other hand this will block further iwconfig SET
- * operations because of the wx_sem hold.
- * Anyway some most set operations set a flag to speed-up
- * (abort) this wq (when syncro scanning) before sleeping
- * on the semaphore
- */
-
- down(&ieee->wx_sem);
-
- if (ieee->current_network.ssid_len == 0) {
- strcpy(ieee->current_network.ssid, IEEE80211_DEFAULT_TX_ESSID);
- ieee->current_network.ssid_len = strlen(IEEE80211_DEFAULT_TX_ESSID);
- ieee->ssid_set = 1;
- }
-
- /* check if we have this cell in our network list */
- ieee80211_softmac_check_all_nets(ieee);
-
- if (ieee->state == IEEE80211_NOLINK)
- ieee->current_network.channel = 10;
- /* if not then the state is not linked. Maybe the user switched to
- * ad-hoc mode just after being in monitor mode, or just after
- * being very few time in managed mode (so the card have had no
- * time to scan all the chans..) or we have just run up the iface
- * after setting ad-hoc mode. So we have to give another try..
- * Here, in ibss mode, should be safe to do this without extra care
- * (in bss mode we had to make sure no-one tried to associate when
- * we had just checked the ieee->state and we was going to start the
- * scan) because in ibss mode the ieee80211_new_net function, when
- * finds a good net, just set the ieee->state to IEEE80211_LINKED,
- * so, at worst, we waste a bit of time to initiate an unneeded syncro
- * scan, that will stop at the first round because it sees the state
- * associated.
- */
- if (ieee->state == IEEE80211_NOLINK)
- ieee80211_start_scan_syncro(ieee);
-
- /* the network definitively is not here.. create a new cell */
- if (ieee->state == IEEE80211_NOLINK) {
- printk("creating new IBSS cell\n");
- if (!ieee->wap_set)
- ieee80211_randomize_cell(ieee);
-
- if (ieee->modulation & IEEE80211_CCK_MODULATION) {
- ieee->current_network.rates_len = 4;
-
- ieee->current_network.rates[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_1MB;
- ieee->current_network.rates[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_2MB;
- ieee->current_network.rates[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_5MB;
- ieee->current_network.rates[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_CCK_RATE_11MB;
-
- } else
- ieee->current_network.rates_len = 0;
-
- if (ieee->modulation & IEEE80211_OFDM_MODULATION) {
- ieee->current_network.rates_ex_len = 8;
-
- ieee->current_network.rates_ex[0] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_6MB;
- ieee->current_network.rates_ex[1] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_9MB;
- ieee->current_network.rates_ex[2] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_12MB;
- ieee->current_network.rates_ex[3] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_18MB;
- ieee->current_network.rates_ex[4] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_24MB;
- ieee->current_network.rates_ex[5] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_36MB;
- ieee->current_network.rates_ex[6] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_48MB;
- ieee->current_network.rates_ex[7] = IEEE80211_BASIC_RATE_MASK | IEEE80211_OFDM_RATE_54MB;
-
- ieee->rate = 540;
- } else {
- ieee->current_network.rates_ex_len = 0;
- ieee->rate = 110;
- }
-
- /* By default, WMM function will be disabled in IBSS mode */
- ieee->current_network.QoS_Enable = 0;
-
- ieee->current_network.atim_window = 0;
- ieee->current_network.capability = WLAN_CAPABILITY_IBSS;
- if (ieee->short_slot)
- ieee->current_network.capability |= WLAN_CAPABILITY_SHORT_SLOT;
- }
-
- ieee->state = IEEE80211_LINKED;
- ieee->set_chan(ieee->dev, ieee->current_network.channel);
- ieee->link_change(ieee->dev);
-
- notify_wx_assoc_event(ieee);
-
- ieee80211_start_send_beacons(ieee);
- printk(KERN_WARNING "after sending beacon packet!\n");
-
- if (ieee->data_hard_resume)
- ieee->data_hard_resume(ieee->dev);
-
- netif_carrier_on(ieee->dev);
-
- up(&ieee->wx_sem);
-}
-
-inline void ieee80211_start_ibss(struct ieee80211_device *ieee)
-{
- queue_delayed_work(ieee->wq, &ieee->start_ibss_wq, 100);
-}
-
-/* this is called only in user context, with wx_sem held */
-void ieee80211_start_bss(struct ieee80211_device *ieee)
-{
- unsigned long flags;
- /* Ref: 802.11d 11.1.3.3
- * STA shall not start a BSS unless properly formed Beacon frame
- * including a Country IE.
- */
- if (IS_DOT11D_ENABLE(ieee) && !IS_COUNTRY_IE_VALID(ieee)) {
- if (!ieee->bGlobalDomain)
- return;
- }
- /* check if we have already found the net we are interested in (if any).
- * if not (we are disassociated and we are not
- * in associating / authenticating phase) start the background scanning.
- */
- ieee80211_softmac_check_all_nets(ieee);
-
- /* ensure no-one start an associating process (thus setting
- * the ieee->state to ieee80211_ASSOCIATING) while we
- * have just cheked it and we are going to enable scan.
- * The ieee80211_new_net function is always called with
- * lock held (from both ieee80211_softmac_check_all_nets and
- * the rx path), so we cannot be in the middle of such function
- */
- spin_lock_irqsave(&ieee->lock, flags);
-
- if (ieee->state == IEEE80211_NOLINK) {
- ieee->actscanning = true;
- ieee80211_rtl_start_scan(ieee);
- }
- spin_unlock_irqrestore(&ieee->lock, flags);
-}
-
-/* called only in userspace context */
-void ieee80211_disassociate(struct ieee80211_device *ieee)
-{
- netif_carrier_off(ieee->dev);
-
- if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)
- ieee80211_reset_queue(ieee);
-
- if (ieee->data_hard_stop)
- ieee->data_hard_stop(ieee->dev);
-
- if (IS_DOT11D_ENABLE(ieee))
- Dot11d_Reset(ieee);
-
- ieee->link_change(ieee->dev);
- if (ieee->state == IEEE80211_LINKED)
- notify_wx_assoc_event(ieee);
- ieee->state = IEEE80211_NOLINK;
-
-}
-static void ieee80211_associate_retry_wq(struct work_struct *work)
-{
- struct delayed_work *dwork = to_delayed_work(work);
- struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, associate_retry_wq);
- unsigned long flags;
- down(&ieee->wx_sem);
- if (!ieee->proto_started)
- goto exit;
- if (ieee->state != IEEE80211_ASSOCIATING_RETRY)
- goto exit;
- /* until we do not set the state to IEEE80211_NOLINK
- * there are no possibility to have someone else trying
- * to start an association procedure (we get here with
- * ieee->state = IEEE80211_ASSOCIATING).
- * When we set the state to IEEE80211_NOLINK it is possible
- * that the RX path run an attempt to associate, but
- * both ieee80211_softmac_check_all_nets and the
- * RX path works with ieee->lock held so there are no
- * problems. If we are still disassociated then start a scan.
- * the lock here is necessary to ensure no one try to start
- * an association procedure when we have just checked the
- * state and we are going to start the scan.
- */
- ieee->state = IEEE80211_NOLINK;
- ieee->beinretry = true;
- ieee80211_softmac_check_all_nets(ieee);
-
- spin_lock_irqsave(&ieee->lock, flags);
-
- if (ieee->state == IEEE80211_NOLINK) {
- ieee->beinretry = false;
- ieee->actscanning = true;
- ieee80211_rtl_start_scan(ieee);
- }
- if (ieee->state == IEEE80211_NOLINK)
- notify_wx_assoc_event(ieee);
- spin_unlock_irqrestore(&ieee->lock, flags);
-
-exit:
- up(&ieee->wx_sem);
-}
-
-struct sk_buff *ieee80211_get_beacon_(struct ieee80211_device *ieee)
-{
- u8 broadcast_addr[] = {0xff, 0xff, 0xff, 0xff, 0xff, 0xff};
-
- struct sk_buff *skb = NULL;
- struct ieee80211_probe_response *b;
-
- skb = ieee80211_probe_resp(ieee, broadcast_addr);
- if (!skb)
- return NULL;
-
- b = (struct ieee80211_probe_response *) skb->data;
- b->header.frame_ctl = cpu_to_le16(IEEE80211_STYPE_BEACON);
-
- return skb;
-}
-
-struct sk_buff *ieee80211_get_beacon(struct ieee80211_device *ieee)
-{
- struct sk_buff *skb;
- struct ieee80211_probe_response *b;
-
- skb = ieee80211_get_beacon_(ieee);
- if (!skb)
- return NULL;
-
- b = (struct ieee80211_probe_response *) skb->data;
- b->header.seq_ctrl = cpu_to_le16(ieee->seq_ctrl[0] << 4);
-
- if (ieee->seq_ctrl[0] == 0xFFF)
- ieee->seq_ctrl[0] = 0;
- else
- ieee->seq_ctrl[0]++;
-
- return skb;
-}
-
-void ieee80211_softmac_stop_protocol(struct ieee80211_device *ieee)
-{
- ieee->sync_scan_hurryup = 1;
- down(&ieee->wx_sem);
- ieee80211_stop_protocol(ieee);
- up(&ieee->wx_sem);
-}
-
-void ieee80211_stop_protocol(struct ieee80211_device *ieee)
-{
- if (!ieee->proto_started)
- return;
-
- ieee->proto_started = 0;
-
- ieee80211_stop_send_beacons(ieee);
- if ((ieee->iw_mode == IW_MODE_INFRA) && (ieee->state == IEEE80211_LINKED))
- SendDisassociation(ieee, NULL, WLAN_REASON_DISASSOC_STA_HAS_LEFT);
-
- del_timer_sync(&ieee->associate_timer);
- cancel_delayed_work(&ieee->associate_retry_wq);
- cancel_delayed_work(&ieee->start_ibss_wq);
- ieee80211_stop_scan(ieee);
-
- ieee80211_disassociate(ieee);
-}
-
-void ieee80211_softmac_start_protocol(struct ieee80211_device *ieee)
-{
- ieee->sync_scan_hurryup = 0;
- down(&ieee->wx_sem);
- ieee80211_start_protocol(ieee);
- up(&ieee->wx_sem);
-}
-
-void ieee80211_start_protocol(struct ieee80211_device *ieee)
-{
- short ch = 0;
- int i = 0;
-
- if (ieee->proto_started)
- return;
-
- ieee->proto_started = 1;
-
- if (ieee->current_network.channel == 0) {
- do {
- ch++;
- if (ch > MAX_CHANNEL_NUMBER)
- return; /* no channel found */
-
- } while (!GET_DOT11D_INFO(ieee)->channel_map[ch]);
-
- ieee->current_network.channel = ch;
- }
-
- if (ieee->current_network.beacon_interval == 0)
- ieee->current_network.beacon_interval = 100;
- ieee->set_chan(ieee->dev, ieee->current_network.channel);
-
- for (i = 0; i < 17; i++) {
- ieee->last_rxseq_num[i] = -1;
- ieee->last_rxfrag_num[i] = -1;
- ieee->last_packet_time[i] = 0;
- }
-
- ieee->init_wmmparam_flag = 0; /* reinitialize AC_xx_PARAM registers. */
-
- /* if the user set the MAC of the ad-hoc cell and then
- * switch to managed mode, shall we make sure that association
- * attempts does not fail just because the user provide the essid
- * and the nic is still checking for the AP MAC ??
- */
- switch (ieee->iw_mode) {
- case IW_MODE_AUTO:
- ieee->iw_mode = IW_MODE_INFRA;
- /* not set break here intentionly */
- case IW_MODE_INFRA:
- ieee80211_start_bss(ieee);
- break;
-
- case IW_MODE_ADHOC:
- ieee80211_start_ibss(ieee);
- break;
-
- case IW_MODE_MASTER:
- ieee80211_start_master_bss(ieee);
- break;
-
- case IW_MODE_MONITOR:
- ieee80211_start_monitor_mode(ieee);
- break;
-
- default:
- ieee->iw_mode = IW_MODE_INFRA;
- ieee80211_start_bss(ieee);
- break;
- }
-}
-
-#define DRV_NAME "Ieee80211"
-void ieee80211_softmac_init(struct ieee80211_device *ieee)
-{
- int i;
- memset(&ieee->current_network, 0, sizeof(struct ieee80211_network));
-
- ieee->state = IEEE80211_NOLINK;
- ieee->sync_scan_hurryup = 0;
- for (i = 0; i < 5; i++)
- ieee->seq_ctrl[i] = 0;
-
- ieee->assoc_id = 0;
- ieee->queue_stop = 0;
- ieee->scanning = 0;
- ieee->softmac_features = 0; /* so IEEE2100-like driver are happy */
- ieee->wap_set = 0;
- ieee->ssid_set = 0;
- ieee->proto_started = 0;
- ieee->basic_rate = IEEE80211_DEFAULT_BASIC_RATE;
- ieee->rate = 3;
- ieee->ps = IEEE80211_PS_MBCAST|IEEE80211_PS_UNICAST;
- ieee->sta_sleep = 0;
- ieee->bInactivePs = false;
- ieee->actscanning = false;
- ieee->ListenInterval = 2;
- ieee->NumRxDataInPeriod = 0;
- ieee->NumRxBcnInPeriod = 0;
- ieee->NumRxOkTotal = 0;
- ieee->NumRxUnicast = 0; /* for keep alive */
- ieee->beinretry = false;
- ieee->bHwRadioOff = false;
-
- init_mgmt_queue(ieee);
-
- ieee->tx_pending.txb = NULL;
-
- init_timer(&ieee->associate_timer);
- ieee->associate_timer.data = (unsigned long)ieee;
- ieee->associate_timer.function = ieee80211_associate_abort_cb;
-
- init_timer(&ieee->beacon_timer);
- ieee->beacon_timer.data = (unsigned long) ieee;
- ieee->beacon_timer.function = ieee80211_send_beacon_cb;
-
- ieee->wq = create_workqueue(DRV_NAME);
-
- INIT_DELAYED_WORK(&ieee->start_ibss_wq, (void *) ieee80211_start_ibss_wq);
- INIT_WORK(&ieee->associate_complete_wq, (void *) ieee80211_associate_complete_wq);
- INIT_WORK(&ieee->associate_procedure_wq, (void *) ieee80211_associate_procedure_wq);
- INIT_DELAYED_WORK(&ieee->softmac_scan_wq, (void *) ieee80211_softmac_scan_wq);
- INIT_DELAYED_WORK(&ieee->associate_retry_wq, (void *) ieee80211_associate_retry_wq);
- INIT_WORK(&ieee->wx_sync_scan_wq, (void *) ieee80211_wx_sync_scan_wq);
-
- sema_init(&ieee->wx_sem, 1);
- sema_init(&ieee->scan_sem, 1);
-
- spin_lock_init(&ieee->mgmt_tx_lock);
- spin_lock_init(&ieee->beacon_lock);
-
- tasklet_init(&ieee->ps_task,
- (void(*)(unsigned long)) ieee80211_sta_ps,
- (unsigned long)ieee);
- ieee->pDot11dInfo = kmalloc(sizeof(RT_DOT11D_INFO), GFP_ATOMIC);
-}
-
-void ieee80211_softmac_free(struct ieee80211_device *ieee)
-{
- down(&ieee->wx_sem);
-
- del_timer_sync(&ieee->associate_timer);
- cancel_delayed_work(&ieee->associate_retry_wq);
-
- /* add for RF power on power of */
- cancel_delayed_work(&ieee->GPIOChangeRFWorkItem);
-
- destroy_workqueue(ieee->wq);
- kfree(ieee->pDot11dInfo);
- up(&ieee->wx_sem);
-}
-
-/* Start of WPA code. This is stolen from the ipw2200 driver */
-static int ieee80211_wpa_enable(struct ieee80211_device *ieee, int value)
-{
- /* This is called when wpa_supplicant loads and closes the driver
- * interface. */
- printk("%s WPA\n", value ? "enabling" : "disabling");
- ieee->wpa_enabled = value;
- return 0;
-}
-
-static void ieee80211_wpa_assoc_frame(struct ieee80211_device *ieee, char *wpa_ie,
- int wpa_ie_len)
-{
- /* make sure WPA is enabled */
- ieee80211_wpa_enable(ieee, 1);
-
- ieee80211_disassociate(ieee);
-}
-
-static int ieee80211_wpa_mlme(struct ieee80211_device *ieee, int command,
- int reason)
-{
- int ret = 0;
-
- switch (command) {
- case IEEE_MLME_STA_DEAUTH:
- /* silently ignore */
- break;
-
- case IEEE_MLME_STA_DISASSOC:
- ieee80211_disassociate(ieee);
- break;
-
- default:
- printk("Unknown MLME request: %d\n", command);
- ret = -EOPNOTSUPP;
- }
-
- return ret;
-}
-
-static int ieee80211_wpa_set_wpa_ie(struct ieee80211_device *ieee,
- struct ieee_param *param, int plen)
-{
- u8 *buf;
-
- if (param->u.wpa_ie.len > MAX_WPA_IE_LEN ||
- (param->u.wpa_ie.len && param->u.wpa_ie.data == NULL))
- return -EINVAL;
-
- if (param->u.wpa_ie.len) {
- buf = kmemdup(param->u.wpa_ie.data, param->u.wpa_ie.len,
- GFP_KERNEL);
- if (buf == NULL)
- return -ENOMEM;
-
- kfree(ieee->wpa_ie);
- ieee->wpa_ie = buf;
- ieee->wpa_ie_len = param->u.wpa_ie.len;
- } else {
- kfree(ieee->wpa_ie);
- ieee->wpa_ie = NULL;
- ieee->wpa_ie_len = 0;
- }
-
- ieee80211_wpa_assoc_frame(ieee, ieee->wpa_ie, ieee->wpa_ie_len);
- return 0;
-}
-
-#define AUTH_ALG_OPEN_SYSTEM 0x1
-#define AUTH_ALG_SHARED_KEY 0x2
-
-static int ieee80211_wpa_set_auth_algs(struct ieee80211_device *ieee, int value)
-{
- struct ieee80211_security sec = {
- .flags = SEC_AUTH_MODE,
- };
- int ret = 0;
-
- if (value & AUTH_ALG_SHARED_KEY) {
- sec.auth_mode = WLAN_AUTH_SHARED_KEY;
- ieee->open_wep = 0;
- } else {
- sec.auth_mode = WLAN_AUTH_OPEN;
- ieee->open_wep = 1;
- }
-
- if (ieee->set_security)
- ieee->set_security(ieee->dev, &sec);
- else
- ret = -EOPNOTSUPP;
-
- return ret;
-}
-
-static int ieee80211_wpa_set_param(struct ieee80211_device *ieee, u8 name,
- u32 value)
-{
- int ret = 0;
- unsigned long flags;
-
- switch (name) {
- case IEEE_PARAM_WPA_ENABLED:
- ret = ieee80211_wpa_enable(ieee, value);
- break;
-
- case IEEE_PARAM_TKIP_COUNTERMEASURES:
- ieee->tkip_countermeasures = value;
- break;
-
- case IEEE_PARAM_DROP_UNENCRYPTED: {
- /* HACK:
- *
- * wpa_supplicant calls set_wpa_enabled when the driver
- * is loaded and unloaded, regardless of if WPA is being
- * used. No other calls are made which can be used to
- * determine if encryption will be used or not prior to
- * association being expected. If encryption is not being
- * used, drop_unencrypted is set to false, else true -- we
- * can use this to determine if the CAP_PRIVACY_ON bit should
- * be set.
- */
- struct ieee80211_security sec = {
- .flags = SEC_ENABLED,
- .enabled = value,
- };
- ieee->drop_unencrypted = value;
- /* We only change SEC_LEVEL for open mode. Others
- * are set by ipw_wpa_set_encryption.
- */
- if (!value) {
- sec.flags |= SEC_LEVEL;
- sec.level = SEC_LEVEL_0;
- } else {
- sec.flags |= SEC_LEVEL;
- sec.level = SEC_LEVEL_1;
- }
- if (ieee->set_security)
- ieee->set_security(ieee->dev, &sec);
- break;
- }
-
- case IEEE_PARAM_PRIVACY_INVOKED:
- ieee->privacy_invoked = value;
- break;
- case IEEE_PARAM_AUTH_ALGS:
- ret = ieee80211_wpa_set_auth_algs(ieee, value);
- break;
- case IEEE_PARAM_IEEE_802_1X:
- ieee->ieee802_1x = value;
- break;
- case IEEE_PARAM_WPAX_SELECT:
- spin_lock_irqsave(&ieee->wpax_suitlist_lock, flags);
- ieee->wpax_type_set = 1;
- ieee->wpax_type_notify = value;
- spin_unlock_irqrestore(&ieee->wpax_suitlist_lock, flags);
- break;
- default:
- printk("Unknown WPA param: %d\n", name);
- ret = -EOPNOTSUPP;
- }
-
- return ret;
-}
-
-/* implementation borrowed from hostap driver */
-
-static int ieee80211_wpa_set_encryption(struct ieee80211_device *ieee,
- struct ieee_param *param, int param_len)
-{
- int ret = 0;
-
- struct ieee80211_crypto_ops *ops;
- struct ieee80211_crypt_data **crypt;
-
- struct ieee80211_security sec = {
- .flags = 0,
- };
-
- param->u.crypt.err = 0;
- param->u.crypt.alg[IEEE_CRYPT_ALG_NAME_LEN - 1] = '\0';
-
- if (param_len !=
- (int) ((char *) param->u.crypt.key - (char *) param) +
- param->u.crypt.key_len) {
- printk("Len mismatch %d, %d\n", param_len,
- param->u.crypt.key_len);
- return -EINVAL;
- }
- if (is_broadcast_ether_addr(param->sta_addr)) {
- if (param->u.crypt.idx >= WEP_KEYS)
- return -EINVAL;
- crypt = &ieee->crypt[param->u.crypt.idx];
- } else {
- return -EINVAL;
- }
-
- if (strcmp(param->u.crypt.alg, "none") == 0) {
- if (crypt) {
- sec.enabled = 0;
- /* FIXME FIXME */
- sec.level = SEC_LEVEL_0;
- sec.flags |= SEC_ENABLED | SEC_LEVEL;
- ieee80211_crypt_delayed_deinit(ieee, crypt);
- }
- goto done;
- }
- sec.enabled = 1;
- /* FIXME FIXME */
- sec.flags |= SEC_ENABLED;
-
- /* IPW HW cannot build TKIP MIC, host decryption still needed. */
- if (!(ieee->host_encrypt || ieee->host_decrypt) &&
- strcmp(param->u.crypt.alg, "TKIP"))
- goto skip_host_crypt;
-
- ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
- if (ops == NULL && strcmp(param->u.crypt.alg, "WEP") == 0)
- ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
- else if (ops == NULL && strcmp(param->u.crypt.alg, "TKIP") == 0)
- ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
- else if (ops == NULL && strcmp(param->u.crypt.alg, "CCMP") == 0)
- ops = ieee80211_get_crypto_ops(param->u.crypt.alg);
- if (ops == NULL) {
- printk("unknown crypto alg '%s'\n", param->u.crypt.alg);
- param->u.crypt.err = IEEE_CRYPT_ERR_UNKNOWN_ALG;
- ret = -EINVAL;
- goto done;
- }
-
- if (*crypt == NULL || (*crypt)->ops != ops) {
- struct ieee80211_crypt_data *new_crypt;
-
- ieee80211_crypt_delayed_deinit(ieee, crypt);
-
- new_crypt = kmalloc(sizeof(*new_crypt), GFP_KERNEL);
- if (new_crypt == NULL) {
- ret = -ENOMEM;
- goto done;
- }
- memset(new_crypt, 0, sizeof(struct ieee80211_crypt_data));
- new_crypt->ops = ops;
- if (new_crypt->ops)
- new_crypt->priv =
- new_crypt->ops->init(param->u.crypt.idx);
-
- if (new_crypt->priv == NULL) {
- kfree(new_crypt);
- param->u.crypt.err = IEEE_CRYPT_ERR_CRYPT_INIT_FAILED;
- ret = -EINVAL;
- goto done;
- }
-
- *crypt = new_crypt;
- }
-
- if (param->u.crypt.key_len > 0 && (*crypt)->ops->set_key &&
- (*crypt)->ops->set_key(param->u.crypt.key,
- param->u.crypt.key_len, param->u.crypt.seq,
- (*crypt)->priv) < 0) {
- printk("key setting failed\n");
- param->u.crypt.err = IEEE_CRYPT_ERR_KEY_SET_FAILED;
- ret = -EINVAL;
- goto done;
- }
-
- skip_host_crypt:
- if (param->u.crypt.set_tx) {
- ieee->tx_keyidx = param->u.crypt.idx;
- sec.active_key = param->u.crypt.idx;
- sec.flags |= SEC_ACTIVE_KEY;
- } else
- sec.flags &= ~SEC_ACTIVE_KEY;
-
- if (param->u.crypt.alg != NULL) {
- memcpy(sec.keys[param->u.crypt.idx],
- param->u.crypt.key,
- param->u.crypt.key_len);
- sec.key_sizes[param->u.crypt.idx] = param->u.crypt.key_len;
- sec.flags |= (1 << param->u.crypt.idx);
-
- if (strcmp(param->u.crypt.alg, "WEP") == 0) {
- sec.flags |= SEC_LEVEL;
- sec.level = SEC_LEVEL_1;
- } else if (strcmp(param->u.crypt.alg, "TKIP") == 0) {
- sec.flags |= SEC_LEVEL;
- sec.level = SEC_LEVEL_2;
- } else if (strcmp(param->u.crypt.alg, "CCMP") == 0) {
- sec.flags |= SEC_LEVEL;
- sec.level = SEC_LEVEL_3;
- }
- }
- done:
- if (ieee->set_security)
- ieee->set_security(ieee->dev, &sec);
-
- /* Do not reset port if card is in Managed mode since resetting will
- * generate new IEEE 802.11 authentication which may end up in looping
- * with IEEE 802.1X. If your hardware requires a reset after WEP
- * configuration (for example... Prism2), implement the reset_port in
- * the callbacks structures used to initialize the 802.11 stack. */
- if (ieee->reset_on_keychange &&
- ieee->iw_mode != IW_MODE_INFRA &&
- ieee->reset_port &&
- ieee->reset_port(ieee->dev)) {
- printk("reset_port failed\n");
- param->u.crypt.err = IEEE_CRYPT_ERR_CARD_CONF_FAILED;
- return -EINVAL;
- }
-
- return ret;
-}
-
-int ieee80211_wpa_supplicant_ioctl(struct ieee80211_device *ieee,
- struct iw_point *p)
-{
- struct ieee_param *param;
- int ret = 0;
-
- down(&ieee->wx_sem);
-
- if (p->length < sizeof(struct ieee_param) || !p->pointer) {
- ret = -EINVAL;
- goto out;
- }
-
- param = memdup_user(p->pointer, p->length);
- if (IS_ERR(param)) {
- ret = PTR_ERR(param);
- goto out;
- }
-
- switch (param->cmd) {
- case IEEE_CMD_SET_WPA_PARAM:
- ret = ieee80211_wpa_set_param(ieee, param->u.wpa_param.name,
- param->u.wpa_param.value);
- break;
- case IEEE_CMD_SET_WPA_IE:
- ret = ieee80211_wpa_set_wpa_ie(ieee, param, p->length);
- break;
- case IEEE_CMD_SET_ENCRYPTION:
- ret = ieee80211_wpa_set_encryption(ieee, param, p->length);
- break;
- case IEEE_CMD_MLME:
- ret = ieee80211_wpa_mlme(ieee, param->u.mlme.command,
- param->u.mlme.reason_code);
- break;
- default:
- printk("Unknown WPA supplicant request: %d\n", param->cmd);
- ret = -EOPNOTSUPP;
- break;
- }
-
- if (ret == 0 && copy_to_user(p->pointer, param, p->length))
- ret = -EFAULT;
-
- kfree(param);
-out:
- up(&ieee->wx_sem);
-
- return ret;
-}
-
-void notify_wx_assoc_event(struct ieee80211_device *ieee)
-{
- union iwreq_data wrqu;
- wrqu.ap_addr.sa_family = ARPHRD_ETHER;
- if (ieee->state == IEEE80211_LINKED)
- memcpy(wrqu.ap_addr.sa_data, ieee->current_network.bssid, ETH_ALEN);
- else
- memset(wrqu.ap_addr.sa_data, 0, ETH_ALEN);
- wireless_send_event(ieee->dev, SIOCGIWAP, &wrqu, NULL);
-}
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c
deleted file mode 100644
index 46f3564..0000000
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_softmac_wx.c
+++ /dev/null
@@ -1,567 +0,0 @@
-/* IEEE 802.11 SoftMAC layer
- * Copyright (c) 2005 Andrea Merello <andrea.merello@gmail.com>
- *
- * Mostly extracted from the rtl8180-sa2400 driver for the
- * in-kernel generic ieee802.11 stack.
- *
- * Some pieces of code might be stolen from ipw2100 driver
- * copyright of who own it's copyright ;-)
- *
- * PS wx handler mostly stolen from hostap, copyright who
- * own it's copyright ;-)
- *
- * released under the GPL
- */
-
-
-#include <linux/etherdevice.h>
-
-#include "ieee80211.h"
-
-/* FIXME: add A freqs */
-
-const long ieee80211_wlan_frequencies[] = {
- 2412, 2417, 2422, 2427,
- 2432, 2437, 2442, 2447,
- 2452, 2457, 2462, 2467,
- 2472, 2484
-};
-
-
-int ieee80211_wx_set_freq(struct ieee80211_device *ieee,
- struct iw_request_info *a, union iwreq_data *wrqu,
- char *b)
-{
- int ret;
- struct iw_freq *fwrq = &wrqu->freq;
-// printk("in %s\n",__func__);
- down(&ieee->wx_sem);
-
- if (ieee->iw_mode == IW_MODE_INFRA) {
- ret = -EOPNOTSUPP;
- goto out;
- }
-
- /* if setting by freq convert to channel */
- if (fwrq->e == 1) {
- if ((fwrq->m >= (int) 2.412e8 &&
- fwrq->m <= (int) 2.487e8)) {
- int f = fwrq->m / 100000;
- int c = 0;
-
- while ((c < 14) && (f != ieee80211_wlan_frequencies[c]))
- c++;
-
- /* hack to fall through */
- fwrq->e = 0;
- fwrq->m = c + 1;
- }
- }
-
- if (fwrq->e > 0 || fwrq->m > 14 || fwrq->m < 1) {
- ret = -EOPNOTSUPP;
- goto out;
-
- } else { /* Set the channel */
-
-
- ieee->current_network.channel = fwrq->m;
- ieee->set_chan(ieee->dev, ieee->current_network.channel);
-
- if (ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER)
- if (ieee->state == IEEE80211_LINKED) {
- ieee80211_stop_send_beacons(ieee);
- ieee80211_start_send_beacons(ieee);
- }
- }
-
- ret = 0;
-out:
- up(&ieee->wx_sem);
- return ret;
-}
-
-
-int ieee80211_wx_get_freq(struct ieee80211_device *ieee,
- struct iw_request_info *a, union iwreq_data *wrqu,
- char *b)
-{
- struct iw_freq *fwrq = &wrqu->freq;
-
- if (ieee->current_network.channel == 0)
- return -1;
-
- fwrq->m = ieee->current_network.channel;
- fwrq->e = 0;
-
- return 0;
-}
-
-int ieee80211_wx_get_wap(struct ieee80211_device *ieee,
- struct iw_request_info *info, union iwreq_data *wrqu,
- char *extra)
-{
- unsigned long flags;
-
- wrqu->ap_addr.sa_family = ARPHRD_ETHER;
-
- if (ieee->iw_mode == IW_MODE_MONITOR)
- return -1;
-
- /* We want avoid to give to the user inconsistent infos*/
- spin_lock_irqsave(&ieee->lock, flags);
-
- if (ieee->state != IEEE80211_LINKED &&
- ieee->state != IEEE80211_LINKED_SCANNING &&
- ieee->wap_set == 0)
-
- memset(wrqu->ap_addr.sa_data, 0, ETH_ALEN);
- else
- memcpy(wrqu->ap_addr.sa_data,
- ieee->current_network.bssid, ETH_ALEN);
-
- spin_unlock_irqrestore(&ieee->lock, flags);
-
- return 0;
-}
-
-
-int ieee80211_wx_set_wap(struct ieee80211_device *ieee,
- struct iw_request_info *info, union iwreq_data *awrq,
- char *extra)
-{
-
- int ret = 0;
- unsigned long flags;
-
- short ifup = ieee->proto_started;//dev->flags & IFF_UP;
- struct sockaddr *temp = (struct sockaddr *)awrq;
-
- //printk("=======Set WAP:");
- ieee->sync_scan_hurryup = 1;
-
- down(&ieee->wx_sem);
- /* use ifconfig hw ether */
- if (ieee->iw_mode == IW_MODE_MASTER) {
- ret = -1;
- goto out;
- }
-
- if (temp->sa_family != ARPHRD_ETHER) {
- ret = -EINVAL;
- goto out;
- }
-
- if (ifup)
- ieee80211_stop_protocol(ieee);
-
- /* just to avoid to give inconsistent infos in the
- * get wx method. not really needed otherwise
- */
- spin_lock_irqsave(&ieee->lock, flags);
-
- memcpy(ieee->current_network.bssid, temp->sa_data, ETH_ALEN);
- ieee->wap_set = !is_zero_ether_addr(temp->sa_data);
- //printk(" %x:%x:%x:%x:%x:%x\n", ieee->current_network.bssid[0],ieee->current_network.bssid[1],ieee->current_network.bssid[2],ieee->current_network.bssid[3],ieee->current_network.bssid[4],ieee->current_network.bssid[5]);
-
- spin_unlock_irqrestore(&ieee->lock, flags);
-
- if (ifup)
- ieee80211_start_protocol(ieee);
-
-out:
- up(&ieee->wx_sem);
- return ret;
-}
-
-int ieee80211_wx_get_essid(struct ieee80211_device *ieee,
- struct iw_request_info *a, union iwreq_data *wrqu,
- char *b)
-{
- int len, ret = 0;
- unsigned long flags;
-
- if (ieee->iw_mode == IW_MODE_MONITOR)
- return -1;
-
- /* We want avoid to give to the user inconsistent infos*/
- spin_lock_irqsave(&ieee->lock, flags);
-
- if (ieee->current_network.ssid[0] == '\0' ||
- ieee->current_network.ssid_len == 0){
- ret = -1;
- goto out;
- }
-
- if (ieee->state != IEEE80211_LINKED &&
- ieee->state != IEEE80211_LINKED_SCANNING &&
- ieee->ssid_set == 0){
- ret = -1;
- goto out;
- }
- len = ieee->current_network.ssid_len;
- wrqu->essid.length = len;
- strncpy(b, ieee->current_network.ssid, len);
- wrqu->essid.flags = 1;
-
-out:
- spin_unlock_irqrestore(&ieee->lock, flags);
-
- return ret;
-
-}
-
-int ieee80211_wx_set_rate(struct ieee80211_device *ieee,
- struct iw_request_info *info, union iwreq_data *wrqu,
- char *extra)
-{
-
- u32 target_rate = wrqu->bitrate.value;
-
- //added by lizhaoming for auto mode
- if (target_rate == -1)
- ieee->rate = 110;
- else
- ieee->rate = target_rate/100000;
-
- //FIXME: we might want to limit rate also in management protocols.
- return 0;
-}
-
-
-
-int ieee80211_wx_get_rate(struct ieee80211_device *ieee,
- struct iw_request_info *info, union iwreq_data *wrqu,
- char *extra)
-{
-
- wrqu->bitrate.value = ieee->rate * 100000;
-
- return 0;
-}
-
-int ieee80211_wx_set_mode(struct ieee80211_device *ieee,
- struct iw_request_info *a, union iwreq_data *wrqu,
- char *b)
-{
-
- ieee->sync_scan_hurryup = 1;
-
- down(&ieee->wx_sem);
-
- if (wrqu->mode == ieee->iw_mode)
- goto out;
-
- if (wrqu->mode == IW_MODE_MONITOR)
- ieee->dev->type = ARPHRD_IEEE80211;
- else
- ieee->dev->type = ARPHRD_ETHER;
-
- if (!ieee->proto_started) {
- ieee->iw_mode = wrqu->mode;
- } else {
- ieee80211_stop_protocol(ieee);
- ieee->iw_mode = wrqu->mode;
- ieee80211_start_protocol(ieee);
- }
-
-out:
- up(&ieee->wx_sem);
- return 0;
-}
-
-
-void ieee80211_wx_sync_scan_wq(struct work_struct *work)
-{
- struct ieee80211_device *ieee = container_of(work, struct ieee80211_device, wx_sync_scan_wq);
- short chan;
-
- chan = ieee->current_network.channel;
-
- if (ieee->data_hard_stop)
- ieee->data_hard_stop(ieee->dev);
-
- ieee80211_stop_send_beacons(ieee);
-
- ieee->state = IEEE80211_LINKED_SCANNING;
- ieee->link_change(ieee->dev);
-
- ieee80211_start_scan_syncro(ieee);
-
- ieee->set_chan(ieee->dev, chan);
-
- ieee->state = IEEE80211_LINKED;
- ieee->link_change(ieee->dev);
-
- if (ieee->data_hard_resume)
- ieee->data_hard_resume(ieee->dev);
-
- if (ieee->iw_mode == IW_MODE_ADHOC || ieee->iw_mode == IW_MODE_MASTER)
- ieee80211_start_send_beacons(ieee);
-
- //YJ,add,080828, In prevent of lossing ping packet during scanning
- //ieee80211_sta_ps_send_null_frame(ieee, false);
- //YJ,add,080828,end
-
- up(&ieee->wx_sem);
-
-}
-
-int ieee80211_wx_set_scan(struct ieee80211_device *ieee,
- struct iw_request_info *a, union iwreq_data *wrqu,
- char *b)
-{
- int ret = 0;
-
- down(&ieee->wx_sem);
-
- if (ieee->iw_mode == IW_MODE_MONITOR || !(ieee->proto_started)) {
- ret = -1;
- goto out;
- }
- //YJ,add,080828
- //In prevent of lossing ping packet during scanning
- //ieee80211_sta_ps_send_null_frame(ieee, true);
- //YJ,add,080828,end
-
- if (ieee->state == IEEE80211_LINKED) {
- queue_work(ieee->wq, &ieee->wx_sync_scan_wq);
- /* intentionally forget to up sem */
- return 0;
- }
-
-out:
- up(&ieee->wx_sem);
- return ret;
-}
-
-int ieee80211_wx_set_essid(struct ieee80211_device *ieee,
- struct iw_request_info *a, union iwreq_data *wrqu,
- char *extra)
-{
-
- int ret = 0, len;
- short proto_started;
- unsigned long flags;
-
- ieee->sync_scan_hurryup = 1;
-
- down(&ieee->wx_sem);
-
- proto_started = ieee->proto_started;
-
- if (wrqu->essid.length > IW_ESSID_MAX_SIZE) {
- ret = -E2BIG;
- goto out;
- }
-
- if (ieee->iw_mode == IW_MODE_MONITOR) {
- ret = -1;
- goto out;
- }
-
- if (proto_started)
- ieee80211_stop_protocol(ieee);
-
- /* this is just to be sure that the GET wx callback
- * has consistent infos. not needed otherwise
- */
- spin_lock_irqsave(&ieee->lock, flags);
-
- if (wrqu->essid.flags && wrqu->essid.length) {
-//YJ,modified,080819
- len = (wrqu->essid.length < IW_ESSID_MAX_SIZE) ? (wrqu->essid.length) : IW_ESSID_MAX_SIZE;
- memset(ieee->current_network.ssid, 0, ieee->current_network.ssid_len); //YJ,add,080819
- strncpy(ieee->current_network.ssid, extra, len);
- ieee->current_network.ssid_len = len;
- ieee->ssid_set = 1;
-//YJ,modified,080819,end
-
- //YJ,add,080819,for hidden ap
- if (len == 0) {
- memset(ieee->current_network.bssid, 0, ETH_ALEN);
- ieee->current_network.capability = 0;
- }
- //YJ,add,080819,for hidden ap,end
- } else {
- ieee->ssid_set = 0;
- ieee->current_network.ssid[0] = '\0';
- ieee->current_network.ssid_len = 0;
- }
- //printk("==========set essid %s!\n",ieee->current_network.ssid);
- spin_unlock_irqrestore(&ieee->lock, flags);
-
- if (proto_started)
- ieee80211_start_protocol(ieee);
-out:
- up(&ieee->wx_sem);
- return ret;
-}
-
-int ieee80211_wx_get_mode(struct ieee80211_device *ieee,
- struct iw_request_info *a, union iwreq_data *wrqu,
- char *b)
-{
-
- wrqu->mode = ieee->iw_mode;
- return 0;
-}
-
-int ieee80211_wx_set_rawtx(struct ieee80211_device *ieee,
- struct iw_request_info *info, union iwreq_data *wrqu,
- char *extra)
-{
-
- int *parms = (int *)extra;
- int enable = (parms[0] > 0);
- short prev = ieee->raw_tx;
-
- down(&ieee->wx_sem);
-
- if (enable)
- ieee->raw_tx = 1;
- else
- ieee->raw_tx = 0;
-
- netdev_info(ieee->dev, "raw TX is %s\n",
- ieee->raw_tx ? "enabled" : "disabled");
-
- if (ieee->iw_mode == IW_MODE_MONITOR) {
- if (prev == 0 && ieee->raw_tx) {
- if (ieee->data_hard_resume)
- ieee->data_hard_resume(ieee->dev);
-
- netif_carrier_on(ieee->dev);
- }
-
- if (prev && ieee->raw_tx == 1)
- netif_carrier_off(ieee->dev);
- }
-
- up(&ieee->wx_sem);
-
- return 0;
-}
-
-int ieee80211_wx_get_name(struct ieee80211_device *ieee,
- struct iw_request_info *info, union iwreq_data *wrqu,
- char *extra)
-{
- strlcpy(wrqu->name, "802.11", IFNAMSIZ);
- if (ieee->modulation & IEEE80211_CCK_MODULATION) {
- strlcat(wrqu->name, "b", IFNAMSIZ);
- if (ieee->modulation & IEEE80211_OFDM_MODULATION)
- strlcat(wrqu->name, "/g", IFNAMSIZ);
- } else if (ieee->modulation & IEEE80211_OFDM_MODULATION)
- strlcat(wrqu->name, "g", IFNAMSIZ);
-
- if ((ieee->state == IEEE80211_LINKED) ||
- (ieee->state == IEEE80211_LINKED_SCANNING))
- strlcat(wrqu->name, " link", IFNAMSIZ);
- else if (ieee->state != IEEE80211_NOLINK)
- strlcat(wrqu->name, " .....", IFNAMSIZ);
-
-
- return 0;
-}
-
-
-/* this is mostly stolen from hostap */
-int ieee80211_wx_set_power(struct ieee80211_device *ieee,
- struct iw_request_info *info, union iwreq_data *wrqu,
- char *extra)
-{
- int ret = 0;
-
- if ((!ieee->sta_wake_up) ||
- (!ieee->ps_request_tx_ack) ||
- (!ieee->enter_sleep_state) ||
- (!ieee->ps_is_queue_empty)) {
-
- printk("ERROR. PS mode tried to be use but driver missed a callback\n\n");
-
- return -1;
- }
-
- down(&ieee->wx_sem);
-
- if (wrqu->power.disabled) {
- ieee->ps = IEEE80211_PS_DISABLED;
-
- goto exit;
- }
- switch (wrqu->power.flags & IW_POWER_MODE) {
- case IW_POWER_UNICAST_R:
- ieee->ps = IEEE80211_PS_UNICAST;
-
- break;
- case IW_POWER_ALL_R:
- ieee->ps = IEEE80211_PS_UNICAST | IEEE80211_PS_MBCAST;
- break;
-
- case IW_POWER_ON:
- ieee->ps = IEEE80211_PS_DISABLED;
- break;
-
- default:
- ret = -EINVAL;
- goto exit;
- }
-
- if (wrqu->power.flags & IW_POWER_TIMEOUT) {
-
- ieee->ps_timeout = wrqu->power.value / 1000;
- printk("Timeout %d\n", ieee->ps_timeout);
- }
-
- if (wrqu->power.flags & IW_POWER_PERIOD) {
-
- ret = -EOPNOTSUPP;
- goto exit;
- //wrq->value / 1024;
-
- }
-exit:
- up(&ieee->wx_sem);
- return ret;
-
-}
-
-/* this is stolen from hostap */
-int ieee80211_wx_get_power(struct ieee80211_device *ieee,
- struct iw_request_info *info, union iwreq_data *wrqu,
- char *extra)
-{
- int ret = 0;
-
- down(&ieee->wx_sem);
-
- if (ieee->ps == IEEE80211_PS_DISABLED) {
- wrqu->power.disabled = 1;
- goto exit;
- }
-
- wrqu->power.disabled = 0;
-
-// if ((wrqu->power.flags & IW_POWER_TYPE) == IW_POWER_TIMEOUT) {
- wrqu->power.flags = IW_POWER_TIMEOUT;
- wrqu->power.value = ieee->ps_timeout * 1000;
-// } else {
-// ret = -EOPNOTSUPP;
-// goto exit;
- //wrqu->power.flags = IW_POWER_PERIOD;
- //wrqu->power.value = ieee->current_network.dtim_period *
- // ieee->current_network.beacon_interval * 1024;
-// }
-
-
- if (ieee->ps & IEEE80211_PS_MBCAST)
- wrqu->power.flags |= IW_POWER_ALL_R;
- else
- wrqu->power.flags |= IW_POWER_UNICAST_R;
-
-exit:
- up(&ieee->wx_sem);
- return ret;
-
-}
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c
deleted file mode 100644
index 0dc5ae4..0000000
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_tx.c
+++ /dev/null
@@ -1,591 +0,0 @@
-/******************************************************************************
-
- Copyright(c) 2003 - 2004 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., 59
- Temple Place - Suite 330, Boston, MA 02111-1307, USA.
-
- The full GNU General Public License is included in this distribution in the
- file called LICENSE.
-
- Contact Information:
- James P. Ketrenos <ipw2100-admin@linux.intel.com>
- Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
-
-******************************************************************************
-
- Few modifications for Realtek's Wi-Fi drivers by
- Andrea Merello <andrea.merello@gmail.com>
-
- A special thanks goes to Realtek for their support !
-
-******************************************************************************/
-
-#include <linux/compiler.h>
-#include <linux/errno.h>
-#include <linux/if_arp.h>
-#include <linux/in6.h>
-#include <linux/in.h>
-#include <linux/ip.h>
-#include <linux/kernel.h>
-#include <linux/module.h>
-#include <linux/netdevice.h>
-#include <linux/pci.h>
-#include <linux/proc_fs.h>
-#include <linux/skbuff.h>
-#include <linux/slab.h>
-#include <linux/tcp.h>
-#include <linux/types.h>
-#include <linux/wireless.h>
-#include <linux/etherdevice.h>
-#include <asm/uaccess.h>
-#include <linux/if_vlan.h>
-
-#include "ieee80211.h"
-
-
-/*
-
-
-802.11 Data Frame
-
-
-802.11 frame_contorl for data frames - 2 bytes
- ,-----------------------------------------------------------------------------------------.
-bits | 0 | 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | a | b | c | d | e |
- |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------|
-val | 0 | 0 | 0 | 1 | x | 0 | 0 | 0 | 1 | 0 | x | x | x | x | x |
- |----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|-----|------|
-desc | ^-ver-^ | ^type-^ | ^-----subtype-----^ | to |from |more |retry| pwr |more |wep |
- | | | x=0 data,x=1 data+ack | DS | DS |frag | | mgm |data | |
- '-----------------------------------------------------------------------------------------'
- /\
- |
-802.11 Data Frame |
- ,--------- 'ctrl' expands to >-----------'
- |
- ,--'---,-------------------------------------------------------------.
-Bytes | 2 | 2 | 6 | 6 | 6 | 2 | 0..2312 | 4 |
- |------|------|---------|---------|---------|------|---------|------|
-Desc. | ctrl | dura | DA/RA | TA | SA | Sequ | Frame | fcs |
- | | tion | (BSSID) | | | ence | data | |
- `--------------------------------------------------| |------'
-Total: 28 non-data bytes `----.----'
- |
- .- 'Frame data' expands to <---------------------------'
- |
- V
- ,---------------------------------------------------.
-Bytes | 1 | 1 | 1 | 3 | 2 | 0-2304 |
- |------|------|---------|----------|------|---------|
-Desc. | SNAP | SNAP | Control |Eth Tunnel| Type | IP |
- | DSAP | SSAP | | | | Packet |
- | 0xAA | 0xAA |0x03 (UI)|0x00-00-F8| | |
- `-----------------------------------------| |
-Total: 8 non-data bytes `----.----'
- |
- .- 'IP Packet' expands, if WEP enabled, to <--'
- |
- V
- ,-----------------------.
-Bytes | 4 | 0-2296 | 4 |
- |-----|-----------|-----|
-Desc. | IV | Encrypted | ICV |
- | | IP Packet | |
- `-----------------------'
-Total: 8 non-data bytes
-
-
-802.3 Ethernet Data Frame
-
- ,-----------------------------------------.
-Bytes | 6 | 6 | 2 | Variable | 4 |
- |-------|-------|------|-----------|------|
-Desc. | Dest. | Source| Type | IP Packet | fcs |
- | MAC | MAC | | | |
- `-----------------------------------------'
-Total: 18 non-data bytes
-
-In the event that fragmentation is required, the incoming payload is split into
-N parts of size ieee->fts. The first fragment contains the SNAP header and the
-remaining packets are just data.
-
-If encryption is enabled, each fragment payload size is reduced by enough space
-to add the prefix and postfix (IV and ICV totalling 8 bytes in the case of WEP)
-So if you have 1500 bytes of payload with ieee->fts set to 500 without
-encryption it will take 3 frames. With WEP it will take 4 frames as the
-payload of each frame is reduced to 492 bytes.
-
-* SKB visualization
-*
-* ,- skb->data
-* |
-* | ETHERNET HEADER ,-<-- PAYLOAD
-* | | 14 bytes from skb->data
-* | 2 bytes for Type --> ,T. | (sizeof ethhdr)
-* | | | |
-* |,-Dest.--. ,--Src.---. | | |
-* | 6 bytes| | 6 bytes | | | |
-* v | | | | | |
-* 0 | v 1 | v | v 2
-* 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5 6 7 8 9 0 1 2 3 4 5
-* ^ | ^ | ^ |
-* | | | | | |
-* | | | | `T' <---- 2 bytes for Type
-* | | | |
-* | | '---SNAP--' <-------- 6 bytes for SNAP
-* | |
-* `-IV--' <-------------------- 4 bytes for IV (WEP)
-*
-* SNAP HEADER
-*
-*/
-
-static u8 P802_1H_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0xf8 };
-static u8 RFC1042_OUI[P80211_OUI_LEN] = { 0x00, 0x00, 0x00 };
-
-static inline int ieee80211_put_snap(u8 *data, u16 h_proto)
-{
- struct ieee80211_snap_hdr *snap;
- u8 *oui;
-
- snap = (struct ieee80211_snap_hdr *)data;
- snap->dsap = 0xaa;
- snap->ssap = 0xaa;
- snap->ctrl = 0x03;
-
- if (h_proto == 0x8137 || h_proto == 0x80f3)
- oui = P802_1H_OUI;
- else
- oui = RFC1042_OUI;
- snap->oui[0] = oui[0];
- snap->oui[1] = oui[1];
- snap->oui[2] = oui[2];
-
- *(u16 *)(data + SNAP_SIZE) = htons(h_proto);
-
- return SNAP_SIZE + sizeof(u16);
-}
-
-int ieee80211_encrypt_fragment(struct ieee80211_device *ieee,
- struct sk_buff *frag, int hdr_len)
-{
- struct ieee80211_crypt_data* crypt = ieee->crypt[ieee->tx_keyidx];
- int res;
-
- /*
- * added to care about null crypt condition, to solve that system hangs
- * when shared keys error
- */
- if (!crypt || !crypt->ops)
- return -1;
-
-#ifdef CONFIG_IEEE80211_CRYPT_TKIP
- struct ieee80211_hdr_4addr *header;
-
- if (ieee->tkip_countermeasures &&
- crypt && crypt->ops && strcmp(crypt->ops->name, "TKIP") == 0) {
- header = (struct ieee80211_hdr_4addr *)frag->data;
- if (net_ratelimit()) {
- netdev_dbg(ieee->dev, "TKIP countermeasures: dropped "
- "TX packet to %pM\n", header->addr1);
- }
- return -1;
- }
-#endif
- /*
- * To encrypt, frame format is:
- * IV (4 bytes), clear payload (including SNAP), ICV (4 bytes)
- *
- * PR: FIXME: Copied from hostap. Check fragmentation/MSDU/MPDU
- * encryption.
- *
- * Host-based IEEE 802.11 fragmentation for TX is not yet supported, so
- * call both MSDU and MPDU encryption functions from here.
- */
- atomic_inc(&crypt->refcnt);
- res = 0;
- if (crypt->ops->encrypt_msdu)
- res = crypt->ops->encrypt_msdu(frag, hdr_len, crypt->priv);
- if (res == 0 && crypt->ops->encrypt_mpdu)
- res = crypt->ops->encrypt_mpdu(frag, hdr_len, crypt->priv);
-
- atomic_dec(&crypt->refcnt);
- if (res < 0) {
- netdev_info(ieee->dev, "Encryption failed: len=%d.\n", frag->len);
- ieee->ieee_stats.tx_discards++;
- return -1;
- }
-
- return 0;
-}
-
-
-void ieee80211_txb_free(struct ieee80211_txb *txb)
-{
- int i;
- if (unlikely(!txb))
- return;
- for (i = 0; i < txb->nr_frags; i++)
- if (txb->fragments[i])
- dev_kfree_skb_any(txb->fragments[i]);
- kfree(txb);
-}
-
-static struct ieee80211_txb *ieee80211_alloc_txb(int nr_frags, int txb_size,
- gfp_t gfp_mask)
-{
- struct ieee80211_txb *txb;
- int i;
- txb = kmalloc(
- sizeof(struct ieee80211_txb) + (sizeof(u8 *) * nr_frags),
- gfp_mask);
- if (!txb)
- return NULL;
-
- memset(txb, 0, sizeof(struct ieee80211_txb));
- txb->nr_frags = nr_frags;
- txb->frag_size = txb_size;
-
- for (i = 0; i < nr_frags; i++) {
- txb->fragments[i] = dev_alloc_skb(txb_size);
- if (unlikely(!txb->fragments[i])) {
- i--;
- break;
- }
- }
- if (unlikely(i != nr_frags)) {
- while (i >= 0)
- dev_kfree_skb_any(txb->fragments[i--]);
- kfree(txb);
- return NULL;
- }
- return txb;
-}
-
-/*
- * Classify the to-be send data packet
- * Need to acquire the sent queue index.
- */
-static int ieee80211_classify(struct sk_buff *skb,
- struct ieee80211_network *network)
-{
- struct ether_header *eh = (struct ether_header *)skb->data;
- unsigned int wme_UP = 0;
-
- if (!network->QoS_Enable) {
- skb->priority = 0;
- return(wme_UP);
- }
-
- if (eh->ether_type == __constant_htons(ETHERTYPE_IP)) {
- const struct iphdr *ih = (struct iphdr *)(skb->data +
- sizeof(struct ether_header));
- wme_UP = (ih->tos >> 5)&0x07;
- } else if (vlan_tx_tag_present(skb)) {/* vtag packet */
-#ifndef VLAN_PRI_SHIFT
-#define VLAN_PRI_SHIFT 13 /* Shift to find VLAN user priority */
-#define VLAN_PRI_MASK 7 /* Mask for user priority bits in VLAN */
-#endif
- u32 tag = vlan_tx_tag_get(skb);
- wme_UP = (tag >> VLAN_PRI_SHIFT) & VLAN_PRI_MASK;
- } else if (ETH_P_PAE == ntohs(((struct ethhdr *)skb->data)->h_proto)) {
- wme_UP = 7;
- }
-
- skb->priority = wme_UP;
- return(wme_UP);
-}
-
-/* SKBs are added to the ieee->tx_queue. */
-int ieee80211_rtl_xmit(struct sk_buff *skb, struct net_device *dev)
-{
- struct ieee80211_device *ieee = netdev_priv(dev);
- struct ieee80211_txb *txb = NULL;
- struct ieee80211_hdr_3addrqos *frag_hdr;
- int i, bytes_per_frag, nr_frags, bytes_last_frag, frag_size;
- unsigned long flags;
- struct net_device_stats *stats = &ieee->stats;
- int ether_type, encrypt;
- int bytes, fc, qos_ctl, hdr_len;
- struct sk_buff *skb_frag;
- struct ieee80211_hdr_3addrqos header = { /* Ensure zero initialized */
- .duration_id = 0,
- .seq_ctl = 0,
- .qos_ctl = 0
- };
- u8 dest[ETH_ALEN], src[ETH_ALEN];
-
- struct ieee80211_crypt_data* crypt;
-
- spin_lock_irqsave(&ieee->lock, flags);
-
- /*
- * If there is no driver handler to take the TXB, don't bother
- * creating it...
- */
- if ((!ieee->hard_start_xmit &&
- !(ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)) ||
- ((!ieee->softmac_data_hard_start_xmit &&
- (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE)))) {
- netdev_warn(ieee->dev, "No xmit handler.\n");
- goto success;
- }
-
- ieee80211_classify(skb,&ieee->current_network);
- if (likely(ieee->raw_tx == 0)){
-
- if (unlikely(skb->len < SNAP_SIZE + sizeof(u16))) {
- netdev_warn(ieee->dev, "skb too small (%d).\n", skb->len);
- goto success;
- }
-
- ether_type = ntohs(((struct ethhdr *)skb->data)->h_proto);
-
- crypt = ieee->crypt[ieee->tx_keyidx];
-
- encrypt = !(ether_type == ETH_P_PAE && ieee->ieee802_1x) &&
- ieee->host_encrypt && crypt && crypt->ops;
-
- if (!encrypt && ieee->ieee802_1x &&
- ieee->drop_unencrypted && ether_type != ETH_P_PAE) {
- stats->tx_dropped++;
- goto success;
- }
-
- #ifdef CONFIG_IEEE80211_DEBUG
- if (crypt && !encrypt && ether_type == ETH_P_PAE) {
- struct eapol *eap = (struct eapol *)(skb->data +
- sizeof(struct ethhdr) - SNAP_SIZE - sizeof(u16));
- IEEE80211_DEBUG_EAP("TX: IEEE 802.11 EAPOL frame: %s\n",
- eap_get_type(eap->type));
- }
- #endif
-
- /* Save source and destination addresses */
- memcpy(&dest, skb->data, ETH_ALEN);
- memcpy(&src, skb->data+ETH_ALEN, ETH_ALEN);
-
- /* Advance the SKB to the start of the payload */
- skb_pull(skb, sizeof(struct ethhdr));
-
- /* Determine total amount of storage required for TXB packets */
- bytes = skb->len + SNAP_SIZE + sizeof(u16);
-
- if (ieee->current_network.QoS_Enable) {
- if (encrypt)
- fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA |
- IEEE80211_FCTL_WEP;
- else
- fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_QOS_DATA;
-
- } else {
- if (encrypt)
- fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA |
- IEEE80211_FCTL_WEP;
- else
- fc = IEEE80211_FTYPE_DATA | IEEE80211_STYPE_DATA;
- }
-
- if (ieee->iw_mode == IW_MODE_INFRA) {
- fc |= IEEE80211_FCTL_TODS;
- /* To DS: Addr1 = BSSID, Addr2 = SA, Addr3 = DA */
- memcpy(&header.addr1, ieee->current_network.bssid, ETH_ALEN);
- memcpy(&header.addr2, &src, ETH_ALEN);
- memcpy(&header.addr3, &dest, ETH_ALEN);
- } else if (ieee->iw_mode == IW_MODE_ADHOC) {
- /*
- * not From/To DS: Addr1 = DA, Addr2 = SA,
- * Addr3 = BSSID
- */
- memcpy(&header.addr1, dest, ETH_ALEN);
- memcpy(&header.addr2, src, ETH_ALEN);
- memcpy(&header.addr3, ieee->current_network.bssid, ETH_ALEN);
- }
- header.frame_ctl = cpu_to_le16(fc);
-
- /*
- * Determine fragmentation size based on destination (multicast
- * and broadcast are not fragmented)
- */
- if (is_multicast_ether_addr(header.addr1)) {
- frag_size = MAX_FRAG_THRESHOLD;
- qos_ctl = QOS_CTL_NOTCONTAIN_ACK;
- } else {
- /* default:392 */
- frag_size = ieee->fts;
- qos_ctl = 0;
- }
-
- if (ieee->current_network.QoS_Enable) {
- hdr_len = IEEE80211_3ADDR_LEN + 2;
- /* skb->priority is set in the ieee80211_classify() */
- qos_ctl |= skb->priority;
- header.qos_ctl = cpu_to_le16(qos_ctl);
- } else {
- hdr_len = IEEE80211_3ADDR_LEN;
- }
-
- /*
- * Determine amount of payload per fragment. Regardless of if
- * this stack is providing the full 802.11 header, one will
- * eventually be affixed to this fragment -- so we must account
- * for it when determining the amount of payload space.
- */
- bytes_per_frag = frag_size - hdr_len;
- if (ieee->config &
- (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
- bytes_per_frag -= IEEE80211_FCS_LEN;
-
- /* Each fragment may need to have room for encryption pre/postfix */
- if (encrypt)
- bytes_per_frag -= crypt->ops->extra_prefix_len +
- crypt->ops->extra_postfix_len;
-
- /*
- * Number of fragments is the total bytes_per_frag /
- * payload_per_fragment
- */
- nr_frags = bytes / bytes_per_frag;
- bytes_last_frag = bytes % bytes_per_frag;
- if (bytes_last_frag)
- nr_frags++;
- else
- bytes_last_frag = bytes_per_frag;
-
- /*
- * When we allocate the TXB we allocate enough space for the
- * reserve and full fragment bytes (bytes_per_frag doesn't
- * include prefix, postfix, header, FCS, etc.)
- */
- txb = ieee80211_alloc_txb(nr_frags, frag_size, GFP_ATOMIC);
- if (unlikely(!txb)) {
- netdev_warn(ieee->dev, "Could not allocate TXB\n");
- goto failed;
- }
- txb->encrypted = encrypt;
- txb->payload_size = bytes;
-
- for (i = 0; i < nr_frags; i++) {
- skb_frag = txb->fragments[i];
- skb_frag->priority = UP2AC(skb->priority);
- if (encrypt)
- skb_reserve(skb_frag, crypt->ops->extra_prefix_len);
-
- frag_hdr = (struct ieee80211_hdr_3addrqos *)skb_put(
- skb_frag, hdr_len);
- memcpy(frag_hdr, &header, hdr_len);
-
- /*
- * If this is not the last fragment, then add the MOREFRAGS
- * bit to the frame control
- */
- if (i != nr_frags - 1) {
- frag_hdr->frame_ctl = cpu_to_le16(
- fc | IEEE80211_FCTL_MOREFRAGS);
- bytes = bytes_per_frag;
-
- } else {
- /* The last fragment takes the remaining length */
- bytes = bytes_last_frag;
- }
- if (ieee->current_network.QoS_Enable) {
- /*
- * add 1 only indicate to corresponding seq
- * number control 2006/7/12
- */
- frag_hdr->seq_ctl = cpu_to_le16(
- ieee->seq_ctrl[UP2AC(skb->priority)+1]<<4 | i);
- } else {
- frag_hdr->seq_ctl = cpu_to_le16(
- ieee->seq_ctrl[0]<<4 | i);
- }
-
- /* Put a SNAP header on the first fragment */
- if (i == 0) {
- ieee80211_put_snap(
- skb_put(skb_frag, SNAP_SIZE + sizeof(u16)),
- ether_type);
- bytes -= SNAP_SIZE + sizeof(u16);
- }
-
- memcpy(skb_put(skb_frag, bytes), skb->data, bytes);
-
- /* Advance the SKB... */
- skb_pull(skb, bytes);
-
- /*
- * Encryption routine will move the header forward in
- * order to insert the IV between the header and the
- * payload
- */
- if (encrypt)
- ieee80211_encrypt_fragment(ieee, skb_frag, hdr_len);
- if (ieee->config &
- (CFG_IEEE80211_COMPUTE_FCS | CFG_IEEE80211_RESERVE_FCS))
- skb_put(skb_frag, 4);
- }
- /* Advance sequence number in data frame. */
- if (ieee->current_network.QoS_Enable) {
- if (ieee->seq_ctrl[UP2AC(skb->priority) + 1] == 0xFFF)
- ieee->seq_ctrl[UP2AC(skb->priority) + 1] = 0;
- else
- ieee->seq_ctrl[UP2AC(skb->priority) + 1]++;
- } else {
- if (ieee->seq_ctrl[0] == 0xFFF)
- ieee->seq_ctrl[0] = 0;
- else
- ieee->seq_ctrl[0]++;
- }
- } else {
- if (unlikely(skb->len < sizeof(struct ieee80211_hdr_3addr))) {
- netdev_warn(ieee->dev, "skb too small (%d).\n", skb->len);
- goto success;
- }
-
- txb = ieee80211_alloc_txb(1, skb->len, GFP_ATOMIC);
- if (!txb) {
- netdev_warn(ieee->dev, "Could not allocate TXB\n");
- goto failed;
- }
-
- txb->encrypted = 0;
- txb->payload_size = skb->len;
- memcpy(skb_put(txb->fragments[0], skb->len), skb->data, skb->len);
- }
-
- success:
- spin_unlock_irqrestore(&ieee->lock, flags);
- dev_kfree_skb_any(skb);
- if (txb) {
- if (ieee->softmac_features & IEEE_SOFTMAC_TX_QUEUE) {
- ieee80211_softmac_xmit(txb, ieee);
- } else {
- if ((*ieee->hard_start_xmit)(txb, dev) == 0) {
- stats->tx_packets++;
- stats->tx_bytes += txb->payload_size;
- return NETDEV_TX_OK;
- }
- ieee80211_txb_free(txb);
- }
- }
-
- return NETDEV_TX_OK;
-
- failed:
- spin_unlock_irqrestore(&ieee->lock, flags);
- netif_stop_queue(dev);
- stats->tx_errors++;
- return NETDEV_TX_BUSY;
-
-}
diff --git a/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c b/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c
deleted file mode 100644
index 07c3f71..0000000
--- a/drivers/staging/rtl8187se/ieee80211/ieee80211_wx.c
+++ /dev/null
@@ -1,713 +0,0 @@
-/*
- * Copyright(c) 2004 Intel Corporation. All rights reserved.
- *
- * Portions of this file are based on the WEP enablement code provided by the
- * Host AP project hostap-drivers v0.1.3
- * Copyright (c) 2001-2002, SSH Communications Security Corp and Jouni Malinen
- * <jkmaline@cc.hut.fi>
- * Copyright (c) 2002-2003, Jouni Malinen <jkmaline@cc.hut.fi>
- *
- * 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., 59
- * Temple Place - Suite 330, Boston, MA 02111-1307, USA.
- *
- * The full GNU General Public License is included in this distribution in the
- * file called LICENSE.
- *
- * Contact Information:
- * James P. Ketrenos <ipw2100-admin@linux.intel.com>
- * Intel Corporation, 5200 N.E. Elam Young Parkway, Hillsboro, OR 97124-6497
- */
-
-#include <linux/wireless.h>
-#include <linux/kmod.h>
-#include <linux/slab.h>
-#include <linux/module.h>
-#include <linux/etherdevice.h>
-
-#include "ieee80211.h"
-static const char *ieee80211_modes[] = {
- "?", "a", "b", "ab", "g", "ag", "bg", "abg"
-};
-
-#define MAX_CUSTOM_LEN 64
-static inline char *rtl818x_translate_scan(struct ieee80211_device *ieee,
- char *start, char *stop,
- struct ieee80211_network *network,
- struct iw_request_info *info)
-{
- char custom[MAX_CUSTOM_LEN];
- char *p;
- struct iw_event iwe;
- int i, j;
- u8 max_rate, rate;
-
- /* First entry *MUST* be the AP MAC address */
- iwe.cmd = SIOCGIWAP;
- iwe.u.ap_addr.sa_family = ARPHRD_ETHER;
- ether_addr_copy(iwe.u.ap_addr.sa_data, network->bssid);
- start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_ADDR_LEN);
-
- /* Remaining entries will be displayed in the order we provide them */
-
- /* Add the ESSID */
- iwe.cmd = SIOCGIWESSID;
- iwe.u.data.flags = 1;
- if (network->ssid_len == 0) {
- iwe.u.data.length = sizeof("<hidden>");
- start = iwe_stream_add_point(info, start, stop, &iwe, "<hidden>");
- } else {
- iwe.u.data.length = min_t(u8, network->ssid_len, 32);
- start = iwe_stream_add_point(info, start, stop, &iwe, network->ssid);
- }
- /* Add the protocol name */
- iwe.cmd = SIOCGIWNAME;
- snprintf(iwe.u.name, IFNAMSIZ, "IEEE 802.11%s", ieee80211_modes[network->mode]);
- start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_CHAR_LEN);
-
- /* Add mode */
- iwe.cmd = SIOCGIWMODE;
- if (network->capability &
- (WLAN_CAPABILITY_BSS | WLAN_CAPABILITY_IBSS)) {
- if (network->capability & WLAN_CAPABILITY_BSS)
- iwe.u.mode = IW_MODE_MASTER;
- else
- iwe.u.mode = IW_MODE_ADHOC;
-
- start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_UINT_LEN);
- }
-
- /* Add frequency/channel */
- iwe.cmd = SIOCGIWFREQ;
- iwe.u.freq.m = network->channel;
- iwe.u.freq.e = 0;
- iwe.u.freq.i = 0;
- start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_FREQ_LEN);
-
- /* Add encryption capability */
- iwe.cmd = SIOCGIWENCODE;
- if (network->capability & WLAN_CAPABILITY_PRIVACY)
- iwe.u.data.flags = IW_ENCODE_ENABLED | IW_ENCODE_NOKEY;
- else
- iwe.u.data.flags = IW_ENCODE_DISABLED;
- iwe.u.data.length = 0;
- start = iwe_stream_add_point(info, start, stop, &iwe, network->ssid);
-
- /* Add basic and extended rates */
- max_rate = 0;
- p = custom;
- p += snprintf(p, MAX_CUSTOM_LEN - (p - custom), " Rates (Mb/s): ");
- for (i = 0, j = 0; i < network->rates_len; ) {
- if (j < network->rates_ex_len &&
- ((network->rates_ex[j] & 0x7F) <
- (network->rates[i] & 0x7F)))
- rate = network->rates_ex[j++] & 0x7F;
- else
- rate = network->rates[i++] & 0x7F;
- if (rate > max_rate)
- max_rate = rate;
- p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
- "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
- }
- for (; j < network->rates_ex_len; j++) {
- rate = network->rates_ex[j] & 0x7F;
- p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
- "%d%s ", rate >> 1, (rate & 1) ? ".5" : "");
- if (rate > max_rate)
- max_rate = rate;
- }
-
- iwe.cmd = SIOCGIWRATE;
- iwe.u.bitrate.fixed = iwe.u.bitrate.disabled = 0;
- iwe.u.bitrate.value = max_rate * 500000;
- start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_PARAM_LEN);
-
- iwe.cmd = IWEVCUSTOM;
- iwe.u.data.length = p - custom;
- if (iwe.u.data.length)
- start = iwe_stream_add_point(info, start, stop, &iwe, custom);
-
- /* Add quality statistics */
- /* TODO: Fix these values... */
- if (network->stats.signal == 0 || network->stats.rssi == 0)
- netdev_info(ieee->dev, "========>signal:%d, rssi:%d\n",
- network->stats.signal, network->stats.rssi);
- iwe.cmd = IWEVQUAL;
- iwe.u.qual.qual = network->stats.signalstrength;
- iwe.u.qual.level = network->stats.signal;
- iwe.u.qual.noise = network->stats.noise;
- iwe.u.qual.updated = network->stats.mask & IEEE80211_STATMASK_WEMASK;
- if (!(network->stats.mask & IEEE80211_STATMASK_RSSI))
- iwe.u.qual.updated |= IW_QUAL_LEVEL_INVALID;
- if (!(network->stats.mask & IEEE80211_STATMASK_NOISE))
- iwe.u.qual.updated |= IW_QUAL_NOISE_INVALID;
- if (!(network->stats.mask & IEEE80211_STATMASK_SIGNAL))
- iwe.u.qual.updated |= IW_QUAL_QUAL_INVALID;
- iwe.u.qual.updated = 7;
- start = iwe_stream_add_event(info, start, stop, &iwe, IW_EV_QUAL_LEN);
-
- iwe.cmd = IWEVCUSTOM;
- p = custom;
-
- iwe.u.data.length = p - custom;
- if (iwe.u.data.length)
- start = iwe_stream_add_point(info, start, stop, &iwe, custom);
-
- memset(&iwe, 0, sizeof(iwe));
- if (network->wpa_ie_len) {
- char buf[MAX_WPA_IE_LEN];
- memcpy(buf, network->wpa_ie, network->wpa_ie_len);
- iwe.cmd = IWEVGENIE;
- iwe.u.data.length = network->wpa_ie_len;
- start = iwe_stream_add_point(info, start, stop, &iwe, buf);
- }
-
- memset(&iwe, 0, sizeof(iwe));
- if (network->rsn_ie_len) {
- char buf[MAX_WPA_IE_LEN];
- memcpy(buf, network->rsn_ie, network->rsn_ie_len);
- iwe.cmd = IWEVGENIE;
- iwe.u.data.length = network->rsn_ie_len;
- start = iwe_stream_add_point(info, start, stop, &iwe, buf);
- }
-
- /* Add EXTRA: Age to display seconds since last beacon/probe response
- * for given network.
- */
- iwe.cmd = IWEVCUSTOM;
- p = custom;
- p += snprintf(p, MAX_CUSTOM_LEN - (p - custom),
- " Last beacon: %lums ago", (jiffies - network->last_scanned) / (HZ / 100));
- iwe.u.data.length = p - custom;
- if (iwe.u.data.length)
- start = iwe_stream_add_point(info, start, stop, &iwe, custom);
-
- return start;
-}
-
-int ieee80211_wx_get_scan(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct ieee80211_network *network;
- unsigned long flags;
- int err = 0;
- char *ev = extra;
- char *stop = ev + wrqu->data.length;
- int i = 0;
-
- IEEE80211_DEBUG_WX("Getting scan\n");
- down(&ieee->wx_sem);
- spin_lock_irqsave(&ieee->lock, flags);
-
- if (!ieee->bHwRadioOff) {
- list_for_each_entry(network, &ieee->network_list, list) {
- i++;
-
- if ((stop-ev) < 200) {
- err = -E2BIG;
- break;
- }
- if (ieee->scan_age == 0 ||
- time_after(network->last_scanned + ieee->scan_age, jiffies)) {
- ev = rtl818x_translate_scan(ieee, ev, stop, network, info);
- } else
- IEEE80211_DEBUG_SCAN(
- "Not showing network '%s ("
- "%pM)' due to age (%lums).\n",
- escape_essid(network->ssid,
- network->ssid_len),
- network->bssid,
- (jiffies - network->last_scanned) / (HZ / 100));
- }
- }
- spin_unlock_irqrestore(&ieee->lock, flags);
- up(&ieee->wx_sem);
- wrqu->data.length = ev - extra;
- wrqu->data.flags = 0;
- IEEE80211_DEBUG_WX("exit: %d networks returned.\n", i);
-
- return err;
-}
-
-int ieee80211_wx_set_encode(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *keybuf)
-{
- struct iw_point *erq = &(wrqu->encoding);
- struct net_device *dev = ieee->dev;
- struct ieee80211_security sec = {
- .flags = 0
- };
- int i, key, key_provided, len;
- struct ieee80211_crypt_data **crypt;
-
- IEEE80211_DEBUG_WX("SET_ENCODE\n");
-
- key = erq->flags & IW_ENCODE_INDEX;
- if (key) {
- if (key > WEP_KEYS)
- return -EINVAL;
- key--;
- key_provided = 1;
- } else {
- key_provided = 0;
- key = ieee->tx_keyidx;
- }
-
- IEEE80211_DEBUG_WX("Key: %d [%s]\n", key, key_provided ?
- "provided" : "default");
-
- crypt = &ieee->crypt[key];
-
- if (erq->flags & IW_ENCODE_DISABLED) {
- if (key_provided && *crypt) {
- IEEE80211_DEBUG_WX("Disabling encryption on key %d.\n",
- key);
- ieee80211_crypt_delayed_deinit(ieee, crypt);
- } else
- IEEE80211_DEBUG_WX("Disabling encryption.\n");
-
- /* Check all the keys to see if any are still configured,
- * and if no key index was provided, de-init them all.
- */
- for (i = 0; i < WEP_KEYS; i++) {
- if (ieee->crypt[i] != NULL) {
- if (key_provided)
- break;
- ieee80211_crypt_delayed_deinit(
- ieee, &ieee->crypt[i]);
- }
- }
-
- if (i == WEP_KEYS) {
- sec.enabled = 0;
- sec.level = SEC_LEVEL_0;
- sec.flags |= SEC_ENABLED | SEC_LEVEL;
- }
-
- goto done;
- }
-
- sec.enabled = 1;
- sec.flags |= SEC_ENABLED;
-
- if (*crypt != NULL && (*crypt)->ops != NULL &&
- strcmp((*crypt)->ops->name, "WEP") != 0) {
- /* changing to use WEP; deinit previously used algorithm
- * on this key.
- */
- ieee80211_crypt_delayed_deinit(ieee, crypt);
- }
-
- if (*crypt == NULL) {
- struct ieee80211_crypt_data *new_crypt;
-
- /* take WEP into use */
- new_crypt = kzalloc(sizeof(struct ieee80211_crypt_data),
- GFP_KERNEL);
- if (new_crypt == NULL)
- return -ENOMEM;
- new_crypt->ops = ieee80211_get_crypto_ops("WEP");
- if (!new_crypt->ops)
- new_crypt->ops = ieee80211_get_crypto_ops("WEP");
-
- if (new_crypt->ops)
- new_crypt->priv = new_crypt->ops->init(key);
-
- if (!new_crypt->ops || !new_crypt->priv) {
- kfree(new_crypt);
- new_crypt = NULL;
-
- netdev_warn(ieee->dev,
- "could not initialize WEP: load module ieee80211_crypt_wep\n");
- return -EOPNOTSUPP;
- }
- *crypt = new_crypt;
- }
-
- /* If a new key was provided, set it up */
- if (erq->length > 0) {
- len = erq->length <= 5 ? 5 : 13;
- memcpy(sec.keys[key], keybuf, erq->length);
- if (len > erq->length)
- memset(sec.keys[key] + erq->length, 0,
- len - erq->length);
- IEEE80211_DEBUG_WX("Setting key %d to '%s' (%d:%d bytes)\n",
- key, escape_essid(sec.keys[key], len),
- erq->length, len);
- sec.key_sizes[key] = len;
- (*crypt)->ops->set_key(sec.keys[key], len, NULL,
- (*crypt)->priv);
- sec.flags |= (1 << key);
- /* This ensures a key will be activated if no key is
- * explicitly set.
- */
- if (key == sec.active_key)
- sec.flags |= SEC_ACTIVE_KEY;
- ieee->tx_keyidx = key;
- } else {
- len = (*crypt)->ops->get_key(sec.keys[key], WEP_KEY_LEN,
- NULL, (*crypt)->priv);
- if (len == 0) {
- /* Set a default key of all 0 */
- IEEE80211_DEBUG_WX("Setting key %d to all zero.\n",
- key);
- memset(sec.keys[key], 0, 13);
- (*crypt)->ops->set_key(sec.keys[key], 13, NULL,
- (*crypt)->priv);
- sec.key_sizes[key] = 13;
- sec.flags |= (1 << key);
- }
-
- /* No key data - just set the default TX key index */
- if (key_provided) {
- IEEE80211_DEBUG_WX(
- "Setting key %d to default Tx key.\n", key);
- ieee->tx_keyidx = key;
- sec.active_key = key;
- sec.flags |= SEC_ACTIVE_KEY;
- }
- }
-
- done:
- ieee->open_wep = !(erq->flags & IW_ENCODE_RESTRICTED);
- sec.auth_mode = ieee->open_wep ? WLAN_AUTH_OPEN : WLAN_AUTH_SHARED_KEY;
- sec.flags |= SEC_AUTH_MODE;
- IEEE80211_DEBUG_WX("Auth: %s\n", sec.auth_mode == WLAN_AUTH_OPEN ?
- "OPEN" : "SHARED KEY");
-
- /* For now we just support WEP, so only set that security level...
- * TODO: When WPA is added this is one place that needs to change
- */
- sec.flags |= SEC_LEVEL;
- sec.level = SEC_LEVEL_1; /* 40 and 104 bit WEP */
-
- if (ieee->set_security)
- ieee->set_security(dev, &sec);
-
- /* Do not reset port if card is in Managed mode since resetting will
- * generate new IEEE 802.11 authentication which may end up in looping
- * with IEEE 802.1X. If your hardware requires a reset after WEP
- * configuration (for example... Prism2), implement the reset_port in
- * the callbacks structures used to initialize the 802.11 stack.
- */
- if (ieee->reset_on_keychange &&
- ieee->iw_mode != IW_MODE_INFRA &&
- ieee->reset_port && ieee->reset_port(dev)) {
- netdev_dbg(ieee->dev, "reset_port failed\n");
- return -EINVAL;
- }
- return 0;
-}
-
-int ieee80211_wx_get_encode(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *keybuf)
-{
- struct iw_point *erq = &(wrqu->encoding);
- int len, key;
- struct ieee80211_crypt_data *crypt;
-
- IEEE80211_DEBUG_WX("GET_ENCODE\n");
-
- if (ieee->iw_mode == IW_MODE_MONITOR)
- return -1;
-
- key = erq->flags & IW_ENCODE_INDEX;
- if (key) {
- if (key > WEP_KEYS)
- return -EINVAL;
- key--;
- } else
- key = ieee->tx_keyidx;
-
- crypt = ieee->crypt[key];
- erq->flags = key + 1;
-
- if (crypt == NULL || crypt->ops == NULL) {
- erq->length = 0;
- erq->flags |= IW_ENCODE_DISABLED;
- return 0;
- }
-
- if (strcmp(crypt->ops->name, "WEP") != 0) {
- /* only WEP is supported with wireless extensions, so just
- * report that encryption is used.
- */
- erq->length = 0;
- erq->flags |= IW_ENCODE_ENABLED;
- return 0;
- }
-
- len = crypt->ops->get_key(keybuf, WEP_KEY_LEN, NULL, crypt->priv);
- erq->length = (len >= 0 ? len : 0);
-
- erq->flags |= IW_ENCODE_ENABLED;
-
- if (ieee->open_wep)
- erq->flags |= IW_ENCODE_OPEN;
- else
- erq->flags |= IW_ENCODE_RESTRICTED;
-
- return 0;
-}
-
-int ieee80211_wx_set_encode_ext(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct net_device *dev = ieee->dev;
- struct iw_point *encoding = &wrqu->encoding;
- struct iw_encode_ext *ext = (struct iw_encode_ext *)extra;
- int i, idx, ret = 0;
- int group_key = 0;
- const char *alg;
- struct ieee80211_crypto_ops *ops;
- struct ieee80211_crypt_data **crypt;
-
- struct ieee80211_security sec = {
- .flags = 0,
- };
- idx = encoding->flags & IW_ENCODE_INDEX;
- if (idx) {
- if (idx < 1 || idx > WEP_KEYS)
- return -EINVAL;
- idx--;
- } else
- idx = ieee->tx_keyidx;
-
- if (ext->ext_flags & IW_ENCODE_EXT_GROUP_KEY) {
- crypt = &ieee->crypt[idx];
- group_key = 1;
- } else {
- /* some Cisco APs use idx>0 for unicast in dynamic WEP */
- if (idx != 0 && ext->alg != IW_ENCODE_ALG_WEP)
- return -EINVAL;
- if (ieee->iw_mode == IW_MODE_INFRA)
- crypt = &ieee->crypt[idx];
- else
- return -EINVAL;
- }
-
- sec.flags |= SEC_ENABLED;
- if ((encoding->flags & IW_ENCODE_DISABLED) ||
- ext->alg == IW_ENCODE_ALG_NONE) {
- if (*crypt)
- ieee80211_crypt_delayed_deinit(ieee, crypt);
-
- for (i = 0; i < WEP_KEYS; i++)
- if (ieee->crypt[i] != NULL)
- break;
-
- if (i == WEP_KEYS) {
- sec.enabled = 0;
- sec.level = SEC_LEVEL_0;
- sec.flags |= SEC_LEVEL;
- }
- goto done;
- }
-
- sec.enabled = 1;
-
- switch (ext->alg) {
- case IW_ENCODE_ALG_WEP:
- alg = "WEP";
- break;
- case IW_ENCODE_ALG_TKIP:
- alg = "TKIP";
- break;
- case IW_ENCODE_ALG_CCMP:
- alg = "CCMP";
- break;
- default:
- IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
- dev->name, ext->alg);
- ret = -EINVAL;
- goto done;
- }
-
- ops = ieee80211_get_crypto_ops(alg);
- if (ops == NULL)
- ops = ieee80211_get_crypto_ops(alg);
- if (ops == NULL) {
- IEEE80211_DEBUG_WX("%s: unknown crypto alg %d\n",
- dev->name, ext->alg);
- netdev_err(ieee->dev, "========>unknown crypto alg %d\n",
- ext->alg);
- ret = -EINVAL;
- goto done;
- }
-
- if (*crypt == NULL || (*crypt)->ops != ops) {
- struct ieee80211_crypt_data *new_crypt;
-
- ieee80211_crypt_delayed_deinit(ieee, crypt);
-
- new_crypt = kzalloc(sizeof(*new_crypt), GFP_KERNEL);
- if (new_crypt == NULL) {
- ret = -ENOMEM;
- goto done;
- }
- new_crypt->ops = ops;
- if (new_crypt->ops)
- new_crypt->priv = new_crypt->ops->init(idx);
- if (new_crypt->priv == NULL) {
- kfree(new_crypt);
- ret = -EINVAL;
- goto done;
- }
- *crypt = new_crypt;
-
- }
-
- if (ext->key_len > 0 && (*crypt)->ops->set_key &&
- (*crypt)->ops->set_key(ext->key, ext->key_len, ext->rx_seq,
- (*crypt)->priv) < 0) {
- IEEE80211_DEBUG_WX("%s: key setting failed\n", dev->name);
- netdev_err(ieee->dev, "key setting failed\n");
- ret = -EINVAL;
- goto done;
- }
-#if 1
- if (ext->ext_flags & IW_ENCODE_EXT_SET_TX_KEY) {
- ieee->tx_keyidx = idx;
- sec.active_key = idx;
- sec.flags |= SEC_ACTIVE_KEY;
- }
-
- if (ext->alg != IW_ENCODE_ALG_NONE) {
- memcpy(sec.keys[idx], ext->key, ext->key_len);
- sec.key_sizes[idx] = ext->key_len;
- sec.flags |= (1 << idx);
- if (ext->alg == IW_ENCODE_ALG_WEP) {
- sec.flags |= SEC_LEVEL;
- sec.level = SEC_LEVEL_1;
- } else if (ext->alg == IW_ENCODE_ALG_TKIP) {
- sec.flags |= SEC_LEVEL;
- sec.level = SEC_LEVEL_2;
- } else if (ext->alg == IW_ENCODE_ALG_CCMP) {
- sec.flags |= SEC_LEVEL;
- sec.level = SEC_LEVEL_3;
- }
- /* Don't set sec level for group keys. */
- if (group_key)
- sec.flags &= ~SEC_LEVEL;
- }
-#endif
-done:
- if (ieee->set_security)
- ieee->set_security(ieee->dev, &sec);
-
- if (ieee->reset_on_keychange &&
- ieee->iw_mode != IW_MODE_INFRA &&
- ieee->reset_port && ieee->reset_port(dev)) {
- IEEE80211_DEBUG_WX("%s: reset_port failed\n", dev->name);
- return -EINVAL;
- }
-
- return ret;
-}
-
-int ieee80211_wx_set_mlme(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct iw_mlme *mlme = (struct iw_mlme *) extra;
-#if 1
- switch (mlme->cmd) {
- case IW_MLME_DEAUTH:
- case IW_MLME_DISASSOC:
- ieee80211_disassociate(ieee);
- break;
- default:
- return -EOPNOTSUPP;
- }
-#endif
- return 0;
-}
-
-int ieee80211_wx_set_auth(struct ieee80211_device *ieee,
- struct iw_request_info *info,
- struct iw_param *data, char *extra)
-{
- switch (data->flags & IW_AUTH_INDEX) {
- case IW_AUTH_WPA_VERSION:
- /* need to support wpa2 here */
- break;
- case IW_AUTH_CIPHER_PAIRWISE:
- case IW_AUTH_CIPHER_GROUP:
- case IW_AUTH_KEY_MGMT:
- /* Host AP driver does not use these parameters and allows
- * wpa_supplicant to control them internally.
- */
- break;
- case IW_AUTH_TKIP_COUNTERMEASURES:
- ieee->tkip_countermeasures = data->value;
- break;
- case IW_AUTH_DROP_UNENCRYPTED:
- ieee->drop_unencrypted = data->value;
- break;
-
- case IW_AUTH_80211_AUTH_ALG:
- ieee->open_wep = (data->value&IW_AUTH_ALG_OPEN_SYSTEM) ? 1 : 0;
- break;
-
-#if 1
- case IW_AUTH_WPA_ENABLED:
- ieee->wpa_enabled = (data->value) ? 1 : 0;
- break;
-
-#endif
- case IW_AUTH_RX_UNENCRYPTED_EAPOL:
- ieee->ieee802_1x = data->value;
- break;
- case IW_AUTH_PRIVACY_INVOKED:
- ieee->privacy_invoked = data->value;
- break;
- default:
- return -EOPNOTSUPP;
- }
- return 0;
-}
-
-#if 1
-int ieee80211_wx_set_gen_ie(struct ieee80211_device *ieee, u8 *ie, size_t len)
-{
- u8 *buf = NULL;
-
- if (len > MAX_WPA_IE_LEN || (len && ie == NULL)) {
- netdev_err(ieee->dev, "return error out, len:%zu\n", len);
- return -EINVAL;
- }
-
- if (len) {
- if (len != ie[1]+2) {
- netdev_err(ieee->dev, "len:%zu, ie:%d\n", len, ie[1]);
- return -EINVAL;
- }
- buf = kmemdup(ie, len, GFP_KERNEL);
- if (buf == NULL)
- return -ENOMEM;
- kfree(ieee->wpa_ie);
- ieee->wpa_ie = buf;
- ieee->wpa_ie_len = len;
- } else {
- kfree(ieee->wpa_ie);
- ieee->wpa_ie = NULL;
- ieee->wpa_ie_len = 0;
- }
-
- return 0;
-
-}
-#endif
diff --git a/drivers/staging/rtl8187se/r8180.h b/drivers/staging/rtl8187se/r8180.h
deleted file mode 100644
index 9f931db..0000000
--- a/drivers/staging/rtl8187se/r8180.h
+++ /dev/null
@@ -1,640 +0,0 @@
-/*
- * This is part of rtl8180 OpenSource driver.
- * 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 Intel Pro Wireless 2100 GPL driver
- *
- * We want to thanks the Authors of those projects and the Ndiswrapper project
- * Authors.
- */
-
-#ifndef R8180H
-#define R8180H
-
-#include <linux/interrupt.h>
-
-#define RTL8180_MODULE_NAME "r8180"
-#define DMESG(x, a...) printk(KERN_INFO RTL8180_MODULE_NAME ": " x "\n", ## a)
-#define DMESGW(x, a...) printk(KERN_WARNING RTL8180_MODULE_NAME ": WW:" x "\n", ## a)
-#define DMESGE(x, a...) printk(KERN_WARNING RTL8180_MODULE_NAME ": EE:" x "\n", ## a)
-
-#include <linux/module.h>
-#include <linux/kernel.h>
-#include <linux/ioport.h>
-#include <linux/sched.h>
-#include <linux/types.h>
-#include <linux/slab.h>
-#include <linux/netdevice.h>
-#include <linux/pci.h>
-#include <linux/etherdevice.h>
-#include <linux/delay.h>
-#include <linux/rtnetlink.h> /* for rtnl_lock() */
-#include <linux/wireless.h>
-#include <linux/timer.h>
-#include <linux/proc_fs.h> /* Necessary because we use the proc fs. */
-#include <linux/if_arp.h>
-#include "ieee80211/ieee80211.h"
-#include <asm/io.h>
-
-#define EPROM_93c46 0
-#define EPROM_93c56 1
-
-#define RTL_IOCTL_WPA_SUPPLICANT (SIOCIWFIRSTPRIV + 30)
-
-#define DEFAULT_FRAG_THRESHOLD 2342U
-#define MIN_FRAG_THRESHOLD 256U
-#define DEFAULT_RTS_THRESHOLD 2342U
-#define MIN_RTS_THRESHOLD 0U
-#define MAX_RTS_THRESHOLD 2342U
-#define DEFAULT_BEACONINTERVAL 0x64U
-
-#define DEFAULT_RETRY_RTS 7
-#define DEFAULT_RETRY_DATA 7
-
-#define BEACON_QUEUE 6
-
-#define aSifsTime 10
-
-#define sCrcLng 4
-#define sAckCtsLng 112 /* bits in ACK and CTS frames. */
-/* +by amy 080312. */
-#define RATE_ADAPTIVE_TIMER_PERIOD 300
-
-enum wireless_mode {
- WIRELESS_MODE_UNKNOWN = 0x00,
- WIRELESS_MODE_A = 0x01,
- WIRELESS_MODE_B = 0x02,
- WIRELESS_MODE_G = 0x04,
- WIRELESS_MODE_AUTO = 0x08,
-};
-
-struct chnl_access_setting {
- u16 sifs_timer;
- u16 difs_timer;
- u16 slot_time_timer;
- u16 eifs_timer;
- u16 cwmin_index;
- u16 cwmax_index;
-};
-
-enum nic_t {
- NIC_8185 = 1,
- NIC_8185B
-};
-
-typedef u32 AC_CODING;
-#define AC0_BE 0 /* ACI: 0x00 */ /* Best Effort. */
-#define AC1_BK 1 /* ACI: 0x01 */ /* Background. */
-#define AC2_VI 2 /* ACI: 0x10 */ /* Video. */
-#define AC3_VO 3 /* ACI: 0x11 */ /* Voice. */
-#define AC_MAX 4 /* Max: define total number; Should not to be used as a real
- * enum.
- */
-
-/*
- * ECWmin/ECWmax field.
- * Ref: WMM spec 2.2.2: WME Parameter Element, p.13.
- */
-typedef union _ECW {
- u8 charData;
- struct {
- u8 ECWmin:4;
- u8 ECWmax:4;
- } f; /* Field */
-} ECW, *PECW;
-
-/*
- * ACI/AIFSN Field. Ref: WMM spec 2.2.2: WME Parameter Element, p.12.
- */
-typedef union _ACI_AIFSN {
- u8 charData;
-
- struct {
- u8 AIFSN:4;
- u8 ACM:1;
- u8 ACI:2;
- u8 Reserved:1;
- } f; /* Field */
-} ACI_AIFSN, *PACI_AIFSN;
-
-/*
- * AC Parameters Record Format.
- * Ref: WMM spec 2.2.2: WME Parameter Element, p.12.
- */
-typedef union _AC_PARAM {
- u32 longData;
- u8 charData[4];
-
- struct {
- ACI_AIFSN AciAifsn;
- ECW Ecw;
- u16 TXOPLimit;
- } f; /* Field */
-} AC_PARAM, *PAC_PARAM;
-
-struct buffer {
- struct buffer *next;
- u32 *buf;
- dma_addr_t dma;
-};
-
-/* YJ,modified,080828. */
-struct stats {
- unsigned long txrdu;
- unsigned long rxrdu;
- unsigned long rxnolast;
- unsigned long rxnodata;
- unsigned long rxnopointer;
- unsigned long txnperr;
- unsigned long txresumed;
- unsigned long rxerr;
- unsigned long rxoverflow;
- unsigned long rxint;
- unsigned long txbkpokint;
- unsigned long txbepoking;
- unsigned long txbkperr;
- unsigned long txbeperr;
- unsigned long txnpokint;
- unsigned long txhpokint;
- unsigned long txhperr;
- unsigned long ints;
- unsigned long shints;
- unsigned long txoverflow;
- unsigned long rxdmafail;
- unsigned long txbeacon;
- unsigned long txbeaconerr;
- unsigned long txlpokint;
- unsigned long txlperr;
- unsigned long txretry; /* retry number tony 20060601 */
- unsigned long rxcrcerrmin; /* crc error (0-500) */
- unsigned long rxcrcerrmid; /* crc error (500-1000) */
- unsigned long rxcrcerrmax; /* crc error (>1000) */
- unsigned long rxicverr; /* ICV error */
-};
-
-#define MAX_LD_SLOT_NUM 10
-#define KEEP_ALIVE_INTERVAL 20 /* in seconds. */
-#define CHECK_FOR_HANG_PERIOD 2 /* be equal to watchdog check time. */
-#define DEFAULT_KEEP_ALIVE_LEVEL 1
-#define DEFAULT_SLOT_NUM 2
-#define POWER_PROFILE_AC 0
-#define POWER_PROFILE_BATTERY 1
-
-struct link_detect_t {
- u32 rx_frame_num[MAX_LD_SLOT_NUM]; /* number of Rx Frame.
- * CheckForHang_period to determine
- * link status.
- */
- u16 slot_num; /* number of CheckForHang period to determine link status,
- * default is 2.
- */
- u16 slot_index;
- u32 num_tx_ok_in_period; /* number of packet transmitted during
- * CheckForHang.
- */
- u32 num_rx_ok_in_period; /* number of packet received during
- * CheckForHang.
- */
- u8 idle_count; /* (KEEP_ALIVE_INTERVAL / CHECK_FOR_HANG_PERIOD) */
- u32 last_num_tx_unicast;
- u32 last_num_rx_unicast;
-
- bool b_busy_traffic; /* when it is set to 1, UI cann't scan at will. */
-};
-
-/* YJ,modified,080828,end */
-
-/* by amy for led
- * ==========================================================================
- * LED customization.
- * ==========================================================================
- */
-enum led_strategy_8185 {
- SW_LED_MODE0,
- SW_LED_MODE1,
- HW_LED, /* HW control 2 LEDs, LED0 and LED1 (there are 4 different
- * control modes). */
-};
-
-enum rt_rf_power_state {
- RF_ON,
- RF_SLEEP,
- RF_OFF
-};
-
-enum _ReasonCode {
- unspec_reason = 0x1,
- auth_not_valid = 0x2,
- deauth_lv_ss = 0x3,
- inactivity = 0x4,
- ap_overload = 0x5,
- class2_err = 0x6,
- class3_err = 0x7,
- disas_lv_ss = 0x8,
- asoc_not_auth = 0x9,
-
- /* ----MIC_CHECK */
- mic_failure = 0xe,
- /* ----END MIC_CHECK */
-
- /* Reason code defined in 802.11i D10.0 p.28. */
- invalid_IE = 0x0d,
- four_way_tmout = 0x0f,
- two_way_tmout = 0x10,
- IE_dismatch = 0x11,
- invalid_Gcipher = 0x12,
- invalid_Pcipher = 0x13,
- invalid_AKMP = 0x14,
- unsup_RSNIEver = 0x15,
- invalid_RSNIE = 0x16,
- auth_802_1x_fail = 0x17,
- ciper_reject = 0x18,
-
- /* Reason code defined in 7.3.1.7, 802.1e D13.0, p.42. Added by Annie,
- * 2005-11-15.
- */
- QoS_unspec = 0x20, /* 32 */
- QAP_bandwidth = 0x21, /* 33 */
- poor_condition = 0x22, /* 34 */
- no_facility = 0x23, /* 35 */
- /* Where is 36??? */
- req_declined = 0x25, /* 37 */
- invalid_param = 0x26, /* 38 */
- req_not_honored = 0x27, /* 39 */
- TS_not_created = 0x2F, /* 47 */
- DL_not_allowed = 0x30, /* 48 */
- dest_not_exist = 0x31, /* 49 */
- dest_not_QSTA = 0x32, /* 50 */
-};
-
-enum rt_ps_mode {
- ACTIVE, /* Active/Continuous access. */
- MAX_PS, /* Max power save mode. */
- FAST_PS /* Fast power save mode. */
-};
-
-/* by amy for power save. */
-struct r8180_priv {
- struct pci_dev *pdev;
-
- short epromtype;
- int irq;
- struct ieee80211_device *ieee80211;
-
- short plcp_preamble_mode; /* 0:auto 1:short 2:long */
-
- spinlock_t irq_th_lock;
- spinlock_t tx_lock;
- spinlock_t ps_lock;
- spinlock_t rf_ps_lock;
-
- u16 irq_mask;
- short irq_enabled;
- struct net_device *dev;
- short chan;
- short sens;
- short max_sens;
- u8 chtxpwr[15]; /* channels from 1 to 14, 0 not used. */
- u8 chtxpwr_ofdm[15]; /* channels from 1 to 14, 0 not used. */
- u8 channel_plan; /* it's the channel plan index. */
- short up;
- short crcmon; /* if 1 allow bad crc frame reception in monitor mode. */
-
- struct timer_list scan_timer;
- spinlock_t scan_lock;
- u8 active_probe;
- struct semaphore wx_sem;
- short hw_wep;
-
- short digphy;
- short antb;
- short diversity;
- u32 key0[4];
- short (*rf_set_sens)(struct net_device *dev, short sens);
- void (*rf_set_chan)(struct net_device *dev, short ch);
- void (*rf_close)(struct net_device *dev);
- void (*rf_init)(struct net_device *dev);
- void (*rf_sleep)(struct net_device *dev);
- void (*rf_wakeup)(struct net_device *dev);
- /* short rate; */
- short promisc;
- /* stats */
- struct stats stats;
- struct link_detect_t link_detect; /* YJ,add,080828 */
- struct iw_statistics wstats;
-
- /* RX stuff. */
- u32 *rxring;
- u32 *rxringtail;
- dma_addr_t rxringdma;
- struct buffer *rxbuffer;
- struct buffer *rxbufferhead;
- int rxringcount;
- u16 rxbuffersize;
-
- struct sk_buff *rx_skb;
-
- short rx_skb_complete;
-
- u32 rx_prevlen;
-
- u32 *txmapring;
- u32 *txbkpring;
- u32 *txbepring;
- u32 *txvipring;
- u32 *txvopring;
- u32 *txhpring;
- dma_addr_t txmapringdma;
- dma_addr_t txbkpringdma;
- dma_addr_t txbepringdma;
- dma_addr_t txvipringdma;
- dma_addr_t txvopringdma;
- dma_addr_t txhpringdma;
- u32 *txmapringtail;
- u32 *txbkpringtail;
- u32 *txbepringtail;
- u32 *txvipringtail;
- u32 *txvopringtail;
- u32 *txhpringtail;
- u32 *txmapringhead;
- u32 *txbkpringhead;
- u32 *txbepringhead;
- u32 *txvipringhead;
- u32 *txvopringhead;
- u32 *txhpringhead;
- struct buffer *txmapbufs;
- struct buffer *txbkpbufs;
- struct buffer *txbepbufs;
- struct buffer *txvipbufs;
- struct buffer *txvopbufs;
- struct buffer *txhpbufs;
- struct buffer *txmapbufstail;
- struct buffer *txbkpbufstail;
- struct buffer *txbepbufstail;
- struct buffer *txvipbufstail;
- struct buffer *txvopbufstail;
- struct buffer *txhpbufstail;
-
- int txringcount;
- int txbuffsize;
- struct tasklet_struct irq_rx_tasklet;
- u8 dma_poll_mask;
-
- /* adhoc/master mode stuff. */
- u32 *txbeaconringtail;
- dma_addr_t txbeaconringdma;
- u32 *txbeaconring;
- int txbeaconcount;
- struct buffer *txbeaconbufs;
- struct buffer *txbeaconbufstail;
-
- u8 retry_data;
- u8 retry_rts;
- u16 rts;
-
- /* by amy for led. */
- enum led_strategy_8185 led_strategy;
- /* by amy for led. */
-
- /* by amy for power save. */
- struct timer_list watch_dog_timer;
- bool bInactivePs;
- bool bSwRfProcessing;
- enum rt_rf_power_state eInactivePowerState;
- enum rt_rf_power_state eRFPowerState;
- u32 RfOffReason;
- bool RFChangeInProgress;
- bool SetRFPowerStateInProgress;
- u8 RFProgType;
- bool bLeisurePs;
- enum rt_ps_mode dot11PowerSaveMode;
- u8 TxPollingTimes;
-
- bool bApBufOurFrame; /* TRUE if AP buffer our unicast data , we will
- * keep eAwake until receive data or timeout.
- */
- u8 WaitBufDataBcnCount;
- u8 WaitBufDataTimeOut;
-
- /* by amy for power save. */
- /* by amy for antenna. */
- u8 EEPROMSwAntennaDiversity;
- bool EEPROMDefaultAntenna1;
- u8 RegSwAntennaDiversityMechanism;
- bool bSwAntennaDiverity;
- u8 RegDefaultAntenna;
- bool bDefaultAntenna1;
- u8 SignalStrength;
- long Stats_SignalStrength;
- long LastSignalStrengthInPercent; /* In percentage, used for smoothing,
- * e.g. Moving Average.
- */
- u8 SignalQuality; /* in 0-100 index. */
- long Stats_SignalQuality;
- long RecvSignalPower; /* in dBm. */
- long Stats_RecvSignalPower;
- u8 LastRxPktAntenna; /* +by amy 080312 Antenna which received the lasted
- * packet. 0: Aux, 1:Main. Added by Roger,
- * 2008.01.25.
- */
- u32 AdRxOkCnt;
- long AdRxSignalStrength;
- u8 CurrAntennaIndex; /* Index to current Antenna (both Tx and Rx). */
- u8 AdTickCount; /* Times of SwAntennaDiversityTimer happened. */
- u8 AdCheckPeriod; /* # of period SwAntennaDiversityTimer to check Rx
- * signal strength for SW Antenna Diversity.
- */
- u8 AdMinCheckPeriod; /* Min value of AdCheckPeriod. */
- u8 AdMaxCheckPeriod; /* Max value of AdCheckPeriod. */
- long AdRxSsThreshold; /* Signal strength threshold to switch antenna. */
- long AdMaxRxSsThreshold; /* Max value of AdRxSsThreshold. */
- bool bAdSwitchedChecking; /* TRUE if we shall shall check Rx signal
- * strength for last time switching antenna.
- */
- long AdRxSsBeforeSwitched; /* Rx signal strength before we switched
- * antenna.
- */
- struct timer_list SwAntennaDiversityTimer;
- /* by amy for antenna {by amy 080312 */
-
- /* Crystal calibration. Added by Roger, 2007.12.11. */
-
- bool bXtalCalibration; /* Crystal calibration.*/
- u8 XtalCal_Xin; /* Crystal calibration for Xin. 0~7.5pF */
- u8 XtalCal_Xout; /* Crystal calibration for Xout. 0~7.5pF */
-
- /* Tx power tracking with thermal meter indication.
- * Added by Roger, 2007.12.11.
- */
-
- bool bTxPowerTrack; /* Tx Power tracking. */
- u8 ThermalMeter; /* Thermal meter reference indication. */
-
- /* Dynamic Initial Gain Adjustment Mechanism. Added by Bruce,
- * 2007-02-14.
- */
- bool bDigMechanism; /* TRUE if DIG is enabled, FALSE ow. */
- bool bRegHighPowerMechanism; /* For High Power Mechanism. 061010,
- * by rcnjko.
- */
- u32 FalseAlarmRegValue;
- u8 RegDigOfdmFaUpTh; /* Upper threshold of OFDM false alarm, which is
- * used in DIG.
- */
- u8 DIG_NumberFallbackVote;
- u8 DIG_NumberUpgradeVote;
- /* For HW antenna diversity, added by Roger, 2008.01.30. */
- u32 AdMainAntennaRxOkCnt; /* Main antenna Rx OK count. */
- u32 AdAuxAntennaRxOkCnt; /* Aux antenna Rx OK count. */
- bool bHWAdSwitched; /* TRUE if we has switched default antenna by HW
- * evaluation.
- */
- /* RF High Power upper/lower threshold. */
- u8 RegHiPwrUpperTh;
- u8 RegHiPwrLowerTh;
- /* RF RSSI High Power upper/lower Threshold. */
- u8 RegRSSIHiPwrUpperTh;
- u8 RegRSSIHiPwrLowerTh;
- /* Current CCK RSSI value to determine CCK high power, asked by SD3 DZ,
- * by Bruce, 2007-04-12.
- */
- u8 CurCCKRSSI;
- bool bCurCCKPkt;
- /* High Power Mechanism. Added by amy, 080312. */
- bool bToUpdateTxPwr;
- long UndecoratedSmoothedSS;
- long UndecoratedSmoothedRxPower;
- u8 RSSI;
- char RxPower;
- u8 InitialGain;
- /* For adjust Dig Threshold during Legacy/Leisure Power Save Mode. */
- u32 DozePeriodInPast2Sec;
- /* Don't access BB/RF under disable PLL situation. */
- u8 InitialGainBackUp;
- u8 RegBModeGainStage;
- /* by amy for rate adaptive */
- struct timer_list rateadapter_timer;
- u32 RateAdaptivePeriod;
- bool bEnhanceTxPwr;
- bool bUpdateARFR;
- int ForcedDataRate; /* Force Data Rate. 0: Auto, 0x02: 1M ~ 0x6C: 54M.)
- */
- u32 NumTxUnicast; /* YJ,add,080828,for keep alive. */
- u8 keepAliveLevel; /*YJ,add,080828,for KeepAlive. */
- unsigned long NumTxOkTotal;
- u16 LastRetryCnt;
- u16 LastRetryRate;
- unsigned long LastTxokCnt;
- unsigned long LastRxokCnt;
- u16 CurrRetryCnt;
- unsigned long LastTxOKBytes;
- unsigned long NumTxOkBytesTotal;
- u8 LastFailTxRate;
- long LastFailTxRateSS;
- u8 FailTxRateCount;
- u32 LastTxThroughput;
- /* for up rate. */
- unsigned short bTryuping;
- u8 CurrTxRate; /* the rate before up. */
- u16 CurrRetryRate;
- u16 TryupingCount;
- u8 TryDownCountLowData;
- u8 TryupingCountNoData;
-
- u8 CurrentOperaRate;
- struct work_struct reset_wq;
- struct work_struct watch_dog_wq;
- short ack_tx_to_ieee;
-
- u8 dma_poll_stop_mask;
-
- u16 ShortRetryLimit;
- u16 LongRetryLimit;
- u16 EarlyRxThreshold;
- u32 TransmitConfig;
- u32 ReceiveConfig;
- u32 IntrMask;
-
- struct chnl_access_setting ChannelAccessSetting;
-};
-
-#define MANAGE_PRIORITY 0
-#define BK_PRIORITY 1
-#define BE_PRIORITY 2
-#define VI_PRIORITY 3
-#define VO_PRIORITY 4
-#define HI_PRIORITY 5
-#define BEACON_PRIORITY 6
-
-#define LOW_PRIORITY VI_PRIORITY
-#define NORM_PRIORITY VO_PRIORITY
-/* AC2Queue mapping. */
-#define AC2Q(_ac) (((_ac) == WME_AC_VO) ? VO_PRIORITY : \
- ((_ac) == WME_AC_VI) ? VI_PRIORITY : \
- ((_ac) == WME_AC_BK) ? BK_PRIORITY : \
- BE_PRIORITY)
-
-short rtl8180_tx(struct net_device *dev, u8 *skbuf, int len, int priority,
- bool morefrag, short fragdesc, int rate);
-
-u8 read_nic_byte(struct net_device *dev, int x);
-u32 read_nic_dword(struct net_device *dev, int x);
-u16 read_nic_word(struct net_device *dev, int x);
-void write_nic_byte(struct net_device *dev, int x, u8 y);
-void write_nic_word(struct net_device *dev, int x, u16 y);
-void write_nic_dword(struct net_device *dev, int x, u32 y);
-void force_pci_posting(struct net_device *dev);
-
-void rtl8180_rtx_disable(struct net_device *);
-void rtl8180_set_anaparam(struct net_device *dev, u32 a);
-void rtl8185_set_anaparam2(struct net_device *dev, u32 a);
-void rtl8180_set_hw_wep(struct net_device *dev);
-void rtl8180_no_hw_wep(struct net_device *dev);
-void rtl8180_update_msr(struct net_device *dev);
-void rtl8180_beacon_tx_disable(struct net_device *dev);
-void rtl8180_beacon_rx_disable(struct net_device *dev);
-int rtl8180_down(struct net_device *dev);
-int rtl8180_up(struct net_device *dev);
-void rtl8180_commit(struct net_device *dev);
-void rtl8180_set_chan(struct net_device *dev, short ch);
-void write_phy(struct net_device *dev, u8 adr, u8 data);
-void write_phy_cck(struct net_device *dev, u8 adr, u32 data);
-void write_phy_ofdm(struct net_device *dev, u8 adr, u32 data);
-void rtl8185_tx_antenna(struct net_device *dev, u8 ant);
-void rtl8185_rf_pins_enable(struct net_device *dev);
-void IPSEnter(struct net_device *dev);
-void IPSLeave(struct net_device *dev);
-int get_curr_tx_free_desc(struct net_device *dev, int priority);
-void UpdateInitialGain(struct net_device *dev);
-bool SetAntennaConfig87SE(struct net_device *dev, u8 DefaultAnt,
- bool bAntDiversity);
-
-void rtl8185b_adapter_start(struct net_device *dev);
-void rtl8185b_rx_enable(struct net_device *dev);
-void rtl8185b_tx_enable(struct net_device *dev);
-void rtl8180_reset(struct net_device *dev);
-void rtl8185b_irq_enable(struct net_device *dev);
-void fix_rx_fifo(struct net_device *dev);
-void fix_tx_fifo(struct net_device *dev);
-void rtl8225z2_SetTXPowerLevel(struct net_device *dev, short ch);
-void rtl8180_rate_adapter(struct work_struct *work);
-bool MgntActSet_RF_State(struct net_device *dev, enum rt_rf_power_state StateToSet,
- u32 ChangeSource);
-
-#endif
-
-/* fun with the built-in ieee80211 stack... */
-extern int ieee80211_crypto_init(void);
-extern void ieee80211_crypto_deinit(void);
-extern int ieee80211_crypto_tkip_init(void);
-extern void ieee80211_crypto_tkip_exit(void);
-extern int ieee80211_crypto_ccmp_init(void);
-extern void ieee80211_crypto_ccmp_exit(void);
-extern int ieee80211_crypto_wep_init(void);
-extern void ieee80211_crypto_wep_exit(void);
diff --git a/drivers/staging/rtl8187se/r8180_93cx6.h b/drivers/staging/rtl8187se/r8180_93cx6.h
deleted file mode 100644
index b52b5b0..0000000
--- a/drivers/staging/rtl8187se/r8180_93cx6.h
+++ /dev/null
@@ -1,54 +0,0 @@
-/*
- This is part of rtl8180 OpenSource driver
- 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 Intel Pro Wireless 2100 GPL driver
-
- We want to tanks the Authors of such projects and the Ndiswrapper project Authors.
-*/
-
-/*This files contains card eeprom (93c46 or 93c56) programming routines*/
-/*memory is addressed by WORDS*/
-
-#include "r8180.h"
-#include "r8180_hw.h"
-
-#define EPROM_DELAY 10
-
-#define EPROM_ANAPARAM_ADDRLWORD 0xd
-#define EPROM_ANAPARAM_ADDRHWORD 0xe
-
-#define RFCHIPID 0x6
-#define RFCHIPID_INTERSIL 1
-#define RFCHIPID_RFMD 2
-#define RFCHIPID_PHILIPS 3
-#define RFCHIPID_MAXIM 4
-#define RFCHIPID_GCT 5
-#define RFCHIPID_RTL8225 9
-#define RF_ZEBRA2 11
-#define EPROM_TXPW_BASE 0x05
-#define RF_ZEBRA4 12
-#define RFCHIPID_RTL8255 0xa
-#define RF_PARAM 0x19
-#define RF_PARAM_DIGPHY_SHIFT 0
-#define RF_PARAM_ANTBDEFAULT_SHIFT 1
-#define RF_PARAM_CARRIERSENSE_SHIFT 2
-#define RF_PARAM_CARRIERSENSE_MASK (3<<2)
-#define ENERGY_TRESHOLD 0x17
-#define EPROM_VERSION 0x1E
-#define MAC_ADR 0x7
-
-#define CIS 0x18
-
-#define EPROM_TXPW_OFDM_CH1_2 0x20
-
-#define EPROM_TXPW_CH1_2 0x30
-
-#define RTL818X_EEPROM_CMD_READ (1 << 0)
-#define RTL818X_EEPROM_CMD_WRITE (1 << 1)
-#define RTL818X_EEPROM_CMD_CK (1 << 2)
-#define RTL818X_EEPROM_CMD_CS (1 << 3)
-
diff --git a/drivers/staging/rtl8187se/r8180_core.c b/drivers/staging/rtl8187se/r8180_core.c
deleted file mode 100644
index a6022d4..0000000
--- a/drivers/staging/rtl8187se/r8180_core.c
+++ /dev/null
@@ -1,3775 +0,0 @@
-/*
- * This is part of rtl818x pci OpenSource driver - v 0.1
- * Copyright (C) Andrea Merello 2004-2005 <andrea.merello@gmail.com>
- * Released under the terms of GPL (General Public License)
- *
- * 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.
- *
- * Parts of BB/RF code are derived from David Young rtl8180 netbsd driver.
- *
- * RSSI calc function from 'The Deuce'
- *
- * Some ideas borrowed from the 8139too.c driver included in linux kernel.
- *
- * We (I?) want to thanks the Authors of those projecs and also the
- * Ndiswrapper's project Authors.
- *
- * A big big thanks goes also to Realtek corp. for their help in my attempt to
- * add RTL8185 and RTL8225 support, and to David Young also.
- *
- * Power management interface routines.
- * Written by Mariusz Matuszek.
- */
-
-#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
-
-#undef RX_DONT_PASS_UL
-#undef DUMMY_RX
-
-#include <linux/slab.h>
-#include <linux/syscalls.h>
-#include <linux/eeprom_93cx6.h>
-#include <linux/interrupt.h>
-#include <linux/proc_fs.h>
-#include <linux/seq_file.h>
-
-#include "r8180_hw.h"
-#include "r8180.h"
-#include "r8180_rtl8225.h" /* RTL8225 Radio frontend */
-#include "r8180_93cx6.h" /* Card EEPROM */
-#include "r8180_wx.h"
-#include "r8180_dm.h"
-
-#include "ieee80211/dot11d.h"
-
-static struct pci_device_id rtl8180_pci_id_tbl[] = {
- {
- .vendor = PCI_VENDOR_ID_REALTEK,
- .device = 0x8199,
- .subvendor = PCI_ANY_ID,
- .subdevice = PCI_ANY_ID,
- .driver_data = 0,
- },
- {
- .vendor = 0,
- .device = 0,
- .subvendor = 0,
- .subdevice = 0,
- .driver_data = 0,
- }
-};
-
-static char ifname[IFNAMSIZ] = "wlan%d";
-static int hwwep;
-
-MODULE_LICENSE("GPL");
-MODULE_DEVICE_TABLE(pci, rtl8180_pci_id_tbl);
-MODULE_AUTHOR("Andrea Merello <andrea.merello@gmail.com>");
-MODULE_DESCRIPTION("Linux driver for Realtek RTL8187SE WiFi cards");
-
-module_param_string(ifname, ifname, sizeof(ifname), S_IRUGO|S_IWUSR);
-module_param(hwwep, int, S_IRUGO|S_IWUSR);
-
-MODULE_PARM_DESC(hwwep, " Try to use hardware WEP support. Still broken and not available on all cards");
-
-static int rtl8180_pci_probe(struct pci_dev *pdev,
- const struct pci_device_id *id);
-
-static void rtl8180_pci_remove(struct pci_dev *pdev);
-
-static void rtl8180_shutdown(struct pci_dev *pdev)
-{
- struct net_device *dev = pci_get_drvdata(pdev);
- if (dev->netdev_ops->ndo_stop)
- dev->netdev_ops->ndo_stop(dev);
- pci_disable_device(pdev);
-}
-
-static int rtl8180_suspend(struct pci_dev *pdev, pm_message_t state)
-{
- struct net_device *dev = pci_get_drvdata(pdev);
-
- if (!netif_running(dev))
- goto out_pci_suspend;
-
- if (dev->netdev_ops->ndo_stop)
- dev->netdev_ops->ndo_stop(dev);
-
- netif_device_detach(dev);
-
-out_pci_suspend:
- pci_save_state(pdev);
- pci_disable_device(pdev);
- pci_set_power_state(pdev, pci_choose_state(pdev, state));
- return 0;
-}
-
-static int rtl8180_resume(struct pci_dev *pdev)
-{
- struct net_device *dev = pci_get_drvdata(pdev);
- int err;
- u32 val;
-
- pci_set_power_state(pdev, PCI_D0);
-
- err = pci_enable_device(pdev);
- if (err) {
- dev_err(&pdev->dev, "pci_enable_device failed on resume\n");
-
- return err;
- }
-
- pci_restore_state(pdev);
-
- /*
- * Suspend/Resume resets the PCI configuration space, so we have to
- * re-disable the RETRY_TIMEOUT register (0x41) to keep PCI Tx retries
- * from interfering with C3 CPU state. pci_restore_state won't help
- * here since it only restores the first 64 bytes pci config header.
- */
- pci_read_config_dword(pdev, 0x40, &val);
- if ((val & 0x0000ff00) != 0)
- pci_write_config_dword(pdev, 0x40, val & 0xffff00ff);
-
- if (!netif_running(dev))
- goto out;
-
- if (dev->netdev_ops->ndo_open)
- dev->netdev_ops->ndo_open(dev);
-
- netif_device_attach(dev);
-out:
- return 0;
-}
-
-static struct pci_driver rtl8180_pci_driver = {
- .name = RTL8180_MODULE_NAME,
- .id_table = rtl8180_pci_id_tbl,
- .probe = rtl8180_pci_probe,
- .remove = rtl8180_pci_remove,
- .suspend = rtl8180_suspend,
- .resume = rtl8180_resume,
- .shutdown = rtl8180_shutdown,
-};
-
-u8 read_nic_byte(struct net_device *dev, int x)
-{
- return 0xff&readb((u8 __iomem *)dev->mem_start + x);
-}
-
-u32 read_nic_dword(struct net_device *dev, int x)
-{
- return readl((u8 __iomem *)dev->mem_start + x);
-}
-
-u16 read_nic_word(struct net_device *dev, int x)
-{
- return readw((u8 __iomem *)dev->mem_start + x);
-}
-
-void write_nic_byte(struct net_device *dev, int x, u8 y)
-{
- writeb(y, (u8 __iomem *)dev->mem_start + x);
- udelay(20);
-}
-
-void write_nic_dword(struct net_device *dev, int x, u32 y)
-{
- writel(y, (u8 __iomem *)dev->mem_start + x);
- udelay(20);
-}
-
-void write_nic_word(struct net_device *dev, int x, u16 y)
-{
- writew(y, (u8 __iomem *)dev->mem_start + x);
- udelay(20);
-}
-
-inline void force_pci_posting(struct net_device *dev)
-{
- read_nic_byte(dev, EPROM_CMD);
- mb();
-}
-
-static irqreturn_t rtl8180_interrupt(int irq, void *netdev);
-void set_nic_rxring(struct net_device *dev);
-void set_nic_txring(struct net_device *dev);
-static struct net_device_stats *rtl8180_stats(struct net_device *dev);
-void rtl8180_commit(struct net_device *dev);
-void rtl8180_start_tx_beacon(struct net_device *dev);
-
-static struct proc_dir_entry *rtl8180_proc;
-
-static int proc_get_registers(struct seq_file *m, void *v)
-{
- struct net_device *dev = m->private;
- int i, n, max = 0xff;
-
- /* This dump the current register page */
- for (n = 0; n <= max;) {
- seq_printf(m, "\nD: %2x > ", n);
-
- for (i = 0; i < 16 && n <= max; i++, n++)
- seq_printf(m, "%2x ", read_nic_byte(dev, n));
- }
- seq_putc(m, '\n');
- return 0;
-}
-
-int get_curr_tx_free_desc(struct net_device *dev, int priority);
-
-static int proc_get_stats_hw(struct seq_file *m, void *v)
-{
- return 0;
-}
-
-static int proc_get_stats_rx(struct seq_file *m, void *v)
-{
- struct net_device *dev = m->private;
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
- seq_printf(m,
- "RX OK: %lu\n"
- "RX Retry: %lu\n"
- "RX CRC Error(0-500): %lu\n"
- "RX CRC Error(500-1000): %lu\n"
- "RX CRC Error(>1000): %lu\n"
- "RX ICV Error: %lu\n",
- priv->stats.rxint,
- priv->stats.rxerr,
- priv->stats.rxcrcerrmin,
- priv->stats.rxcrcerrmid,
- priv->stats.rxcrcerrmax,
- priv->stats.rxicverr
- );
-
- return 0;
-}
-
-static int proc_get_stats_tx(struct seq_file *m, void *v)
-{
- struct net_device *dev = m->private;
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- unsigned long totalOK;
-
- totalOK = priv->stats.txnpokint + priv->stats.txhpokint +
- priv->stats.txlpokint;
-
- seq_printf(m,
- "TX OK: %lu\n"
- "TX Error: %lu\n"
- "TX Retry: %lu\n"
- "TX beacon OK: %lu\n"
- "TX beacon error: %lu\n",
- totalOK,
- priv->stats.txnperr+priv->stats.txhperr+priv->stats.txlperr,
- priv->stats.txretry,
- priv->stats.txbeacon,
- priv->stats.txbeaconerr
- );
-
- return 0;
-}
-
-static void rtl8180_proc_module_init(void)
-{
- DMESG("Initializing proc filesystem");
- rtl8180_proc = proc_mkdir(RTL8180_MODULE_NAME, init_net.proc_net);
-}
-
-static void rtl8180_proc_module_remove(void)
-{
- remove_proc_entry(RTL8180_MODULE_NAME, init_net.proc_net);
-}
-
-static void rtl8180_proc_remove_one(struct net_device *dev)
-{
- remove_proc_subtree(dev->name, rtl8180_proc);
-}
-
-/*
- * seq_file wrappers for procfile show routines.
- */
-static int rtl8180_proc_open(struct inode *inode, struct file *file)
-{
- struct net_device *dev = proc_get_parent_data(inode);
- int (*show)(struct seq_file *, void *) = PDE_DATA(inode);
-
- return single_open(file, show, dev);
-}
-
-static const struct file_operations rtl8180_proc_fops = {
- .open = rtl8180_proc_open,
- .read = seq_read,
- .llseek = seq_lseek,
- .release = single_release,
-};
-
-/*
- * Table of proc files we need to create.
- */
-struct rtl8180_proc_file {
- char name[12];
- int (*show)(struct seq_file *, void *);
-};
-
-static const struct rtl8180_proc_file rtl8180_proc_files[] = {
- { "stats-hw", &proc_get_stats_hw },
- { "stats-rx", &proc_get_stats_rx },
- { "stats-tx", &proc_get_stats_tx },
- { "registers", &proc_get_registers },
- { "" }
-};
-
-static void rtl8180_proc_init_one(struct net_device *dev)
-{
- const struct rtl8180_proc_file *f;
- struct proc_dir_entry *dir;
-
- dir = proc_mkdir_data(dev->name, 0, rtl8180_proc, dev);
- if (!dir) {
- DMESGE("Unable to initialize /proc/net/r8180/%s\n", dev->name);
- return;
- }
-
- for (f = rtl8180_proc_files; f->name[0]; f++) {
- if (!proc_create_data(f->name, S_IFREG | S_IRUGO, dir,
- &rtl8180_proc_fops, f->show)) {
- DMESGE("Unable to initialize /proc/net/r8180/%s/%s\n",
- dev->name, f->name);
- return;
- }
- }
-}
-
-/*
- * FIXME: check if we can use some standard already-existent
- * data type+functions in kernel.
- */
-
-static short buffer_add(struct buffer **buffer, u32 *buf, dma_addr_t dma,
- struct buffer **bufferhead)
-{
- struct buffer *tmp;
-
- if (!*buffer) {
-
- *buffer = kmalloc(sizeof(struct buffer), GFP_KERNEL);
-
- if (*buffer == NULL) {
- DMESGE("Failed to kmalloc head of TX/RX struct");
- return -1;
- }
- (*buffer)->next = *buffer;
- (*buffer)->buf = buf;
- (*buffer)->dma = dma;
- if (bufferhead != NULL)
- (*bufferhead) = (*buffer);
- return 0;
- }
- tmp = *buffer;
-
- while (tmp->next != (*buffer))
- tmp = tmp->next;
- tmp->next = kmalloc(sizeof(struct buffer), GFP_KERNEL);
- if (tmp->next == NULL) {
- DMESGE("Failed to kmalloc TX/RX struct");
- return -1;
- }
- tmp->next->buf = buf;
- tmp->next->dma = dma;
- tmp->next->next = *buffer;
-
- return 0;
-}
-
-static void buffer_free(struct net_device *dev, struct buffer **buffer, int len,
- short consistent)
-{
-
- struct buffer *tmp, *next;
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- struct pci_dev *pdev = priv->pdev;
-
- if (!*buffer)
- return;
-
- tmp = *buffer;
-
- do {
- next = tmp->next;
- if (consistent) {
- pci_free_consistent(pdev, len,
- tmp->buf, tmp->dma);
- } else {
- pci_unmap_single(pdev, tmp->dma,
- len, PCI_DMA_FROMDEVICE);
- kfree(tmp->buf);
- }
- kfree(tmp);
- tmp = next;
- } while (next != *buffer);
-
- *buffer = NULL;
-}
-
-int get_curr_tx_free_desc(struct net_device *dev, int priority)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- u32 *tail;
- u32 *head;
- int ret;
-
- switch (priority) {
- case MANAGE_PRIORITY:
- head = priv->txmapringhead;
- tail = priv->txmapringtail;
- break;
- case BK_PRIORITY:
- head = priv->txbkpringhead;
- tail = priv->txbkpringtail;
- break;
- case BE_PRIORITY:
- head = priv->txbepringhead;
- tail = priv->txbepringtail;
- break;
- case VI_PRIORITY:
- head = priv->txvipringhead;
- tail = priv->txvipringtail;
- break;
- case VO_PRIORITY:
- head = priv->txvopringhead;
- tail = priv->txvopringtail;
- break;
- case HI_PRIORITY:
- head = priv->txhpringhead;
- tail = priv->txhpringtail;
- break;
- default:
- return -1;
- }
-
- if (head <= tail)
- ret = priv->txringcount - (tail - head)/8;
- else
- ret = (head - tail)/8;
-
- if (ret > priv->txringcount)
- DMESG("BUG");
-
- return ret;
-}
-
-static short check_nic_enought_desc(struct net_device *dev, int priority)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- struct ieee80211_device *ieee = netdev_priv(dev);
- int requiredbyte;
- int required;
-
- requiredbyte = priv->ieee80211->fts +
- sizeof(struct ieee80211_header_data);
-
- if (ieee->current_network.QoS_Enable)
- requiredbyte += 2;
-
- required = requiredbyte / (priv->txbuffsize-4);
-
- if (requiredbyte % priv->txbuffsize)
- required++;
-
- /* for now we keep two free descriptor as a safety boundary
- * between the tail and the head
- */
-
- return required + 2 < get_curr_tx_free_desc(dev, priority);
-}
-
-void fix_tx_fifo(struct net_device *dev)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- u32 *tmp;
- int i;
-
- for (tmp = priv->txmapring, i = 0;
- i < priv->txringcount;
- tmp += 8, i++) {
- *tmp = *tmp & ~(1<<31);
- }
-
- for (tmp = priv->txbkpring, i = 0;
- i < priv->txringcount;
- tmp += 8, i++) {
- *tmp = *tmp & ~(1<<31);
- }
-
- for (tmp = priv->txbepring, i = 0;
- i < priv->txringcount;
- tmp += 8, i++) {
- *tmp = *tmp & ~(1<<31);
- }
- for (tmp = priv->txvipring, i = 0;
- i < priv->txringcount;
- tmp += 8, i++) {
- *tmp = *tmp & ~(1<<31);
- }
-
- for (tmp = priv->txvopring, i = 0;
- i < priv->txringcount;
- tmp += 8, i++) {
- *tmp = *tmp & ~(1<<31);
- }
-
- for (tmp = priv->txhpring, i = 0;
- i < priv->txringcount;
- tmp += 8, i++) {
- *tmp = *tmp & ~(1<<31);
- }
-
- for (tmp = priv->txbeaconring, i = 0;
- i < priv->txbeaconcount;
- tmp += 8, i++) {
- *tmp = *tmp & ~(1<<31);
- }
-
- priv->txmapringtail = priv->txmapring;
- priv->txmapringhead = priv->txmapring;
- priv->txmapbufstail = priv->txmapbufs;
-
- priv->txbkpringtail = priv->txbkpring;
- priv->txbkpringhead = priv->txbkpring;
- priv->txbkpbufstail = priv->txbkpbufs;
-
- priv->txbepringtail = priv->txbepring;
- priv->txbepringhead = priv->txbepring;
- priv->txbepbufstail = priv->txbepbufs;
-
- priv->txvipringtail = priv->txvipring;
- priv->txvipringhead = priv->txvipring;
- priv->txvipbufstail = priv->txvipbufs;
-
- priv->txvopringtail = priv->txvopring;
- priv->txvopringhead = priv->txvopring;
- priv->txvopbufstail = priv->txvopbufs;
-
- priv->txhpringtail = priv->txhpring;
- priv->txhpringhead = priv->txhpring;
- priv->txhpbufstail = priv->txhpbufs;
-
- priv->txbeaconringtail = priv->txbeaconring;
- priv->txbeaconbufstail = priv->txbeaconbufs;
- set_nic_txring(dev);
-
- ieee80211_reset_queue(priv->ieee80211);
- priv->ack_tx_to_ieee = 0;
-}
-
-void fix_rx_fifo(struct net_device *dev)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- u32 *tmp;
- struct buffer *rxbuf;
- u8 rx_desc_size;
-
- rx_desc_size = 8; /* 4*8 = 32 bytes */
-
- for (tmp = priv->rxring, rxbuf = priv->rxbufferhead;
- (tmp < (priv->rxring)+(priv->rxringcount)*rx_desc_size);
- tmp += rx_desc_size, rxbuf = rxbuf->next) {
- *(tmp+2) = rxbuf->dma;
- *tmp = *tmp & ~0xfff;
- *tmp = *tmp | priv->rxbuffersize;
- *tmp |= (1<<31);
- }
-
- priv->rxringtail = priv->rxring;
- priv->rxbuffer = priv->rxbufferhead;
- priv->rx_skb_complete = 1;
- set_nic_rxring(dev);
-}
-
-static void rtl8180_irq_disable(struct net_device *dev)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
- write_nic_dword(dev, IMR, 0);
- force_pci_posting(dev);
- priv->irq_enabled = 0;
-}
-
-void rtl8180_set_mode(struct net_device *dev, int mode)
-{
- u8 ecmd;
-
- ecmd = read_nic_byte(dev, EPROM_CMD);
- ecmd = ecmd & ~EPROM_CMD_OPERATING_MODE_MASK;
- ecmd = ecmd | (mode<<EPROM_CMD_OPERATING_MODE_SHIFT);
- ecmd = ecmd & ~(1<<EPROM_CS_SHIFT);
- ecmd = ecmd & ~(1<<EPROM_CK_SHIFT);
- write_nic_byte(dev, EPROM_CMD, ecmd);
-}
-
-void rtl8180_beacon_tx_enable(struct net_device *dev);
-
-void rtl8180_update_msr(struct net_device *dev)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- u8 msr;
- u32 rxconf;
-
- msr = read_nic_byte(dev, MSR);
- msr &= ~MSR_LINK_MASK;
-
- rxconf = read_nic_dword(dev, RX_CONF);
-
- if (priv->ieee80211->state == IEEE80211_LINKED) {
- if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
- msr |= (MSR_LINK_ADHOC<<MSR_LINK_SHIFT);
- else if (priv->ieee80211->iw_mode == IW_MODE_MASTER)
- msr |= (MSR_LINK_MASTER<<MSR_LINK_SHIFT);
- else if (priv->ieee80211->iw_mode == IW_MODE_INFRA)
- msr |= (MSR_LINK_MANAGED<<MSR_LINK_SHIFT);
- else
- msr |= (MSR_LINK_NONE<<MSR_LINK_SHIFT);
- rxconf |= (1<<RX_CHECK_BSSID_SHIFT);
-
- } else {
- msr |= (MSR_LINK_NONE<<MSR_LINK_SHIFT);
- rxconf &= ~(1<<RX_CHECK_BSSID_SHIFT);
- }
-
- write_nic_byte(dev, MSR, msr);
- write_nic_dword(dev, RX_CONF, rxconf);
-}
-
-void rtl8180_set_chan(struct net_device *dev, short ch)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
- if ((ch > 14) || (ch < 1)) {
- netdev_err(dev, "In %s: Invalid channel %d\n", __func__, ch);
- return;
- }
-
- priv->chan = ch;
- priv->rf_set_chan(dev, priv->chan);
-}
-
-void set_nic_txring(struct net_device *dev)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
- write_nic_dword(dev, TX_MANAGEPRIORITY_RING_ADDR, priv->txmapringdma);
- write_nic_dword(dev, TX_BKPRIORITY_RING_ADDR, priv->txbkpringdma);
- write_nic_dword(dev, TX_BEPRIORITY_RING_ADDR, priv->txbepringdma);
- write_nic_dword(dev, TX_VIPRIORITY_RING_ADDR, priv->txvipringdma);
- write_nic_dword(dev, TX_VOPRIORITY_RING_ADDR, priv->txvopringdma);
- write_nic_dword(dev, TX_HIGHPRIORITY_RING_ADDR, priv->txhpringdma);
- write_nic_dword(dev, TX_BEACON_RING_ADDR, priv->txbeaconringdma);
-}
-
-void rtl8180_beacon_tx_enable(struct net_device *dev)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
- rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
- priv->dma_poll_stop_mask &= ~(TPPOLLSTOP_BQ);
- write_nic_byte(dev, TPPollStop, priv->dma_poll_mask);
- rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
-}
-
-void rtl8180_beacon_tx_disable(struct net_device *dev)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
- rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
- priv->dma_poll_stop_mask |= TPPOLLSTOP_BQ;
- write_nic_byte(dev, TPPollStop, priv->dma_poll_stop_mask);
- rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
-
-}
-
-void rtl8180_rtx_disable(struct net_device *dev)
-{
- u8 cmd;
- struct r8180_priv *priv = ieee80211_priv(dev);
-
- cmd = read_nic_byte(dev, CMD);
- write_nic_byte(dev, CMD, cmd &
- ~((1<<CMD_RX_ENABLE_SHIFT)|(1<<CMD_TX_ENABLE_SHIFT)));
- force_pci_posting(dev);
- mdelay(10);
-
- if (!priv->rx_skb_complete)
- dev_kfree_skb_any(priv->rx_skb);
-}
-
-static short alloc_tx_desc_ring(struct net_device *dev, int bufsize, int count,
- int addr)
-{
- int i;
- u32 *desc;
- u32 *tmp;
- dma_addr_t dma_desc, dma_tmp;
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- struct pci_dev *pdev = priv->pdev;
- void *buf;
-
- if ((bufsize & 0xfff) != bufsize) {
- DMESGE("TX buffer allocation too large");
- return 0;
- }
- desc = (u32 *)pci_alloc_consistent(pdev,
- sizeof(u32)*8*count+256, &dma_desc);
- if (desc == NULL)
- return -1;
-
- if (dma_desc & 0xff)
- /*
- * descriptor's buffer must be 256 byte aligned
- * we shouldn't be here, since we set DMA mask !
- */
- WARN(1, "DMA buffer is not aligned\n");
-
- tmp = desc;
-
- for (i = 0; i < count; i++) {
- buf = (void *)pci_alloc_consistent(pdev, bufsize, &dma_tmp);
- if (buf == NULL)
- return -ENOMEM;
-
- switch (addr) {
- case TX_MANAGEPRIORITY_RING_ADDR:
- if (-1 == buffer_add(&priv->txmapbufs,
- buf, dma_tmp, NULL)) {
- DMESGE("Unable to allocate mem for buffer NP");
- return -ENOMEM;
- }
- break;
- case TX_BKPRIORITY_RING_ADDR:
- if (-1 == buffer_add(&priv->txbkpbufs,
- buf, dma_tmp, NULL)) {
- DMESGE("Unable to allocate mem for buffer LP");
- return -ENOMEM;
- }
- break;
- case TX_BEPRIORITY_RING_ADDR:
- if (-1 == buffer_add(&priv->txbepbufs,
- buf, dma_tmp, NULL)) {
- DMESGE("Unable to allocate mem for buffer NP");
- return -ENOMEM;
- }
- break;
- case TX_VIPRIORITY_RING_ADDR:
- if (-1 == buffer_add(&priv->txvipbufs,
- buf, dma_tmp, NULL)) {
- DMESGE("Unable to allocate mem for buffer LP");
- return -ENOMEM;
- }
- break;
- case TX_VOPRIORITY_RING_ADDR:
- if (-1 == buffer_add(&priv->txvopbufs,
- buf, dma_tmp, NULL)) {
- DMESGE("Unable to allocate mem for buffer NP");
- return -ENOMEM;
- }
- break;
- case TX_HIGHPRIORITY_RING_ADDR:
- if (-1 == buffer_add(&priv->txhpbufs,
- buf, dma_tmp, NULL)) {
- DMESGE("Unable to allocate mem for buffer HP");
- return -ENOMEM;
- }
- break;
- case TX_BEACON_RING_ADDR:
- if (-1 == buffer_add(&priv->txbeaconbufs,
- buf, dma_tmp, NULL)) {
- DMESGE("Unable to allocate mem for buffer BP");
- return -ENOMEM;
- }
- break;
- }
- *tmp = *tmp & ~(1<<31); /* descriptor empty, owned by the drv */
- *(tmp+2) = (u32)dma_tmp;
- *(tmp+3) = bufsize;
-
- if (i+1 < count)
- *(tmp+4) = (u32)dma_desc+((i+1)*8*4);
- else
- *(tmp+4) = (u32)dma_desc;
-
- tmp = tmp+8;
- }
-
- switch (addr) {
- case TX_MANAGEPRIORITY_RING_ADDR:
- priv->txmapringdma = dma_desc;
- priv->txmapring = desc;
- break;
- case TX_BKPRIORITY_RING_ADDR:
- priv->txbkpringdma = dma_desc;
- priv->txbkpring = desc;
- break;
- case TX_BEPRIORITY_RING_ADDR:
- priv->txbepringdma = dma_desc;
- priv->txbepring = desc;
- break;
- case TX_VIPRIORITY_RING_ADDR:
- priv->txvipringdma = dma_desc;
- priv->txvipring = desc;
- break;
- case TX_VOPRIORITY_RING_ADDR:
- priv->txvopringdma = dma_desc;
- priv->txvopring = desc;
- break;
- case TX_HIGHPRIORITY_RING_ADDR:
- priv->txhpringdma = dma_desc;
- priv->txhpring = desc;
- break;
- case TX_BEACON_RING_ADDR:
- priv->txbeaconringdma = dma_desc;
- priv->txbeaconring = desc;
- break;
-
- }
-
- return 0;
-}
-
-static void free_tx_desc_rings(struct net_device *dev)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- struct pci_dev *pdev = priv->pdev;
- int count = priv->txringcount;
-
- pci_free_consistent(pdev, sizeof(u32)*8*count+256,
- priv->txmapring, priv->txmapringdma);
- buffer_free(dev, &(priv->txmapbufs), priv->txbuffsize, 1);
-
- pci_free_consistent(pdev, sizeof(u32)*8*count+256,
- priv->txbkpring, priv->txbkpringdma);
- buffer_free(dev, &(priv->txbkpbufs), priv->txbuffsize, 1);
-
- pci_free_consistent(pdev, sizeof(u32)*8*count+256,
- priv->txbepring, priv->txbepringdma);
- buffer_free(dev, &(priv->txbepbufs), priv->txbuffsize, 1);
-
- pci_free_consistent(pdev, sizeof(u32)*8*count+256,
- priv->txvipring, priv->txvipringdma);
- buffer_free(dev, &(priv->txvipbufs), priv->txbuffsize, 1);
-
- pci_free_consistent(pdev, sizeof(u32)*8*count+256,
- priv->txvopring, priv->txvopringdma);
- buffer_free(dev, &(priv->txvopbufs), priv->txbuffsize, 1);
-
- pci_free_consistent(pdev, sizeof(u32)*8*count+256,
- priv->txhpring, priv->txhpringdma);
- buffer_free(dev, &(priv->txhpbufs), priv->txbuffsize, 1);
-
- count = priv->txbeaconcount;
- pci_free_consistent(pdev, sizeof(u32)*8*count+256,
- priv->txbeaconring, priv->txbeaconringdma);
- buffer_free(dev, &(priv->txbeaconbufs), priv->txbuffsize, 1);
-}
-
-static void free_rx_desc_ring(struct net_device *dev)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- struct pci_dev *pdev = priv->pdev;
- int count = priv->rxringcount;
-
- pci_free_consistent(pdev, sizeof(u32)*8*count+256,
- priv->rxring, priv->rxringdma);
-
- buffer_free(dev, &(priv->rxbuffer), priv->rxbuffersize, 0);
-}
-
-static short alloc_rx_desc_ring(struct net_device *dev, u16 bufsize, int count)
-{
- int i;
- u32 *desc;
- u32 *tmp;
- dma_addr_t dma_desc, dma_tmp;
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- struct pci_dev *pdev = priv->pdev;
- void *buf;
- u8 rx_desc_size;
-
- rx_desc_size = 8; /* 4*8 = 32 bytes */
-
- if ((bufsize & 0xfff) != bufsize) {
- DMESGE("RX buffer allocation too large");
- return -1;
- }
-
- desc = (u32 *)pci_alloc_consistent(pdev,
- sizeof(u32) * rx_desc_size * count + 256, &dma_desc);
-
- if (dma_desc & 0xff)
- /*
- * descriptor's buffer must be 256 byte aligned
- * should never happen since we specify the DMA mask
- */
- WARN(1, "DMA buffer is not aligned\n");
-
- priv->rxring = desc;
- priv->rxringdma = dma_desc;
- tmp = desc;
-
- for (i = 0; i < count; i++) {
- buf = kmalloc(bufsize * sizeof(u8), GFP_ATOMIC);
- if (buf == NULL) {
- DMESGE("Failed to kmalloc RX buffer");
- return -1;
- }
-
- dma_tmp = pci_map_single(pdev, buf, bufsize * sizeof(u8),
- PCI_DMA_FROMDEVICE);
- if (pci_dma_mapping_error(pdev, dma_tmp))
- return -1;
- if (-1 == buffer_add(&(priv->rxbuffer), buf, dma_tmp,
- &(priv->rxbufferhead))) {
- DMESGE("Unable to allocate mem RX buf");
- return -1;
- }
- *tmp = 0; /* zero pads the header of the descriptor */
- *tmp = *tmp | (bufsize&0xfff);
- *(tmp+2) = (u32)dma_tmp;
- *tmp = *tmp | (1<<31); /* descriptor void, owned by the NIC */
-
- tmp = tmp+rx_desc_size;
- }
-
- /* this is the last descriptor */
- *(tmp - rx_desc_size) = *(tmp - rx_desc_size) | (1 << 30);
-
- return 0;
-}
-
-
-void set_nic_rxring(struct net_device *dev)
-{
- u8 pgreg;
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
- pgreg = read_nic_byte(dev, PGSELECT);
- write_nic_byte(dev, PGSELECT, pgreg & ~(1<<PGSELECT_PG_SHIFT));
-
- write_nic_dword(dev, RXRING_ADDR, priv->rxringdma);
-}
-
-void rtl8180_reset(struct net_device *dev)
-{
- u8 cr;
-
- rtl8180_irq_disable(dev);
-
- cr = read_nic_byte(dev, CMD);
- cr = cr & 2;
- cr = cr | (1<<CMD_RST_SHIFT);
- write_nic_byte(dev, CMD, cr);
-
- force_pci_posting(dev);
-
- mdelay(200);
-
- if (read_nic_byte(dev, CMD) & (1<<CMD_RST_SHIFT))
- DMESGW("Card reset timeout!");
- else
- DMESG("Card successfully reset");
-
- rtl8180_set_mode(dev, EPROM_CMD_LOAD);
- force_pci_posting(dev);
- mdelay(200);
-}
-
-inline u16 ieeerate2rtlrate(int rate)
-{
- switch (rate) {
- case 10:
- return 0;
- case 20:
- return 1;
- case 55:
- return 2;
- case 110:
- return 3;
- case 60:
- return 4;
- case 90:
- return 5;
- case 120:
- return 6;
- case 180:
- return 7;
- case 240:
- return 8;
- case 360:
- return 9;
- case 480:
- return 10;
- case 540:
- return 11;
- default:
- return 3;
- }
-}
-
-static u16 rtl_rate[] = {10, 20, 55, 110, 60,
- 90, 120, 180, 240, 360, 480, 540, 720};
-
-inline u16 rtl8180_rate2rate(short rate)
-{
- if (rate > 12)
- return 10;
- return rtl_rate[rate];
-}
-
-inline u8 rtl8180_IsWirelessBMode(u16 rate)
-{
- if (((rate <= 110) && (rate != 60) && (rate != 90)) || (rate == 220))
- return 1;
- else
- return 0;
-}
-
-u16 N_DBPSOfRate(u16 DataRate);
-
-static u16 ComputeTxTime(u16 FrameLength, u16 DataRate, u8 bManagementFrame,
- u8 bShortPreamble)
-{
- u16 FrameTime;
- u16 N_DBPS;
- u16 Ceiling;
-
- if (rtl8180_IsWirelessBMode(DataRate)) {
- 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 */
- FrameTime++;
- } else { /* 802.11g DSSS-OFDM PLCP length field calculation. */
- N_DBPS = N_DBPSOfRate(DataRate);
- Ceiling = (16 + 8*FrameLength + 6) / N_DBPS
- + (((16 + 8*FrameLength + 6) % N_DBPS) ? 1 : 0);
- FrameTime = (u16)(16 + 4 + 4*Ceiling + 6);
- }
- return FrameTime;
-}
-
-u16 N_DBPSOfRate(u16 DataRate)
-{
- u16 N_DBPS = 24;
-
- switch (DataRate) {
- case 60:
- N_DBPS = 24;
- break;
- case 90:
- N_DBPS = 36;
- break;
- case 120:
- N_DBPS = 48;
- break;
- case 180:
- N_DBPS = 72;
- break;
- case 240:
- N_DBPS = 96;
- break;
- case 360:
- N_DBPS = 144;
- break;
- case 480:
- N_DBPS = 192;
- break;
- case 540:
- N_DBPS = 216;
- break;
- default:
- break;
- }
-
- return N_DBPS;
-}
-
-/*
- * For Netgear case, they want good-looking signal strength.
- */
-static long NetgearSignalStrengthTranslate(long LastSS, long CurrSS)
-{
- long RetSS;
-
- /* Step 1. Scale mapping. */
- if (CurrSS >= 71 && CurrSS <= 100)
- RetSS = 90 + ((CurrSS - 70) / 3);
- else if (CurrSS >= 41 && CurrSS <= 70)
- RetSS = 78 + ((CurrSS - 40) / 3);
- else if (CurrSS >= 31 && CurrSS <= 40)
- RetSS = 66 + (CurrSS - 30);
- else if (CurrSS >= 21 && CurrSS <= 30)
- RetSS = 54 + (CurrSS - 20);
- else if (CurrSS >= 5 && CurrSS <= 20)
- RetSS = 42 + (((CurrSS - 5) * 2) / 3);
- else if (CurrSS == 4)
- RetSS = 36;
- else if (CurrSS == 3)
- RetSS = 27;
- else if (CurrSS == 2)
- RetSS = 18;
- else if (CurrSS == 1)
- RetSS = 9;
- else
- RetSS = CurrSS;
-
- /* Step 2. Smoothing. */
- if (LastSS > 0)
- RetSS = ((LastSS * 5) + (RetSS) + 5) / 6;
-
- return RetSS;
-}
-
-/*
- * Translate 0-100 signal strength index into dBm.
- */
-static long TranslateToDbm8185(u8 SignalStrengthIndex)
-{
- long SignalPower;
-
- /* Translate to dBm (x=0.5y-95). */
- SignalPower = (long)((SignalStrengthIndex + 1) >> 1);
- SignalPower -= 95;
-
- return SignalPower;
-}
-
-/*
- * Perform signal smoothing for dynamic mechanism.
- * This is different with PerformSignalSmoothing8185 in smoothing formula.
- * No dramatic adjustment is applied because dynamic mechanism need some
- * degree of correctness. Ported from 8187B.
- */
-static void PerformUndecoratedSignalSmoothing8185(struct r8180_priv *priv,
- bool bCckRate)
-{
- long smoothedSS;
- long smoothedRx;
-
- /* Determine the current packet is CCK rate. */
- priv->bCurCCKPkt = bCckRate;
-
- smoothedSS = priv->SignalStrength * 10;
-
- if (priv->UndecoratedSmoothedSS >= 0)
- smoothedSS = ((priv->UndecoratedSmoothedSS * 5) +
- smoothedSS) / 6;
-
- priv->UndecoratedSmoothedSS = smoothedSS;
-
- smoothedRx = ((priv->UndecoratedSmoothedRxPower * 50) +
- (priv->RxPower * 11)) / 60;
-
- priv->UndecoratedSmoothedRxPower = smoothedRx;
-
- if (bCckRate)
- priv->CurCCKRSSI = priv->RSSI;
- else
- priv->CurCCKRSSI = 0;
-}
-
-
-/*
- * This is rough RX isr handling routine
- */
-static void rtl8180_rx(struct net_device *dev)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- struct sk_buff *tmp_skb;
- short first, last;
- u32 len;
- int lastlen;
- unsigned char quality, signal;
- u8 rate;
- u32 *tmp, *tmp2;
- u8 rx_desc_size;
- u8 padding;
- char rxpower = 0;
- u32 RXAGC = 0;
- long RxAGC_dBm = 0;
- u8 LNA = 0, BB = 0;
- u8 LNA_gain[4] = {02, 17, 29, 39};
- u8 Antenna = 0;
- struct ieee80211_hdr_4addr *hdr;
- u16 fc, type;
- u8 bHwError = 0, bCRC = 0, bICV = 0;
- bool bCckRate = false;
- u8 RSSI = 0;
- long SignalStrengthIndex = 0;
- struct ieee80211_rx_stats stats = {
- .signal = 0,
- .noise = -98,
- .rate = 0,
- .freq = IEEE80211_24GHZ_BAND,
- };
-
- stats.nic_type = NIC_8185B;
- rx_desc_size = 8;
-
- if ((*(priv->rxringtail)) & (1<<31)) {
- /* we have got an RX int, but the descriptor. we are pointing
- * is empty.
- */
-
- priv->stats.rxnodata++;
- priv->ieee80211->stats.rx_errors++;
-
- tmp2 = NULL;
- tmp = priv->rxringtail;
- do {
- if (tmp == priv->rxring)
- tmp = priv->rxring + (priv->rxringcount - 1) *
- rx_desc_size;
- else
- tmp -= rx_desc_size;
-
- if (!(*tmp & (1<<31)))
- tmp2 = tmp;
- } while (tmp != priv->rxring);
-
- if (tmp2)
- priv->rxringtail = tmp2;
- }
-
- /* while there are filled descriptors */
- while (!(*(priv->rxringtail) & (1<<31))) {
- if (*(priv->rxringtail) & (1<<26))
- DMESGW("RX buffer overflow");
- if (*(priv->rxringtail) & (1<<12))
- priv->stats.rxicverr++;
-
- if (*(priv->rxringtail) & (1<<27)) {
- priv->stats.rxdmafail++;
- goto drop;
- }
-
- pci_dma_sync_single_for_cpu(priv->pdev,
- priv->rxbuffer->dma,
- priv->rxbuffersize * sizeof(u8),
- PCI_DMA_FROMDEVICE);
-
- first = *(priv->rxringtail) & (1<<29) ? 1 : 0;
- if (first)
- priv->rx_prevlen = 0;
-
- last = *(priv->rxringtail) & (1<<28) ? 1 : 0;
- if (last) {
- lastlen = ((*priv->rxringtail) & 0xfff);
-
- /* if the last descriptor (that should tell us the total
- * packet len) tell us something less than the
- * descriptors len we had until now, then there is some
- * problem..
- * workaround to prevent kernel panic
- */
- if (lastlen < priv->rx_prevlen)
- len = 0;
- else
- len = lastlen-priv->rx_prevlen;
-
- if (*(priv->rxringtail) & (1<<13)) {
- if ((*(priv->rxringtail) & 0xfff) < 500)
- priv->stats.rxcrcerrmin++;
- else if ((*(priv->rxringtail) & 0x0fff) > 1000)
- priv->stats.rxcrcerrmax++;
- else
- priv->stats.rxcrcerrmid++;
-
- }
-
- } else {
- len = priv->rxbuffersize;
- }
-
- if (first && last) {
- padding = ((*(priv->rxringtail+3))&(0x04000000))>>26;
- } else if (first) {
- padding = ((*(priv->rxringtail+3))&(0x04000000))>>26;
- if (padding)
- len -= 2;
- } else {
- padding = 0;
- }
- padding = 0;
- priv->rx_prevlen += len;
-
- if (priv->rx_prevlen > MAX_FRAG_THRESHOLD + 100) {
- /* HW is probably passing several buggy frames without
- * FD or LD flag set.
- * Throw this garbage away to prevent skb memory
- * exhausting
- */
- if (!priv->rx_skb_complete)
- dev_kfree_skb_any(priv->rx_skb);
- priv->rx_skb_complete = 1;
- }
-
- signal = (unsigned char)((*(priv->rxringtail + 3) &
- 0x00ff0000) >> 16);
- signal = (signal & 0xfe) >> 1;
-
- quality = (unsigned char)((*(priv->rxringtail+3)) & (0xff));
-
- stats.mac_time[0] = *(priv->rxringtail+1);
- stats.mac_time[1] = *(priv->rxringtail+2);
-
- rxpower = ((char)((*(priv->rxringtail + 4) &
- 0x00ff0000) >> 16)) / 2 - 42;
-
- RSSI = ((u8)((*(priv->rxringtail + 3) &
- 0x0000ff00) >> 8)) & 0x7f;
-
- rate = ((*(priv->rxringtail)) &
- ((1<<23)|(1<<22)|(1<<21)|(1<<20)))>>20;
-
- stats.rate = rtl8180_rate2rate(rate);
- Antenna = (*(priv->rxringtail + 3) & 0x00008000) == 0 ? 0 : 1;
- if (!rtl8180_IsWirelessBMode(stats.rate)) { /* OFDM rate. */
- RxAGC_dBm = rxpower+1; /* bias */
- } else { /* CCK rate. */
- RxAGC_dBm = signal; /* bit 0 discard */
-
- LNA = (u8) (RxAGC_dBm & 0x60) >> 5; /* bit 6~ bit 5 */
- BB = (u8) (RxAGC_dBm & 0x1F); /* bit 4 ~ bit 0 */
-
- /* Pin_11b=-(LNA_gain+BB_gain) (dBm) */
- RxAGC_dBm = -(LNA_gain[LNA] + (BB * 2));
-
- RxAGC_dBm += 4; /* bias */
- }
-
- if (RxAGC_dBm & 0x80) /* absolute value */
- RXAGC = ~(RxAGC_dBm)+1;
- bCckRate = rtl8180_IsWirelessBMode(stats.rate);
- /* Translate RXAGC into 1-100. */
- if (!rtl8180_IsWirelessBMode(stats.rate)) { /* OFDM rate. */
- if (RXAGC > 90)
- RXAGC = 90;
- else if (RXAGC < 25)
- RXAGC = 25;
- RXAGC = (90-RXAGC)*100/65;
- } else { /* CCK rate. */
- if (RXAGC > 95)
- RXAGC = 95;
- else if (RXAGC < 30)
- RXAGC = 30;
- RXAGC = (95-RXAGC)*100/65;
- }
- priv->SignalStrength = (u8)RXAGC;
- priv->RecvSignalPower = RxAGC_dBm;
- priv->RxPower = rxpower;
- priv->RSSI = RSSI;
- /* SQ translation formula is provided by SD3 DZ. 2006.06.27 */
- if (quality >= 127)
- /* 0 causes epc to show signal zero, walk around now */
- quality = 1;
- else if (quality < 27)
- quality = 100;
- else
- quality = 127 - quality;
- priv->SignalQuality = quality;
-
- stats.signal = (u8) quality;
-
- stats.signalstrength = RXAGC;
- if (stats.signalstrength > 100)
- stats.signalstrength = 100;
- stats.signalstrength = (stats.signalstrength * 70) / 100 + 30;
- stats.rssi = priv->wstats.qual.qual = priv->SignalQuality;
- stats.noise = priv->wstats.qual.noise =
- 100 - priv->wstats.qual.qual;
- bHwError = (((*(priv->rxringtail)) & (0x00000fff)) == 4080) |
- (((*(priv->rxringtail)) & (0x04000000)) != 0) |
- (((*(priv->rxringtail)) & (0x08000000)) != 0) |
- (((~(*(priv->rxringtail))) & (0x10000000)) != 0) |
- (((~(*(priv->rxringtail))) & (0x20000000)) != 0);
- bCRC = ((*(priv->rxringtail)) & (0x00002000)) >> 13;
- bICV = ((*(priv->rxringtail)) & (0x00001000)) >> 12;
- hdr = (struct ieee80211_hdr_4addr *)priv->rxbuffer->buf;
- fc = le16_to_cpu(hdr->frame_ctl);
- type = WLAN_FC_GET_TYPE(fc);
-
- if (IEEE80211_FTYPE_CTL != type &&
- !bHwError && !bCRC && !bICV &&
- eqMacAddr(priv->ieee80211->current_network.bssid,
- fc & IEEE80211_FCTL_TODS ? hdr->addr1 :
- fc & IEEE80211_FCTL_FROMDS ? hdr->addr2 :
- hdr->addr3)) {
-
- /* Perform signal smoothing for dynamic
- * mechanism on demand. This is different
- * with PerformSignalSmoothing8185 in smoothing
- * fomula. No dramatic adjustion is apply
- * because dynamic mechanism need some degree
- * of correctness. */
- PerformUndecoratedSignalSmoothing8185(priv, bCckRate);
-
- /* For good-looking singal strength. */
- SignalStrengthIndex = NetgearSignalStrengthTranslate(
- priv->LastSignalStrengthInPercent,
- priv->SignalStrength);
-
- priv->LastSignalStrengthInPercent = SignalStrengthIndex;
- priv->Stats_SignalStrength =
- TranslateToDbm8185((u8)SignalStrengthIndex);
-
- /*
- * We need more correct power of received packets and
- * the "SignalStrength" of RxStats is beautified, so we
- * record the correct power here.
- */
-
- priv->Stats_SignalQuality = (long)(
- priv->Stats_SignalQuality * 5 +
- (long)priv->SignalQuality + 5) / 6;
-
- priv->Stats_RecvSignalPower = (long)(
- priv->Stats_RecvSignalPower * 5 +
- priv->RecvSignalPower - 1) / 6;
-
- /*
- * Figure out which antenna received the last packet.
- * 0: aux, 1: main
- */
- priv->LastRxPktAntenna = Antenna ? 1 : 0;
- SwAntennaDiversityRxOk8185(dev, priv->SignalStrength);
- }
-
- if (first) {
- if (!priv->rx_skb_complete) {
- /* seems that HW sometimes fails to receive and
- * doesn't provide the last descriptor.
- */
- dev_kfree_skb_any(priv->rx_skb);
- priv->stats.rxnolast++;
- }
- priv->rx_skb = dev_alloc_skb(len+2);
- if (!priv->rx_skb)
- goto drop;
-
- priv->rx_skb_complete = 0;
- priv->rx_skb->dev = dev;
- } else {
- /* if we are here we should have already RXed the first
- * frame.
- * If we get here and the skb is not allocated then
- * we have just throw out garbage (skb not allocated)
- * and we are still rxing garbage....
- */
- if (!priv->rx_skb_complete) {
-
- tmp_skb = dev_alloc_skb(
- priv->rx_skb->len + len + 2);
-
- if (!tmp_skb)
- goto drop;
-
- tmp_skb->dev = dev;
-
- memcpy(skb_put(tmp_skb, priv->rx_skb->len),
- priv->rx_skb->data,
- priv->rx_skb->len);
-
- dev_kfree_skb_any(priv->rx_skb);
-
- priv->rx_skb = tmp_skb;
- }
- }
-
- if (!priv->rx_skb_complete) {
- memcpy(skb_put(priv->rx_skb, len), ((unsigned char *)
- priv->rxbuffer->buf) + (padding ? 2 : 0), len);
- }
-
- if (last && !priv->rx_skb_complete) {
- if (priv->rx_skb->len > 4)
- skb_trim(priv->rx_skb, priv->rx_skb->len-4);
- if (!ieee80211_rtl_rx(priv->ieee80211,
- priv->rx_skb, &stats))
- dev_kfree_skb_any(priv->rx_skb);
- priv->rx_skb_complete = 1;
- }
-
- pci_dma_sync_single_for_device(priv->pdev,
- priv->rxbuffer->dma,
- priv->rxbuffersize * sizeof(u8),
- PCI_DMA_FROMDEVICE);
-
-drop: /* this is used when we have not enough mem */
- /* restore the descriptor */
- *(priv->rxringtail+2) = priv->rxbuffer->dma;
- *(priv->rxringtail) = *(priv->rxringtail) & ~0xfff;
- *(priv->rxringtail) =
- *(priv->rxringtail) | priv->rxbuffersize;
-
- *(priv->rxringtail) =
- *(priv->rxringtail) | (1<<31);
-
- priv->rxringtail += rx_desc_size;
- if (priv->rxringtail >=
- (priv->rxring)+(priv->rxringcount)*rx_desc_size)
- priv->rxringtail = priv->rxring;
-
- priv->rxbuffer = (priv->rxbuffer->next);
- }
-}
-
-
-static void rtl8180_dma_kick(struct net_device *dev, int priority)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
- rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
- write_nic_byte(dev, TX_DMA_POLLING,
- (1 << (priority + 1)) | priv->dma_poll_mask);
- rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
-
- force_pci_posting(dev);
-}
-
-static void rtl8180_data_hard_stop(struct net_device *dev)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
- rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
- priv->dma_poll_stop_mask |= TPPOLLSTOP_AC_VIQ;
- write_nic_byte(dev, TPPollStop, priv->dma_poll_stop_mask);
- rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
-}
-
-static void rtl8180_data_hard_resume(struct net_device *dev)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
- rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
- priv->dma_poll_stop_mask &= ~(TPPOLLSTOP_AC_VIQ);
- write_nic_byte(dev, TPPollStop, priv->dma_poll_stop_mask);
- rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
-}
-
-/*
- * This function TX data frames when the ieee80211 stack requires this.
- * It checks also if we need to stop the ieee tx queue, eventually do it
- */
-static void rtl8180_hard_data_xmit(struct sk_buff *skb, struct net_device *dev,
- int rate)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- int mode;
- struct ieee80211_hdr_3addr *h = (struct ieee80211_hdr_3addr *)skb->data;
- bool morefrag = le16_to_cpu(h->frame_control) & IEEE80211_FCTL_MOREFRAGS;
- unsigned long flags;
- int priority;
-
- mode = priv->ieee80211->iw_mode;
-
- rate = ieeerate2rtlrate(rate);
- /*
- * This function doesn't require lock because we make sure it's called
- * with the tx_lock already acquired.
- * This come from the kernel's hard_xmit callback (through the ieee
- * stack, or from the try_wake_queue (again through the ieee stack.
- */
- priority = AC2Q(skb->priority);
- spin_lock_irqsave(&priv->tx_lock, flags);
-
- if (priv->ieee80211->bHwRadioOff) {
- spin_unlock_irqrestore(&priv->tx_lock, flags);
-
- return;
- }
-
- if (!check_nic_enought_desc(dev, priority)) {
- DMESGW("Error: no descriptor left by previous TX (avail %d) ",
- get_curr_tx_free_desc(dev, priority));
- ieee80211_rtl_stop_queue(priv->ieee80211);
- }
- rtl8180_tx(dev, skb->data, skb->len, priority, morefrag, 0, rate);
- if (!check_nic_enought_desc(dev, priority))
- ieee80211_rtl_stop_queue(priv->ieee80211);
-
- spin_unlock_irqrestore(&priv->tx_lock, flags);
-}
-
-/*
- * This is a rough attempt to TX a frame
- * This is called by the ieee 80211 stack to TX management frames.
- * If the ring is full packets are dropped (for data frame the queue
- * is stopped before this can happen). For this reason it is better
- * if the descriptors are larger than the largest management frame
- * we intend to TX: i'm unsure what the HW does if it will not find
- * the last fragment of a frame because it has been dropped...
- * Since queues for Management and Data frames are different we
- * might use a different lock than tx_lock (for example mgmt_tx_lock)
- */
-/* these function may loop if invoked with 0 descriptors or 0 len buffer */
-static int rtl8180_hard_start_xmit(struct sk_buff *skb, struct net_device *dev)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- unsigned long flags;
- int priority;
-
- priority = MANAGE_PRIORITY;
-
- spin_lock_irqsave(&priv->tx_lock, flags);
-
- if (priv->ieee80211->bHwRadioOff) {
- spin_unlock_irqrestore(&priv->tx_lock, flags);
- dev_kfree_skb_any(skb);
- return NETDEV_TX_OK;
- }
-
- rtl8180_tx(dev, skb->data, skb->len, priority,
- 0, 0, ieeerate2rtlrate(priv->ieee80211->basic_rate));
-
- priv->ieee80211->stats.tx_bytes += skb->len;
- priv->ieee80211->stats.tx_packets++;
- spin_unlock_irqrestore(&priv->tx_lock, flags);
-
- dev_kfree_skb_any(skb);
- return NETDEV_TX_OK;
-}
-
-static void rtl8180_prepare_beacon(struct net_device *dev)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- struct sk_buff *skb;
-
- u16 word = read_nic_word(dev, BcnItv);
- word &= ~BcnItv_BcnItv; /* clear Bcn_Itv */
-
- /* word |= 0x64; */
- word |= cpu_to_le16(priv->ieee80211->current_network.beacon_interval);
-
- write_nic_word(dev, BcnItv, word);
-
- skb = ieee80211_get_beacon(priv->ieee80211);
- if (skb) {
- rtl8180_tx(dev, skb->data, skb->len, BEACON_PRIORITY,
- 0, 0, ieeerate2rtlrate(priv->ieee80211->basic_rate));
- dev_kfree_skb_any(skb);
- }
-}
-
-/*
- * This function do the real dirty work: it enqueues a TX command descriptor in
- * the ring buffer, copyes the frame in a TX buffer and kicks the NIC to ensure
- * it does the DMA transfer.
- */
-short rtl8180_tx(struct net_device *dev, u8 *txbuf, int len, int priority,
- bool morefrag, short descfrag, int rate)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- u32 *tail, *temp_tail;
- u32 *begin;
- u32 *buf;
- int i;
- int remain;
- int buflen;
- int count;
- struct buffer *buflist;
- struct ieee80211_hdr_3addr *frag_hdr =
- (struct ieee80211_hdr_3addr *)txbuf;
- u8 dest[ETH_ALEN];
- u8 bUseShortPreamble = 0;
- u8 bCTSEnable = 0;
- u8 bRTSEnable = 0;
- u16 Duration = 0;
- u16 RtsDur = 0;
- u16 ThisFrameTime = 0;
- u16 TxDescDuration = 0;
- bool ownbit_flag = false;
-
- switch (priority) {
- case MANAGE_PRIORITY:
- tail = priv->txmapringtail;
- begin = priv->txmapring;
- buflist = priv->txmapbufstail;
- count = priv->txringcount;
- break;
- case BK_PRIORITY:
- tail = priv->txbkpringtail;
- begin = priv->txbkpring;
- buflist = priv->txbkpbufstail;
- count = priv->txringcount;
- break;
- case BE_PRIORITY:
- tail = priv->txbepringtail;
- begin = priv->txbepring;
- buflist = priv->txbepbufstail;
- count = priv->txringcount;
- break;
- case VI_PRIORITY:
- tail = priv->txvipringtail;
- begin = priv->txvipring;
- buflist = priv->txvipbufstail;
- count = priv->txringcount;
- break;
- case VO_PRIORITY:
- tail = priv->txvopringtail;
- begin = priv->txvopring;
- buflist = priv->txvopbufstail;
- count = priv->txringcount;
- break;
- case HI_PRIORITY:
- tail = priv->txhpringtail;
- begin = priv->txhpring;
- buflist = priv->txhpbufstail;
- count = priv->txringcount;
- break;
- case BEACON_PRIORITY:
- tail = priv->txbeaconringtail;
- begin = priv->txbeaconring;
- buflist = priv->txbeaconbufstail;
- count = priv->txbeaconcount;
- break;
- default:
- return -1;
- break;
- }
-
- memcpy(&dest, frag_hdr->addr1, ETH_ALEN);
- if (is_multicast_ether_addr(dest)) {
- Duration = 0;
- RtsDur = 0;
- bRTSEnable = 0;
- bCTSEnable = 0;
-
- ThisFrameTime = ComputeTxTime(len + sCrcLng,
- rtl8180_rate2rate(rate), 0, bUseShortPreamble);
- TxDescDuration = ThisFrameTime;
- } else { /* Unicast packet */
- u16 AckTime;
-
- /* for Keep alive */
- priv->NumTxUnicast++;
-
- /* Figure out ACK rate according to BSS basic rate
- * and Tx rate.
- * AckCTSLng = 14 use 1M bps send
- */
- AckTime = ComputeTxTime(14, 10, 0, 0);
-
- if (((len + sCrcLng) > priv->rts) && priv->rts) { /* RTS/CTS. */
- u16 RtsTime, CtsTime;
- bRTSEnable = 1;
- bCTSEnable = 0;
-
- /* Rate and time required for RTS. */
- RtsTime = ComputeTxTime(sAckCtsLng / 8,
- priv->ieee80211->basic_rate, 0, 0);
-
- /* Rate and time required for CTS.
- * AckCTSLng = 14 use 1M bps send
- */
- CtsTime = ComputeTxTime(14, 10, 0, 0);
-
- /* Figure out time required to transmit this frame. */
- ThisFrameTime = ComputeTxTime(len + sCrcLng,
- rtl8180_rate2rate(rate), 0,
- bUseShortPreamble);
-
- /* RTS-CTS-ThisFrame-ACK. */
- RtsDur = CtsTime + ThisFrameTime +
- AckTime + 3 * aSifsTime;
-
- TxDescDuration = RtsTime + RtsDur;
- } else { /* Normal case. */
- bCTSEnable = 0;
- bRTSEnable = 0;
- RtsDur = 0;
-
- ThisFrameTime = ComputeTxTime(len + sCrcLng,
- rtl8180_rate2rate(rate), 0, bUseShortPreamble);
- TxDescDuration = ThisFrameTime + aSifsTime + AckTime;
- }
-
- if (!(le16_to_cpu(frag_hdr->frame_control) & IEEE80211_FCTL_MOREFRAGS)) {
- /* ThisFrame-ACK. */
- Duration = aSifsTime + AckTime;
- } else { /* One or more fragments remained. */
- u16 NextFragTime;
-
- /* pretend following packet length = current packet */
- NextFragTime = ComputeTxTime(len + sCrcLng,
- rtl8180_rate2rate(rate), 0, bUseShortPreamble);
-
- /* ThisFrag-ACk-NextFrag-ACK. */
- Duration = NextFragTime + 3 * aSifsTime + 2 * AckTime;
- }
-
- } /* End of Unicast packet */
-
- frag_hdr->duration_id = Duration;
-
- buflen = priv->txbuffsize;
- remain = len;
- temp_tail = tail;
-
- while (remain != 0) {
- mb();
- if (!buflist) {
- DMESGE("TX buffer error, cannot TX frames. pri %d.",
- priority);
- return -1;
- }
- buf = buflist->buf;
-
- if ((*tail & (1 << 31)) && (priority != BEACON_PRIORITY)) {
- DMESGW("No more TX desc, returning %x of %x",
- remain, len);
- priv->stats.txrdu++;
- return remain;
- }
-
- *tail = 0; /* zeroes header */
- *(tail+1) = 0;
- *(tail+3) = 0;
- *(tail+5) = 0;
- *(tail+6) = 0;
- *(tail+7) = 0;
-
- /* FIXME: should be triggered by HW encryption parameters.*/
- *tail |= (1<<15); /* no encrypt */
-
- if (remain == len && !descfrag) {
- ownbit_flag = false;
- *tail = *tail | (1 << 29); /* first segment of packet */
- *tail = *tail | (len);
- } else {
- ownbit_flag = true;
- }
-
- for (i = 0; i < buflen && remain > 0; i++, remain--) {
- /* copy data into descriptor pointed DMAble buffer */
- ((u8 *)buf)[i] = txbuf[i];
-
- if (remain == 4 && i+4 >= buflen)
- break;
- /* ensure the last desc has at least 4 bytes payload */
- }
- txbuf = txbuf + i;
- *(tail+3) = *(tail+3) & ~0xfff;
- *(tail+3) = *(tail+3) | i; /* buffer length */
-
- if (bCTSEnable)
- *tail |= (1<<18);
-
- if (bRTSEnable) { /* rts enable */
- /* RTS RATE */
- *tail |= (ieeerate2rtlrate(
- priv->ieee80211->basic_rate) << 19);
-
- *tail |= (1<<23); /* rts enable */
- *(tail+1) |= (RtsDur&0xffff); /* RTS Duration */
- }
- *(tail+3) |= ((TxDescDuration&0xffff)<<16); /* DURATION */
-
- *(tail + 5) |= (11 << 8); /* retry lim; */
-
- *tail = *tail | ((rate&0xf) << 24);
-
- if (morefrag)
- *tail = (*tail) | (1<<17); /* more fragment */
- if (!remain)
- *tail = (*tail) | (1<<28); /* last segment of frame */
-
- *(tail+5) = *(tail+5)|(2<<27);
- *(tail+7) = *(tail+7)|(1<<4);
-
- wmb();
- if (ownbit_flag)
- /* descriptor ready to be txed */
- *tail |= (1 << 31);
-
- if ((tail - begin)/8 == count-1)
- tail = begin;
- else
- tail = tail+8;
-
- buflist = buflist->next;
-
- mb();
-
- switch (priority) {
- case MANAGE_PRIORITY:
- priv->txmapringtail = tail;
- priv->txmapbufstail = buflist;
- break;
- case BK_PRIORITY:
- priv->txbkpringtail = tail;
- priv->txbkpbufstail = buflist;
- break;
- case BE_PRIORITY:
- priv->txbepringtail = tail;
- priv->txbepbufstail = buflist;
- break;
- case VI_PRIORITY:
- priv->txvipringtail = tail;
- priv->txvipbufstail = buflist;
- break;
- case VO_PRIORITY:
- priv->txvopringtail = tail;
- priv->txvopbufstail = buflist;
- break;
- case HI_PRIORITY:
- priv->txhpringtail = tail;
- priv->txhpbufstail = buflist;
- break;
- case BEACON_PRIORITY:
- /*
- * The HW seems to be happy with the 1st
- * descriptor filled and the 2nd empty...
- * So always update descriptor 1 and never
- * touch 2nd
- */
- break;
- }
- }
- *temp_tail = *temp_tail | (1<<31); /* descriptor ready to be txed */
- rtl8180_dma_kick(dev, priority);
-
- return 0;
-}
-
-void rtl8180_irq_rx_tasklet(struct r8180_priv *priv);
-
-static void rtl8180_link_change(struct net_device *dev)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- u16 beacon_interval;
- struct ieee80211_network *net = &priv->ieee80211->current_network;
-
- rtl8180_update_msr(dev);
-
- rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
-
- write_nic_dword(dev, BSSID, ((u32 *)net->bssid)[0]);
- write_nic_word(dev, BSSID+4, ((u16 *)net->bssid)[2]);
-
- beacon_interval = read_nic_word(dev, BEACON_INTERVAL);
- beacon_interval &= ~BEACON_INTERVAL_MASK;
- beacon_interval |= net->beacon_interval;
- write_nic_word(dev, BEACON_INTERVAL, beacon_interval);
-
- rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
-
- rtl8180_set_chan(dev, priv->chan);
-}
-
-static void rtl8180_rq_tx_ack(struct net_device *dev)
-{
-
- struct r8180_priv *priv = ieee80211_priv(dev);
-
- write_nic_byte(dev, CONFIG4,
- read_nic_byte(dev, CONFIG4) | CONFIG4_PWRMGT);
- priv->ack_tx_to_ieee = 1;
-}
-
-static short rtl8180_is_tx_queue_empty(struct net_device *dev)
-{
-
- struct r8180_priv *priv = ieee80211_priv(dev);
- u32 *d;
-
- for (d = priv->txmapring;
- d < priv->txmapring + priv->txringcount; d += 8)
- if (*d & (1<<31))
- return 0;
-
- for (d = priv->txbkpring;
- d < priv->txbkpring + priv->txringcount; d += 8)
- if (*d & (1<<31))
- return 0;
-
- for (d = priv->txbepring;
- d < priv->txbepring + priv->txringcount; d += 8)
- if (*d & (1<<31))
- return 0;
-
- for (d = priv->txvipring;
- d < priv->txvipring + priv->txringcount; d += 8)
- if (*d & (1<<31))
- return 0;
-
- for (d = priv->txvopring;
- d < priv->txvopring + priv->txringcount; d += 8)
- if (*d & (1<<31))
- return 0;
-
- for (d = priv->txhpring;
- d < priv->txhpring + priv->txringcount; d += 8)
- if (*d & (1<<31))
- return 0;
- return 1;
-}
-
-static void rtl8180_hw_wakeup(struct net_device *dev)
-{
- unsigned long flags;
- struct r8180_priv *priv = ieee80211_priv(dev);
-
- spin_lock_irqsave(&priv->ps_lock, flags);
- write_nic_byte(dev, CONFIG4,
- read_nic_byte(dev, CONFIG4) & ~CONFIG4_PWRMGT);
- if (priv->rf_wakeup)
- priv->rf_wakeup(dev);
- spin_unlock_irqrestore(&priv->ps_lock, flags);
-}
-
-static void rtl8180_hw_sleep_down(struct net_device *dev)
-{
- unsigned long flags;
- struct r8180_priv *priv = ieee80211_priv(dev);
-
- spin_lock_irqsave(&priv->ps_lock, flags);
- if (priv->rf_sleep)
- priv->rf_sleep(dev);
- spin_unlock_irqrestore(&priv->ps_lock, flags);
-}
-
-static void rtl8180_hw_sleep(struct net_device *dev, u32 th, u32 tl)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- u32 rb = jiffies;
- unsigned long flags;
-
- spin_lock_irqsave(&priv->ps_lock, flags);
-
- /*
- * Writing HW register with 0 equals to disable
- * the timer, that is not really what we want
- */
- tl -= MSECS(4+16+7);
-
- /*
- * If the interval in which we are requested to sleep is too
- * short then give up and remain awake
- */
- if (((tl >= rb) && (tl-rb) <= MSECS(MIN_SLEEP_TIME))
- || ((rb > tl) && (rb-tl) < MSECS(MIN_SLEEP_TIME))) {
- spin_unlock_irqrestore(&priv->ps_lock, flags);
- netdev_warn(dev, "too short to sleep\n");
- return;
- }
-
- {
- u32 tmp = (tl > rb) ? (tl-rb) : (rb-tl);
-
- priv->DozePeriodInPast2Sec += jiffies_to_msecs(tmp);
- /* as tl may be less than rb */
- queue_delayed_work(priv->ieee80211->wq,
- &priv->ieee80211->hw_wakeup_wq, tmp);
- }
- /*
- * If we suspect the TimerInt is gone beyond tl
- * while setting it, then give up
- */
-
- if (((tl > rb) && ((tl-rb) > MSECS(MAX_SLEEP_TIME))) ||
- ((tl < rb) && ((rb-tl) > MSECS(MAX_SLEEP_TIME)))) {
- spin_unlock_irqrestore(&priv->ps_lock, flags);
- return;
- }
-
- queue_work(priv->ieee80211->wq, (void *)&priv->ieee80211->hw_sleep_wq);
- spin_unlock_irqrestore(&priv->ps_lock, flags);
-}
-
-static void rtl8180_wmm_single_param_update(struct net_device *dev,
- u8 mode, AC_CODING eACI, PAC_PARAM param)
-{
- u8 u1bAIFS;
- u32 u4bAcParam;
-
- /* Retrieve parameters to update. */
- /* Mode G/A: slotTimeTimer = 9; Mode B: 20 */
- u1bAIFS = param->f.AciAifsn.f.AIFSN * ((mode & IEEE_G) == IEEE_G ?
- 9 : 20) + aSifsTime;
- u4bAcParam = (((u32)param->f.TXOPLimit << AC_PARAM_TXOP_LIMIT_OFFSET) |
- ((u32)param->f.Ecw.f.ECWmax << AC_PARAM_ECW_MAX_OFFSET) |
- ((u32)param->f.Ecw.f.ECWmin << AC_PARAM_ECW_MIN_OFFSET) |
- ((u32)u1bAIFS << AC_PARAM_AIFS_OFFSET));
-
- switch (eACI) {
- case AC1_BK:
- write_nic_dword(dev, AC_BK_PARAM, u4bAcParam);
- return;
- case AC0_BE:
- write_nic_dword(dev, AC_BE_PARAM, u4bAcParam);
- return;
- case AC2_VI:
- write_nic_dword(dev, AC_VI_PARAM, u4bAcParam);
- return;
- case AC3_VO:
- write_nic_dword(dev, AC_VO_PARAM, u4bAcParam);
- return;
- default:
- pr_warn("SetHwReg8185(): invalid ACI: %d!\n", eACI);
- return;
- }
-}
-
-static void rtl8180_wmm_param_update(struct work_struct *work)
-{
- struct ieee80211_device *ieee = container_of(work,
- struct ieee80211_device, wmm_param_update_wq);
- struct net_device *dev = ieee->dev;
- u8 *ac_param = (u8 *)(ieee->current_network.wmm_param);
- u8 mode = ieee->current_network.mode;
- AC_CODING eACI;
- AC_PARAM AcParam;
-
- if (!ieee->current_network.QoS_Enable) {
- /* legacy ac_xx_param update */
- AcParam.longData = 0;
- AcParam.f.AciAifsn.f.AIFSN = 2; /* Follow 802.11 DIFS. */
- AcParam.f.AciAifsn.f.ACM = 0;
- AcParam.f.Ecw.f.ECWmin = 3; /* Follow 802.11 CWmin. */
- AcParam.f.Ecw.f.ECWmax = 7; /* Follow 802.11 CWmax. */
- AcParam.f.TXOPLimit = 0;
-
- for (eACI = 0; eACI < AC_MAX; eACI++) {
- AcParam.f.AciAifsn.f.ACI = (u8)eACI;
-
- rtl8180_wmm_single_param_update(dev, mode, eACI,
- (PAC_PARAM)&AcParam);
- }
- return;
- }
-
- for (eACI = 0; eACI < AC_MAX; eACI++) {
- rtl8180_wmm_single_param_update(dev, mode,
- ((PAC_PARAM)ac_param)->f.AciAifsn.f.ACI,
- (PAC_PARAM)ac_param);
-
- ac_param += sizeof(AC_PARAM);
- }
-}
-
-void rtl8180_restart_wq(struct work_struct *work);
-void rtl8180_watch_dog_wq(struct work_struct *work);
-void rtl8180_hw_wakeup_wq(struct work_struct *work);
-void rtl8180_hw_sleep_wq(struct work_struct *work);
-void rtl8180_sw_antenna_wq(struct work_struct *work);
-void rtl8180_watch_dog(struct net_device *dev);
-
-static void watch_dog_adaptive(unsigned long data)
-{
- struct r8180_priv *priv = ieee80211_priv((struct net_device *)data);
-
- if (!priv->up) {
- DMESG("<----watch_dog_adaptive():driver is not up!\n");
- return;
- }
-
- /* Tx High Power Mechanism. */
- if (CheckHighPower((struct net_device *)data))
- queue_work(priv->ieee80211->wq,
- (void *)&priv->ieee80211->tx_pw_wq);
-
- /* Tx Power Tracking on 87SE. */
- if (CheckTxPwrTracking((struct net_device *)data))
- TxPwrTracking87SE((struct net_device *)data);
-
- /* Perform DIG immediately. */
- if (CheckDig((struct net_device *)data))
- queue_work(priv->ieee80211->wq,
- (void *)&priv->ieee80211->hw_dig_wq);
-
- rtl8180_watch_dog((struct net_device *)data);
-
- queue_work(priv->ieee80211->wq,
- (void *)&priv->ieee80211->GPIOChangeRFWorkItem);
-
- priv->watch_dog_timer.expires = jiffies +
- MSECS(IEEE80211_WATCH_DOG_TIME);
-
- add_timer(&priv->watch_dog_timer);
-}
-
-static struct rtl8187se_channel_list channel_plan_list[] = {
- /* FCC */
- {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40,
- 44, 48, 52, 56, 60, 64}, 19},
-
- /* IC */
- {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11}, 11},
-
- /* ETSI */
- {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40,
- 44, 48, 52, 56, 60, 64}, 21},
-
- /* Spain. Change to ETSI. */
- {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40,
- 44, 48, 52, 56, 60, 64}, 21},
-
- /* France. Change to ETSI. */
- {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40,
- 44, 48, 52, 56, 60, 64}, 21},
-
- /* MKK */
- {{14, 36, 40, 44, 48, 52, 56, 60, 64}, 9},
-
- /* MKK1 */
- {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 36,
- 40, 44, 48, 52, 56, 60, 64}, 22},
-
- /* Israel. */
- {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40,
- 44, 48, 52, 56, 60, 64}, 21},
-
- /* For 11a , TELEC */
- {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 34, 38, 42, 46}, 17},
-
- /* For Global Domain. 1-11 active, 12-14 passive. */
- {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14}, 14},
-
- /* world wide 13: ch1~ch11 active, ch12~13 passive */
- {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13}, 13}
-};
-
-static void rtl8180_set_channel_map(u8 channel_plan,
- struct ieee80211_device *ieee)
-{
- int i;
-
- ieee->MinPassiveChnlNum = MAX_CHANNEL_NUMBER+1;
- ieee->IbssStartChnl = 0;
-
- switch (channel_plan) {
- case COUNTRY_CODE_FCC:
- case COUNTRY_CODE_IC:
- case COUNTRY_CODE_ETSI:
- case COUNTRY_CODE_SPAIN:
- case COUNTRY_CODE_FRANCE:
- case COUNTRY_CODE_MKK:
- case COUNTRY_CODE_MKK1:
- case COUNTRY_CODE_ISRAEL:
- case COUNTRY_CODE_TELEC:
- {
- Dot11d_Init(ieee);
- ieee->bGlobalDomain = false;
- if (channel_plan_list[channel_plan].len != 0) {
- /* Clear old channel map */
- memset(GET_DOT11D_INFO(ieee)->channel_map, 0, sizeof(GET_DOT11D_INFO(ieee)->channel_map));
- /* Set new channel map */
- for (i = 0; i < channel_plan_list[channel_plan].len; i++) {
- if (channel_plan_list[channel_plan].channel[i] <= 14)
- GET_DOT11D_INFO(ieee)->channel_map[channel_plan_list[channel_plan].channel[i]] = 1;
- }
- }
- break;
- }
- case COUNTRY_CODE_GLOBAL_DOMAIN:
- {
- GET_DOT11D_INFO(ieee)->bEnabled = false;
- Dot11d_Reset(ieee);
- ieee->bGlobalDomain = true;
- break;
- }
- case COUNTRY_CODE_WORLD_WIDE_13_INDEX:
- {
- ieee->MinPassiveChnlNum = 12;
- ieee->IbssStartChnl = 10;
- break;
- }
- default:
- {
- Dot11d_Init(ieee);
- ieee->bGlobalDomain = false;
- memset(GET_DOT11D_INFO(ieee)->channel_map, 0, sizeof(GET_DOT11D_INFO(ieee)->channel_map));
- for (i = 1; i <= 14; i++)
- GET_DOT11D_INFO(ieee)->channel_map[i] = 1;
- break;
- }
- }
-}
-
-void GPIOChangeRFWorkItemCallBack(struct work_struct *work);
-
-static void rtl8180_statistics_init(struct stats *pstats)
-{
- memset(pstats, 0, sizeof(struct stats));
-}
-
-static void rtl8180_link_detect_init(struct link_detect_t *plink_detect)
-{
- memset(plink_detect, 0, sizeof(struct link_detect_t));
- plink_detect->slot_num = DEFAULT_SLOT_NUM;
-}
-
-static void rtl8187se_eeprom_register_read(struct eeprom_93cx6 *eeprom)
-{
- struct net_device *dev = eeprom->data;
- u8 reg = read_nic_byte(dev, EPROM_CMD);
-
- eeprom->reg_data_in = reg & RTL818X_EEPROM_CMD_WRITE;
- eeprom->reg_data_out = reg & RTL818X_EEPROM_CMD_READ;
- eeprom->reg_data_clock = reg & RTL818X_EEPROM_CMD_CK;
- eeprom->reg_chip_select = reg & RTL818X_EEPROM_CMD_CS;
-}
-
-static void rtl8187se_eeprom_register_write(struct eeprom_93cx6 *eeprom)
-{
- struct net_device *dev = eeprom->data;
- u8 reg = 2 << 6;
-
- if (eeprom->reg_data_in)
- reg |= RTL818X_EEPROM_CMD_WRITE;
- if (eeprom->reg_data_out)
- reg |= RTL818X_EEPROM_CMD_READ;
- if (eeprom->reg_data_clock)
- reg |= RTL818X_EEPROM_CMD_CK;
- if (eeprom->reg_chip_select)
- reg |= RTL818X_EEPROM_CMD_CS;
-
- write_nic_byte(dev, EPROM_CMD, reg);
- read_nic_byte(dev, EPROM_CMD);
- udelay(10);
-}
-
-static short rtl8180_init(struct net_device *dev)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- u16 word;
- u16 usValue;
- u16 tmpu16;
- int i, j;
- struct eeprom_93cx6 eeprom;
- u16 eeprom_val;
-
- eeprom.data = dev;
- eeprom.register_read = rtl8187se_eeprom_register_read;
- eeprom.register_write = rtl8187se_eeprom_register_write;
- eeprom.width = PCI_EEPROM_WIDTH_93C46;
-
- eeprom_93cx6_read(&eeprom, EEPROM_COUNTRY_CODE>>1, &eeprom_val);
- priv->channel_plan = eeprom_val & 0xFF;
- if (priv->channel_plan > COUNTRY_CODE_GLOBAL_DOMAIN) {
- netdev_err(dev, "rtl8180_init: Invalid channel plan! Set to default.\n");
- priv->channel_plan = 0;
- }
-
- DMESG("Channel plan is %d\n", priv->channel_plan);
- rtl8180_set_channel_map(priv->channel_plan, priv->ieee80211);
-
- /* FIXME: these constants are placed in a bad pleace. */
- priv->txbuffsize = 2048; /* 1024; */
- priv->txringcount = 32; /* 32; */
- priv->rxbuffersize = 2048; /* 1024; */
- priv->rxringcount = 64; /* 32; */
- priv->txbeaconcount = 2;
- priv->rx_skb_complete = 1;
-
- priv->RFChangeInProgress = false;
- priv->SetRFPowerStateInProgress = false;
- priv->RFProgType = 0;
-
- priv->irq_enabled = 0;
-
- rtl8180_statistics_init(&priv->stats);
- rtl8180_link_detect_init(&priv->link_detect);
-
- priv->ack_tx_to_ieee = 0;
- 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;
- priv->ieee80211->active_scan = 1;
- priv->ieee80211->rate = 110; /* 11 mbps */
- priv->ieee80211->modulation = IEEE80211_CCK_MODULATION;
- priv->ieee80211->host_encrypt = 1;
- priv->ieee80211->host_decrypt = 1;
- priv->ieee80211->sta_wake_up = rtl8180_hw_wakeup;
- priv->ieee80211->ps_request_tx_ack = rtl8180_rq_tx_ack;
- priv->ieee80211->enter_sleep_state = rtl8180_hw_sleep;
- priv->ieee80211->ps_is_queue_empty = rtl8180_is_tx_queue_empty;
-
- priv->hw_wep = hwwep;
- priv->dev = dev;
- priv->retry_rts = DEFAULT_RETRY_RTS;
- priv->retry_data = DEFAULT_RETRY_DATA;
- priv->RFChangeInProgress = false;
- priv->SetRFPowerStateInProgress = false;
- priv->RFProgType = 0;
- priv->bInactivePs = true; /* false; */
- priv->ieee80211->bInactivePs = priv->bInactivePs;
- priv->bSwRfProcessing = false;
- priv->eRFPowerState = RF_OFF;
- priv->RfOffReason = 0;
- priv->led_strategy = SW_LED_MODE0;
- priv->TxPollingTimes = 0;
- priv->bLeisurePs = true;
- priv->dot11PowerSaveMode = ACTIVE;
- priv->AdMinCheckPeriod = 5;
- priv->AdMaxCheckPeriod = 10;
- priv->AdMaxRxSsThreshold = 30; /* 60->30 */
- priv->AdRxSsThreshold = 20; /* 50->20 */
- priv->AdCheckPeriod = priv->AdMinCheckPeriod;
- priv->AdTickCount = 0;
- priv->AdRxSignalStrength = -1;
- priv->RegSwAntennaDiversityMechanism = 0;
- priv->RegDefaultAntenna = 0;
- priv->SignalStrength = 0;
- priv->AdRxOkCnt = 0;
- priv->CurrAntennaIndex = 0;
- priv->AdRxSsBeforeSwitched = 0;
- init_timer(&priv->SwAntennaDiversityTimer);
- priv->SwAntennaDiversityTimer.data = (unsigned long)dev;
- priv->SwAntennaDiversityTimer.function =
- (void *)SwAntennaDiversityTimerCallback;
- priv->bDigMechanism = true;
- priv->InitialGain = 6;
- priv->bXtalCalibration = false;
- priv->XtalCal_Xin = 0;
- priv->XtalCal_Xout = 0;
- priv->bTxPowerTrack = false;
- priv->ThermalMeter = 0;
- priv->FalseAlarmRegValue = 0;
- priv->RegDigOfdmFaUpTh = 0xc; /* Upper threshold of OFDM false alarm,
- which is used in DIG. */
- priv->DIG_NumberFallbackVote = 0;
- priv->DIG_NumberUpgradeVote = 0;
- priv->LastSignalStrengthInPercent = 0;
- priv->Stats_SignalStrength = 0;
- priv->LastRxPktAntenna = 0;
- priv->SignalQuality = 0; /* in 0-100 index. */
- priv->Stats_SignalQuality = 0;
- priv->RecvSignalPower = 0; /* in dBm. */
- priv->Stats_RecvSignalPower = 0;
- priv->AdMainAntennaRxOkCnt = 0;
- priv->AdAuxAntennaRxOkCnt = 0;
- priv->bHWAdSwitched = false;
- priv->bRegHighPowerMechanism = true;
- priv->RegHiPwrUpperTh = 77;
- priv->RegHiPwrLowerTh = 75;
- priv->RegRSSIHiPwrUpperTh = 70;
- priv->RegRSSIHiPwrLowerTh = 20;
- priv->bCurCCKPkt = false;
- priv->UndecoratedSmoothedSS = -1;
- priv->bToUpdateTxPwr = false;
- priv->CurCCKRSSI = 0;
- priv->RxPower = 0;
- priv->RSSI = 0;
- priv->NumTxOkTotal = 0;
- priv->NumTxUnicast = 0;
- priv->keepAliveLevel = DEFAULT_KEEP_ALIVE_LEVEL;
- priv->CurrRetryCnt = 0;
- priv->LastRetryCnt = 0;
- priv->LastTxokCnt = 0;
- priv->LastRxokCnt = 0;
- priv->LastRetryRate = 0;
- priv->bTryuping = 0;
- priv->CurrTxRate = 0;
- priv->CurrRetryRate = 0;
- priv->TryupingCount = 0;
- priv->TryupingCountNoData = 0;
- priv->TryDownCountLowData = 0;
- priv->LastTxOKBytes = 0;
- priv->LastFailTxRate = 0;
- priv->LastFailTxRateSS = 0;
- priv->FailTxRateCount = 0;
- priv->LastTxThroughput = 0;
- priv->NumTxOkBytesTotal = 0;
- priv->ForcedDataRate = 0;
- priv->RegBModeGainStage = 1;
-
- priv->promisc = (dev->flags & IFF_PROMISC) ? 1 : 0;
- spin_lock_init(&priv->irq_th_lock);
- spin_lock_init(&priv->tx_lock);
- spin_lock_init(&priv->ps_lock);
- spin_lock_init(&priv->rf_ps_lock);
- sema_init(&priv->wx_sem, 1);
- INIT_WORK(&priv->reset_wq, (void *)rtl8180_restart_wq);
- INIT_DELAYED_WORK(&priv->ieee80211->hw_wakeup_wq,
- (void *)rtl8180_hw_wakeup_wq);
- INIT_DELAYED_WORK(&priv->ieee80211->hw_sleep_wq,
- (void *)rtl8180_hw_sleep_wq);
- INIT_WORK(&priv->ieee80211->wmm_param_update_wq,
- (void *)rtl8180_wmm_param_update);
- INIT_DELAYED_WORK(&priv->ieee80211->rate_adapter_wq,
- (void *)rtl8180_rate_adapter);
- INIT_DELAYED_WORK(&priv->ieee80211->hw_dig_wq,
- (void *)rtl8180_hw_dig_wq);
- INIT_DELAYED_WORK(&priv->ieee80211->tx_pw_wq,
- (void *)rtl8180_tx_pw_wq);
- INIT_DELAYED_WORK(&priv->ieee80211->GPIOChangeRFWorkItem,
- (void *) GPIOChangeRFWorkItemCallBack);
- tasklet_init(&priv->irq_rx_tasklet,
- (void(*)(unsigned long)) rtl8180_irq_rx_tasklet,
- (unsigned long)priv);
-
- init_timer(&priv->watch_dog_timer);
- priv->watch_dog_timer.data = (unsigned long)dev;
- priv->watch_dog_timer.function = watch_dog_adaptive;
-
- init_timer(&priv->rateadapter_timer);
- priv->rateadapter_timer.data = (unsigned long)dev;
- priv->rateadapter_timer.function = timer_rate_adaptive;
- priv->RateAdaptivePeriod = RATE_ADAPTIVE_TIMER_PERIOD;
- priv->bEnhanceTxPwr = false;
-
- priv->ieee80211->softmac_hard_start_xmit = rtl8180_hard_start_xmit;
- priv->ieee80211->set_chan = rtl8180_set_chan;
- priv->ieee80211->link_change = rtl8180_link_change;
- priv->ieee80211->softmac_data_hard_start_xmit = rtl8180_hard_data_xmit;
- priv->ieee80211->data_hard_stop = rtl8180_data_hard_stop;
- priv->ieee80211->data_hard_resume = rtl8180_data_hard_resume;
-
- priv->ieee80211->init_wmmparam_flag = 0;
-
- priv->ieee80211->start_send_beacons = rtl8180_start_tx_beacon;
- priv->ieee80211->stop_send_beacons = rtl8180_beacon_tx_disable;
- priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
-
- priv->ShortRetryLimit = 7;
- priv->LongRetryLimit = 7;
- priv->EarlyRxThreshold = 7;
-
- priv->TransmitConfig = (1<<TCR_DurProcMode_OFFSET) |
- (7<<TCR_MXDMA_OFFSET) |
- (priv->ShortRetryLimit<<TCR_SRL_OFFSET) |
- (priv->LongRetryLimit<<TCR_LRL_OFFSET);
-
- priv->ReceiveConfig = RCR_AMF | RCR_ADF | RCR_ACF |
- RCR_AB | RCR_AM | RCR_APM |
- (7<<RCR_MXDMA_OFFSET) |
- (priv->EarlyRxThreshold<<RCR_FIFO_OFFSET) |
- (priv->EarlyRxThreshold == 7 ?
- RCR_ONLYERLPKT : 0);
-
- priv->IntrMask = IMR_TMGDOK | IMR_TBDER |
- IMR_THPDER | IMR_THPDOK |
- IMR_TVODER | IMR_TVODOK |
- IMR_TVIDER | IMR_TVIDOK |
- IMR_TBEDER | IMR_TBEDOK |
- IMR_TBKDER | IMR_TBKDOK |
- IMR_RDU |
- IMR_RER | IMR_ROK |
- IMR_RQoSOK;
-
- priv->InitialGain = 6;
-
- DMESG("MAC controller is a RTL8187SE b/g");
-
- priv->ieee80211->modulation |= IEEE80211_OFDM_MODULATION;
- priv->ieee80211->short_slot = 1;
-
- eeprom_93cx6_read(&eeprom, EEPROM_SW_REVD_OFFSET, &usValue);
- DMESG("usValue is %#hx\n", usValue);
- /* 3Read AntennaDiversity */
-
- /* SW Antenna Diversity. */
- priv->EEPROMSwAntennaDiversity = (usValue & EEPROM_SW_AD_MASK) ==
- EEPROM_SW_AD_ENABLE;
-
- /* Default Antenna to use. */
- priv->EEPROMDefaultAntenna1 = (usValue & EEPROM_DEF_ANT_MASK) ==
- EEPROM_DEF_ANT_1;
-
- if (priv->RegSwAntennaDiversityMechanism == 0) /* Auto */
- /* 0: default from EEPROM. */
- priv->bSwAntennaDiverity = priv->EEPROMSwAntennaDiversity;
- else
- /* 1:disable antenna diversity, 2: enable antenna diversity. */
- priv->bSwAntennaDiverity =
- priv->RegSwAntennaDiversityMechanism == 2;
-
- if (priv->RegDefaultAntenna == 0)
- /* 0: default from EEPROM. */
- priv->bDefaultAntenna1 = priv->EEPROMDefaultAntenna1;
- else
- /* 1: main, 2: aux. */
- priv->bDefaultAntenna1 = priv->RegDefaultAntenna == 2;
-
- priv->plcp_preamble_mode = 2;
- /* the eeprom type is stored in RCR register bit #6 */
- if (RCR_9356SEL & read_nic_dword(dev, RCR))
- priv->epromtype = EPROM_93c56;
- else
- priv->epromtype = EPROM_93c46;
-
- eeprom_93cx6_multiread(&eeprom, 0x7, (__le16 *)
- dev->dev_addr, 3);
-
- for (i = 1, j = 0; i < 14; i += 2, j++) {
- eeprom_93cx6_read(&eeprom, EPROM_TXPW_CH1_2 + j, &word);
- priv->chtxpwr[i] = word & 0xff;
- priv->chtxpwr[i+1] = (word & 0xff00)>>8;
- }
- for (i = 1, j = 0; i < 14; i += 2, j++) {
- eeprom_93cx6_read(&eeprom, EPROM_TXPW_OFDM_CH1_2 + j, &word);
- priv->chtxpwr_ofdm[i] = word & 0xff;
- priv->chtxpwr_ofdm[i+1] = (word & 0xff00) >> 8;
- }
-
- /* 3Read crystal calibration and thermal meter indication on 87SE. */
- eeprom_93cx6_read(&eeprom, EEPROM_RSV>>1, &tmpu16);
-
- /* Crystal calibration for Xin and Xout resp. */
- priv->XtalCal_Xout = tmpu16 & EEPROM_XTAL_CAL_XOUT_MASK;
- priv->XtalCal_Xin = (tmpu16 & EEPROM_XTAL_CAL_XIN_MASK) >> 4;
- if ((tmpu16 & EEPROM_XTAL_CAL_ENABLE) >> 12)
- priv->bXtalCalibration = true;
-
- /* Thermal meter reference indication. */
- priv->ThermalMeter = (u8)((tmpu16 & EEPROM_THERMAL_METER_MASK) >> 8);
- if ((tmpu16 & EEPROM_THERMAL_METER_ENABLE) >> 13)
- priv->bTxPowerTrack = true;
-
- priv->rf_sleep = rtl8225z4_rf_sleep;
- priv->rf_wakeup = rtl8225z4_rf_wakeup;
- DMESGW("**PLEASE** REPORT SUCCESSFUL/UNSUCCESSFUL TO Realtek!");
-
- priv->rf_close = rtl8225z2_rf_close;
- priv->rf_init = rtl8225z2_rf_init;
- priv->rf_set_chan = rtl8225z2_rf_set_chan;
- priv->rf_set_sens = NULL;
-
- if (0 != alloc_rx_desc_ring(dev, priv->rxbuffersize, priv->rxringcount))
- return -ENOMEM;
-
- if (0 != alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txringcount,
- TX_MANAGEPRIORITY_RING_ADDR))
- return -ENOMEM;
-
- if (0 != alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txringcount,
- TX_BKPRIORITY_RING_ADDR))
- return -ENOMEM;
-
- if (0 != alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txringcount,
- TX_BEPRIORITY_RING_ADDR))
- return -ENOMEM;
-
- if (0 != alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txringcount,
- TX_VIPRIORITY_RING_ADDR))
- return -ENOMEM;
-
- if (0 != alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txringcount,
- TX_VOPRIORITY_RING_ADDR))
- return -ENOMEM;
-
- if (0 != alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txringcount,
- TX_HIGHPRIORITY_RING_ADDR))
- return -ENOMEM;
-
- if (0 != alloc_tx_desc_ring(dev, priv->txbuffsize, priv->txbeaconcount,
- TX_BEACON_RING_ADDR))
- return -ENOMEM;
-
- if (request_irq(dev->irq, rtl8180_interrupt,
- IRQF_SHARED, dev->name, dev)) {
- DMESGE("Error allocating IRQ %d", dev->irq);
- return -1;
- } else {
- priv->irq = dev->irq;
- DMESG("IRQ %d", dev->irq);
- }
-
- return 0;
-}
-
-void rtl8180_no_hw_wep(struct net_device *dev)
-{
-}
-
-void rtl8180_set_hw_wep(struct net_device *dev)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- u8 pgreg;
- u8 security;
- u32 key0_word4;
-
- pgreg = read_nic_byte(dev, PGSELECT);
- write_nic_byte(dev, PGSELECT, pgreg & ~(1<<PGSELECT_PG_SHIFT));
-
- key0_word4 = read_nic_dword(dev, KEY0+4+4+4);
- key0_word4 &= ~0xff;
- key0_word4 |= priv->key0[3] & 0xff;
- write_nic_dword(dev, KEY0, (priv->key0[0]));
- write_nic_dword(dev, KEY0+4, (priv->key0[1]));
- write_nic_dword(dev, KEY0+4+4, (priv->key0[2]));
- write_nic_dword(dev, KEY0+4+4+4, (key0_word4));
-
- security = read_nic_byte(dev, SECURITY);
- security |= (1<<SECURITY_WEP_TX_ENABLE_SHIFT);
- security |= (1<<SECURITY_WEP_RX_ENABLE_SHIFT);
- security &= ~SECURITY_ENCRYP_MASK;
- security |= (SECURITY_ENCRYP_104<<SECURITY_ENCRYP_SHIFT);
-
- write_nic_byte(dev, SECURITY, security);
-
- DMESG("key %x %x %x %x", read_nic_dword(dev, KEY0+4+4+4),
- read_nic_dword(dev, KEY0+4+4), read_nic_dword(dev, KEY0+4),
- read_nic_dword(dev, KEY0));
-}
-
-
-void rtl8185_rf_pins_enable(struct net_device *dev)
-{
- write_nic_word(dev, RFPinsEnable, 0x1fff); /* | tmp); */
-}
-
-void rtl8185_set_anaparam2(struct net_device *dev, u32 a)
-{
- u8 conf3;
-
- rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
-
- conf3 = read_nic_byte(dev, CONFIG3);
- write_nic_byte(dev, CONFIG3, conf3 | (1<<CONFIG3_ANAPARAM_W_SHIFT));
- write_nic_dword(dev, ANAPARAM2, a);
-
- conf3 = read_nic_byte(dev, CONFIG3);
- write_nic_byte(dev, CONFIG3, conf3 & ~(1<<CONFIG3_ANAPARAM_W_SHIFT));
- rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
-}
-
-void rtl8180_set_anaparam(struct net_device *dev, u32 a)
-{
- u8 conf3;
-
- rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
-
- conf3 = read_nic_byte(dev, CONFIG3);
- write_nic_byte(dev, CONFIG3, conf3 | (1<<CONFIG3_ANAPARAM_W_SHIFT));
- write_nic_dword(dev, ANAPARAM, a);
-
- conf3 = read_nic_byte(dev, CONFIG3);
- write_nic_byte(dev, CONFIG3, conf3 & ~(1<<CONFIG3_ANAPARAM_W_SHIFT));
- rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
-}
-
-void rtl8185_tx_antenna(struct net_device *dev, u8 ant)
-{
- write_nic_byte(dev, TX_ANTENNA, ant);
- force_pci_posting(dev);
- mdelay(1);
-}
-
-static void rtl8185_write_phy(struct net_device *dev, u8 adr, u32 data)
-{
- u32 phyw;
-
- adr |= 0x80;
-
- phyw = ((data<<8) | adr);
-
- /* Note: we must write 0xff7c after 0x7d-0x7f to write BB register. */
- write_nic_byte(dev, 0x7f, ((phyw & 0xff000000) >> 24));
- write_nic_byte(dev, 0x7e, ((phyw & 0x00ff0000) >> 16));
- write_nic_byte(dev, 0x7d, ((phyw & 0x0000ff00) >> 8));
- write_nic_byte(dev, 0x7c, ((phyw & 0x000000ff)));
-}
-
-inline void write_phy_ofdm(struct net_device *dev, u8 adr, u32 data)
-{
- data = data & 0xff;
- rtl8185_write_phy(dev, adr, data);
-}
-
-void write_phy_cck(struct net_device *dev, u8 adr, u32 data)
-{
- data = data & 0xff;
- rtl8185_write_phy(dev, adr, data | 0x10000);
-}
-
-/*
- * This configures registers for beacon tx and enables it via
- * rtl8180_beacon_tx_enable(). rtl8180_beacon_tx_disable() might
- * be used to stop beacon transmission
- */
-void rtl8180_start_tx_beacon(struct net_device *dev)
-{
- u16 word;
-
- DMESG("Enabling beacon TX");
- rtl8180_prepare_beacon(dev);
- rtl8180_irq_disable(dev);
- rtl8180_beacon_tx_enable(dev);
-
- word = read_nic_word(dev, AtimWnd) & ~AtimWnd_AtimWnd;
- write_nic_word(dev, AtimWnd, word); /* word |= */
-
- word = read_nic_word(dev, BintrItv);
- word &= ~BintrItv_BintrItv;
- word |= 1000; /* priv->ieee80211->current_network.beacon_interval *
- * ((priv->txbeaconcount > 1)?(priv->txbeaconcount-1):1);
- * FIXME: check if correct ^^ worked with 0x3e8;
- */
- write_nic_word(dev, BintrItv, word);
-
- rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
-
- rtl8185b_irq_enable(dev);
-}
-
-static struct net_device_stats *rtl8180_stats(struct net_device *dev)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
-
- return &priv->ieee80211->stats;
-}
-
-/*
- * Change current and default preamble mode.
- */
-static bool MgntActSet_802_11_PowerSaveMode(struct r8180_priv *priv,
- enum rt_ps_mode rtPsMode)
-{
- /* Currently, we do not change power save mode on IBSS mode. */
- if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
- return false;
-
- priv->ieee80211->ps = rtPsMode;
-
- return true;
-}
-
-static void LeisurePSEnter(struct r8180_priv *priv)
-{
- if (priv->bLeisurePs)
- if (priv->ieee80211->ps == IEEE80211_PS_DISABLED)
- /* IEEE80211_PS_ENABLE */
- MgntActSet_802_11_PowerSaveMode(priv,
- IEEE80211_PS_MBCAST | IEEE80211_PS_UNICAST);
-}
-
-static void LeisurePSLeave(struct r8180_priv *priv)
-{
- if (priv->bLeisurePs)
- if (priv->ieee80211->ps != IEEE80211_PS_DISABLED)
- MgntActSet_802_11_PowerSaveMode(
- priv, IEEE80211_PS_DISABLED);
-}
-
-void rtl8180_hw_wakeup_wq(struct work_struct *work)
-{
- struct delayed_work *dwork = to_delayed_work(work);
- struct ieee80211_device *ieee = container_of(
- dwork, struct ieee80211_device, hw_wakeup_wq);
- struct net_device *dev = ieee->dev;
-
- rtl8180_hw_wakeup(dev);
-}
-
-void rtl8180_hw_sleep_wq(struct work_struct *work)
-{
- struct delayed_work *dwork = to_delayed_work(work);
- struct ieee80211_device *ieee = container_of(
- dwork, struct ieee80211_device, hw_sleep_wq);
- struct net_device *dev = ieee->dev;
-
- rtl8180_hw_sleep_down(dev);
-}
-
-static void MgntLinkKeepAlive(struct r8180_priv *priv)
-{
- if (priv->keepAliveLevel == 0)
- return;
-
- if (priv->ieee80211->state == IEEE80211_LINKED) {
- /*
- * Keep-Alive.
- */
-
- if ((priv->keepAliveLevel == 2) ||
- (priv->link_detect.last_num_tx_unicast ==
- priv->NumTxUnicast &&
- priv->link_detect.last_num_rx_unicast ==
- priv->ieee80211->NumRxUnicast)
- ) {
- priv->link_detect.idle_count++;
-
- /*
- * Send a Keep-Alive packet packet to AP if we had
- * been idle for a while.
- */
- if (priv->link_detect.idle_count >=
- KEEP_ALIVE_INTERVAL /
- CHECK_FOR_HANG_PERIOD - 1) {
- priv->link_detect.idle_count = 0;
- ieee80211_sta_ps_send_null_frame(
- priv->ieee80211, false);
- }
- } else {
- priv->link_detect.idle_count = 0;
- }
- priv->link_detect.last_num_tx_unicast = priv->NumTxUnicast;
- priv->link_detect.last_num_rx_unicast =
- priv->ieee80211->NumRxUnicast;
- }
-}
-
-void rtl8180_watch_dog(struct net_device *dev)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- bool bEnterPS = false;
- bool bBusyTraffic = false;
- u32 TotalRxNum = 0;
- u16 SlotIndex = 0;
- u16 i = 0;
- if (priv->ieee80211->actscanning == false) {
- if ((priv->ieee80211->iw_mode != IW_MODE_ADHOC) &&
- (priv->ieee80211->state == IEEE80211_NOLINK) &&
- (priv->ieee80211->beinretry == false) &&
- (priv->eRFPowerState == RF_ON))
- IPSEnter(dev);
- }
- if ((priv->ieee80211->state == IEEE80211_LINKED) &&
- (priv->ieee80211->iw_mode == IW_MODE_INFRA)) {
- SlotIndex = (priv->link_detect.slot_index++) %
- priv->link_detect.slot_num;
-
- priv->link_detect.rx_frame_num[SlotIndex] =
- priv->ieee80211->NumRxDataInPeriod +
- priv->ieee80211->NumRxBcnInPeriod;
-
- for (i = 0; i < priv->link_detect.slot_num; i++)
- TotalRxNum += priv->link_detect.rx_frame_num[i];
-
- if (TotalRxNum == 0) {
- priv->ieee80211->state = IEEE80211_ASSOCIATING;
- queue_work(priv->ieee80211->wq,
- &priv->ieee80211->associate_procedure_wq);
- }
- }
-
- MgntLinkKeepAlive(priv);
-
- LeisurePSLeave(priv);
-
- if (priv->ieee80211->state == IEEE80211_LINKED) {
- priv->link_detect.num_rx_ok_in_period =
- priv->ieee80211->NumRxDataInPeriod;
- if (priv->link_detect.num_rx_ok_in_period > 666 ||
- priv->link_detect.num_tx_ok_in_period > 666) {
- bBusyTraffic = true;
- }
- if ((priv->link_detect.num_rx_ok_in_period +
- priv->link_detect.num_tx_ok_in_period > 8)
- || (priv->link_detect.num_rx_ok_in_period > 2)) {
- bEnterPS = false;
- } else
- bEnterPS = true;
-
- if (bEnterPS)
- LeisurePSEnter(priv);
- else
- LeisurePSLeave(priv);
- } else
- LeisurePSLeave(priv);
- priv->link_detect.b_busy_traffic = bBusyTraffic;
- priv->link_detect.num_rx_ok_in_period = 0;
- priv->link_detect.num_tx_ok_in_period = 0;
- priv->ieee80211->NumRxDataInPeriod = 0;
- priv->ieee80211->NumRxBcnInPeriod = 0;
-}
-
-static int _rtl8180_up(struct net_device *dev)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
-
- priv->up = 1;
-
- DMESG("Bringing up iface");
- rtl8185b_adapter_start(dev);
- rtl8185b_rx_enable(dev);
- rtl8185b_tx_enable(dev);
- if (priv->bInactivePs) {
- if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
- IPSLeave(dev);
- }
- timer_rate_adaptive((unsigned long)dev);
- watch_dog_adaptive((unsigned long)dev);
- if (priv->bSwAntennaDiverity)
- SwAntennaDiversityTimerCallback(dev);
- ieee80211_softmac_start_protocol(priv->ieee80211);
- return 0;
-}
-
-static int rtl8180_open(struct net_device *dev)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- int ret;
-
- down(&priv->wx_sem);
- ret = rtl8180_up(dev);
- up(&priv->wx_sem);
- return ret;
-}
-
-int rtl8180_up(struct net_device *dev)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
-
- if (priv->up == 1)
- return -1;
-
- return _rtl8180_up(dev);
-}
-
-static int rtl8180_close(struct net_device *dev)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- int ret;
-
- down(&priv->wx_sem);
- ret = rtl8180_down(dev);
- up(&priv->wx_sem);
-
- return ret;
-}
-
-int rtl8180_down(struct net_device *dev)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
-
- if (priv->up == 0)
- return -1;
-
- priv->up = 0;
-
- ieee80211_softmac_stop_protocol(priv->ieee80211);
- /* FIXME */
- if (!netif_queue_stopped(dev))
- netif_stop_queue(dev);
- rtl8180_rtx_disable(dev);
- rtl8180_irq_disable(dev);
- del_timer_sync(&priv->watch_dog_timer);
- del_timer_sync(&priv->rateadapter_timer);
- cancel_delayed_work(&priv->ieee80211->rate_adapter_wq);
- cancel_delayed_work(&priv->ieee80211->hw_wakeup_wq);
- cancel_delayed_work(&priv->ieee80211->hw_sleep_wq);
- cancel_delayed_work(&priv->ieee80211->hw_dig_wq);
- cancel_delayed_work(&priv->ieee80211->tx_pw_wq);
- del_timer_sync(&priv->SwAntennaDiversityTimer);
- SetZebraRFPowerState8185(dev, RF_OFF);
- memset(&priv->ieee80211->current_network,
- 0, sizeof(struct ieee80211_network));
- priv->ieee80211->state = IEEE80211_NOLINK;
- return 0;
-}
-
-void rtl8180_restart_wq(struct work_struct *work)
-{
- struct r8180_priv *priv = container_of(
- work, struct r8180_priv, reset_wq);
- struct net_device *dev = priv->dev;
-
- down(&priv->wx_sem);
-
- rtl8180_commit(dev);
-
- up(&priv->wx_sem);
-}
-
-static void rtl8180_restart(struct net_device *dev)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
-
- schedule_work(&priv->reset_wq);
-}
-
-void rtl8180_commit(struct net_device *dev)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
-
- if (priv->up == 0)
- return;
-
- del_timer_sync(&priv->watch_dog_timer);
- del_timer_sync(&priv->rateadapter_timer);
- cancel_delayed_work(&priv->ieee80211->rate_adapter_wq);
- cancel_delayed_work(&priv->ieee80211->hw_wakeup_wq);
- cancel_delayed_work(&priv->ieee80211->hw_sleep_wq);
- cancel_delayed_work(&priv->ieee80211->hw_dig_wq);
- cancel_delayed_work(&priv->ieee80211->tx_pw_wq);
- del_timer_sync(&priv->SwAntennaDiversityTimer);
- ieee80211_softmac_stop_protocol(priv->ieee80211);
- rtl8180_irq_disable(dev);
- rtl8180_rtx_disable(dev);
- _rtl8180_up(dev);
-}
-
-static void r8180_set_multicast(struct net_device *dev)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- short promisc;
-
- promisc = (dev->flags & IFF_PROMISC) ? 1 : 0;
-
- if (promisc != priv->promisc)
- rtl8180_restart(dev);
-
- priv->promisc = promisc;
-}
-
-static int r8180_set_mac_adr(struct net_device *dev, void *mac)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- struct sockaddr *addr = mac;
-
- down(&priv->wx_sem);
-
- memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN);
-
- if (priv->ieee80211->iw_mode == IW_MODE_MASTER)
- memcpy(priv->ieee80211->current_network.bssid,
- dev->dev_addr, ETH_ALEN);
-
- if (priv->up) {
- rtl8180_down(dev);
- rtl8180_up(dev);
- }
-
- up(&priv->wx_sem);
-
- return 0;
-}
-
-/* based on ipw2200 driver */
-static int rtl8180_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- struct iwreq *wrq = (struct iwreq *) rq;
- int ret = -1;
-
- switch (cmd) {
- case RTL_IOCTL_WPA_SUPPLICANT:
- ret = ieee80211_wpa_supplicant_ioctl(
- priv->ieee80211, &wrq->u.data);
- return ret;
- default:
- return -EOPNOTSUPP;
- }
-
- return -EOPNOTSUPP;
-}
-
-static const struct net_device_ops rtl8180_netdev_ops = {
- .ndo_open = rtl8180_open,
- .ndo_stop = rtl8180_close,
- .ndo_get_stats = rtl8180_stats,
- .ndo_tx_timeout = rtl8180_restart,
- .ndo_do_ioctl = rtl8180_ioctl,
- .ndo_set_rx_mode = r8180_set_multicast,
- .ndo_set_mac_address = r8180_set_mac_adr,
- .ndo_validate_addr = eth_validate_addr,
- .ndo_change_mtu = eth_change_mtu,
- .ndo_start_xmit = ieee80211_rtl_xmit,
-};
-
-static int rtl8180_pci_probe(struct pci_dev *pdev,
- const struct pci_device_id *id)
-{
- unsigned long ioaddr = 0;
- struct net_device *dev = NULL;
- struct r8180_priv *priv = NULL;
- u8 unit = 0;
- int ret = -ENODEV;
-
- unsigned long pmem_start, pmem_len, pmem_flags;
-
- DMESG("Configuring chip resources");
-
- if (pci_enable_device(pdev)) {
- DMESG("Failed to enable PCI device");
- return -EIO;
- }
-
- pci_set_master(pdev);
- pci_set_dma_mask(pdev, 0xffffff00ULL);
- pci_set_consistent_dma_mask(pdev, 0xffffff00ULL);
- dev = alloc_ieee80211(sizeof(struct r8180_priv));
- if (!dev) {
- ret = -ENOMEM;
- goto fail_free;
- }
- priv = ieee80211_priv(dev);
- priv->ieee80211 = netdev_priv(dev);
-
- pci_set_drvdata(pdev, dev);
- SET_NETDEV_DEV(dev, &pdev->dev);
-
- priv = ieee80211_priv(dev);
- priv->pdev = pdev;
-
- pmem_start = pci_resource_start(pdev, 1);
- pmem_len = pci_resource_len(pdev, 1);
- pmem_flags = pci_resource_flags(pdev, 1);
-
- if (!(pmem_flags & IORESOURCE_MEM)) {
- DMESG("region #1 not a MMIO resource, aborting");
- goto fail;
- }
-
- if (!request_mem_region(pmem_start, pmem_len, RTL8180_MODULE_NAME)) {
- DMESG("request_mem_region failed!");
- goto fail;
- }
-
- ioaddr = (unsigned long)ioremap_nocache(pmem_start, pmem_len);
- if (ioaddr == (unsigned long)NULL) {
- DMESG("ioremap failed!");
- goto fail1;
- }
-
- dev->mem_start = ioaddr; /* shared mem start */
- dev->mem_end = ioaddr + pci_resource_len(pdev, 0); /* shared mem end */
-
- pci_read_config_byte(pdev, 0x05, &unit);
- pci_write_config_byte(pdev, 0x05, unit & (~0x04));
-
- dev->irq = pdev->irq;
- priv->irq = 0;
-
- dev->netdev_ops = &rtl8180_netdev_ops;
- dev->wireless_handlers = &r8180_wx_handlers_def;
-
- dev->type = ARPHRD_ETHER;
- dev->watchdog_timeo = HZ*3;
-
- if (dev_alloc_name(dev, ifname) < 0) {
- DMESG("Oops: devname already taken! Trying wlan%%d...\n");
- strcpy(ifname, "wlan%d");
- dev_alloc_name(dev, ifname);
- }
-
- if (rtl8180_init(dev) != 0) {
- DMESG("Initialization failed");
- goto fail1;
- }
-
- netif_carrier_off(dev);
-
- if (register_netdev(dev))
- goto fail1;
-
- rtl8180_proc_init_one(dev);
-
- DMESG("Driver probe completed\n");
- return 0;
-fail1:
- if (dev->mem_start != (unsigned long)NULL) {
- iounmap((void __iomem *)dev->mem_start);
- release_mem_region(pci_resource_start(pdev, 1),
- pci_resource_len(pdev, 1));
- }
-fail:
- if (dev) {
- if (priv->irq) {
- free_irq(dev->irq, dev);
- dev->irq = 0;
- }
- free_ieee80211(dev);
- }
-
-fail_free:
- pci_disable_device(pdev);
-
- DMESG("wlan driver load failed\n");
- return ret;
-}
-
-static void rtl8180_pci_remove(struct pci_dev *pdev)
-{
- struct r8180_priv *priv;
- struct net_device *dev = pci_get_drvdata(pdev);
-
- if (dev) {
- unregister_netdev(dev);
-
- priv = ieee80211_priv(dev);
-
- rtl8180_proc_remove_one(dev);
- rtl8180_down(dev);
- priv->rf_close(dev);
- rtl8180_reset(dev);
- mdelay(10);
-
- if (priv->irq) {
- DMESG("Freeing irq %d", dev->irq);
- free_irq(dev->irq, dev);
- priv->irq = 0;
- }
-
- free_rx_desc_ring(dev);
- free_tx_desc_rings(dev);
-
- if (dev->mem_start != (unsigned long)NULL) {
- iounmap((void __iomem *)dev->mem_start);
- release_mem_region(pci_resource_start(pdev, 1),
- pci_resource_len(pdev, 1));
- }
-
- free_ieee80211(dev);
- }
- pci_disable_device(pdev);
-
- DMESG("wlan driver removed\n");
-}
-
-static int __init rtl8180_pci_module_init(void)
-{
- int ret;
-
- ret = ieee80211_crypto_init();
- if (ret) {
- pr_err("ieee80211_crypto_init() failed %d\n", ret);
- return ret;
- }
- ret = ieee80211_crypto_tkip_init();
- if (ret) {
- pr_err("ieee80211_crypto_tkip_init() failed %d\n", ret);
- return ret;
- }
- ret = ieee80211_crypto_ccmp_init();
- if (ret) {
- pr_err("ieee80211_crypto_ccmp_init() failed %d\n", ret);
- return ret;
- }
- ret = ieee80211_crypto_wep_init();
- if (ret) {
- pr_err("ieee80211_crypto_wep_init() failed %d\n", ret);
- return ret;
- }
-
- pr_info("\nLinux kernel driver for RTL8180 / RTL8185 based WLAN cards\n");
- pr_info("Copyright (c) 2004-2005, Andrea Merello\n");
- DMESG("Initializing module");
- DMESG("Wireless extensions version %d", WIRELESS_EXT);
- rtl8180_proc_module_init();
-
- if (pci_register_driver(&rtl8180_pci_driver)) {
- DMESG("No device found");
- return -ENODEV;
- }
- return 0;
-}
-
-static void __exit rtl8180_pci_module_exit(void)
-{
- pci_unregister_driver(&rtl8180_pci_driver);
- rtl8180_proc_module_remove();
- ieee80211_crypto_tkip_exit();
- ieee80211_crypto_ccmp_exit();
- ieee80211_crypto_wep_exit();
- ieee80211_crypto_deinit();
- DMESG("Exiting");
-}
-
-static void rtl8180_try_wake_queue(struct net_device *dev, int pri)
-{
- unsigned long flags;
- short enough_desc;
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
- spin_lock_irqsave(&priv->tx_lock, flags);
- enough_desc = check_nic_enought_desc(dev, pri);
- spin_unlock_irqrestore(&priv->tx_lock, flags);
-
- if (enough_desc)
- ieee80211_rtl_wake_queue(priv->ieee80211);
-}
-
-static void rtl8180_tx_isr(struct net_device *dev, int pri, short error)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- u32 *tail; /* tail virtual addr */
- u32 *head; /* head virtual addr */
- u32 *begin; /* start of ring virtual addr */
- u32 *nicv; /* nic pointer virtual addr */
- u32 nic; /* nic pointer physical addr */
- u32 nicbegin; /* start of ring physical addr */
- unsigned long flag;
- /* physical addr are ok on 32 bits since we set DMA mask */
- int offs;
- int j, i;
- int hd;
- if (error)
- priv->stats.txretry++;
- spin_lock_irqsave(&priv->tx_lock, flag);
- switch (pri) {
- case MANAGE_PRIORITY:
- tail = priv->txmapringtail;
- begin = priv->txmapring;
- head = priv->txmapringhead;
- nic = read_nic_dword(dev, TX_MANAGEPRIORITY_RING_ADDR);
- nicbegin = priv->txmapringdma;
- break;
- case BK_PRIORITY:
- tail = priv->txbkpringtail;
- begin = priv->txbkpring;
- head = priv->txbkpringhead;
- nic = read_nic_dword(dev, TX_BKPRIORITY_RING_ADDR);
- nicbegin = priv->txbkpringdma;
- break;
- case BE_PRIORITY:
- tail = priv->txbepringtail;
- begin = priv->txbepring;
- head = priv->txbepringhead;
- nic = read_nic_dword(dev, TX_BEPRIORITY_RING_ADDR);
- nicbegin = priv->txbepringdma;
- break;
- case VI_PRIORITY:
- tail = priv->txvipringtail;
- begin = priv->txvipring;
- head = priv->txvipringhead;
- nic = read_nic_dword(dev, TX_VIPRIORITY_RING_ADDR);
- nicbegin = priv->txvipringdma;
- break;
- case VO_PRIORITY:
- tail = priv->txvopringtail;
- begin = priv->txvopring;
- head = priv->txvopringhead;
- nic = read_nic_dword(dev, TX_VOPRIORITY_RING_ADDR);
- nicbegin = priv->txvopringdma;
- break;
- case HI_PRIORITY:
- tail = priv->txhpringtail;
- begin = priv->txhpring;
- head = priv->txhpringhead;
- nic = read_nic_dword(dev, TX_HIGHPRIORITY_RING_ADDR);
- nicbegin = priv->txhpringdma;
- break;
-
- default:
- spin_unlock_irqrestore(&priv->tx_lock, flag);
- return;
- }
-
- nicv = (u32 *)((nic - nicbegin) + (u8 *)begin);
- if ((head <= tail && (nicv > tail || nicv < head)) ||
- (head > tail && (nicv > tail && nicv < head))) {
- DMESGW("nic has lost pointer");
- spin_unlock_irqrestore(&priv->tx_lock, flag);
- rtl8180_restart(dev);
- return;
- }
-
- /*
- * We check all the descriptors between the head and the nic,
- * but not the currently pointed by the nic (the next to be txed)
- * and the previous of the pointed (might be in process ??)
- */
- offs = (nic - nicbegin);
- offs = offs / 8 / 4;
- hd = (head - begin) / 8;
-
- if (offs >= hd)
- j = offs - hd;
- else
- j = offs + (priv->txringcount-1-hd);
-
- j -= 2;
- if (j < 0)
- j = 0;
-
- for (i = 0; i < j; i++) {
- if ((*head) & (1<<31))
- break;
- if (((*head)&(0x10000000)) != 0) {
- priv->CurrRetryCnt += (u16)((*head) & (0x000000ff));
- if (!error)
- priv->NumTxOkTotal++;
- }
-
- if (!error)
- priv->NumTxOkBytesTotal += (*(head+3)) & (0x00000fff);
-
- *head = *head & ~(1<<31);
-
- if ((head - begin)/8 == priv->txringcount-1)
- head = begin;
- else
- head += 8;
- }
-
- /*
- * The head has been moved to the last certainly TXed
- * (or at least processed by the nic) packet.
- * The driver take forcefully owning of all these packets
- * If the packet previous of the nic pointer has been
- * processed this doesn't matter: it will be checked
- * here at the next round. Anyway if no more packet are
- * TXed no memory leak occur at all.
- */
-
- switch (pri) {
- case MANAGE_PRIORITY:
- priv->txmapringhead = head;
-
- if (priv->ack_tx_to_ieee) {
- if (rtl8180_is_tx_queue_empty(dev)) {
- priv->ack_tx_to_ieee = 0;
- ieee80211_ps_tx_ack(priv->ieee80211, !error);
- }
- }
- break;
- case BK_PRIORITY:
- priv->txbkpringhead = head;
- break;
- case BE_PRIORITY:
- priv->txbepringhead = head;
- break;
- case VI_PRIORITY:
- priv->txvipringhead = head;
- break;
- case VO_PRIORITY:
- priv->txvopringhead = head;
- break;
- case HI_PRIORITY:
- priv->txhpringhead = head;
- break;
- }
-
- spin_unlock_irqrestore(&priv->tx_lock, flag);
-}
-
-static irqreturn_t rtl8180_interrupt(int irq, void *netdev)
-{
- struct net_device *dev = (struct net_device *) netdev;
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- unsigned long flags;
- u32 inta;
-
- /* We should return IRQ_NONE, but for now let me keep this */
- if (priv->irq_enabled == 0)
- return IRQ_HANDLED;
-
- spin_lock_irqsave(&priv->irq_th_lock, flags);
-
- /* ISR: 4bytes */
- inta = read_nic_dword(dev, ISR);
- write_nic_dword(dev, ISR, inta); /* reset int situation */
-
- priv->stats.shints++;
-
- if (!inta) {
- spin_unlock_irqrestore(&priv->irq_th_lock, flags);
- return IRQ_HANDLED;
- /*
- * most probably we can safely return IRQ_NONE,
- * but for now is better to avoid problems
- */
- }
-
- if (inta == 0xffff) {
- /* HW disappeared */
- spin_unlock_irqrestore(&priv->irq_th_lock, flags);
- return IRQ_HANDLED;
- }
-
- priv->stats.ints++;
-
- if (!netif_running(dev)) {
- spin_unlock_irqrestore(&priv->irq_th_lock, flags);
- return IRQ_HANDLED;
- }
-
- if (inta & ISR_TimeOut)
- write_nic_dword(dev, TimerInt, 0);
-
- if (inta & ISR_TBDOK)
- priv->stats.txbeacon++;
-
- if (inta & ISR_TBDER)
- priv->stats.txbeaconerr++;
-
- if (inta & IMR_TMGDOK)
- rtl8180_tx_isr(dev, MANAGE_PRIORITY, 0);
-
- if (inta & ISR_THPDER) {
- priv->stats.txhperr++;
- rtl8180_tx_isr(dev, HI_PRIORITY, 1);
- priv->ieee80211->stats.tx_errors++;
- }
-
- if (inta & ISR_THPDOK) { /* High priority tx ok */
- priv->link_detect.num_tx_ok_in_period++;
- priv->stats.txhpokint++;
- rtl8180_tx_isr(dev, HI_PRIORITY, 0);
- }
-
- if (inta & ISR_RER)
- priv->stats.rxerr++;
-
- if (inta & ISR_TBKDER) { /* corresponding to BK_PRIORITY */
- priv->stats.txbkperr++;
- priv->ieee80211->stats.tx_errors++;
- rtl8180_tx_isr(dev, BK_PRIORITY, 1);
- rtl8180_try_wake_queue(dev, BK_PRIORITY);
- }
-
- if (inta & ISR_TBEDER) { /* corresponding to BE_PRIORITY */
- priv->stats.txbeperr++;
- priv->ieee80211->stats.tx_errors++;
- rtl8180_tx_isr(dev, BE_PRIORITY, 1);
- rtl8180_try_wake_queue(dev, BE_PRIORITY);
- }
- if (inta & ISR_TNPDER) { /* corresponding to VO_PRIORITY */
- priv->stats.txnperr++;
- priv->ieee80211->stats.tx_errors++;
- rtl8180_tx_isr(dev, NORM_PRIORITY, 1);
- rtl8180_try_wake_queue(dev, NORM_PRIORITY);
- }
-
- if (inta & ISR_TLPDER) { /* corresponding to VI_PRIORITY */
- priv->stats.txlperr++;
- priv->ieee80211->stats.tx_errors++;
- rtl8180_tx_isr(dev, LOW_PRIORITY, 1);
- rtl8180_try_wake_queue(dev, LOW_PRIORITY);
- }
-
- if (inta & ISR_ROK) {
- priv->stats.rxint++;
- tasklet_schedule(&priv->irq_rx_tasklet);
- }
-
- if (inta & ISR_RQoSOK) {
- priv->stats.rxint++;
- tasklet_schedule(&priv->irq_rx_tasklet);
- }
-
- if (inta & ISR_BcnInt)
- rtl8180_prepare_beacon(dev);
-
- if (inta & ISR_RDU) {
- DMESGW("No RX descriptor available");
- priv->stats.rxrdu++;
- tasklet_schedule(&priv->irq_rx_tasklet);
- }
-
- if (inta & ISR_RXFOVW) {
- priv->stats.rxoverflow++;
- tasklet_schedule(&priv->irq_rx_tasklet);
- }
-
- if (inta & ISR_TXFOVW)
- priv->stats.txoverflow++;
-
- if (inta & ISR_TNPDOK) { /* Normal priority tx ok */
- priv->link_detect.num_tx_ok_in_period++;
- priv->stats.txnpokint++;
- rtl8180_tx_isr(dev, NORM_PRIORITY, 0);
- rtl8180_try_wake_queue(dev, NORM_PRIORITY);
- }
-
- if (inta & ISR_TLPDOK) { /* Low priority tx ok */
- priv->link_detect.num_tx_ok_in_period++;
- priv->stats.txlpokint++;
- rtl8180_tx_isr(dev, LOW_PRIORITY, 0);
- rtl8180_try_wake_queue(dev, LOW_PRIORITY);
- }
-
- if (inta & ISR_TBKDOK) { /* corresponding to BK_PRIORITY */
- priv->stats.txbkpokint++;
- priv->link_detect.num_tx_ok_in_period++;
- rtl8180_tx_isr(dev, BK_PRIORITY, 0);
- rtl8180_try_wake_queue(dev, BE_PRIORITY);
- }
-
- if (inta & ISR_TBEDOK) { /* corresponding to BE_PRIORITY */
- priv->stats.txbeperr++;
- priv->link_detect.num_tx_ok_in_period++;
- rtl8180_tx_isr(dev, BE_PRIORITY, 0);
- rtl8180_try_wake_queue(dev, BE_PRIORITY);
- }
- force_pci_posting(dev);
- spin_unlock_irqrestore(&priv->irq_th_lock, flags);
-
- return IRQ_HANDLED;
-}
-
-void rtl8180_irq_rx_tasklet(struct r8180_priv *priv)
-{
- rtl8180_rx(priv->dev);
-}
-
-void GPIOChangeRFWorkItemCallBack(struct work_struct *work)
-{
- struct ieee80211_device *ieee = container_of(
- work, struct ieee80211_device, GPIOChangeRFWorkItem.work);
- struct net_device *dev = ieee->dev;
- struct r8180_priv *priv = ieee80211_priv(dev);
- u8 btPSR;
- u8 btConfig0;
- enum rt_rf_power_state eRfPowerStateToSet;
- bool bActuallySet = false;
-
- char *argv[3];
- static char *RadioPowerPath = "/etc/acpi/events/RadioPower.sh";
- static char *envp[] = {"HOME=/", "TERM=linux",
- "PATH=/usr/bin:/bin", NULL};
- static int readf_count;
-
- readf_count = (readf_count+1)%0xffff;
- /* We should turn off LED before polling FF51[4]. */
-
- /* Turn off LED. */
- btPSR = read_nic_byte(dev, PSR);
- write_nic_byte(dev, PSR, (btPSR & ~BIT3));
-
- /* It need to delay 4us suggested */
- udelay(4);
-
- /* HW radio On/Off according to the value of FF51[4](config0) */
- btConfig0 = btPSR = read_nic_byte(dev, CONFIG0);
-
- eRfPowerStateToSet = (btConfig0 & BIT4) ? RF_ON : RF_OFF;
-
- /* Turn LED back on when radio enabled */
- if (eRfPowerStateToSet == RF_ON)
- write_nic_byte(dev, PSR, btPSR | BIT3);
-
- if ((priv->ieee80211->bHwRadioOff == true) &&
- (eRfPowerStateToSet == RF_ON)) {
- priv->ieee80211->bHwRadioOff = false;
- bActuallySet = true;
- } else if ((priv->ieee80211->bHwRadioOff == false) &&
- (eRfPowerStateToSet == RF_OFF)) {
- priv->ieee80211->bHwRadioOff = true;
- bActuallySet = true;
- }
-
- if (bActuallySet) {
- MgntActSet_RF_State(dev, eRfPowerStateToSet, RF_CHANGE_BY_HW);
-
- /* To update the UI status for Power status changed */
- if (priv->ieee80211->bHwRadioOff == true)
- argv[1] = "RFOFF";
- else
- argv[1] = "RFON";
- argv[0] = RadioPowerPath;
- argv[2] = NULL;
-
- call_usermodehelper(RadioPowerPath, argv, envp, UMH_WAIT_PROC);
- }
-}
-
-module_init(rtl8180_pci_module_init);
-module_exit(rtl8180_pci_module_exit);
diff --git a/drivers/staging/rtl8187se/r8180_dm.c b/drivers/staging/rtl8187se/r8180_dm.c
deleted file mode 100644
index 8c020e0..0000000
--- a/drivers/staging/rtl8187se/r8180_dm.c
+++ /dev/null
@@ -1,1139 +0,0 @@
-#include "r8180_dm.h"
-#include "r8180_hw.h"
-#include "r8180_93cx6.h"
-
- /* Return TRUE if we shall perform High Power Mechanism, FALSE otherwise. */
-#define RATE_ADAPTIVE_TIMER_PERIOD 300
-
-bool CheckHighPower(struct net_device *dev)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- struct ieee80211_device *ieee = priv->ieee80211;
-
- if (!priv->bRegHighPowerMechanism)
- return false;
-
- if (ieee->state == IEEE80211_LINKED_SCANNING)
- return false;
-
- return true;
-}
-
-/*
- * Description:
- * Update Tx power level if necessary.
- * See also DoRxHighPower() and SetTxPowerLevel8185() for reference.
- *
- * Note:
- * The reason why we udpate Tx power level here instead of DoRxHighPower()
- * is the number of IO to change Tx power is much more than channel TR switch
- * and they are related to OFDM and MAC registers.
- * So, we don't want to update it so frequently in per-Rx packet base.
- */
-static void DoTxHighPower(struct net_device *dev)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- u16 HiPwrUpperTh = 0;
- u16 HiPwrLowerTh = 0;
- u8 RSSIHiPwrUpperTh;
- u8 RSSIHiPwrLowerTh;
- u8 u1bTmp;
- char OfdmTxPwrIdx, CckTxPwrIdx;
-
- HiPwrUpperTh = priv->RegHiPwrUpperTh;
- HiPwrLowerTh = priv->RegHiPwrLowerTh;
-
- HiPwrUpperTh = HiPwrUpperTh * 10;
- HiPwrLowerTh = HiPwrLowerTh * 10;
- RSSIHiPwrUpperTh = priv->RegRSSIHiPwrUpperTh;
- RSSIHiPwrLowerTh = priv->RegRSSIHiPwrLowerTh;
-
- /* lzm add 080826 */
- OfdmTxPwrIdx = priv->chtxpwr_ofdm[priv->ieee80211->current_network.channel];
- CckTxPwrIdx = priv->chtxpwr[priv->ieee80211->current_network.channel];
-
- if ((priv->UndecoratedSmoothedSS > HiPwrUpperTh) ||
- (priv->bCurCCKPkt && (priv->CurCCKRSSI > RSSIHiPwrUpperTh))) {
- /* Stevenl suggested that degrade 8dbm in high power sate. 2007-12-04 Isaiah */
-
- priv->bToUpdateTxPwr = true;
- u1bTmp = read_nic_byte(dev, CCK_TXAGC);
-
- /* If it never enter High Power. */
- if (CckTxPwrIdx == u1bTmp) {
- u1bTmp = (u1bTmp > 16) ? (u1bTmp - 16) : 0; /* 8dbm */
- write_nic_byte(dev, CCK_TXAGC, u1bTmp);
-
- u1bTmp = read_nic_byte(dev, OFDM_TXAGC);
- u1bTmp = (u1bTmp > 16) ? (u1bTmp - 16) : 0; /* 8dbm */
- write_nic_byte(dev, OFDM_TXAGC, u1bTmp);
- }
-
- } else if ((priv->UndecoratedSmoothedSS < HiPwrLowerTh) &&
- (!priv->bCurCCKPkt || priv->CurCCKRSSI < RSSIHiPwrLowerTh)) {
- if (priv->bToUpdateTxPwr) {
- priv->bToUpdateTxPwr = false;
- /* SD3 required. */
- u1bTmp = read_nic_byte(dev, CCK_TXAGC);
- if (u1bTmp < CckTxPwrIdx) {
- write_nic_byte(dev, CCK_TXAGC, CckTxPwrIdx);
- }
-
- u1bTmp = read_nic_byte(dev, OFDM_TXAGC);
- if (u1bTmp < OfdmTxPwrIdx) {
- write_nic_byte(dev, OFDM_TXAGC, OfdmTxPwrIdx);
- }
- }
- }
-}
-
-
-/*
- * Description:
- * Callback function of UpdateTxPowerWorkItem.
- * Because of some event happened, e.g. CCX TPC, High Power Mechanism,
- * We update Tx power of current channel again.
- */
-void rtl8180_tx_pw_wq(struct work_struct *work)
-{
- struct delayed_work *dwork = to_delayed_work(work);
- struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, tx_pw_wq);
- struct net_device *dev = ieee->dev;
-
- DoTxHighPower(dev);
-}
-
-
-/*
- * Return TRUE if we shall perform DIG Mechanism, FALSE otherwise.
- */
-bool CheckDig(struct net_device *dev)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- struct ieee80211_device *ieee = priv->ieee80211;
-
- if (!priv->bDigMechanism)
- return false;
-
- if (ieee->state != IEEE80211_LINKED)
- return false;
-
- if ((priv->ieee80211->rate / 5) < 36) /* Schedule Dig under all OFDM rates. By Bruce, 2007-06-01. */
- return false;
- return true;
-}
-/*
- * Implementation of DIG for Zebra and Zebra2.
- */
-static void DIG_Zebra(struct net_device *dev)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- u16 CCKFalseAlarm, OFDMFalseAlarm;
- u16 OfdmFA1, OfdmFA2;
- int InitialGainStep = 7; /* The number of initial gain stages. */
- int LowestGainStage = 4; /* The capable lowest stage of performing dig workitem. */
- u32 AwakePeriodIn2Sec = 0;
-
- CCKFalseAlarm = (u16)(priv->FalseAlarmRegValue & 0x0000ffff);
- OFDMFalseAlarm = (u16)((priv->FalseAlarmRegValue >> 16) & 0x0000ffff);
- OfdmFA1 = 0x15;
- OfdmFA2 = ((u16)(priv->RegDigOfdmFaUpTh)) << 8;
-
- /* The number of initial gain steps is different, by Bruce, 2007-04-13. */
- if (priv->InitialGain == 0) { /* autoDIG */
- /* Advised from SD3 DZ */
- priv->InitialGain = 4; /* In 87B, m74dBm means State 4 (m82dBm) */
- }
- /* Advised from SD3 DZ */
- OfdmFA1 = 0x20;
-
-#if 1 /* lzm reserved 080826 */
- AwakePeriodIn2Sec = (2000 - priv->DozePeriodInPast2Sec);
- priv->DozePeriodInPast2Sec = 0;
-
- if (AwakePeriodIn2Sec) {
- OfdmFA1 = (u16)((OfdmFA1 * AwakePeriodIn2Sec) / 2000);
- OfdmFA2 = (u16)((OfdmFA2 * AwakePeriodIn2Sec) / 2000);
- } else {
- ;
- }
-#endif
-
- InitialGainStep = 8;
- LowestGainStage = priv->RegBModeGainStage; /* Lowest gain stage. */
-
- if (OFDMFalseAlarm > OfdmFA1) {
- if (OFDMFalseAlarm > OfdmFA2) {
- priv->DIG_NumberFallbackVote++;
- if (priv->DIG_NumberFallbackVote > 1) {
- /* serious OFDM False Alarm, need fallback */
- if (priv->InitialGain < InitialGainStep) {
- priv->InitialGainBackUp = priv->InitialGain;
-
- priv->InitialGain = (priv->InitialGain + 1);
- UpdateInitialGain(dev);
- }
- priv->DIG_NumberFallbackVote = 0;
- priv->DIG_NumberUpgradeVote = 0;
- }
- } else {
- if (priv->DIG_NumberFallbackVote)
- priv->DIG_NumberFallbackVote--;
- }
- priv->DIG_NumberUpgradeVote = 0;
- } else {
- if (priv->DIG_NumberFallbackVote)
- priv->DIG_NumberFallbackVote--;
- priv->DIG_NumberUpgradeVote++;
-
- if (priv->DIG_NumberUpgradeVote > 9) {
- if (priv->InitialGain > LowestGainStage) { /* In 87B, m78dBm means State 4 (m864dBm) */
- priv->InitialGainBackUp = priv->InitialGain;
-
- priv->InitialGain = (priv->InitialGain - 1);
- UpdateInitialGain(dev);
- }
- priv->DIG_NumberFallbackVote = 0;
- priv->DIG_NumberUpgradeVote = 0;
- }
- }
-}
-
-/*
- * Dispatch DIG implementation according to RF.
- */
-static void DynamicInitGain(struct net_device *dev)
-{
- DIG_Zebra(dev);
-}
-
-void rtl8180_hw_dig_wq(struct work_struct *work)
-{
- struct delayed_work *dwork = to_delayed_work(work);
- struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, hw_dig_wq);
- struct net_device *dev = ieee->dev;
- struct r8180_priv *priv = ieee80211_priv(dev);
-
- /* Read CCK and OFDM False Alarm. */
- priv->FalseAlarmRegValue = read_nic_dword(dev, CCK_FALSE_ALARM);
-
-
- /* Adjust Initial Gain dynamically. */
- DynamicInitGain(dev);
-
-}
-
-static int IncludedInSupportedRates(struct r8180_priv *priv, u8 TxRate)
-{
- u8 rate_len;
- u8 rate_ex_len;
- u8 RateMask = 0x7F;
- u8 idx;
- unsigned short Found = 0;
- u8 NaiveTxRate = TxRate&RateMask;
-
- rate_len = priv->ieee80211->current_network.rates_len;
- rate_ex_len = priv->ieee80211->current_network.rates_ex_len;
- for (idx = 0; idx < rate_len; idx++) {
- if ((priv->ieee80211->current_network.rates[idx] & RateMask) == NaiveTxRate) {
- Found = 1;
- goto found_rate;
- }
- }
- for (idx = 0; idx < rate_ex_len; idx++) {
- if ((priv->ieee80211->current_network.rates_ex[idx] & RateMask) == NaiveTxRate) {
- Found = 1;
- goto found_rate;
- }
- }
- return Found;
-found_rate:
- return Found;
-}
-
-/*
- * Get the Tx rate one degree up form the input rate in the supported rates.
- * Return the upgrade rate if it is successed, otherwise return the input rate.
- */
-static u8 GetUpgradeTxRate(struct net_device *dev, u8 rate)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- u8 UpRate;
-
- /* Upgrade 1 degree. */
- switch (rate) {
- case 108: /* Up to 54Mbps. */
- UpRate = 108;
- break;
-
- case 96: /* Up to 54Mbps. */
- UpRate = 108;
- break;
-
- case 72: /* Up to 48Mbps. */
- UpRate = 96;
- break;
-
- case 48: /* Up to 36Mbps. */
- UpRate = 72;
- break;
-
- case 36: /* Up to 24Mbps. */
- UpRate = 48;
- break;
-
- case 22: /* Up to 18Mbps. */
- UpRate = 36;
- break;
-
- case 11: /* Up to 11Mbps. */
- UpRate = 22;
- break;
-
- case 4: /* Up to 5.5Mbps. */
- UpRate = 11;
- break;
-
- case 2: /* Up to 2Mbps. */
- UpRate = 4;
- break;
-
- default:
- printk("GetUpgradeTxRate(): Input Tx Rate(%d) is undefined!\n", rate);
- return rate;
- }
- /* Check if the rate is valid. */
- if (IncludedInSupportedRates(priv, UpRate)) {
- return UpRate;
- } else {
- return rate;
- }
- return rate;
-}
-/*
- * Get the Tx rate one degree down form the input rate in the supported rates.
- * Return the degrade rate if it is successed, otherwise return the input rate.
- */
-
-static u8 GetDegradeTxRate(struct net_device *dev, u8 rate)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- u8 DownRate;
-
- /* Upgrade 1 degree. */
- switch (rate) {
- case 108: /* Down to 48Mbps. */
- DownRate = 96;
- break;
-
- case 96: /* Down to 36Mbps. */
- DownRate = 72;
- break;
-
- case 72: /* Down to 24Mbps. */
- DownRate = 48;
- break;
-
- case 48: /* Down to 18Mbps. */
- DownRate = 36;
- break;
-
- case 36: /* Down to 11Mbps. */
- DownRate = 22;
- break;
-
- case 22: /* Down to 5.5Mbps. */
- DownRate = 11;
- break;
-
- case 11: /* Down to 2Mbps. */
- DownRate = 4;
- break;
-
- case 4: /* Down to 1Mbps. */
- DownRate = 2;
- break;
-
- case 2: /* Down to 1Mbps. */
- DownRate = 2;
- break;
-
- default:
- printk("GetDegradeTxRate(): Input Tx Rate(%d) is undefined!\n", rate);
- return rate;
- }
- /* Check if the rate is valid. */
- if (IncludedInSupportedRates(priv, DownRate)) {
- return DownRate;
- } else {
- return rate;
- }
- return rate;
-}
-/*
- * Helper function to determine if specified data rate is
- * CCK rate.
- */
-
-static bool MgntIsCckRate(u16 rate)
-{
- bool bReturn = false;
-
- if ((rate <= 22) && (rate != 12) && (rate != 18)) {
- bReturn = true;
- }
-
- return bReturn;
-}
-/*
- * Description:
- * Tx Power tracking mechanism routine on 87SE.
- */
-void TxPwrTracking87SE(struct net_device *dev)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- u8 tmpu1Byte, CurrentThermal, Idx;
- char CckTxPwrIdx, OfdmTxPwrIdx;
-
- tmpu1Byte = read_nic_byte(dev, EN_LPF_CAL);
- CurrentThermal = (tmpu1Byte & 0xf0) >> 4; /*[ 7:4]: thermal meter indication. */
- CurrentThermal = (CurrentThermal > 0x0c) ? 0x0c : CurrentThermal;/* lzm add 080826 */
-
- if (CurrentThermal != priv->ThermalMeter) {
- /* Update Tx Power level on each channel. */
- for (Idx = 1; Idx < 15; Idx++) {
- CckTxPwrIdx = priv->chtxpwr[Idx];
- OfdmTxPwrIdx = priv->chtxpwr_ofdm[Idx];
-
- if (CurrentThermal > priv->ThermalMeter) {
- /* higher thermal meter. */
- CckTxPwrIdx += (CurrentThermal - priv->ThermalMeter) * 2;
- OfdmTxPwrIdx += (CurrentThermal - priv->ThermalMeter) * 2;
-
- if (CckTxPwrIdx > 35)
- CckTxPwrIdx = 35; /* Force TxPower to maximal index. */
- if (OfdmTxPwrIdx > 35)
- OfdmTxPwrIdx = 35;
- } else {
- /* lower thermal meter. */
- CckTxPwrIdx -= (priv->ThermalMeter - CurrentThermal) * 2;
- OfdmTxPwrIdx -= (priv->ThermalMeter - CurrentThermal) * 2;
-
- if (CckTxPwrIdx < 0)
- CckTxPwrIdx = 0;
- if (OfdmTxPwrIdx < 0)
- OfdmTxPwrIdx = 0;
- }
-
- /* Update TxPower level on CCK and OFDM resp. */
- priv->chtxpwr[Idx] = CckTxPwrIdx;
- priv->chtxpwr_ofdm[Idx] = OfdmTxPwrIdx;
- }
-
- /* Update TxPower level immediately. */
- rtl8225z2_SetTXPowerLevel(dev, priv->ieee80211->current_network.channel);
- }
- priv->ThermalMeter = CurrentThermal;
-}
-static void StaRateAdaptive87SE(struct net_device *dev)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- unsigned long CurrTxokCnt;
- u16 CurrRetryCnt;
- u16 CurrRetryRate;
- unsigned long CurrRxokCnt;
- bool bTryUp = false;
- bool bTryDown = false;
- u8 TryUpTh = 1;
- u8 TryDownTh = 2;
- u32 TxThroughput;
- long CurrSignalStrength;
- bool bUpdateInitialGain = false;
- u8 u1bOfdm = 0, u1bCck = 0;
- char OfdmTxPwrIdx, CckTxPwrIdx;
-
- priv->RateAdaptivePeriod = RATE_ADAPTIVE_TIMER_PERIOD;
-
-
- CurrRetryCnt = priv->CurrRetryCnt;
- CurrTxokCnt = priv->NumTxOkTotal - priv->LastTxokCnt;
- CurrRxokCnt = priv->ieee80211->NumRxOkTotal - priv->LastRxokCnt;
- CurrSignalStrength = priv->Stats_RecvSignalPower;
- TxThroughput = (u32)(priv->NumTxOkBytesTotal - priv->LastTxOKBytes);
- priv->LastTxOKBytes = priv->NumTxOkBytesTotal;
- priv->CurrentOperaRate = priv->ieee80211->rate / 5;
- /* 2 Compute retry ratio. */
- if (CurrTxokCnt > 0) {
- CurrRetryRate = (u16)(CurrRetryCnt * 100 / CurrTxokCnt);
- } else {
- /* It may be serious retry. To distinguish serious retry or no packets modified by Bruce */
- CurrRetryRate = (u16)(CurrRetryCnt * 100 / 1);
- }
-
- priv->LastRetryCnt = priv->CurrRetryCnt;
- priv->LastTxokCnt = priv->NumTxOkTotal;
- priv->LastRxokCnt = priv->ieee80211->NumRxOkTotal;
- priv->CurrRetryCnt = 0;
-
- /* 2No Tx packets, return to init_rate or not? */
- if (CurrRetryRate == 0 && CurrTxokCnt == 0) {
- /*
- * After 9 (30*300ms) seconds in this condition, we try to raise rate.
- */
- priv->TryupingCountNoData++;
-
- /* [TRC Dell Lab] Extend raised period from 4.5sec to 9sec, Isaiah 2008-02-15 18:00 */
- if (priv->TryupingCountNoData > 30) {
- priv->TryupingCountNoData = 0;
- priv->CurrentOperaRate = GetUpgradeTxRate(dev, priv->CurrentOperaRate);
- /* Reset Fail Record */
- priv->LastFailTxRate = 0;
- priv->LastFailTxRateSS = -200;
- priv->FailTxRateCount = 0;
- }
- goto SetInitialGain;
- } else {
- priv->TryupingCountNoData = 0; /*Reset trying up times. */
- }
-
-
- /*
- * For Netgear case, I comment out the following signal strength estimation,
- * which can results in lower rate to transmit when sample is NOT enough (e.g. PING request).
- *
- * Restructure rate adaptive as the following main stages:
- * (1) Add retry threshold in 54M upgrading condition with signal strength.
- * (2) Add the mechanism to degrade to CCK rate according to signal strength
- * and retry rate.
- * (3) Remove all Initial Gain Updates over OFDM rate. To avoid the complicated
- * situation, Initial Gain Update is upon on DIG mechanism except CCK rate.
- * (4) Add the mechanism of trying to upgrade tx rate.
- * (5) Record the information of upping tx rate to avoid trying upping tx rate constantly.
- *
- */
-
- /*
- * 11Mbps or 36Mbps
- * Check more times in these rate(key rates).
- */
- if (priv->CurrentOperaRate == 22 || priv->CurrentOperaRate == 72)
- TryUpTh += 9;
- /*
- * Let these rates down more difficult.
- */
- if (MgntIsCckRate(priv->CurrentOperaRate) || priv->CurrentOperaRate == 36)
- TryDownTh += 1;
-
- /* 1 Adjust Rate. */
- if (priv->bTryuping == true) {
- /* 2 For Test Upgrading mechanism
- * Note:
- * Sometimes the throughput is upon on the capability between the AP and NIC,
- * thus the low data rate does not improve the performance.
- * We randomly upgrade the data rate and check if the retry rate is improved.
- */
-
- /* Upgrading rate did not improve the retry rate, fallback to the original rate. */
- if ((CurrRetryRate > 25) && TxThroughput < priv->LastTxThroughput) {
- /*Not necessary raising rate, fall back rate. */
- bTryDown = true;
- } else {
- priv->bTryuping = false;
- }
- } else if (CurrSignalStrength > -47 && (CurrRetryRate < 50)) {
- /*
- * 2For High Power
- *
- * Return to highest data rate, if signal strength is good enough.
- * SignalStrength threshold(-50dbm) is for RTL8186.
- * Revise SignalStrength threshold to -51dbm.
- */
- /* Also need to check retry rate for safety, by Bruce, 2007-06-05. */
- if (priv->CurrentOperaRate != priv->ieee80211->current_network.HighestOperaRate) {
- bTryUp = true;
- /* Upgrade Tx Rate directly. */
- priv->TryupingCount += TryUpTh;
- }
-
- } else if (CurrTxokCnt > 9 && CurrTxokCnt < 100 && CurrRetryRate >= 600) {
- /*
- *2 For Serious Retry
- *
- * Traffic is not busy but our Tx retry is serious.
- */
- bTryDown = true;
- /* Let Rate Mechanism to degrade tx rate directly. */
- priv->TryDownCountLowData += TryDownTh;
- } else if (priv->CurrentOperaRate == 108) {
- /* 2For 54Mbps */
- /* Air Link */
- if ((CurrRetryRate > 26) && (priv->LastRetryRate > 25)) {
- bTryDown = true;
- }
- /* Cable Link */
- else if ((CurrRetryRate > 17) && (priv->LastRetryRate > 16) && (CurrSignalStrength > -72)) {
- bTryDown = true;
- }
-
- if (bTryDown && (CurrSignalStrength < -75)) /* cable link */
- priv->TryDownCountLowData += TryDownTh;
- } else if (priv->CurrentOperaRate == 96) {
- /* 2For 48Mbps */
- /* Air Link */
- if (((CurrRetryRate > 48) && (priv->LastRetryRate > 47))) {
- bTryDown = true;
- } else if (((CurrRetryRate > 21) && (priv->LastRetryRate > 20)) && (CurrSignalStrength > -74)) { /* Cable Link */
- /* Down to rate 36Mbps. */
- bTryDown = true;
- } else if ((CurrRetryRate > (priv->LastRetryRate + 50)) && (priv->FailTxRateCount > 2)) {
- bTryDown = true;
- priv->TryDownCountLowData += TryDownTh;
- } else if ((CurrRetryRate < 8) && (priv->LastRetryRate < 8)) { /* TO DO: need to consider (RSSI) */
- bTryUp = true;
- }
-
- if (bTryDown && (CurrSignalStrength < -75)) {
- priv->TryDownCountLowData += TryDownTh;
- }
- } else if (priv->CurrentOperaRate == 72) {
- /* 2For 36Mbps */
- if ((CurrRetryRate > 43) && (priv->LastRetryRate > 41)) {
- /* Down to rate 24Mbps. */
- bTryDown = true;
- } else if ((CurrRetryRate > (priv->LastRetryRate + 50)) && (priv->FailTxRateCount > 2)) {
- bTryDown = true;
- priv->TryDownCountLowData += TryDownTh;
- } else if ((CurrRetryRate < 15) && (priv->LastRetryRate < 16)) { /* TO DO: need to consider (RSSI) */
- bTryUp = true;
- }
-
- if (bTryDown && (CurrSignalStrength < -80))
- priv->TryDownCountLowData += TryDownTh;
-
- } else if (priv->CurrentOperaRate == 48) {
- /* 2For 24Mbps */
- /* Air Link */
- if (((CurrRetryRate > 63) && (priv->LastRetryRate > 62))) {
- bTryDown = true;
- } else if (((CurrRetryRate > 33) && (priv->LastRetryRate > 32)) && (CurrSignalStrength > -82)) { /* Cable Link */
- bTryDown = true;
- } else if ((CurrRetryRate > (priv->LastRetryRate + 50)) && (priv->FailTxRateCount > 2)) {
- bTryDown = true;
- priv->TryDownCountLowData += TryDownTh;
- } else if ((CurrRetryRate < 20) && (priv->LastRetryRate < 21)) { /* TO DO: need to consider (RSSI) */
- bTryUp = true;
- }
-
- if (bTryDown && (CurrSignalStrength < -82))
- priv->TryDownCountLowData += TryDownTh;
-
- } else if (priv->CurrentOperaRate == 36) {
- if (((CurrRetryRate > 85) && (priv->LastRetryRate > 86))) {
- bTryDown = true;
- } else if ((CurrRetryRate > (priv->LastRetryRate + 50)) && (priv->FailTxRateCount > 2)) {
- bTryDown = true;
- priv->TryDownCountLowData += TryDownTh;
- } else if ((CurrRetryRate < 22) && (priv->LastRetryRate < 23)) { /* TO DO: need to consider (RSSI) */
- bTryUp = true;
- }
- } else if (priv->CurrentOperaRate == 22) {
- /* 2For 11Mbps */
- if (CurrRetryRate > 95) {
- bTryDown = true;
- } else if ((CurrRetryRate < 29) && (priv->LastRetryRate < 30)) { /*TO DO: need to consider (RSSI) */
- bTryUp = true;
- }
- } else if (priv->CurrentOperaRate == 11) {
- /* 2For 5.5Mbps */
- if (CurrRetryRate > 149) {
- bTryDown = true;
- } else if ((CurrRetryRate < 60) && (priv->LastRetryRate < 65)) {
- bTryUp = true;
- }
- } else if (priv->CurrentOperaRate == 4) {
- /* 2For 2 Mbps */
- if ((CurrRetryRate > 99) && (priv->LastRetryRate > 99)) {
- bTryDown = true;
- } else if ((CurrRetryRate < 65) && (priv->LastRetryRate < 70)) {
- bTryUp = true;
- }
- } else if (priv->CurrentOperaRate == 2) {
- /* 2For 1 Mbps */
- if ((CurrRetryRate < 70) && (priv->LastRetryRate < 75)) {
- bTryUp = true;
- }
- }
-
- if (bTryUp && bTryDown)
- printk("StaRateAdaptive87B(): Tx Rate tried upping and downing simultaneously!\n");
-
- /* 1 Test Upgrading Tx Rate
- * Sometimes the cause of the low throughput (high retry rate) is the compatibility between the AP and NIC.
- * To test if the upper rate may cause lower retry rate, this mechanism randomly occurs to test upgrading tx rate.
- */
- if (!bTryUp && !bTryDown && (priv->TryupingCount == 0) && (priv->TryDownCountLowData == 0)
- && priv->CurrentOperaRate != priv->ieee80211->current_network.HighestOperaRate && priv->FailTxRateCount < 2) {
- if (jiffies % (CurrRetryRate + 101) == 0) {
- bTryUp = true;
- priv->bTryuping = true;
- }
- }
-
- /* 1 Rate Mechanism */
- if (bTryUp) {
- priv->TryupingCount++;
- priv->TryDownCountLowData = 0;
-
- /*
- * Check more times if we need to upgrade indeed.
- * Because the largest value of pHalData->TryupingCount is 0xFFFF and
- * the largest value of pHalData->FailTxRateCount is 0x14,
- * this condition will be satisfied at most every 2 min.
- */
-
- if ((priv->TryupingCount > (TryUpTh + priv->FailTxRateCount * priv->FailTxRateCount)) ||
- (CurrSignalStrength > priv->LastFailTxRateSS) || priv->bTryuping) {
- priv->TryupingCount = 0;
- /*
- * When transferring from CCK to OFDM, DIG is an important issue.
- */
- if (priv->CurrentOperaRate == 22)
- bUpdateInitialGain = true;
-
- /*
- * The difference in throughput between 48Mbps and 36Mbps is 8M.
- * So, we must be careful in this rate scale. Isaiah 2008-02-15.
- */
- if (((priv->CurrentOperaRate == 72) || (priv->CurrentOperaRate == 48) || (priv->CurrentOperaRate == 36)) &&
- (priv->FailTxRateCount > 2))
- priv->RateAdaptivePeriod = (RATE_ADAPTIVE_TIMER_PERIOD / 2);
-
- /* (1)To avoid upgrade frequently to the fail tx rate, add the FailTxRateCount into the threshold. */
- /* (2)If the signal strength is increased, it may be able to upgrade. */
-
- priv->CurrentOperaRate = GetUpgradeTxRate(dev, priv->CurrentOperaRate);
-
- if (priv->CurrentOperaRate == 36) {
- priv->bUpdateARFR = true;
- write_nic_word(dev, ARFR, 0x0F8F); /* bypass 12/9/6 */
- } else if (priv->bUpdateARFR) {
- priv->bUpdateARFR = false;
- write_nic_word(dev, ARFR, 0x0FFF); /* set 1M ~ 54Mbps. */
- }
-
- /* Update Fail Tx rate and count. */
- if (priv->LastFailTxRate != priv->CurrentOperaRate) {
- priv->LastFailTxRate = priv->CurrentOperaRate;
- priv->FailTxRateCount = 0;
- priv->LastFailTxRateSS = -200; /* Set lowest power. */
- }
- }
- } else {
- if (priv->TryupingCount > 0)
- priv->TryupingCount--;
- }
-
- if (bTryDown) {
- priv->TryDownCountLowData++;
- priv->TryupingCount = 0;
-
- /* Check if Tx rate can be degraded or Test trying upgrading should fallback. */
- if (priv->TryDownCountLowData > TryDownTh || priv->bTryuping) {
- priv->TryDownCountLowData = 0;
- priv->bTryuping = false;
- /* Update fail information. */
- if (priv->LastFailTxRate == priv->CurrentOperaRate) {
- priv->FailTxRateCount++;
- /* Record the Tx fail rate signal strength. */
- if (CurrSignalStrength > priv->LastFailTxRateSS)
- priv->LastFailTxRateSS = CurrSignalStrength;
- } else {
- priv->LastFailTxRate = priv->CurrentOperaRate;
- priv->FailTxRateCount = 1;
- priv->LastFailTxRateSS = CurrSignalStrength;
- }
- priv->CurrentOperaRate = GetDegradeTxRate(dev, priv->CurrentOperaRate);
-
- /* Reduce chariot training time at weak signal strength situation. SD3 ED demand. */
- if ((CurrSignalStrength < -80) && (priv->CurrentOperaRate > 72)) {
- priv->CurrentOperaRate = 72;
- }
-
- if (priv->CurrentOperaRate == 36) {
- priv->bUpdateARFR = true;
- write_nic_word(dev, ARFR, 0x0F8F); /* bypass 12/9/6 */
- } else if (priv->bUpdateARFR) {
- priv->bUpdateARFR = false;
- write_nic_word(dev, ARFR, 0x0FFF); /* set 1M ~ 54Mbps. */
- }
-
- /*
- * When it is CCK rate, it may need to update initial gain to receive lower power packets.
- */
- if (MgntIsCckRate(priv->CurrentOperaRate)) {
- bUpdateInitialGain = true;
- }
- }
- } else {
- if (priv->TryDownCountLowData > 0)
- priv->TryDownCountLowData--;
- }
-
- /*
- * Keep the Tx fail rate count to equal to 0x15 at most.
- * Reduce the fail count at least to 10 sec if tx rate is tending stable.
- */
- if (priv->FailTxRateCount >= 0x15 ||
- (!bTryUp && !bTryDown && priv->TryDownCountLowData == 0 && priv->TryupingCount && priv->FailTxRateCount > 0x6)) {
- priv->FailTxRateCount--;
- }
-
-
- OfdmTxPwrIdx = priv->chtxpwr_ofdm[priv->ieee80211->current_network.channel];
- CckTxPwrIdx = priv->chtxpwr[priv->ieee80211->current_network.channel];
-
- /* Mac0x9e increase 2 level in 36M~18M situation */
- if ((priv->CurrentOperaRate < 96) && (priv->CurrentOperaRate > 22)) {
- u1bCck = read_nic_byte(dev, CCK_TXAGC);
- u1bOfdm = read_nic_byte(dev, OFDM_TXAGC);
-
- /* case 1: Never enter High power */
- if (u1bCck == CckTxPwrIdx) {
- if (u1bOfdm != (OfdmTxPwrIdx + 2)) {
- priv->bEnhanceTxPwr = true;
- u1bOfdm = ((u1bOfdm + 2) > 35) ? 35 : (u1bOfdm + 2);
- write_nic_byte(dev, OFDM_TXAGC, u1bOfdm);
- }
- } else if (u1bCck < CckTxPwrIdx) {
- /* case 2: enter high power */
- if (!priv->bEnhanceTxPwr) {
- priv->bEnhanceTxPwr = true;
- u1bOfdm = ((u1bOfdm + 2) > 35) ? 35 : (u1bOfdm + 2);
- write_nic_byte(dev, OFDM_TXAGC, u1bOfdm);
- }
- }
- } else if (priv->bEnhanceTxPwr) { /* 54/48/11/5.5/2/1 */
- u1bCck = read_nic_byte(dev, CCK_TXAGC);
- u1bOfdm = read_nic_byte(dev, OFDM_TXAGC);
-
- /* case 1: Never enter High power */
- if (u1bCck == CckTxPwrIdx) {
- priv->bEnhanceTxPwr = false;
- write_nic_byte(dev, OFDM_TXAGC, OfdmTxPwrIdx);
- }
- /* case 2: enter high power */
- else if (u1bCck < CckTxPwrIdx) {
- priv->bEnhanceTxPwr = false;
- u1bOfdm = ((u1bOfdm - 2) > 0) ? (u1bOfdm - 2) : 0;
- write_nic_byte(dev, OFDM_TXAGC, u1bOfdm);
- }
- }
-
- /*
- * We need update initial gain when we set tx rate "from OFDM to CCK" or
- * "from CCK to OFDM".
- */
-SetInitialGain:
- if (bUpdateInitialGain) {
- if (MgntIsCckRate(priv->CurrentOperaRate)) { /* CCK */
- if (priv->InitialGain > priv->RegBModeGainStage) {
- priv->InitialGainBackUp = priv->InitialGain;
-
- if (CurrSignalStrength < -85) /* Low power, OFDM [0x17] = 26. */
- /* SD3 SYs suggest that CurrSignalStrength < -65, ofdm 0x17=26. */
- priv->InitialGain = priv->RegBModeGainStage;
-
- else if (priv->InitialGain > priv->RegBModeGainStage + 1)
- priv->InitialGain -= 2;
-
- else
- priv->InitialGain--;
-
- printk("StaRateAdaptive87SE(): update init_gain to index %d for date rate %d\n", priv->InitialGain, priv->CurrentOperaRate);
- UpdateInitialGain(dev);
- }
- } else { /* OFDM */
- if (priv->InitialGain < 4) {
- priv->InitialGainBackUp = priv->InitialGain;
-
- priv->InitialGain++;
- printk("StaRateAdaptive87SE(): update init_gain to index %d for date rate %d\n", priv->InitialGain, priv->CurrentOperaRate);
- UpdateInitialGain(dev);
- }
- }
- }
-
- /* Record the related info */
- priv->LastRetryRate = CurrRetryRate;
- priv->LastTxThroughput = TxThroughput;
- priv->ieee80211->rate = priv->CurrentOperaRate * 5;
-}
-
-void rtl8180_rate_adapter(struct work_struct *work)
-{
- struct delayed_work *dwork = to_delayed_work(work);
- struct ieee80211_device *ieee = container_of(dwork, struct ieee80211_device, rate_adapter_wq);
- struct net_device *dev = ieee->dev;
- StaRateAdaptive87SE(dev);
-}
-void timer_rate_adaptive(unsigned long data)
-{
- struct r8180_priv *priv = ieee80211_priv((struct net_device *)data);
- if (!priv->up) {
- return;
- }
- if ((priv->ieee80211->iw_mode != IW_MODE_MASTER)
- && (priv->ieee80211->state == IEEE80211_LINKED) &&
- (priv->ForcedDataRate == 0)) {
- queue_work(priv->ieee80211->wq, (void *)&priv->ieee80211->rate_adapter_wq);
- }
- priv->rateadapter_timer.expires = jiffies + MSECS(priv->RateAdaptivePeriod);
- add_timer(&priv->rateadapter_timer);
-}
-
-void SwAntennaDiversityRxOk8185(struct net_device *dev, u8 SignalStrength)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
- priv->AdRxOkCnt++;
-
- if (priv->AdRxSignalStrength != -1) {
- priv->AdRxSignalStrength = ((priv->AdRxSignalStrength * 7) + (SignalStrength * 3)) / 10;
- } else { /* Initialization case. */
- priv->AdRxSignalStrength = SignalStrength;
- }
-
- if (priv->LastRxPktAntenna) /* Main antenna. */
- priv->AdMainAntennaRxOkCnt++;
- else /* Aux antenna. */
- priv->AdAuxAntennaRxOkCnt++;
-}
- /* Change Antenna Switch. */
-bool SetAntenna8185(struct net_device *dev, u8 u1bAntennaIndex)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- bool bAntennaSwitched = false;
-
- switch (u1bAntennaIndex) {
- case 0:
- /* Mac register, main antenna */
- write_nic_byte(dev, ANTSEL, 0x03);
- /* base band */
- write_phy_cck(dev, 0x11, 0x9b); /* Config CCK RX antenna. */
- write_phy_ofdm(dev, 0x0d, 0x5c); /* Config OFDM RX antenna. */
-
- bAntennaSwitched = true;
- break;
-
- case 1:
- /* Mac register, aux antenna */
- write_nic_byte(dev, ANTSEL, 0x00);
- /* base band */
- write_phy_cck(dev, 0x11, 0xbb); /* Config CCK RX antenna. */
- write_phy_ofdm(dev, 0x0d, 0x54); /* Config OFDM RX antenna. */
-
- bAntennaSwitched = true;
-
- break;
-
- default:
- printk("SetAntenna8185: unknown u1bAntennaIndex(%d)\n", u1bAntennaIndex);
- break;
- }
-
- if (bAntennaSwitched)
- priv->CurrAntennaIndex = u1bAntennaIndex;
-
- return bAntennaSwitched;
-}
- /* Toggle Antenna switch. */
-bool SwitchAntenna(struct net_device *dev)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
- bool bResult;
-
- if (priv->CurrAntennaIndex == 0) {
- bResult = SetAntenna8185(dev, 1);
- } else {
- bResult = SetAntenna8185(dev, 0);
- }
-
- return bResult;
-}
-/*
- * Engine of SW Antenna Diversity mechanism.
- * Since 8187 has no Tx part information,
- * this implementation is only dependend on Rx part information.
- */
-void SwAntennaDiversity(struct net_device *dev)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- bool bSwCheckSS = false;
- if (bSwCheckSS) {
- priv->AdTickCount++;
-
- printk("(1) AdTickCount: %d, AdCheckPeriod: %d\n",
- priv->AdTickCount, priv->AdCheckPeriod);
- printk("(2) AdRxSignalStrength: %ld, AdRxSsThreshold: %ld\n",
- priv->AdRxSignalStrength, priv->AdRxSsThreshold);
- }
-
- /* Case 1. No Link. */
- if (priv->ieee80211->state != IEEE80211_LINKED) {
- priv->bAdSwitchedChecking = false;
- /* I switch antenna here to prevent any one of antenna is broken before link established, 2006.04.18, by rcnjko.. */
- SwitchAntenna(dev);
-
- /* Case 2. Linked but no packet receive.d */
- } else if (priv->AdRxOkCnt == 0) {
- priv->bAdSwitchedChecking = false;
- SwitchAntenna(dev);
-
- /* Case 3. Evaluate last antenna switch action and undo it if necessary. */
- } else if (priv->bAdSwitchedChecking == true) {
- priv->bAdSwitchedChecking = false;
-
- /* Adjust Rx signal strength threshold. */
- priv->AdRxSsThreshold = (priv->AdRxSignalStrength + priv->AdRxSsBeforeSwitched) / 2;
-
- priv->AdRxSsThreshold = (priv->AdRxSsThreshold > priv->AdMaxRxSsThreshold) ?
- priv->AdMaxRxSsThreshold : priv->AdRxSsThreshold;
- if (priv->AdRxSignalStrength < priv->AdRxSsBeforeSwitched) {
- /* Rx signal strength is not improved after we swtiched antenna. => Swich back. */
- /* Increase Antenna Diversity checking period due to bad decision. */
- priv->AdCheckPeriod *= 2;
- /* Increase Antenna Diversity checking period. */
- if (priv->AdCheckPeriod > priv->AdMaxCheckPeriod)
- priv->AdCheckPeriod = priv->AdMaxCheckPeriod;
-
- /* Wrong decision => switch back. */
- SwitchAntenna(dev);
- } else {
- /* Rx Signal Strength is improved. */
-
- /* Reset Antenna Diversity checking period to its min value. */
- priv->AdCheckPeriod = priv->AdMinCheckPeriod;
- }
-
- }
- /* Case 4. Evaluate if we shall switch antenna now. */
- /* Cause Table Speed is very fast in TRC Dell Lab, we check it every time. */
- else {
- priv->AdTickCount = 0;
-
- /*
- * <Roger_Notes> We evaluate RxOk counts for each antenna first and than
- * evaluate signal strength.
- * The following operation can overcome the disability of CCA on both two antennas
- * When signal strength was extremely low or high.
- * 2008.01.30.
- */
-
- /*
- * Evaluate RxOk count from each antenna if we shall switch default antenna now.
- */
- if ((priv->AdMainAntennaRxOkCnt < priv->AdAuxAntennaRxOkCnt)
- && (priv->CurrAntennaIndex == 0)) {
- /* We set Main antenna as default but RxOk count was less than Aux ones. */
-
- /* Switch to Aux antenna. */
- SwitchAntenna(dev);
- priv->bHWAdSwitched = true;
- } else if ((priv->AdAuxAntennaRxOkCnt < priv->AdMainAntennaRxOkCnt)
- && (priv->CurrAntennaIndex == 1)) {
- /* We set Aux antenna as default but RxOk count was less than Main ones. */
-
- /* Switch to Main antenna. */
- SwitchAntenna(dev);
- priv->bHWAdSwitched = true;
- } else {
- /* Default antenna is better. */
-
- /* Still need to check current signal strength. */
- priv->bHWAdSwitched = false;
- }
- /*
- * <Roger_Notes> We evaluate Rx signal strength ONLY when default antenna
- * didn't change by HW evaluation.
- * 2008.02.27.
- *
- * [TRC Dell Lab] SignalStrength is inaccuracy. Isaiah 2008-03-05
- * For example, Throughput of aux is better than main antenna(about 10M v.s 2M),
- * but AdRxSignalStrength is less than main.
- * Our guess is that main antenna have lower throughput and get many change
- * to receive more CCK packets(ex.Beacon) which have stronger SignalStrength.
- */
- if ((!priv->bHWAdSwitched) && (bSwCheckSS)) {
- /* Evaluate Rx signal strength if we shall switch antenna now. */
- if (priv->AdRxSignalStrength < priv->AdRxSsThreshold) {
- /* Rx signal strength is weak => Switch Antenna. */
- priv->AdRxSsBeforeSwitched = priv->AdRxSignalStrength;
- priv->bAdSwitchedChecking = true;
-
- SwitchAntenna(dev);
- } else {
- /* Rx signal strength is OK. */
- priv->bAdSwitchedChecking = false;
- /* Increase Rx signal strength threshold if necessary. */
- if ((priv->AdRxSignalStrength > (priv->AdRxSsThreshold + 10)) && /* Signal is much stronger than current threshold */
- priv->AdRxSsThreshold <= priv->AdMaxRxSsThreshold) { /* Current threhold is not yet reach upper limit. */
-
- priv->AdRxSsThreshold = (priv->AdRxSsThreshold + priv->AdRxSignalStrength) / 2;
- priv->AdRxSsThreshold = (priv->AdRxSsThreshold > priv->AdMaxRxSsThreshold) ?
- priv->AdMaxRxSsThreshold : priv->AdRxSsThreshold;/* +by amy 080312 */
- }
-
- /* Reduce Antenna Diversity checking period if possible. */
- if (priv->AdCheckPeriod > priv->AdMinCheckPeriod)
- priv->AdCheckPeriod /= 2;
- }
- }
- }
- /* Reset antenna diversity Rx related statistics. */
- priv->AdRxOkCnt = 0;
- priv->AdMainAntennaRxOkCnt = 0;
- priv->AdAuxAntennaRxOkCnt = 0;
-}
-
- /* Return TRUE if we shall perform Tx Power Tracking Mechanism, FALSE otherwise. */
-bool CheckTxPwrTracking(struct net_device *dev)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
- if (!priv->bTxPowerTrack)
- return false;
-
- /* if 87SE is in High Power , don't do Tx Power Tracking. asked by SD3 ED. 2008-08-08 Isaiah */
- if (priv->bToUpdateTxPwr)
- return false;
-
- return true;
-}
-
-
- /* Timer callback function of SW Antenna Diversity. */
-void SwAntennaDiversityTimerCallback(struct net_device *dev)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- enum rt_rf_power_state rtState;
-
- /* We do NOT need to switch antenna while RF is off. */
- rtState = priv->eRFPowerState;
- do {
- if (rtState == RF_OFF) {
- break;
- } else if (rtState == RF_SLEEP) {
- /* Don't access BB/RF under Disable PLL situation. */
- break;
- }
- SwAntennaDiversity(dev);
-
- } while (false);
-
- if (priv->up) {
- priv->SwAntennaDiversityTimer.expires = jiffies + MSECS(ANTENNA_DIVERSITY_TIMER_PERIOD);
- add_timer(&priv->SwAntennaDiversityTimer);
- }
-}
-
diff --git a/drivers/staging/rtl8187se/r8180_dm.h b/drivers/staging/rtl8187se/r8180_dm.h
deleted file mode 100644
index cb4046f..0000000
--- a/drivers/staging/rtl8187se/r8180_dm.h
+++ /dev/null
@@ -1,23 +0,0 @@
-#ifndef R8180_DM_H
-#define R8180_DM_H
-
-#include "r8180.h"
-/* #include "r8180_hw.h" */
-/* #include "r8180_93cx6.h" */
-void SwAntennaDiversityRxOk8185(struct net_device *dev, u8 SignalStrength);
-bool SetAntenna8185(struct net_device *dev, u8 u1bAntennaIndex);
-bool SwitchAntenna(struct net_device *dev);
-void SwAntennaDiversity(struct net_device *dev);
-void SwAntennaDiversityTimerCallback(struct net_device *dev);
-bool CheckDig(struct net_device *dev);
-bool CheckHighPower(struct net_device *dev);
-void rtl8180_hw_dig_wq(struct work_struct *work);
-void rtl8180_tx_pw_wq(struct work_struct *work);
-void rtl8180_rate_adapter(struct work_struct *work);
-void TxPwrTracking87SE(struct net_device *dev);
-bool CheckTxPwrTracking(struct net_device *dev);
-void rtl8180_rate_adapter(struct work_struct *work);
-void timer_rate_adaptive(unsigned long data);
-
-
-#endif
diff --git a/drivers/staging/rtl8187se/r8180_hw.h b/drivers/staging/rtl8187se/r8180_hw.h
deleted file mode 100644
index e59d74f..0000000
--- a/drivers/staging/rtl8187se/r8180_hw.h
+++ /dev/null
@@ -1,588 +0,0 @@
-/*
- This is part of rtl8180 OpenSource driver.
- 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 Intel Pro Wireless
- 2100 GPL driver.
-
- We want to tanks the Authors of those projects
- and the Ndiswrapper project Authors.
-*/
-
-/* Mariusz Matuszek added full registers definition with Realtek's name */
-
-/* this file contains register definitions for the rtl8180 MAC controller */
-#ifndef R8180_HW
-#define R8180_HW
-
-
-#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 BIT9 0x00000200
-#define BIT11 0x00000800
-#define BIT13 0x00002000
-#define BIT15 0x00008000
-#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
-
-#define MAX_SLEEP_TIME (10000)
-#define MIN_SLEEP_TIME (50)
-
-#define BB_HOST_BANG_EN (1<<2)
-#define BB_HOST_BANG_CLK (1<<1)
-
-#define MAC0 0
-#define MAC4 4
-
-#define CMD 0x37
-#define CMD_RST_SHIFT 4
-#define CMD_RX_ENABLE_SHIFT 3
-#define CMD_TX_ENABLE_SHIFT 2
-
-#define EPROM_CMD 0x50
-#define EPROM_CMD_RESERVED_MASK ((1<<5)|(1<<4))
-#define EPROM_CMD_OPERATING_MODE_SHIFT 6
-#define EPROM_CMD_OPERATING_MODE_MASK ((1<<7)|(1<<6))
-#define EPROM_CMD_CONFIG 0x3
-#define EPROM_CMD_NORMAL 0
-#define EPROM_CMD_LOAD 1
-#define EPROM_CMD_PROGRAM 2
-#define EPROM_CS_SHIFT 3
-#define EPROM_CK_SHIFT 2
-#define EPROM_W_SHIFT 1
-#define EPROM_R_SHIFT 0
-#define CONFIG2_DMA_POLLING_MODE_SHIFT 3
-
-#define INTA_TXOVERFLOW (1<<15)
-#define INTA_TIMEOUT (1<<14)
-#define INTA_HIPRIORITYDESCERR (1<<9)
-#define INTA_HIPRIORITYDESCOK (1<<8)
-#define INTA_NORMPRIORITYDESCERR (1<<7)
-#define INTA_NORMPRIORITYDESCOK (1<<6)
-#define INTA_RXOVERFLOW (1<<5)
-#define INTA_RXDESCERR (1<<4)
-#define INTA_LOWPRIORITYDESCERR (1<<3)
-#define INTA_LOWPRIORITYDESCOK (1<<2)
-#define INTA_RXOK (1)
-#define INTA_MASK 0x3c
-
-#define RXRING_ADDR 0xe4 /* page 0 */
-#define PGSELECT 0x5e
-#define PGSELECT_PG_SHIFT 0
-#define RX_CONF 0x44
-#define MAC_FILTER_MASK ((1<<0) | (1<<1) | (1<<2) | (1<<3) | (1<<5) | \
-(1<<12) | (1<<18) | (1<<19) | (1<<20) | (1<<21) | (1<<22) | (1<<23))
-#define RX_CHECK_BSSID_SHIFT 23
-#define ACCEPT_PWR_FRAME_SHIFT 22
-#define ACCEPT_MNG_FRAME_SHIFT 20
-#define ACCEPT_CTL_FRAME_SHIFT 19
-#define ACCEPT_DATA_FRAME_SHIFT 18
-#define ACCEPT_ICVERR_FRAME_SHIFT 12
-#define ACCEPT_CRCERR_FRAME_SHIFT 5
-#define ACCEPT_BCAST_FRAME_SHIFT 3
-#define ACCEPT_MCAST_FRAME_SHIFT 2
-#define ACCEPT_ALLMAC_FRAME_SHIFT 0
-#define ACCEPT_NICMAC_FRAME_SHIFT 1
-
-#define RX_FIFO_THRESHOLD_MASK ((1<<13) | (1<<14) | (1<<15))
-#define RX_FIFO_THRESHOLD_SHIFT 13
-#define RX_FIFO_THRESHOLD_NONE 7
-#define RX_AUTORESETPHY_SHIFT 28
-
-#define TX_CONF 0x40
-#define TX_CONF_HEADER_AUTOICREMENT_SHIFT 30
-#define TX_LOOPBACK_SHIFT 17
-#define TX_LOOPBACK_NONE 0
-#define TX_LOOPBACK_CONTINUE 3
-#define TX_LOOPBACK_MASK ((1<<17)|(1<<18))
-#define TX_DPRETRY_SHIFT 0
-#define R8180_MAX_RETRY 255
-#define TX_RTSRETRY_SHIFT 8
-#define TX_NOICV_SHIFT 19
-#define TX_NOCRC_SHIFT 16
-#define TX_DMA_POLLING 0xd9
-#define TX_DMA_POLLING_BEACON_SHIFT 7
-#define TX_DMA_POLLING_HIPRIORITY_SHIFT 6
-#define TX_DMA_POLLING_NORMPRIORITY_SHIFT 5
-#define TX_DMA_POLLING_LOWPRIORITY_SHIFT 4
-#define TX_MANAGEPRIORITY_RING_ADDR 0x0C
-#define TX_BKPRIORITY_RING_ADDR 0x10
-#define TX_BEPRIORITY_RING_ADDR 0x14
-#define TX_VIPRIORITY_RING_ADDR 0x20
-#define TX_VOPRIORITY_RING_ADDR 0x24
-#define TX_HIGHPRIORITY_RING_ADDR 0x28
-#define MAX_RX_DMA_MASK ((1<<8) | (1<<9) | (1<<10))
-#define MAX_RX_DMA_2048 7
-#define MAX_RX_DMA_1024 6
-#define MAX_RX_DMA_SHIFT 10
-#define INT_TIMEOUT 0x48
-#define CONFIG3_CLKRUN_SHIFT 2
-#define CONFIG3_ANAPARAM_W_SHIFT 6
-#define ANAPARAM 0x54
-#define BEACON_INTERVAL 0x70
-#define BEACON_INTERVAL_MASK ((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)| \
-(1<<6)|(1<<7)|(1<<8)|(1<<9))
-#define ATIM_MASK ((1<<0)|(1<<1)|(1<<2)|(1<<3)|(1<<4)|(1<<5)|(1<<6)|(1<<7)| \
-(1<<8)|(1<<9))
-#define ATIM 0x72
-#define EPROM_CS_SHIFT 3
-#define EPROM_CK_SHIFT 2
-#define PHY_ADR 0x7c
-#define SECURITY 0x5f /* 1209 this is sth wrong */
-#define SECURITY_WEP_TX_ENABLE_SHIFT 1
-#define SECURITY_WEP_RX_ENABLE_SHIFT 0
-#define SECURITY_ENCRYP_104 1
-#define SECURITY_ENCRYP_SHIFT 4
-#define SECURITY_ENCRYP_MASK ((1<<4)|(1<<5))
-#define KEY0 0x90 /* 1209 this is sth wrong */
-#define CONFIG2_ANTENNA_SHIFT 6
-#define TX_BEACON_RING_ADDR 0x4c
-#define CONFIG0_WEP40_SHIFT 7
-#define CONFIG0_WEP104_SHIFT 6
-#define AGCRESET_SHIFT 5
-
-
-
-/*
- * Operational registers offsets in PCI (I/O) space.
- * RealTek names are used.
- */
-
-#define TSFTR 0x0018
-
-#define TLPDA 0x0020
-
-#define BSSID 0x002E
-
-#define CR 0x0037
-
-#define RF_SW_CONFIG 0x8 /* store data which is transmitted to RF for driver */
-#define RF_SW_CFG_SI BIT1
-#define EIFS 0x2D /* Extended InterFrame Space Timer, in unit of 4 us. */
-
-#define BRSR 0x34 /* Basic rate set */
-
-#define IMR 0x006C
-#define ISR 0x003C
-
-#define TCR 0x0040
-
-#define RCR 0x0044
-
-#define TimerInt 0x0048
-
-#define CR9346 0x0050
-
-#define CONFIG0 0x0051
-#define CONFIG2 0x0053
-
-#define MSR 0x0058
-
-#define CONFIG3 0x0059
-#define CONFIG4 0x005A
- /* SD3 szuyitasi: Mac0x57= CC -> B0 Mac0x60= D1 -> C6 */
- /* Mac0x60 = 0x000004C6 power save parameters */
- #define ANAPARM_ASIC_ON 0xB0054D00
- #define ANAPARM2_ASIC_ON 0x000004C6
-
- #define ANAPARM_ON ANAPARM_ASIC_ON
- #define ANAPARM2_ON ANAPARM2_ASIC_ON
-
-#define TESTR 0x005B
-
-#define PSR 0x005E
-
-#define BcnItv 0x0070
-
-#define AtimWnd 0x0072
-
-#define BintrItv 0x0074
-
-#define PhyAddr 0x007C
-#define PhyDataR 0x007E
-
-/* following are for rtl8185 */
-#define RFPinsOutput 0x80
-#define RFPinsEnable 0x82
-#define RF_TIMING 0x8c
-#define RFPinsSelect 0x84
-#define ANAPARAM2 0x60
-#define RF_PARA 0x88
-#define RFPinsInput 0x86
-#define GP_ENABLE 0x90
-#define GPIO 0x91
-#define SW_CONTROL_GPIO 0x400
-#define TX_ANTENNA 0x9f
-#define TX_GAIN_OFDM 0x9e
-#define TX_GAIN_CCK 0x9d
-#define WPA_CONFIG 0xb0
-#define TX_AGC_CTL 0x9c
-#define TX_AGC_CTL_PERPACKET_GAIN_SHIFT 0
-#define TX_AGC_CTL_PERPACKET_ANTSEL_SHIFT 1
-#define TX_AGC_CTL_FEEDBACK_ANT 2
-#define RESP_RATE 0x34
-#define SIFS 0xb4
-#define DIFS 0xb5
-
-#define SLOT 0xb6
-#define CW_CONF 0xbc
-#define CW_CONF_PERPACKET_RETRY_SHIFT 1
-#define CW_CONF_PERPACKET_CW_SHIFT 0
-#define CW_VAL 0xbd
-#define MAX_RESP_RATE_SHIFT 4
-#define MIN_RESP_RATE_SHIFT 0
-#define RATE_FALLBACK 0xbe
-
-#define CONFIG5 0x00D8
-
-#define PHYPR 0xDA /* 0xDA - 0x0B PHY Parameter Register. */
-
-#define FEMR 0x1D4 /* Function Event Mask register */
-
-#define FFER 0x00FC
-#define FFER_END 0x00FF
-
-
-
-/*
- * Bitmasks for specific register functions.
- * Names are derived from the register name and function name.
- *
- * <REGISTER>_<FUNCTION>[<bit>]
- *
- * this leads to some awkward names...
- */
-
-#define BRSR_BPLCP ((1 << 8))
-#define BRSR_MBR ((1 << 1)|(1 << 0))
-#define BRSR_MBR_8185 ((1 << 11)|(1 << 10)|(1 << 9)|(1 << 8)|(1 << 7)|(1 << 6)|(1 << 5)|(1 << 4)|(1 << 3)|(1 << 2)|(1 << 1)|(1 << 0))
-#define BRSR_MBR0 ((1 << 0))
-#define BRSR_MBR1 ((1 << 1))
-
-#define CR_RST ((1 << 4))
-#define CR_RE ((1 << 3))
-#define CR_TE ((1 << 2))
-#define CR_MulRW ((1 << 0))
-
-#define IMR_Dot11hInt ((1 << 25)) /*802.11h Measurement Interrupt */
-#define IMR_BcnDmaInt ((1 << 24)) /*Beacon DMA Interrupt */ /*What differenct between BcnDmaInt and BcnInt??? */
-#define IMR_WakeInt ((1 << 23)) /*Wake Up Interrupt */
-#define IMR_TXFOVW ((1 << 22)) /*Tx FIFO Overflow Interrupt */
-#define IMR_TimeOut1 ((1 << 21)) /*Time Out Interrupt 1 */
-#define IMR_BcnInt ((1 << 20)) /*Beacon Time out Interrupt */
-#define IMR_ATIMInt ((1 << 19)) /*ATIM Time Out Interrupt */
-#define IMR_TBDER ((1 << 18)) /*Tx Beacon Descriptor Error Interrupt */
-#define IMR_TBDOK ((1 << 17)) /*Tx Beacon Descriptor OK Interrupt */
-#define IMR_THPDER ((1 << 16)) /*Tx High Priority Descriptor Error Interrupt */
-#define IMR_THPDOK ((1 << 15)) /*Tx High Priority Descriptor OK Interrupt */
-#define IMR_TVODER ((1 << 14)) /*Tx AC_VO Descriptor Error Interrupt */
-#define IMR_TVODOK ((1 << 13)) /*Tx AC_VO Descriptor OK Interrupt */
-#define IMR_FOVW ((1 << 12)) /*Rx FIFO Overflow Interrupt */
-#define IMR_RDU ((1 << 11)) /*Rx Descriptor Unavailable Interrupt */
-#define IMR_TVIDER ((1 << 10)) /*Tx AC_VI Descriptor Error Interrupt */
-#define IMR_TVIDOK ((1 << 9)) /*Tx AC_VI Descriptor OK Interrupt */
-#define IMR_RER ((1 << 8)) /*Rx Error Interrupt */
-#define IMR_ROK ((1 << 7)) /*Receive OK Interrupt */
-#define IMR_TBEDER ((1 << 6)) /*Tx AC_BE Descriptor Error Interrupt */
-#define IMR_TBEDOK ((1 << 5)) /*Tx AC_BE Descriptor OK Interrupt */
-#define IMR_TBKDER ((1 << 4)) /*Tx AC_BK Descriptor Error Interrupt */
-#define IMR_TBKDOK ((1 << 3)) /*Tx AC_BK Descriptor OK Interrupt */
-#define IMR_RQoSOK ((1 << 2)) /*Rx QoS OK Interrupt */
-#define IMR_TimeOut2 ((1 << 1)) /*Time Out Interrupt 2 */
-#define IMR_TimeOut3 ((1 << 0)) /*Time Out Interrupt 3 */
-#define IMR_TMGDOK ((1 << 30))
-#define ISR_Dot11hInt ((1 << 25)) /*802.11h Measurement Interrupt */
-#define ISR_BcnDmaInt ((1 << 24)) /*Beacon DMA Interrupt */ /*What differenct between BcnDmaInt and BcnInt??? */
-#define ISR_WakeInt ((1 << 23)) /*Wake Up Interrupt */
-#define ISR_TXFOVW ((1 << 22)) /*Tx FIFO Overflow Interrupt */
-#define ISR_TimeOut1 ((1 << 21)) /*Time Out Interrupt 1 */
-#define ISR_BcnInt ((1 << 20)) /*Beacon Time out Interrupt */
-#define ISR_ATIMInt ((1 << 19)) /*ATIM Time Out Interrupt */
-#define ISR_TBDER ((1 << 18)) /*Tx Beacon Descriptor Error Interrupt */
-#define ISR_TBDOK ((1 << 17)) /*Tx Beacon Descriptor OK Interrupt */
-#define ISR_THPDER ((1 << 16)) /*Tx High Priority Descriptor Error Interrupt */
-#define ISR_THPDOK ((1 << 15)) /*Tx High Priority Descriptor OK Interrupt */
-#define ISR_TVODER ((1 << 14)) /*Tx AC_VO Descriptor Error Interrupt */
-#define ISR_TVODOK ((1 << 13)) /*Tx AC_VO Descriptor OK Interrupt */
-#define ISR_FOVW ((1 << 12)) /*Rx FIFO Overflow Interrupt */
-#define ISR_RDU ((1 << 11)) /*Rx Descriptor Unavailable Interrupt */
-#define ISR_TVIDER ((1 << 10)) /*Tx AC_VI Descriptor Error Interrupt */
-#define ISR_TVIDOK ((1 << 9)) /*Tx AC_VI Descriptor OK Interrupt */
-#define ISR_RER ((1 << 8)) /*Rx Error Interrupt */
-#define ISR_ROK ((1 << 7)) /*Receive OK Interrupt */
-#define ISR_TBEDER ((1 << 6)) /*Tx AC_BE Descriptor Error Interrupt */
-#define ISR_TBEDOK ((1 << 5)) /*Tx AC_BE Descriptor OK Interrupt */
-#define ISR_TBKDER ((1 << 4)) /*Tx AC_BK Descriptor Error Interrupt */
-#define ISR_TBKDOK ((1 << 3)) /*Tx AC_BK Descriptor OK Interrupt */
-#define ISR_RQoSOK ((1 << 2)) /*Rx QoS OK Interrupt */
-#define ISR_TimeOut2 ((1 << 1)) /*Time Out Interrupt 2 */
-#define ISR_TimeOut3 ((1 << 0)) /*Time Out Interrupt 3 */
-
-/* these definition is used for Tx/Rx test temporarily */
-#define ISR_TLPDER ISR_TVIDER
-#define ISR_TLPDOK ISR_TVIDOK
-#define ISR_TNPDER ISR_TVODER
-#define ISR_TNPDOK ISR_TVODOK
-#define ISR_TimeOut ISR_TimeOut1
-#define ISR_RXFOVW ISR_FOVW
-
-
-#define HW_VERID_R8180_F 3
-#define HW_VERID_R8180_ABCD 2
-#define HW_VERID_R8185_ABC 4
-#define HW_VERID_R8185_D 5
-#define HW_VERID_R8185B_B 6
-
-#define TCR_CWMIN ((1 << 31))
-#define TCR_SWSEQ ((1 << 30))
-#define TCR_HWVERID_MASK ((1 << 27)|(1 << 26)|(1 << 25))
-#define TCR_HWVERID_SHIFT 25
-#define TCR_SAT ((1 << 24))
-#define TCR_PLCP_LEN TCR_SAT /* rtl8180 */
-#define TCR_MXDMA_MASK ((1 << 23)|(1 << 22)|(1 << 21))
-#define TCR_MXDMA_1024 6
-#define TCR_MXDMA_2048 7
-#define TCR_MXDMA_SHIFT 21
-#define TCR_DISCW ((1 << 20))
-#define TCR_ICV ((1 << 19))
-#define TCR_LBK ((1 << 18)|(1 << 17))
-#define TCR_LBK1 ((1 << 18))
-#define TCR_LBK0 ((1 << 17))
-#define TCR_CRC ((1 << 16))
-#define TCR_DPRETRY_MASK ((1 << 15)|(1 << 14)|(1 << 13)|(1 << 12)|(1 << 11)|(1 << 10)|(1 << 9)|(1 << 8))
-#define TCR_RTSRETRY_MASK ((1 << 0)|(1 << 1)|(1 << 2)|(1 << 3)|(1 << 4)|(1 << 5)|(1 << 6)|(1 << 7))
-#define TCR_PROBE_NOTIMESTAMP_SHIFT 29 /* rtl8185 */
-
-#define RCR_ONLYERLPKT ((1 << 31))
-#define RCR_CS_SHIFT 29
-#define RCR_CS_MASK ((1 << 30) | (1 << 29))
-#define RCR_ENMARP ((1 << 28))
-#define RCR_CBSSID ((1 << 23))
-#define RCR_APWRMGT ((1 << 22))
-#define RCR_ADD3 ((1 << 21))
-#define RCR_AMF ((1 << 20))
-#define RCR_ACF ((1 << 19))
-#define RCR_ADF ((1 << 18))
-#define RCR_RXFTH ((1 << 15)|(1 << 14)|(1 << 13))
-#define RCR_RXFTH2 ((1 << 15))
-#define RCR_RXFTH1 ((1 << 14))
-#define RCR_RXFTH0 ((1 << 13))
-#define RCR_AICV ((1 << 12))
-#define RCR_MXDMA ((1 << 10)|(1 << 9)|(1 << 8))
-#define RCR_MXDMA2 ((1 << 10))
-#define RCR_MXDMA1 ((1 << 9))
-#define RCR_MXDMA0 ((1 << 8))
-#define RCR_9356SEL ((1 << 6))
-#define RCR_ACRC32 ((1 << 5))
-#define RCR_AB ((1 << 3))
-#define RCR_AM ((1 << 2))
-#define RCR_APM ((1 << 1))
-#define RCR_AAP ((1 << 0))
-
-#define CR9346_EEM ((1 << 7)|(1 << 6))
-#define CR9346_EEM1 ((1 << 7))
-#define CR9346_EEM0 ((1 << 6))
-#define CR9346_EECS ((1 << 3))
-#define CR9346_EESK ((1 << 2))
-#define CR9346_EED1 ((1 << 1))
-#define CR9346_EED0 ((1 << 0))
-
-#define CONFIG3_PARM_En ((1 << 6))
-#define CONFIG3_FuncRegEn ((1 << 1))
-
-#define CONFIG4_PWRMGT ((1 << 5))
-
-#define MSR_LINK_MASK ((1 << 2)|(1 << 3))
-#define MSR_LINK_MANAGED 2
-#define MSR_LINK_NONE 0
-#define MSR_LINK_SHIFT 2
-#define MSR_LINK_ADHOC 1
-#define MSR_LINK_MASTER 3
-
-#define BcnItv_BcnItv (0x01FF)
-
-#define AtimWnd_AtimWnd (0x01FF)
-
-#define BintrItv_BintrItv (0x01FF)
-
-#define FEMR_INTR ((1 << 15))
-#define FEMR_WKUP ((1 << 14))
-#define FEMR_GWAKE ((1 << 4))
-
-#define FFER_INTR ((1 << 15))
-#define FFER_GWAKE ((1 << 4))
-
-/* Three wire mode. */
-#define SW_THREE_WIRE 0
-#define HW_THREE_WIRE 2
-/* RTL8187S by amy */
-#define HW_THREE_WIRE_PI 5
-#define HW_THREE_WIRE_SI 6
-/* by amy */
-#define TCR_LRL_OFFSET 0
-#define TCR_SRL_OFFSET 8
-#define TCR_MXDMA_OFFSET 21
-#define TCR_DISReqQsize_OFFSET 28
-#define TCR_DurProcMode_OFFSET 30
-
-#define RCR_MXDMA_OFFSET 8
-#define RCR_FIFO_OFFSET 13
-
-#define AckTimeOutReg 0x79 /* ACK timeout register, in unit of 4 us. */
-
-#define RFTiming 0x8C
-
-#define TPPollStop 0x93
-
-#define TXAGC_CTL 0x9C /*< RJ_TODO_8185B> TX_AGC_CONTROL (0x9C seems be removed at 8185B, see p37). */
-#define CCK_TXAGC 0x9D
-#define OFDM_TXAGC 0x9E
-#define ANTSEL 0x9F
-
-#define ACM_CONTROL 0x00BF /* ACM Control Registe */
-
-#define IntMig 0xE2 /* Interrupt Migration (0xE2 ~ 0xE3) */
-
-#define TID_AC_MAP 0xE8 /* TID to AC Mapping Register */
-
-#define ANAPARAM3 0xEE /* <RJ_TODO_8185B> How to use it? */
-
-#define AC_VO_PARAM 0xF0 /* AC_VO Parameters Record */
-#define AC_VI_PARAM 0xF4 /* AC_VI Parameters Record */
-#define AC_BE_PARAM 0xF8 /* AC_BE Parameters Record */
-#define AC_BK_PARAM 0xFC /* AC_BK Parameters Record */
-
-#define GPIOCtrl 0x16B /*GPIO Control Register. */
-#define ARFR 0x1E0 /* Auto Rate Fallback Register (0x1e0 ~ 0x1e2) */
-
-#define RFSW_CTRL 0x272 /* 0x272-0x273. */
-#define SW_3W_DB0 0x274 /* Software 3-wire data buffer bit 31~0. */
-#define SW_3W_DB1 0x278 /* Software 3-wire data buffer bit 63~32. */
-#define SW_3W_CMD0 0x27C /* Software 3-wire Control/Status Register. */
-#define SW_3W_CMD1 0x27D /* Software 3-wire Control/Status Register. */
-
-#define PI_DATA_READ 0X360 /* 0x360 - 0x361 Parallel Interface Data Register. */
-#define SI_DATA_READ 0x362 /* 0x362 - 0x363 Serial Interface Data Register. */
-
-/*
-----------------------------------------------------------------------------
- 8185B TPPollStop bits (offset 0x93, 1 byte)
-----------------------------------------------------------------------------
-*/
-#define TPPOLLSTOP_BQ (0x01 << 7)
-#define TPPOLLSTOP_AC_VIQ (0x01 << 4)
-
-#define MSR_LINK_ENEDCA (1<<4)
-
-/*
-----------------------------------------------------------------------------
- 8187B AC_XX_PARAM bits
-----------------------------------------------------------------------------
-*/
-#define AC_PARAM_TXOP_LIMIT_OFFSET 16
-#define AC_PARAM_ECW_MAX_OFFSET 12
-#define AC_PARAM_ECW_MIN_OFFSET 8
-#define AC_PARAM_AIFS_OFFSET 0
-
-/*
-----------------------------------------------------------------------------
- 8187B ACM_CONTROL bits (Offset 0xBF, 1 Byte)
-----------------------------------------------------------------------------
-*/
-#define VOQ_ACM_EN (0x01 << 7) /*BIT7 */
-#define VIQ_ACM_EN (0x01 << 6) /*BIT6 */
-#define BEQ_ACM_EN (0x01 << 5) /*BIT5 */
-#define ACM_HW_EN (0x01 << 4) /*BIT4 */
-#define VOQ_ACM_CTL (0x01 << 2) /*BIT2 */ /* Set to 1 when AC_VO used time reaches or exceeds the admitted time */
-#define VIQ_ACM_CTL (0x01 << 1) /*BIT1 */ /* Set to 1 when AC_VI used time reaches or exceeds the admitted time */
-#define BEQ_ACM_CTL (0x01 << 0) /*BIT0 */ /* Set to 1 when AC_BE used time reaches or exceeds the admitted time */
-
-
-/*
-----------------------------------------------------------------------------
- 8185B SW_3W_CMD bits (Offset 0x27C-0x27D, 16bit)
-----------------------------------------------------------------------------
-*/
-#define SW_3W_CMD0_HOLD ((1 << 7))
-#define SW_3W_CMD1_RE ((1 << 0)) /* BIT8 */
-#define SW_3W_CMD1_WE ((1 << 1)) /* BIT9 */
-#define SW_3W_CMD1_DONE ((1 << 2)) /* BIT10 */
-
-#define BB_HOST_BANG_RW (1 << 3)
-
-/*
-----------------------------------------------------------------------------
- 8185B RATE_FALLBACK_CTL bits (Offset 0xBE, 8bit)
-----------------------------------------------------------------------------
-*/
-#define RATE_FALLBACK_CTL_ENABLE ((1 << 7))
-#define RATE_FALLBACK_CTL_ENABLE_RTSCTS ((1 << 6))
-/* Auto rate fallback per 2^n retry. */
-#define RATE_FALLBACK_CTL_AUTO_STEP0 0x00
-#define RATE_FALLBACK_CTL_AUTO_STEP1 0x01
-#define RATE_FALLBACK_CTL_AUTO_STEP2 0x02
-#define RATE_FALLBACK_CTL_AUTO_STEP3 0x03
-
-
-#define RTL8225z2_ANAPARAM_OFF 0x55480658
-#define RTL8225z2_ANAPARAM2_OFF 0x72003f70
-/* by amy for power save */
-#define RF_CHANGE_BY_HW BIT30
-#define RF_CHANGE_BY_PS BIT29
-#define RF_CHANGE_BY_IPS BIT28
-/* by amy for power save */
-/* by amy for antenna */
-#define EEPROM_SW_REVD_OFFSET 0x3f
-
-/* BIT[8-9] is for SW Antenna Diversity.
- * Only the value EEPROM_SW_AD_ENABLE means enable, other values are disable.
- */
-#define EEPROM_SW_AD_MASK 0x0300
-#define EEPROM_SW_AD_ENABLE 0x0100
-
-/* BIT[10-11] determine if Antenna 1 is the Default Antenna.
- * Only the value EEPROM_DEF_ANT_1 means TRUE, other values are FALSE.
- */
-#define EEPROM_DEF_ANT_MASK 0x0C00
-#define EEPROM_DEF_ANT_1 0x0400
-/*by amy for antenna */
-/* {by amy 080312 */
-/* 0x7C, 0x7D Crystal calibration and Tx Power tracking mechanism. Added by Roger. 2007.12.10. */
-#define EEPROM_RSV 0x7C
-#define EEPROM_XTAL_CAL_XOUT_MASK 0x0F /* 0x7C[3:0], Crystal calibration for Xout. */
-#define EEPROM_XTAL_CAL_XIN_MASK 0xF0 /* 0x7C[7:4], Crystal calibration for Xin. */
-#define EEPROM_THERMAL_METER_MASK 0x0F00 /* 0x7D[3:0], Thermal meter reference level. */
-#define EEPROM_XTAL_CAL_ENABLE 0x1000 /* 0x7D[4], Crystal calibration enabled/disabled BIT. */
-#define EEPROM_THERMAL_METER_ENABLE 0x2000 /* 0x7D[5], Thermal meter enabled/disabled BIT. */
-#define EN_LPF_CAL 0x238 /* Enable LPF Calibration. */
-#define PWR_METER_EN BIT1
-/* <RJ_TODO_8185B> where are false alarm counters in 8185B? */
-#define CCK_FALSE_ALARM 0xD0
-/* by amy 080312} */
-
-/* YJ,add for Country IE, 080630 */
-#define EEPROM_COUNTRY_CODE 0x2E
-/* YJ,add,080630,end */
-
-#endif
diff --git a/drivers/staging/rtl8187se/r8180_rtl8225.h b/drivers/staging/rtl8187se/r8180_rtl8225.h
deleted file mode 100644
index 7df7392..0000000
--- a/drivers/staging/rtl8187se/r8180_rtl8225.h
+++ /dev/null
@@ -1,34 +0,0 @@
-/*
- * This is part of the rtl8180-sa2400 driver released under the GPL (See file
- * COPYING for details).
- *
- * Copyright (c) 2005 Andrea Merello <andrea.merello@gmail.com>
- *
- * This files contains programming code for the rtl8225 radio frontend.
- *
- * *Many* thanks to Realtek Corp. for their great support!
- */
-
-#include "r8180.h"
-
-#define RTL8225_ANAPARAM_ON 0xa0000b59
-#define RTL8225_ANAPARAM_OFF 0xa00beb59
-#define RTL8225_ANAPARAM2_OFF 0x840dec11
-#define RTL8225_ANAPARAM2_ON 0x860dec11
-#define RTL8225_ANAPARAM_SLEEP 0xa00bab59
-#define RTL8225_ANAPARAM2_SLEEP 0x840dec11
-
-void rtl8225z2_rf_init(struct net_device *dev);
-void rtl8225z2_rf_set_chan(struct net_device *dev, short ch);
-void rtl8225z2_rf_close(struct net_device *dev);
-
-void RF_WriteReg(struct net_device *dev, u8 offset, u16 data);
-u16 RF_ReadReg(struct net_device *dev, u8 offset);
-
-void rtl8180_set_mode(struct net_device *dev, int mode);
-void rtl8180_set_mode(struct net_device *dev, int mode);
-bool SetZebraRFPowerState8185(struct net_device *dev,
- enum rt_rf_power_state eRFPowerState);
-void rtl8225z4_rf_sleep(struct net_device *dev);
-void rtl8225z4_rf_wakeup(struct net_device *dev);
-
diff --git a/drivers/staging/rtl8187se/r8180_rtl8225z2.c b/drivers/staging/rtl8187se/r8180_rtl8225z2.c
deleted file mode 100644
index 47104fa..0000000
--- a/drivers/staging/rtl8187se/r8180_rtl8225z2.c
+++ /dev/null
@@ -1,811 +0,0 @@
-/*
- * This is part of the rtl8180-sa2400 driver
- * released under the GPL (See file COPYING for details).
- * Copyright (c) 2005 Andrea Merello <andrea.merello@gmail.com>
- *
- * This files contains programming code for the rtl8225
- * radio frontend.
- *
- * *Many* thanks to Realtek Corp. for their great support!
- */
-
-#include "r8180_hw.h"
-#include "r8180_rtl8225.h"
-#include "r8180_93cx6.h"
-
-#include "ieee80211/dot11d.h"
-
-static void write_rtl8225(struct net_device *dev, u8 adr, u16 data)
-{
- int i;
- u16 out, select;
- u8 bit;
- u32 bangdata = (data << 4) | (adr & 0xf);
-
- out = read_nic_word(dev, RFPinsOutput) & 0xfff3;
-
- write_nic_word(dev, RFPinsEnable,
- (read_nic_word(dev, RFPinsEnable) | 0x7));
-
- select = read_nic_word(dev, RFPinsSelect);
-
- write_nic_word(dev, RFPinsSelect, select | 0x7 |
- SW_CONTROL_GPIO);
-
- force_pci_posting(dev);
- udelay(10);
-
- write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN);
-
- force_pci_posting(dev);
- udelay(2);
-
- write_nic_word(dev, RFPinsOutput, out);
-
- force_pci_posting(dev);
- udelay(10);
-
- for (i = 15; i >= 0; i--) {
- bit = (bangdata & (1 << i)) >> i;
-
- write_nic_word(dev, RFPinsOutput, bit | out);
-
- write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
- write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
-
- i--;
- bit = (bangdata & (1 << i)) >> i;
-
- write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
- write_nic_word(dev, RFPinsOutput, bit | out | BB_HOST_BANG_CLK);
-
- write_nic_word(dev, RFPinsOutput, bit | out);
-
- }
-
- write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN);
-
- force_pci_posting(dev);
- udelay(10);
-
- write_nic_word(dev, RFPinsOutput, out | BB_HOST_BANG_EN);
-
- write_nic_word(dev, RFPinsSelect, select | SW_CONTROL_GPIO);
-
- rtl8185_rf_pins_enable(dev);
-}
-
-static const u8 rtl8225_agc[] = {
- 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e, 0x9e,
- 0x9d, 0x9c, 0x9b, 0x9a, 0x99, 0x98, 0x97, 0x96,
- 0x95, 0x94, 0x93, 0x92, 0x91, 0x90, 0x8f, 0x8e,
- 0x8d, 0x8c, 0x8b, 0x8a, 0x89, 0x88, 0x87, 0x86,
- 0x85, 0x84, 0x83, 0x82, 0x81, 0x80, 0x3f, 0x3e,
- 0x3d, 0x3c, 0x3b, 0x3a, 0x39, 0x38, 0x37, 0x36,
- 0x35, 0x34, 0x33, 0x32, 0x31, 0x30, 0x2f, 0x2e,
- 0x2d, 0x2c, 0x2b, 0x2a, 0x29, 0x28, 0x27, 0x26,
- 0x25, 0x24, 0x23, 0x22, 0x21, 0x20, 0x1f, 0x1e,
- 0x1d, 0x1c, 0x1b, 0x1a, 0x19, 0x18, 0x17, 0x16,
- 0x15, 0x14, 0x13, 0x12, 0x11, 0x10, 0x0f, 0x0e,
- 0x0d, 0x0c, 0x0b, 0x0a, 0x09, 0x08, 0x07, 0x06,
- 0x05, 0x04, 0x03, 0x02, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
- 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01,
-};
-
-static const u32 rtl8225_chan[] = {
- 0,
- 0x0080, 0x0100, 0x0180, 0x0200, 0x0280, 0x0300, 0x0380,
- 0x0400, 0x0480, 0x0500, 0x0580, 0x0600, 0x0680, 0x074A,
-};
-
-static const u8 rtl8225z2_gain_bg[] = {
- 0x23, 0x15, 0xa5, /* -82-1dBm */
- 0x23, 0x15, 0xb5, /* -82-2dBm */
- 0x23, 0x15, 0xc5, /* -82-3dBm */
- 0x33, 0x15, 0xc5, /* -78dBm */
- 0x43, 0x15, 0xc5, /* -74dBm */
- 0x53, 0x15, 0xc5, /* -70dBm */
- 0x63, 0x15, 0xc5, /* -66dBm */
-};
-
-static const u8 rtl8225z2_gain_a[] = {
- 0x13, 0x27, 0x5a, /* -82dBm */
- 0x23, 0x23, 0x58, /* -82dBm */
- 0x33, 0x1f, 0x56, /* -82dBm */
- 0x43, 0x1b, 0x54, /* -78dBm */
- 0x53, 0x17, 0x51, /* -74dBm */
- 0x63, 0x24, 0x4f, /* -70dBm */
- 0x73, 0x0f, 0x4c, /* -66dBm */
-};
-
-static const u16 rtl8225z2_rxgain[] = {
- 0x0400, 0x0401, 0x0402, 0x0403, 0x0404, 0x0405, 0x0408, 0x0409,
- 0x040a, 0x040b, 0x0502, 0x0503, 0x0504, 0x0505, 0x0540, 0x0541,
- 0x0542, 0x0543, 0x0544, 0x0545, 0x0580, 0x0581, 0x0582, 0x0583,
- 0x0584, 0x0585, 0x0588, 0x0589, 0x058a, 0x058b, 0x0643, 0x0644,
- 0x0645, 0x0680, 0x0681, 0x0682, 0x0683, 0x0684, 0x0685, 0x0688,
- 0x0689, 0x068a, 0x068b, 0x068c, 0x0742, 0x0743, 0x0744, 0x0745,
- 0x0780, 0x0781, 0x0782, 0x0783, 0x0784, 0x0785, 0x0788, 0x0789,
- 0x078a, 0x078b, 0x078c, 0x078d, 0x0790, 0x0791, 0x0792, 0x0793,
- 0x0794, 0x0795, 0x0798, 0x0799, 0x079a, 0x079b, 0x079c, 0x079d,
- 0x07a0, 0x07a1, 0x07a2, 0x07a3, 0x07a4, 0x07a5, 0x07a8, 0x07a9,
- 0x03aa, 0x03ab, 0x03ac, 0x03ad, 0x03b0, 0x03b1, 0x03b2, 0x03b3,
- 0x03b4, 0x03b5, 0x03b8, 0x03b9, 0x03ba, 0x03bb
-
-};
-
-static void rtl8225z2_set_gain(struct net_device *dev, short gain)
-{
- const u8 *rtl8225_gain;
- struct r8180_priv *priv = ieee80211_priv(dev);
- u8 mode = priv->ieee80211->mode;
-
- if (mode == IEEE_B || mode == IEEE_G)
- rtl8225_gain = rtl8225z2_gain_bg;
- else
- rtl8225_gain = rtl8225z2_gain_a;
-
- write_phy_ofdm(dev, 0x0b, rtl8225_gain[gain * 3]);
- write_phy_ofdm(dev, 0x1b, rtl8225_gain[gain * 3 + 1]);
- write_phy_ofdm(dev, 0x1d, rtl8225_gain[gain * 3 + 2]);
- write_phy_ofdm(dev, 0x21, 0x37);
-}
-
-static u32 read_rtl8225(struct net_device *dev, u8 adr)
-{
- u32 data2Write = ((u32)(adr & 0x1f)) << 27;
- u32 dataRead;
- u32 mask;
- u16 oval, oval2, oval3, tmp;
- int i;
- short bit, rw;
- u8 wLength = 6;
- u8 rLength = 12;
- u8 low2high = 0;
-
- oval = read_nic_word(dev, RFPinsOutput);
- oval2 = read_nic_word(dev, RFPinsEnable);
- oval3 = read_nic_word(dev, RFPinsSelect);
-
- write_nic_word(dev, RFPinsEnable, (oval2|0xf));
- write_nic_word(dev, RFPinsSelect, (oval3|0xf));
-
- dataRead = 0;
-
- oval &= ~0xf;
-
- write_nic_word(dev, RFPinsOutput, oval | BB_HOST_BANG_EN);
- udelay(4);
-
- write_nic_word(dev, RFPinsOutput, oval);
- udelay(5);
-
- rw = 0;
-
- mask = (low2high) ? 0x01 : (((u32)0x01)<<(32-1));
-
- for (i = 0; i < wLength/2; i++) {
- bit = ((data2Write&mask) != 0) ? 1 : 0;
- write_nic_word(dev, RFPinsOutput, bit | oval | rw);
- udelay(1);
-
- write_nic_word(dev, RFPinsOutput,
- bit | oval | BB_HOST_BANG_CLK | rw);
- udelay(2);
- write_nic_word(dev, RFPinsOutput,
- bit | oval | BB_HOST_BANG_CLK | rw);
- udelay(2);
-
- mask = (low2high) ? (mask<<1) : (mask>>1);
-
- if (i == 2) {
- rw = BB_HOST_BANG_RW;
- write_nic_word(dev, RFPinsOutput,
- bit | oval | BB_HOST_BANG_CLK | rw);
- udelay(2);
- write_nic_word(dev, RFPinsOutput, bit | oval | rw);
- udelay(2);
- break;
- }
-
- bit = ((data2Write&mask) != 0) ? 1 : 0;
-
- write_nic_word(dev, RFPinsOutput,
- oval | bit | rw | BB_HOST_BANG_CLK);
- udelay(2);
- write_nic_word(dev, RFPinsOutput,
- oval | bit | rw | BB_HOST_BANG_CLK);
- udelay(2);
-
- write_nic_word(dev, RFPinsOutput, oval | bit | rw);
- udelay(1);
-
- mask = (low2high) ? (mask<<1) : (mask>>1);
- }
-
- write_nic_word(dev, RFPinsOutput, rw|oval);
- udelay(2);
- mask = (low2high) ? 0x01 : (((u32)0x01) << (12-1));
-
- /*
- * We must set data pin to HW controlled, otherwise RF can't driver it
- * and value RF register won't be able to read back properly.
- */
- write_nic_word(dev, RFPinsEnable, (oval2 & (~0x01)));
-
- for (i = 0; i < rLength; i++) {
- write_nic_word(dev, RFPinsOutput, rw|oval); udelay(1);
-
- write_nic_word(dev, RFPinsOutput, rw|oval|BB_HOST_BANG_CLK);
- udelay(2);
- write_nic_word(dev, RFPinsOutput, rw|oval|BB_HOST_BANG_CLK);
- udelay(2);
- write_nic_word(dev, RFPinsOutput, rw|oval|BB_HOST_BANG_CLK);
- udelay(2);
- tmp = read_nic_word(dev, RFPinsInput);
-
- dataRead |= (tmp & BB_HOST_BANG_CLK ? mask : 0);
-
- write_nic_word(dev, RFPinsOutput, (rw|oval)); udelay(2);
-
- mask = (low2high) ? (mask<<1) : (mask>>1);
- }
-
- write_nic_word(dev, RFPinsOutput,
- BB_HOST_BANG_EN | BB_HOST_BANG_RW | oval);
- udelay(2);
-
- write_nic_word(dev, RFPinsEnable, oval2);
- write_nic_word(dev, RFPinsSelect, oval3); /* Set To SW Switch */
- write_nic_word(dev, RFPinsOutput, 0x3a0);
-
- return dataRead;
-}
-
-void rtl8225z2_rf_close(struct net_device *dev)
-{
- RF_WriteReg(dev, 0x4, 0x1f);
-
- force_pci_posting(dev);
- mdelay(1);
-
- rtl8180_set_anaparam(dev, RTL8225z2_ANAPARAM_OFF);
- rtl8185_set_anaparam2(dev, RTL8225z2_ANAPARAM2_OFF);
-}
-
-/*
- * Map dBm into Tx power index according to current HW model, for example,
- * RF and PA, and current wireless mode.
- */
-static s8 DbmToTxPwrIdx(struct r8180_priv *priv,
- enum wireless_mode mode, s32 PowerInDbm)
-{
- bool bUseDefault = true;
- s8 TxPwrIdx = 0;
-
- /*
- * OFDM Power in dBm = Index * 0.5 + 0
- * CCK Power in dBm = Index * 0.25 + 13
- */
- s32 tmp = 0;
-
- if (mode == WIRELESS_MODE_G) {
- bUseDefault = false;
- tmp = (2 * PowerInDbm);
-
- if (tmp < 0)
- TxPwrIdx = 0;
- else if (tmp > 40) /* 40 means 20 dBm. */
- TxPwrIdx = 40;
- else
- TxPwrIdx = (s8)tmp;
- } else if (mode == WIRELESS_MODE_B) {
- bUseDefault = false;
- tmp = (4 * PowerInDbm) - 52;
-
- if (tmp < 0)
- TxPwrIdx = 0;
- else if (tmp > 28) /* 28 means 20 dBm. */
- TxPwrIdx = 28;
- else
- TxPwrIdx = (s8)tmp;
- }
-
- /*
- * TRUE if we want to use a default implementation.
- * We shall set it to FALSE when we have exact translation formula
- * for target IC. 070622, by rcnjko.
- */
- if (bUseDefault) {
- if (PowerInDbm < 0)
- TxPwrIdx = 0;
- else if (PowerInDbm > 35)
- TxPwrIdx = 35;
- else
- TxPwrIdx = (u8)PowerInDbm;
- }
-
- return TxPwrIdx;
-}
-
-void rtl8225z2_SetTXPowerLevel(struct net_device *dev, short ch)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- u8 max_cck_power_level;
- u8 max_ofdm_power_level;
- u8 min_ofdm_power_level;
- char cck_power_level = (char)(0xff & priv->chtxpwr[ch]);
- char ofdm_power_level = (char)(0xff & priv->chtxpwr_ofdm[ch]);
-
- if (IS_DOT11D_ENABLE(priv->ieee80211) &&
- IS_DOT11D_STATE_DONE(priv->ieee80211)) {
- u8 MaxTxPwrInDbm = DOT11D_GetMaxTxPwrInDbm(priv->ieee80211, ch);
- u8 CckMaxPwrIdx = DbmToTxPwrIdx(priv, WIRELESS_MODE_B,
- MaxTxPwrInDbm);
- u8 OfdmMaxPwrIdx = DbmToTxPwrIdx(priv, WIRELESS_MODE_G,
- MaxTxPwrInDbm);
-
- if (cck_power_level > CckMaxPwrIdx)
- cck_power_level = CckMaxPwrIdx;
- if (ofdm_power_level > OfdmMaxPwrIdx)
- ofdm_power_level = OfdmMaxPwrIdx;
- }
-
- max_cck_power_level = 15;
- max_ofdm_power_level = 25;
- min_ofdm_power_level = 10;
-
- if (cck_power_level > 35)
- cck_power_level = 35;
-
- write_nic_byte(dev, CCK_TXAGC, cck_power_level);
- force_pci_posting(dev);
- mdelay(1);
-
- if (ofdm_power_level > 35)
- ofdm_power_level = 35;
-
- if (priv->up == 0) {
- write_phy_ofdm(dev, 2, 0x42);
- write_phy_ofdm(dev, 5, 0x00);
- write_phy_ofdm(dev, 6, 0x40);
- write_phy_ofdm(dev, 7, 0x00);
- write_phy_ofdm(dev, 8, 0x40);
- }
-
- write_nic_byte(dev, OFDM_TXAGC, ofdm_power_level);
-
- if (ofdm_power_level <= 11) {
- write_phy_ofdm(dev, 0x07, 0x5c);
- write_phy_ofdm(dev, 0x09, 0x5c);
- }
-
- if (ofdm_power_level <= 17) {
- write_phy_ofdm(dev, 0x07, 0x54);
- write_phy_ofdm(dev, 0x09, 0x54);
- } else {
- write_phy_ofdm(dev, 0x07, 0x50);
- write_phy_ofdm(dev, 0x09, 0x50);
- }
-
- force_pci_posting(dev);
- mdelay(1);
-}
-
-void rtl8225z2_rf_set_chan(struct net_device *dev, short ch)
-{
- rtl8225z2_SetTXPowerLevel(dev, ch);
-
- RF_WriteReg(dev, 0x7, rtl8225_chan[ch]);
-
- if ((RF_ReadReg(dev, 0x7) & 0x0F80) != rtl8225_chan[ch])
- RF_WriteReg(dev, 0x7, rtl8225_chan[ch]);
-
- mdelay(1);
-
- force_pci_posting(dev);
- mdelay(10);
-}
-
-static void rtl8225_host_pci_init(struct net_device *dev)
-{
- write_nic_word(dev, RFPinsOutput, 0x480);
-
- rtl8185_rf_pins_enable(dev);
-
- write_nic_word(dev, RFPinsSelect, 0x88 | SW_CONTROL_GPIO);
-
- write_nic_byte(dev, GP_ENABLE, 0);
-
- force_pci_posting(dev);
- mdelay(200);
-
- /* bit 6 is for RF on/off detection */
- write_nic_word(dev, GP_ENABLE, 0xff & (~(1 << 6)));
-}
-
-void rtl8225z2_rf_init(struct net_device *dev)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- int i;
- short channel = 1;
- u16 brsr;
- u32 data;
-
- priv->chan = channel;
-
- rtl8225_host_pci_init(dev);
-
- write_nic_dword(dev, RF_TIMING, 0x000a8008);
-
- brsr = read_nic_word(dev, BRSR);
-
- write_nic_word(dev, BRSR, 0xffff);
-
- write_nic_dword(dev, RF_PARA, 0x100044);
-
- rtl8180_set_mode(dev, EPROM_CMD_CONFIG);
- write_nic_byte(dev, CONFIG3, 0x44);
- rtl8180_set_mode(dev, EPROM_CMD_NORMAL);
-
- rtl8185_rf_pins_enable(dev);
-
- write_rtl8225(dev, 0x0, 0x2bf); mdelay(1);
- write_rtl8225(dev, 0x1, 0xee0); mdelay(1);
- write_rtl8225(dev, 0x2, 0x44d); mdelay(1);
- write_rtl8225(dev, 0x3, 0x441); mdelay(1);
- write_rtl8225(dev, 0x4, 0x8c3); mdelay(1);
- write_rtl8225(dev, 0x5, 0xc72); mdelay(1);
- write_rtl8225(dev, 0x6, 0xe6); mdelay(1);
- write_rtl8225(dev, 0x7, rtl8225_chan[channel]); mdelay(1);
- write_rtl8225(dev, 0x8, 0x3f); mdelay(1);
- write_rtl8225(dev, 0x9, 0x335); mdelay(1);
- write_rtl8225(dev, 0xa, 0x9d4); mdelay(1);
- write_rtl8225(dev, 0xb, 0x7bb); mdelay(1);
- write_rtl8225(dev, 0xc, 0x850); mdelay(1);
- write_rtl8225(dev, 0xd, 0xcdf); mdelay(1);
- write_rtl8225(dev, 0xe, 0x2b); mdelay(1);
- write_rtl8225(dev, 0xf, 0x114);
-
- mdelay(100);
-
- write_rtl8225(dev, 0x0, 0x1b7);
-
- for (i = 0; i < ARRAY_SIZE(rtl8225z2_rxgain); i++) {
- write_rtl8225(dev, 0x1, i + 1);
- write_rtl8225(dev, 0x2, rtl8225z2_rxgain[i]);
- }
-
- write_rtl8225(dev, 0x3, 0x80);
- write_rtl8225(dev, 0x5, 0x4);
-
- write_rtl8225(dev, 0x0, 0xb7);
-
- write_rtl8225(dev, 0x2, 0xc4d);
-
- /* FIXME!! rtl8187 we have to check if calibrarion
- * is successful and eventually cal. again (repeat
- * the two write on reg 2)
- */
- data = read_rtl8225(dev, 6);
- if (!(data & 0x00000080)) {
- write_rtl8225(dev, 0x02, 0x0c4d);
- force_pci_posting(dev); mdelay(200);
- write_rtl8225(dev, 0x02, 0x044d);
- force_pci_posting(dev); mdelay(100);
- data = read_rtl8225(dev, 6);
- if (!(data & 0x00000080))
- DMESGW("RF Calibration Failed!!!!\n");
- }
-
- mdelay(200);
-
- write_rtl8225(dev, 0x0, 0x2bf);
-
- for (i = 0; i < ARRAY_SIZE(rtl8225_agc); i++) {
- write_phy_ofdm(dev, 0xb, rtl8225_agc[i]);
- mdelay(1);
-
- /* enable writing AGC table */
- write_phy_ofdm(dev, 0xa, i + 0x80);
- mdelay(1);
- }
-
- force_pci_posting(dev);
- mdelay(1);
-
- write_phy_ofdm(dev, 0x00, 0x01); mdelay(1);
- write_phy_ofdm(dev, 0x01, 0x02); mdelay(1);
- write_phy_ofdm(dev, 0x02, 0x62); mdelay(1);
- write_phy_ofdm(dev, 0x03, 0x00); mdelay(1);
- write_phy_ofdm(dev, 0x04, 0x00); mdelay(1);
- write_phy_ofdm(dev, 0x05, 0x00); mdelay(1);
- write_phy_ofdm(dev, 0x06, 0x40); mdelay(1);
- write_phy_ofdm(dev, 0x07, 0x00); mdelay(1);
- write_phy_ofdm(dev, 0x08, 0x40); mdelay(1);
- write_phy_ofdm(dev, 0x09, 0xfe); mdelay(1);
- write_phy_ofdm(dev, 0x0a, 0x08); mdelay(1);
- write_phy_ofdm(dev, 0x0b, 0x80); mdelay(1);
- write_phy_ofdm(dev, 0x0c, 0x01); mdelay(1);
- write_phy_ofdm(dev, 0x0d, 0x43);
- write_phy_ofdm(dev, 0x0e, 0xd3); mdelay(1);
- write_phy_ofdm(dev, 0x0f, 0x38); mdelay(1);
- write_phy_ofdm(dev, 0x10, 0x84); mdelay(1);
- write_phy_ofdm(dev, 0x11, 0x07); mdelay(1);
- write_phy_ofdm(dev, 0x12, 0x20); mdelay(1);
- write_phy_ofdm(dev, 0x13, 0x20); mdelay(1);
- write_phy_ofdm(dev, 0x14, 0x00); mdelay(1);
- write_phy_ofdm(dev, 0x15, 0x40); mdelay(1);
- write_phy_ofdm(dev, 0x16, 0x00); mdelay(1);
- write_phy_ofdm(dev, 0x17, 0x40); mdelay(1);
- write_phy_ofdm(dev, 0x18, 0xef); mdelay(1);
- write_phy_ofdm(dev, 0x19, 0x19); mdelay(1);
- write_phy_ofdm(dev, 0x1a, 0x20); mdelay(1);
- write_phy_ofdm(dev, 0x1b, 0x15); mdelay(1);
- write_phy_ofdm(dev, 0x1c, 0x04); mdelay(1);
- write_phy_ofdm(dev, 0x1d, 0xc5); mdelay(1);
- write_phy_ofdm(dev, 0x1e, 0x95); mdelay(1);
- write_phy_ofdm(dev, 0x1f, 0x75); mdelay(1);
- write_phy_ofdm(dev, 0x20, 0x1f); mdelay(1);
- write_phy_ofdm(dev, 0x21, 0x17); mdelay(1);
- write_phy_ofdm(dev, 0x22, 0x16); mdelay(1);
- write_phy_ofdm(dev, 0x23, 0x80); mdelay(1); /* FIXME maybe not needed */
- write_phy_ofdm(dev, 0x24, 0x46); mdelay(1);
- write_phy_ofdm(dev, 0x25, 0x00); mdelay(1);
- write_phy_ofdm(dev, 0x26, 0x90); mdelay(1);
- write_phy_ofdm(dev, 0x27, 0x88); mdelay(1);
-
- rtl8225z2_set_gain(dev, 4);
-
- write_phy_cck(dev, 0x0, 0x98); mdelay(1);
- write_phy_cck(dev, 0x3, 0x20); mdelay(1);
- write_phy_cck(dev, 0x4, 0x7e); mdelay(1);
- write_phy_cck(dev, 0x5, 0x12); mdelay(1);
- write_phy_cck(dev, 0x6, 0xfc); mdelay(1);
- write_phy_cck(dev, 0x7, 0x78); mdelay(1);
- write_phy_cck(dev, 0x8, 0x2e); mdelay(1);
- write_phy_cck(dev, 0x10, 0x93); mdelay(1);
- write_phy_cck(dev, 0x11, 0x88); mdelay(1);
- write_phy_cck(dev, 0x12, 0x47); mdelay(1);
- write_phy_cck(dev, 0x13, 0xd0);
- write_phy_cck(dev, 0x19, 0x00);
- write_phy_cck(dev, 0x1a, 0xa0);
- write_phy_cck(dev, 0x1b, 0x08);
- write_phy_cck(dev, 0x40, 0x86); /* CCK Carrier Sense Threshold */
- write_phy_cck(dev, 0x41, 0x8d); mdelay(1);
- write_phy_cck(dev, 0x42, 0x15); mdelay(1);
- write_phy_cck(dev, 0x43, 0x18); mdelay(1);
- write_phy_cck(dev, 0x44, 0x36); mdelay(1);
- write_phy_cck(dev, 0x45, 0x35); mdelay(1);
- write_phy_cck(dev, 0x46, 0x2e); mdelay(1);
- write_phy_cck(dev, 0x47, 0x25); mdelay(1);
- write_phy_cck(dev, 0x48, 0x1c); mdelay(1);
- write_phy_cck(dev, 0x49, 0x12); mdelay(1);
- write_phy_cck(dev, 0x4a, 0x09); mdelay(1);
- write_phy_cck(dev, 0x4b, 0x04); mdelay(1);
- write_phy_cck(dev, 0x4c, 0x05); mdelay(1);
-
- write_nic_byte(dev, 0x5b, 0x0d); mdelay(1);
-
- rtl8225z2_SetTXPowerLevel(dev, channel);
-
- /* RX antenna default to A */
- write_phy_cck(dev, 0x11, 0x9b); mdelay(1); /* B: 0xDB */
- write_phy_ofdm(dev, 0x26, 0x90); mdelay(1); /* B: 0x10 */
-
- rtl8185_tx_antenna(dev, 0x03); /* B: 0x00 */
-
- /* switch to high-speed 3-wire
- * last digit. 2 for both cck and ofdm
- */
- write_nic_dword(dev, 0x94, 0x15c00002);
- rtl8185_rf_pins_enable(dev);
-
- rtl8225z2_rf_set_chan(dev, priv->chan);
-}
-
-#define MAX_DOZE_WAITING_TIMES_85B 20
-#define MAX_POLLING_24F_TIMES_87SE 10
-#define LPS_MAX_SLEEP_WAITING_TIMES_87SE 5
-
-bool SetZebraRFPowerState8185(struct net_device *dev,
- enum rt_rf_power_state eRFPowerState)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- u8 btCR9346, btConfig3;
- bool bActionAllowed = true, bTurnOffBB = true;
- u8 u1bTmp;
- int i;
- bool bResult = true;
- u8 QueueID;
-
- if (priv->SetRFPowerStateInProgress == true)
- return false;
-
- priv->SetRFPowerStateInProgress = true;
-
- btCR9346 = read_nic_byte(dev, CR9346);
- write_nic_byte(dev, CR9346, (btCR9346 | 0xC0));
-
- btConfig3 = read_nic_byte(dev, CONFIG3);
- write_nic_byte(dev, CONFIG3, (btConfig3 | CONFIG3_PARM_En));
-
- switch (eRFPowerState) {
- case RF_ON:
- write_nic_word(dev, 0x37C, 0x00EC);
-
- /* turn on AFE */
- write_nic_byte(dev, 0x54, 0x00);
- write_nic_byte(dev, 0x62, 0x00);
-
- /* turn on RF */
- RF_WriteReg(dev, 0x0, 0x009f); udelay(500);
- RF_WriteReg(dev, 0x4, 0x0972); udelay(500);
-
- /* turn on RF again */
- RF_WriteReg(dev, 0x0, 0x009f); udelay(500);
- RF_WriteReg(dev, 0x4, 0x0972); udelay(500);
-
- /* turn on BB */
- write_phy_ofdm(dev, 0x10, 0x40);
- write_phy_ofdm(dev, 0x12, 0x40);
-
- /* Avoid power down at init time. */
- write_nic_byte(dev, CONFIG4, priv->RFProgType);
-
- u1bTmp = read_nic_byte(dev, 0x24E);
- write_nic_byte(dev, 0x24E, (u1bTmp & (~(BIT5 | BIT6))));
- break;
- case RF_SLEEP:
- for (QueueID = 0, i = 0; QueueID < 6;) {
- if (get_curr_tx_free_desc(dev, QueueID) ==
- priv->txringcount) {
- QueueID++;
- continue;
- } else {
- priv->TxPollingTimes++;
- if (priv->TxPollingTimes >=
- LPS_MAX_SLEEP_WAITING_TIMES_87SE) {
- bActionAllowed = false;
- break;
- } else
- udelay(10);
- }
- }
-
- if (bActionAllowed) {
- /* turn off BB RXIQ matrix to cut off rx signal */
- write_phy_ofdm(dev, 0x10, 0x00);
- write_phy_ofdm(dev, 0x12, 0x00);
-
- /* turn off RF */
- RF_WriteReg(dev, 0x4, 0x0000);
- RF_WriteReg(dev, 0x0, 0x0000);
-
- /* turn off AFE except PLL */
- write_nic_byte(dev, 0x62, 0xff);
- write_nic_byte(dev, 0x54, 0xec);
-
- mdelay(1);
-
- {
- int i = 0;
- while (true) {
- u8 tmp24F = read_nic_byte(dev, 0x24f);
-
- if ((tmp24F == 0x01) ||
- (tmp24F == 0x09)) {
- bTurnOffBB = true;
- break;
- } else {
- udelay(10);
- i++;
- priv->TxPollingTimes++;
-
- if (priv->TxPollingTimes >= LPS_MAX_SLEEP_WAITING_TIMES_87SE) {
- bTurnOffBB = false;
- break;
- } else
- udelay(10);
- }
- }
- }
-
- if (bTurnOffBB) {
- /* turn off BB */
- u1bTmp = read_nic_byte(dev, 0x24E);
- write_nic_byte(dev, 0x24E,
- (u1bTmp | BIT5 | BIT6));
-
- /* turn off AFE PLL */
- write_nic_byte(dev, 0x54, 0xFC);
- write_nic_word(dev, 0x37C, 0x00FC);
- }
- }
- break;
- case RF_OFF:
- for (QueueID = 0, i = 0; QueueID < 6;) {
- if (get_curr_tx_free_desc(dev, QueueID) ==
- priv->txringcount) {
- QueueID++;
- continue;
- } else {
- udelay(10);
- i++;
- }
-
- if (i >= MAX_DOZE_WAITING_TIMES_85B)
- break;
- }
-
- /* turn off BB RXIQ matrix to cut off rx signal */
- write_phy_ofdm(dev, 0x10, 0x00);
- write_phy_ofdm(dev, 0x12, 0x00);
-
- /* turn off RF */
- RF_WriteReg(dev, 0x4, 0x0000);
- RF_WriteReg(dev, 0x0, 0x0000);
-
- /* turn off AFE except PLL */
- write_nic_byte(dev, 0x62, 0xff);
- write_nic_byte(dev, 0x54, 0xec);
-
- mdelay(1);
-
- {
- int i = 0;
-
- while (true) {
- u8 tmp24F = read_nic_byte(dev, 0x24f);
-
- if ((tmp24F == 0x01) || (tmp24F == 0x09)) {
- bTurnOffBB = true;
- break;
- } else {
- bTurnOffBB = false;
- udelay(10);
- i++;
- }
-
- if (i > MAX_POLLING_24F_TIMES_87SE)
- break;
- }
- }
-
- if (bTurnOffBB) {
- /* turn off BB */
- u1bTmp = read_nic_byte(dev, 0x24E);
- write_nic_byte(dev, 0x24E, (u1bTmp | BIT5 | BIT6));
-
- /* turn off AFE PLL (80M) */
- write_nic_byte(dev, 0x54, 0xFC);
- write_nic_word(dev, 0x37C, 0x00FC);
- }
- break;
- }
-
- btConfig3 &= ~(CONFIG3_PARM_En);
- write_nic_byte(dev, CONFIG3, btConfig3);
-
- btCR9346 &= ~(0xC0);
- write_nic_byte(dev, CR9346, btCR9346);
-
- if (bResult && bActionAllowed)
- priv->eRFPowerState = eRFPowerState;
-
- priv->SetRFPowerStateInProgress = false;
-
- return bResult && bActionAllowed;
-}
-
-void rtl8225z4_rf_sleep(struct net_device *dev)
-{
- MgntActSet_RF_State(dev, RF_SLEEP, RF_CHANGE_BY_PS);
-}
-
-void rtl8225z4_rf_wakeup(struct net_device *dev)
-{
- MgntActSet_RF_State(dev, RF_ON, RF_CHANGE_BY_PS);
-}
diff --git a/drivers/staging/rtl8187se/r8180_wx.c b/drivers/staging/rtl8187se/r8180_wx.c
deleted file mode 100644
index b552491..0000000
--- a/drivers/staging/rtl8187se/r8180_wx.c
+++ /dev/null
@@ -1,1409 +0,0 @@
-/*
- This file contains wireless extension handlers.
-
- This is part of rtl8180 OpenSource driver.
- 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 Intel Pro Wireless 2100 GPL driver.
-
- We want to thanks the Authors of those projects and the Ndiswrapper
- project Authors.
-*/
-
-
-#include "r8180.h"
-#include "r8180_hw.h"
-
-#include <net/iw_handler.h>
-#include "ieee80211/dot11d.h"
-
-static u32 rtl8180_rates[] = {1000000, 2000000, 5500000, 11000000,
- 6000000, 9000000, 12000000, 18000000, 24000000, 36000000, 48000000, 54000000};
-
-#define RATE_COUNT ARRAY_SIZE(rtl8180_rates)
-
-static struct rtl8187se_channel_list default_channel_plan[] = {
- {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 36, 40, 44, 48, 52, 56, 60, 64}, 19}, /* 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, 36, 40, 44, 48, 52, 56, 60, 64}, 21}, /* Spain. Change to ETSI. */
- {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 36, 40, 44, 48, 52, 56, 60, 64}, 21}, /* France. Change to ETSI. */
- {{14, 36, 40, 44, 48, 52, 56, 60, 64}, 9}, /* 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, 36, 40, 44, 48, 52, 56, 60, 64}, 21}, /* Israel */
- {{1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 34, 38, 42, 46}, 17}, /* For 11a , TELEC */
- {{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 int r8180_wx_get_freq(struct net_device *dev,
- struct iw_request_info *a,
- union iwreq_data *wrqu, char *b)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
-
- return ieee80211_wx_get_freq(priv->ieee80211, a, wrqu, b);
-}
-
-
-static int r8180_wx_set_key(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *key)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- struct iw_point *erq = &(wrqu->encoding);
-
- if (priv->ieee80211->bHwRadioOff)
- return 0;
-
- if (erq->length > 0) {
- u32 *tkey = (u32 *) key;
- priv->key0[0] = tkey[0];
- priv->key0[1] = tkey[1];
- priv->key0[2] = tkey[2];
- priv->key0[3] = tkey[3] & 0xff;
- DMESG("Setting wep key to %x %x %x %x",
- tkey[0], tkey[1], tkey[2], tkey[3]);
- rtl8180_set_hw_wep(dev);
- }
- return 0;
-}
-
-
-static int r8180_wx_set_beaconinterval(struct net_device *dev,
- struct iw_request_info *aa,
- union iwreq_data *wrqu, char *b)
-{
- int *parms = (int *)b;
- int bi = parms[0];
-
- struct r8180_priv *priv = ieee80211_priv(dev);
-
- if (priv->ieee80211->bHwRadioOff)
- return 0;
-
- down(&priv->wx_sem);
- DMESG("setting beacon interval to %x", bi);
-
- priv->ieee80211->current_network.beacon_interval = bi;
- rtl8180_commit(dev);
- up(&priv->wx_sem);
-
- return 0;
-}
-
-
-
-static int r8180_wx_get_mode(struct net_device *dev, struct iw_request_info *a,
- union iwreq_data *wrqu, char *b)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- return ieee80211_wx_get_mode(priv->ieee80211, a, wrqu, b);
-}
-
-
-
-static int r8180_wx_get_rate(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- return ieee80211_wx_get_rate(priv->ieee80211, info, wrqu, extra);
-}
-
-
-
-static int r8180_wx_set_rate(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- int ret;
- struct r8180_priv *priv = ieee80211_priv(dev);
-
-
- if (priv->ieee80211->bHwRadioOff)
- return 0;
-
- down(&priv->wx_sem);
-
- ret = ieee80211_wx_set_rate(priv->ieee80211, info, wrqu, extra);
-
- up(&priv->wx_sem);
-
- return ret;
-}
-
-
-static int r8180_wx_set_crcmon(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- int *parms = (int *)extra;
- int enable = (parms[0] > 0);
- short prev = priv->crcmon;
-
-
- if (priv->ieee80211->bHwRadioOff)
- return 0;
-
- down(&priv->wx_sem);
-
- if (enable)
- priv->crcmon = 1;
- else
- priv->crcmon = 0;
-
- DMESG("bad CRC in monitor mode are %s",
- priv->crcmon ? "accepted" : "rejected");
-
- if (prev != priv->crcmon && priv->up) {
- rtl8180_down(dev);
- rtl8180_up(dev);
- }
-
- up(&priv->wx_sem);
-
- return 0;
-}
-
-
-static int r8180_wx_set_mode(struct net_device *dev, struct iw_request_info *a,
- union iwreq_data *wrqu, char *b)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- int ret;
-
-
- if (priv->ieee80211->bHwRadioOff)
- return 0;
-
- down(&priv->wx_sem);
- if (priv->bInactivePs) {
- if (wrqu->mode == IW_MODE_ADHOC)
- IPSLeave(dev);
- }
- ret = ieee80211_wx_set_mode(priv->ieee80211, a, wrqu, b);
-
- up(&priv->wx_sem);
- return ret;
-}
-
-/* YJ,add,080819,for hidden ap */
-struct iw_range_with_scan_capa {
- /* Informative stuff (to choose between different interface) */
-
- __u32 throughput; /* To give an idea... */
-
- /* In theory this value should be the maximum benchmarked
- * TCP/IP throughput, because with most of these devices the
- * bit rate is meaningless (overhead an co) to estimate how
- * fast the connection will go and pick the fastest one.
- * I suggest people to play with Netperf or any benchmark...
- */
-
- /* NWID (or domain id) */
- __u32 min_nwid; /* Minimal NWID we are able to set */
- __u32 max_nwid; /* Maximal NWID we are able to set */
-
- /* Old Frequency (backward compat - moved lower ) */
- __u16 old_num_channels;
- __u8 old_num_frequency;
-
- /* Scan capabilities */
- __u8 scan_capa;
-};
-/* YJ,add,080819,for hidden ap */
-
-
-static int rtl8180_wx_get_range(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct iw_range *range = (struct iw_range *)extra;
- struct r8180_priv *priv = ieee80211_priv(dev);
- u16 val;
- int i;
-
- wrqu->data.length = sizeof(*range);
- memset(range, 0, sizeof(*range));
-
- /* Let's try to keep this struct in the same order as in
- * linux/include/wireless.h
- */
-
- /* TODO: See what values we can set, and remove the ones we can't
- * set, or fill them with some default data.
- */
-
- /* ~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 */
-
- /* 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 */
- if (priv->rf_set_sens != NULL)
- range->sensitivity = priv->max_sens; /* signal level threshold range */
-
- range->max_qual.qual = 100;
- /* TODO: Find real max RSSI and stick here */
- range->max_qual.level = 0;
- range->max_qual.noise = -98;
- range->max_qual.updated = 7; /* Updated all three */
-
- range->avg_qual.qual = 92; /* > 8% missed beacons is 'bad' */
- /* TODO: Find real 'good' to 'bad' threshold value for RSSI */
- range->avg_qual.level = 20 + -98;
- range->avg_qual.noise = 0;
- range->avg_qual.updated = 7; /* Updated all three */
-
- range->num_bitrates = RATE_COUNT;
-
- for (i = 0; i < RATE_COUNT && i < IW_MAX_BITRATES; i++)
- range->bitrate[i] = rtl8180_rates[i];
-
- range->min_frag = MIN_FRAG_THRESHOLD;
- range->max_frag = MAX_FRAG_THRESHOLD;
-
- range->pm_capa = 0;
-
- range->we_version_compiled = WIRELESS_EXT;
- range->we_version_source = 16;
-
- range->num_channels = 14;
-
- for (i = 0, val = 0; i < 14; i++) {
-
- /* 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 ? */
- }
-
- if (val == IW_MAX_FREQUENCIES)
- break;
- }
-
- range->num_frequency = val;
- range->enc_capa = IW_ENC_CAPA_WPA | IW_ENC_CAPA_WPA2 |
- IW_ENC_CAPA_CIPHER_TKIP | IW_ENC_CAPA_CIPHER_CCMP;
-
- return 0;
-}
-
-
-static int r8180_wx_set_scan(struct net_device *dev, struct iw_request_info *a,
- union iwreq_data *wrqu, char *b)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- int ret;
- struct ieee80211_device *ieee = priv->ieee80211;
-
-
- if (priv->ieee80211->bHwRadioOff)
- return 0;
-
- if (wrqu->data.flags & IW_SCAN_THIS_ESSID) {
- struct iw_scan_req *req = (struct iw_scan_req *)b;
- if (req->essid_len) {
- ieee->current_network.ssid_len = req->essid_len;
- memcpy(ieee->current_network.ssid, req->essid, req->essid_len);
- }
- }
-
- down(&priv->wx_sem);
- if (priv->up) {
- priv->ieee80211->actscanning = true;
- if (priv->bInactivePs && (priv->ieee80211->state != IEEE80211_LINKED)) {
- IPSLeave(dev);
- ieee80211_softmac_ips_scan_syncro(priv->ieee80211);
- ret = 0;
- } else {
- /* prevent scan in BusyTraffic */
- /* FIXME: Need to consider last scan time */
- if ((priv->link_detect.b_busy_traffic) && (true)) {
- ret = 0;
- printk("Now traffic is busy, please try later!\n");
- } else
- /* prevent scan in BusyTraffic,end */
- ret = ieee80211_wx_set_scan(priv->ieee80211, a, wrqu, b);
- }
- } else
- ret = -1;
-
- up(&priv->wx_sem);
-
- return ret;
-}
-
-
-static int r8180_wx_get_scan(struct net_device *dev, struct iw_request_info *a,
- union iwreq_data *wrqu, char *b)
-{
-
- int ret;
- struct r8180_priv *priv = ieee80211_priv(dev);
-
- down(&priv->wx_sem);
- if (priv->up)
- ret = ieee80211_wx_get_scan(priv->ieee80211, a, wrqu, b);
- else
- ret = -1;
-
- up(&priv->wx_sem);
- return ret;
-}
-
-
-static int r8180_wx_set_essid(struct net_device *dev,
- struct iw_request_info *a,
- union iwreq_data *wrqu, char *b)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
-
- int ret;
-
- if (priv->ieee80211->bHwRadioOff)
- return 0;
-
- down(&priv->wx_sem);
- if (priv->bInactivePs)
- IPSLeave(dev);
-
- ret = ieee80211_wx_set_essid(priv->ieee80211, a, wrqu, b);
-
- up(&priv->wx_sem);
- return ret;
-}
-
-
-static int r8180_wx_get_essid(struct net_device *dev,
- struct iw_request_info *a,
- union iwreq_data *wrqu, char *b)
-{
- int ret;
- struct r8180_priv *priv = ieee80211_priv(dev);
-
- down(&priv->wx_sem);
-
- ret = ieee80211_wx_get_essid(priv->ieee80211, a, wrqu, b);
-
- up(&priv->wx_sem);
-
- return ret;
-}
-
-
-static int r8180_wx_set_freq(struct net_device *dev, struct iw_request_info *a,
- union iwreq_data *wrqu, char *b)
-{
- int ret;
- struct r8180_priv *priv = ieee80211_priv(dev);
-
-
- if (priv->ieee80211->bHwRadioOff)
- return 0;
-
- down(&priv->wx_sem);
-
- ret = ieee80211_wx_set_freq(priv->ieee80211, a, wrqu, b);
-
- up(&priv->wx_sem);
- return ret;
-}
-
-
-static int r8180_wx_get_name(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- return ieee80211_wx_get_name(priv->ieee80211, info, wrqu, extra);
-}
-
-static int r8180_wx_set_frag(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
-
- if (priv->ieee80211->bHwRadioOff)
- return 0;
-
- if (wrqu->frag.disabled)
- priv->ieee80211->fts = DEFAULT_FRAG_THRESHOLD;
- else {
- if (wrqu->frag.value < MIN_FRAG_THRESHOLD ||
- wrqu->frag.value > MAX_FRAG_THRESHOLD)
- return -EINVAL;
-
- priv->ieee80211->fts = wrqu->frag.value & ~0x1;
- }
-
- return 0;
-}
-
-
-static int r8180_wx_get_frag(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
-
- wrqu->frag.value = priv->ieee80211->fts;
- wrqu->frag.fixed = 0; /* no auto select */
- wrqu->frag.disabled = (wrqu->frag.value == DEFAULT_FRAG_THRESHOLD);
-
- return 0;
-}
-
-
-static int r8180_wx_set_wap(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *awrq, char *extra)
-{
- int ret;
- struct r8180_priv *priv = ieee80211_priv(dev);
-
- if (priv->ieee80211->bHwRadioOff)
- return 0;
-
- down(&priv->wx_sem);
-
- ret = ieee80211_wx_set_wap(priv->ieee80211, info, awrq, extra);
-
- up(&priv->wx_sem);
- return ret;
-
-}
-
-
-static int r8180_wx_get_wap(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
-
- return ieee80211_wx_get_wap(priv->ieee80211, info, wrqu, extra);
-}
-
-
-static int r8180_wx_set_enc(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *key)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- int ret;
-
- if (priv->ieee80211->bHwRadioOff)
- return 0;
-
-
- down(&priv->wx_sem);
-
- if (priv->hw_wep)
- ret = r8180_wx_set_key(dev, info, wrqu, key);
- else {
- DMESG("Setting SW wep key");
- ret = ieee80211_wx_set_encode(priv->ieee80211, info, wrqu, key);
- }
-
- up(&priv->wx_sem);
- return ret;
-}
-
-
-static int r8180_wx_get_enc(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *key)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
-
- return ieee80211_wx_get_encode(priv->ieee80211, info, wrqu, key);
-}
-
-
-static int r8180_wx_set_scan_type(struct net_device *dev,
- struct iw_request_info *aa,
- union iwreq_data *wrqu, char *p)
-{
-
- struct r8180_priv *priv = ieee80211_priv(dev);
- int *parms = (int *)p;
- int mode = parms[0];
-
- if (priv->ieee80211->bHwRadioOff)
- return 0;
-
- priv->ieee80211->active_scan = mode;
-
- return 1;
-}
-
-static int r8180_wx_set_retry(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- int err = 0;
-
- if (priv->ieee80211->bHwRadioOff)
- return 0;
-
- down(&priv->wx_sem);
-
- if (wrqu->retry.flags & IW_RETRY_LIFETIME ||
- wrqu->retry.disabled) {
- err = -EINVAL;
- goto exit;
- }
- if (!(wrqu->retry.flags & IW_RETRY_LIMIT)) {
- err = -EINVAL;
- goto exit;
- }
-
- if (wrqu->retry.value > R8180_MAX_RETRY) {
- err = -EINVAL;
- goto exit;
- }
- if (wrqu->retry.flags & IW_RETRY_MAX) {
- priv->retry_rts = wrqu->retry.value;
- DMESG("Setting retry for RTS/CTS data to %d", wrqu->retry.value);
-
- } else {
- priv->retry_data = wrqu->retry.value;
- DMESG("Setting retry for non RTS/CTS data to %d", wrqu->retry.value);
- }
-
- /* FIXME !
- * We might try to write directly the TX config register
- * or to restart just the (R)TX process.
- * I'm unsure if whole reset is really needed
- */
-
- rtl8180_commit(dev);
-exit:
- up(&priv->wx_sem);
-
- return err;
-}
-
-static int r8180_wx_get_retry(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
-
-
- wrqu->retry.disabled = 0; /* can't be disabled */
-
- if ((wrqu->retry.flags & IW_RETRY_TYPE) ==
- IW_RETRY_LIFETIME)
- return -EINVAL;
-
- if (wrqu->retry.flags & IW_RETRY_MAX) {
- wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MAX;
- wrqu->retry.value = priv->retry_rts;
- } else {
- wrqu->retry.flags = IW_RETRY_LIMIT | IW_RETRY_MIN;
- wrqu->retry.value = priv->retry_data;
- }
-
- return 0;
-}
-
-static int r8180_wx_get_sens(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8180_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;
- return 0;
-}
-
-
-static int r8180_wx_set_sens(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
-
- struct r8180_priv *priv = ieee80211_priv(dev);
-
- short err = 0;
-
- if (priv->ieee80211->bHwRadioOff)
- return 0;
-
- down(&priv->wx_sem);
- if (priv->rf_set_sens == NULL) {
- err = -1; /* we have not this support for this radio */
- goto exit;
- }
- if (priv->rf_set_sens(dev, wrqu->sens.value) == 0)
- priv->sens = wrqu->sens.value;
- else
- err = -EINVAL;
-
-exit:
- up(&priv->wx_sem);
-
- return err;
-}
-
-
-static int r8180_wx_set_rawtx(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- int ret;
-
- if (priv->ieee80211->bHwRadioOff)
- return 0;
-
- down(&priv->wx_sem);
-
- ret = ieee80211_wx_set_rawtx(priv->ieee80211, info, wrqu, extra);
-
- up(&priv->wx_sem);
-
- return ret;
-
-}
-
-static int r8180_wx_get_power(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- int ret;
- struct r8180_priv *priv = ieee80211_priv(dev);
-
- down(&priv->wx_sem);
-
- ret = ieee80211_wx_get_power(priv->ieee80211, info, wrqu, extra);
-
- up(&priv->wx_sem);
-
- return ret;
-}
-
-static int r8180_wx_set_power(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- int ret;
- struct r8180_priv *priv = ieee80211_priv(dev);
-
-
- if (priv->ieee80211->bHwRadioOff)
- return 0;
-
- down(&priv->wx_sem);
- printk("=>>>>>>>>>>=============================>set power:%d, %d!\n", wrqu->power.disabled, wrqu->power.flags);
- if (wrqu->power.disabled == 0) {
- wrqu->power.flags |= IW_POWER_ALL_R;
- wrqu->power.flags |= IW_POWER_TIMEOUT;
- wrqu->power.value = 1000;
- }
-
- ret = ieee80211_wx_set_power(priv->ieee80211, info, wrqu, extra);
-
- up(&priv->wx_sem);
-
- return ret;
-}
-
-static int r8180_wx_set_rts(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
-
-
- if (priv->ieee80211->bHwRadioOff)
- return 0;
-
- if (wrqu->rts.disabled)
- priv->rts = DEFAULT_RTS_THRESHOLD;
- else {
- if (wrqu->rts.value < MIN_RTS_THRESHOLD ||
- wrqu->rts.value > MAX_RTS_THRESHOLD)
- return -EINVAL;
-
- priv->rts = wrqu->rts.value;
- }
-
- return 0;
-}
-static int r8180_wx_get_rts(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
-
-
-
- wrqu->rts.value = priv->rts;
- wrqu->rts.fixed = 0; /* no auto select */
- wrqu->rts.disabled = (wrqu->rts.value == 0);
-
- return 0;
-}
-static int dummy(struct net_device *dev, struct iw_request_info *a,
- union iwreq_data *wrqu, char *b)
-{
- return -1;
-}
-
-static int r8180_wx_get_iwmode(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- struct ieee80211_device *ieee;
- int ret = 0;
-
-
-
- down(&priv->wx_sem);
-
- ieee = priv->ieee80211;
-
- strcpy(extra, "802.11");
- if (ieee->modulation & IEEE80211_CCK_MODULATION) {
- strcat(extra, "b");
- if (ieee->modulation & IEEE80211_OFDM_MODULATION)
- strcat(extra, "/g");
- } else if (ieee->modulation & IEEE80211_OFDM_MODULATION)
- strcat(extra, "g");
-
- up(&priv->wx_sem);
-
- return ret;
-}
-static int r8180_wx_set_iwmode(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- struct ieee80211_device *ieee = priv->ieee80211;
- int *param = (int *)extra;
- int ret = 0;
- int modulation = 0, mode = 0;
-
-
- if (priv->ieee80211->bHwRadioOff)
- return 0;
-
- down(&priv->wx_sem);
-
- if (*param == 1) {
- modulation |= IEEE80211_CCK_MODULATION;
- mode = IEEE_B;
- printk(KERN_INFO "B mode!\n");
- } else if (*param == 2) {
- modulation |= IEEE80211_OFDM_MODULATION;
- mode = IEEE_G;
- printk(KERN_INFO "G mode!\n");
- } else if (*param == 3) {
- modulation |= IEEE80211_CCK_MODULATION;
- modulation |= IEEE80211_OFDM_MODULATION;
- mode = IEEE_B|IEEE_G;
- printk(KERN_INFO "B/G mode!\n");
- }
-
- if (ieee->proto_started) {
- ieee80211_stop_protocol(ieee);
- ieee->mode = mode;
- ieee->modulation = modulation;
- ieee80211_start_protocol(ieee);
- } else {
- ieee->mode = mode;
- ieee->modulation = modulation;
- }
-
- up(&priv->wx_sem);
-
- return ret;
-}
-static int r8180_wx_get_preamble(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
-
-
-
- down(&priv->wx_sem);
-
-
-
- *extra = (char) priv->plcp_preamble_mode; /* 0:auto 1:short 2:long */
- up(&priv->wx_sem);
-
- return 0;
-}
-static int r8180_wx_set_preamble(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- int ret = 0;
-
-
- if (priv->ieee80211->bHwRadioOff)
- return 0;
-
- down(&priv->wx_sem);
- if (*extra < 0 || *extra > 2)
- ret = -1;
- else
- priv->plcp_preamble_mode = *((short *)extra);
-
-
-
- up(&priv->wx_sem);
-
- return ret;
-}
-static int r8180_wx_get_siglevel(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- int ret = 0;
-
-
-
- down(&priv->wx_sem);
- /* Modify by hikaru 6.5 */
- *((int *)extra) = priv->wstats.qual.level;/*for interface test ,it should be the priv->wstats.qual.level; */
-
-
-
- up(&priv->wx_sem);
-
- return ret;
-}
-static int r8180_wx_get_sigqual(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- int ret = 0;
-
-
-
- down(&priv->wx_sem);
- /* Modify by hikaru 6.5 */
- *((int *)extra) = priv->wstats.qual.qual;/* for interface test ,it should be the priv->wstats.qual.qual; */
-
-
-
- up(&priv->wx_sem);
-
- return ret;
-}
-static int r8180_wx_reset_stats(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- down(&priv->wx_sem);
-
- priv->stats.txrdu = 0;
- priv->stats.rxrdu = 0;
- priv->stats.rxnolast = 0;
- priv->stats.rxnodata = 0;
- priv->stats.rxnopointer = 0;
- priv->stats.txnperr = 0;
- priv->stats.txresumed = 0;
- priv->stats.rxerr = 0;
- priv->stats.rxoverflow = 0;
- priv->stats.rxint = 0;
-
- priv->stats.txnpokint = 0;
- priv->stats.txhpokint = 0;
- priv->stats.txhperr = 0;
- priv->stats.ints = 0;
- priv->stats.shints = 0;
- priv->stats.txoverflow = 0;
- priv->stats.rxdmafail = 0;
- priv->stats.txbeacon = 0;
- priv->stats.txbeaconerr = 0;
- priv->stats.txlpokint = 0;
- priv->stats.txlperr = 0;
- priv->stats.txretry = 0;/* 20060601 */
- priv->stats.rxcrcerrmin = 0 ;
- priv->stats.rxcrcerrmid = 0;
- priv->stats.rxcrcerrmax = 0;
- priv->stats.rxicverr = 0;
-
- up(&priv->wx_sem);
-
- return 0;
-
-}
-static int r8180_wx_radio_on(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
-
- if (priv->ieee80211->bHwRadioOff)
- return 0;
-
-
- down(&priv->wx_sem);
- priv->rf_wakeup(dev);
-
- up(&priv->wx_sem);
-
- return 0;
-
-}
-
-static int r8180_wx_radio_off(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
-
- if (priv->ieee80211->bHwRadioOff)
- return 0;
-
-
- down(&priv->wx_sem);
- priv->rf_sleep(dev);
-
- up(&priv->wx_sem);
-
- return 0;
-
-}
-static int r8180_wx_get_channelplan(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
-
-
-
- down(&priv->wx_sem);
- *extra = priv->channel_plan;
-
-
-
- up(&priv->wx_sem);
-
- return 0;
-}
-static int r8180_wx_set_channelplan(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- int *val = (int *)extra;
- int i;
- printk("-----in fun %s\n", __func__);
-
- if (priv->ieee80211->bHwRadioOff)
- return 0;
-
- /* unsigned long flags; */
- down(&priv->wx_sem);
- if (default_channel_plan[*val].len != 0) {
- priv->channel_plan = *val;
- /* Clear old channel map 8 */
- for (i = 1; i <= MAX_CHANNEL_NUMBER; i++)
- GET_DOT11D_INFO(priv->ieee80211)->channel_map[i] = 0;
-
- /* Set new channel map */
- for (i = 1; i <= default_channel_plan[*val].len; i++)
- GET_DOT11D_INFO(priv->ieee80211)->channel_map[default_channel_plan[*val].channel[i-1]] = 1;
-
- }
- up(&priv->wx_sem);
-
- return 0;
-}
-
-static int r8180_wx_get_version(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- /* struct ieee80211_device *ieee; */
-
- down(&priv->wx_sem);
- strcpy(extra, "1020.0808");
- up(&priv->wx_sem);
-
- return 0;
-}
-
-/* added by amy 080818 */
-/*receive datarate from user typing valid rate is from 2 to 108 (1 - 54M), if input 0, return to normal rate adaptive. */
-static int r8180_wx_set_forcerate(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- u8 forcerate = *extra;
-
- down(&priv->wx_sem);
-
- printk("==============>%s(): forcerate is %d\n", __func__, forcerate);
- if ((forcerate == 2) || (forcerate == 4) || (forcerate == 11) || (forcerate == 22) || (forcerate == 12) ||
- (forcerate == 18) || (forcerate == 24) || (forcerate == 36) || (forcerate == 48) || (forcerate == 72) ||
- (forcerate == 96) || (forcerate == 108)) {
- priv->ForcedDataRate = 1;
- priv->ieee80211->rate = forcerate * 5;
- } else if (forcerate == 0) {
- priv->ForcedDataRate = 0;
- printk("OK! return rate adaptive\n");
- } else
- printk("ERR: wrong rate\n");
- up(&priv->wx_sem);
- return 0;
-}
-
-static int r8180_wx_set_enc_ext(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
-
- struct r8180_priv *priv = ieee80211_priv(dev);
-
- int ret = 0;
-
- if (priv->ieee80211->bHwRadioOff)
- return 0;
-
- down(&priv->wx_sem);
- ret = ieee80211_wx_set_encode_ext(priv->ieee80211, info, wrqu, extra);
- up(&priv->wx_sem);
- return ret;
-
-}
-static int r8180_wx_set_auth(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- int ret = 0;
-
- if (priv->ieee80211->bHwRadioOff)
- return 0;
-
- down(&priv->wx_sem);
- ret = ieee80211_wx_set_auth(priv->ieee80211, info, &wrqu->param, extra);
- up(&priv->wx_sem);
- return ret;
-}
-
-static int r8180_wx_set_mlme(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- int ret = 0;
- struct r8180_priv *priv = ieee80211_priv(dev);
-
-
- if (priv->ieee80211->bHwRadioOff)
- return 0;
-
-
- down(&priv->wx_sem);
-#if 1
- ret = ieee80211_wx_set_mlme(priv->ieee80211, info, wrqu, extra);
-#endif
- up(&priv->wx_sem);
- return ret;
-}
-static int r8180_wx_set_gen_ie(struct net_device *dev,
- struct iw_request_info *info,
- union iwreq_data *wrqu, char *extra)
-{
- int ret = 0;
- struct r8180_priv *priv = ieee80211_priv(dev);
-
-
- if (priv->ieee80211->bHwRadioOff)
- return 0;
-
- down(&priv->wx_sem);
-#if 1
- ret = ieee80211_wx_set_gen_ie(priv->ieee80211, extra, wrqu->data.length);
-#endif
- up(&priv->wx_sem);
- return ret;
-
-
-}
-
-static const iw_handler r8180_wx_handlers[] = {
- IW_HANDLER(SIOCGIWNAME, r8180_wx_get_name),
- IW_HANDLER(SIOCSIWNWID, dummy),
- IW_HANDLER(SIOCGIWNWID, dummy),
- IW_HANDLER(SIOCSIWFREQ, r8180_wx_set_freq),
- IW_HANDLER(SIOCGIWFREQ, r8180_wx_get_freq),
- IW_HANDLER(SIOCSIWMODE, r8180_wx_set_mode),
- IW_HANDLER(SIOCGIWMODE, r8180_wx_get_mode),
- IW_HANDLER(SIOCSIWSENS, r8180_wx_set_sens),
- IW_HANDLER(SIOCGIWSENS, r8180_wx_get_sens),
- IW_HANDLER(SIOCGIWRANGE, rtl8180_wx_get_range),
- IW_HANDLER(SIOCSIWSPY, dummy),
- IW_HANDLER(SIOCGIWSPY, dummy),
- IW_HANDLER(SIOCSIWAP, r8180_wx_set_wap),
- IW_HANDLER(SIOCGIWAP, r8180_wx_get_wap),
- IW_HANDLER(SIOCSIWMLME, r8180_wx_set_mlme),
- IW_HANDLER(SIOCGIWAPLIST, dummy), /* deprecated */
- IW_HANDLER(SIOCSIWSCAN, r8180_wx_set_scan),
- IW_HANDLER(SIOCGIWSCAN, r8180_wx_get_scan),
- IW_HANDLER(SIOCSIWESSID, r8180_wx_set_essid),
- IW_HANDLER(SIOCGIWESSID, r8180_wx_get_essid),
- IW_HANDLER(SIOCSIWNICKN, dummy),
- IW_HANDLER(SIOCGIWNICKN, dummy),
- IW_HANDLER(SIOCSIWRATE, r8180_wx_set_rate),
- IW_HANDLER(SIOCGIWRATE, r8180_wx_get_rate),
- IW_HANDLER(SIOCSIWRTS, r8180_wx_set_rts),
- IW_HANDLER(SIOCGIWRTS, r8180_wx_get_rts),
- IW_HANDLER(SIOCSIWFRAG, r8180_wx_set_frag),
- IW_HANDLER(SIOCGIWFRAG, r8180_wx_get_frag),
- IW_HANDLER(SIOCSIWTXPOW, dummy),
- IW_HANDLER(SIOCGIWTXPOW, dummy),
- IW_HANDLER(SIOCSIWRETRY, r8180_wx_set_retry),
- IW_HANDLER(SIOCGIWRETRY, r8180_wx_get_retry),
- IW_HANDLER(SIOCSIWENCODE, r8180_wx_set_enc),
- IW_HANDLER(SIOCGIWENCODE, r8180_wx_get_enc),
- IW_HANDLER(SIOCSIWPOWER, r8180_wx_set_power),
- IW_HANDLER(SIOCGIWPOWER, r8180_wx_get_power),
- IW_HANDLER(SIOCSIWGENIE, r8180_wx_set_gen_ie),
- IW_HANDLER(SIOCSIWAUTH, r8180_wx_set_auth),
- IW_HANDLER(SIOCSIWENCODEEXT, r8180_wx_set_enc_ext),
-};
-
-static const struct iw_priv_args r8180_private_args[] = {
- {
- SIOCIWFIRSTPRIV + 0x0,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "badcrc"
- },
- { SIOCIWFIRSTPRIV + 0x1,
- 0, 0, "dummy"
-
- },
- {
- SIOCIWFIRSTPRIV + 0x2,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "beaconint"
- },
- { SIOCIWFIRSTPRIV + 0x3,
- 0, 0, "dummy"
-
- },
- {
- SIOCIWFIRSTPRIV + 0x4,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "activescan"
-
- },
- { SIOCIWFIRSTPRIV + 0x5,
- 0, 0, "dummy"
-
- },
- {
- SIOCIWFIRSTPRIV + 0x6,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "rawtx"
-
- },
- { SIOCIWFIRSTPRIV + 0x7,
- 0, 0, "dummy"
-
- },
- {
- SIOCIWFIRSTPRIV + 0x8,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setiwmode"
- },
- {
- SIOCIWFIRSTPRIV + 0x9,
- 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 32, "getiwmode"
- },
- {
- SIOCIWFIRSTPRIV + 0xA,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setpreamble"
- },
- {
- SIOCIWFIRSTPRIV + 0xB,
- 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getpreamble"
- },
- { SIOCIWFIRSTPRIV + 0xC,
- 0, 0, "dummy"
- },
- {
- SIOCIWFIRSTPRIV + 0xD,
- 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getrssi"
- },
- { SIOCIWFIRSTPRIV + 0xE,
- 0, 0, "dummy"
- },
- {
- SIOCIWFIRSTPRIV + 0xF,
- 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getlinkqual"
- },
- {
- SIOCIWFIRSTPRIV + 0x10,
- 0, 0, "resetstats"
- },
- {
- SIOCIWFIRSTPRIV + 0x11,
- 0, 0, "dummy"
- },
- {
- SIOCIWFIRSTPRIV + 0x12,
- 0, 0, "radioon"
- },
- {
- SIOCIWFIRSTPRIV + 0x13,
- 0, 0, "radiooff"
- },
- {
- SIOCIWFIRSTPRIV + 0x14,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setchannel"
- },
- {
- SIOCIWFIRSTPRIV + 0x15,
- 0, IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, "getchannel"
- },
- {
- SIOCIWFIRSTPRIV + 0x16,
- 0, 0, "dummy"
- },
- {
- SIOCIWFIRSTPRIV + 0x17,
- 0, IW_PRIV_TYPE_CHAR | IW_PRIV_SIZE_FIXED | 32, "getversion"
- },
- {
- SIOCIWFIRSTPRIV + 0x18,
- IW_PRIV_TYPE_INT | IW_PRIV_SIZE_FIXED | 1, 0, "setrate"
- },
-};
-
-
-static iw_handler r8180_private_handler[] = {
- r8180_wx_set_crcmon, /*SIOCIWSECONDPRIV*/
- dummy,
- r8180_wx_set_beaconinterval,
- dummy,
- /* r8180_wx_set_monitor_type, */
- r8180_wx_set_scan_type,
- dummy,
- r8180_wx_set_rawtx,
- dummy,
- r8180_wx_set_iwmode,
- r8180_wx_get_iwmode,
- r8180_wx_set_preamble,
- r8180_wx_get_preamble,
- dummy,
- r8180_wx_get_siglevel,
- dummy,
- r8180_wx_get_sigqual,
- r8180_wx_reset_stats,
- dummy,/* r8180_wx_get_stats */
- r8180_wx_radio_on,
- r8180_wx_radio_off,
- r8180_wx_set_channelplan,
- r8180_wx_get_channelplan,
- dummy,
- r8180_wx_get_version,
- r8180_wx_set_forcerate,
-};
-
-static inline int is_same_network(struct ieee80211_network *src,
- struct ieee80211_network *dst,
- struct ieee80211_device *ieee)
-{
- /* A network is only a duplicate if the channel, BSSID, ESSID
- * and the capability field (in particular IBSS and BSS) all match.
- * We treat all <hidden> with the same BSSID and channel
- * as one network
- */
- if (src->channel != dst->channel)
- return 0;
-
- if (memcmp(src->bssid, dst->bssid, ETH_ALEN) != 0)
- return 0;
-
- if (ieee->iw_mode != IW_MODE_INFRA) {
- if (src->ssid_len != dst->ssid_len)
- return 0;
- if (memcmp(src->ssid, dst->ssid, src->ssid_len) != 0)
- return 0;
- }
-
- if ((src->capability & WLAN_CAPABILITY_IBSS) !=
- (dst->capability & WLAN_CAPABILITY_IBSS))
- return 0;
- if ((src->capability & WLAN_CAPABILITY_BSS) !=
- (dst->capability & WLAN_CAPABILITY_BSS))
- return 0;
-
- return 1;
-}
-
-/* WB modified to show signal to GUI on 18-01-2008 */
-static struct iw_statistics *r8180_get_wireless_stats(struct net_device *dev)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- struct ieee80211_device *ieee = priv->ieee80211;
- struct iw_statistics *wstats = &priv->wstats;
- 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;
- wstats->qual.noise = 0;
- wstats->qual.updated = IW_QUAL_ALL_UPDATED | IW_QUAL_DBM;
- return wstats;
- }
-
- tmp_level = (&ieee->current_network)->stats.signal;
- tmp_qual = (&ieee->current_network)->stats.signalstrength;
- tmp_noise = (&ieee->current_network)->stats.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;
- return wstats;
-}
-
-struct iw_handler_def r8180_wx_handlers_def = {
- .standard = r8180_wx_handlers,
- .num_standard = ARRAY_SIZE(r8180_wx_handlers),
- .private = r8180_private_handler,
- .num_private = ARRAY_SIZE(r8180_private_handler),
- .num_private_args = sizeof(r8180_private_args) / sizeof(struct iw_priv_args),
- .get_wireless_stats = r8180_get_wireless_stats,
- .private_args = (struct iw_priv_args *)r8180_private_args,
-};
-
-
diff --git a/drivers/staging/rtl8187se/r8180_wx.h b/drivers/staging/rtl8187se/r8180_wx.h
deleted file mode 100644
index d471520..0000000
--- a/drivers/staging/rtl8187se/r8180_wx.h
+++ /dev/null
@@ -1,21 +0,0 @@
-/*
- This is part of rtl8180 OpenSource driver - v 0.3
- Copyright (C) Andrea Merello 2004 <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 Intel Pro Wireless 2100 GPL driver
-
- We want to thanks the Authors of such projects and the Ndiswrapper project Authors.
-*/
-
-/* this file (will) contains wireless extension handlers*/
-
-#ifndef R8180_WX_H
-#define R8180_WX_H
-#include <linux/wireless.h>
-#include "ieee80211/ieee80211.h"
-extern struct iw_handler_def r8180_wx_handlers_def;
-
-#endif
diff --git a/drivers/staging/rtl8187se/r8185b_init.c b/drivers/staging/rtl8187se/r8185b_init.c
deleted file mode 100644
index cc6f100..0000000
--- a/drivers/staging/rtl8187se/r8185b_init.c
+++ /dev/null
@@ -1,1464 +0,0 @@
-/*
- * Copyright (c) Realtek Semiconductor Corp. All rights reserved.
- *
- * Module Name:
- * r8185b_init.c
- *
- * Abstract:
- * Hardware Initialization and Hardware IO for RTL8185B
- *
- * Major Change History:
- * When Who What
- * ---------- --------------- -------------------------------
- * 2006-11-15 Xiong Created
- *
- * Notes:
- * This file is ported from RTL8185B Windows driver.
- *
- *
- */
-
-/*--------------------------Include File------------------------------------*/
-#include <linux/spinlock.h>
-#include "r8180_hw.h"
-#include "r8180.h"
-#include "r8180_rtl8225.h" /* RTL8225 Radio frontend */
-#include "r8180_93cx6.h" /* Card EEPROM */
-#include "r8180_wx.h"
-#include "ieee80211/dot11d.h"
-/* #define CONFIG_RTL8180_IO_MAP */
-#define TC_3W_POLL_MAX_TRY_CNT 5
-
-static u8 MAC_REG_TABLE[][2] = {
- /*
- * PAGE 0:
- * 0x34(BRSR), 0xBE(RATE_FALLBACK_CTL), 0x1E0(ARFR) would set in
- * HwConfigureRTL8185()
- * 0x272(RFSW_CTRL), 0x1CE(AESMSK_QC) set in InitializeAdapter8185().
- * 0x1F0~0x1F8 set in MacConfig_85BASIC()
- */
- {0x08, 0xae}, {0x0a, 0x72}, {0x5b, 0x42},
- {0x84, 0x88}, {0x85, 0x24}, {0x88, 0x54}, {0x8b, 0xb8}, {0x8c, 0x03},
- {0x8d, 0x40}, {0x8e, 0x00}, {0x8f, 0x00}, {0x5b, 0x18}, {0x91, 0x03},
- {0x94, 0x0F}, {0x95, 0x32},
- {0x96, 0x00}, {0x97, 0x07}, {0xb4, 0x22}, {0xdb, 0x00},
- {0xf0, 0x32}, {0xf1, 0x32}, {0xf2, 0x00}, {0xf3, 0x00}, {0xf4, 0x32},
- {0xf5, 0x43}, {0xf6, 0x00}, {0xf7, 0x00}, {0xf8, 0x46}, {0xf9, 0xa4},
- {0xfa, 0x00}, {0xfb, 0x00}, {0xfc, 0x96}, {0xfd, 0xa4}, {0xfe, 0x00},
- {0xff, 0x00},
-
- /*
- * PAGE 1:
- * For Flextronics system Logo PCIHCT failure:
- * 0x1C4~0x1CD set no-zero value to avoid PCI configuration
- * space 0x45[7]=1
- */
- {0x5e, 0x01},
- {0x58, 0x00}, {0x59, 0x00}, {0x5a, 0x04}, {0x5b, 0x00}, {0x60, 0x24},
- {0x61, 0x97}, {0x62, 0xF0}, {0x63, 0x09}, {0x80, 0x0F}, {0x81, 0xFF},
- {0x82, 0xFF}, {0x83, 0x03},
- /* lzm add 080826 */
- {0xC4, 0x22}, {0xC5, 0x22}, {0xC6, 0x22}, {0xC7, 0x22}, {0xC8, 0x22},
- /* lzm add 080826 */
- {0xC9, 0x22}, {0xCA, 0x22}, {0xCB, 0x22}, {0xCC, 0x22}, {0xCD, 0x22},
- {0xe2, 0x00},
-
-
- /* PAGE 2: */
- {0x5e, 0x02},
- {0x0c, 0x04}, {0x4c, 0x30}, {0x4d, 0x08}, {0x50, 0x05}, {0x51, 0xf5},
- {0x52, 0x04}, {0x53, 0xa0}, {0x54, 0xff}, {0x55, 0xff}, {0x56, 0xff},
- {0x57, 0xff}, {0x58, 0x08}, {0x59, 0x08}, {0x5a, 0x08}, {0x5b, 0x08},
- {0x60, 0x08}, {0x61, 0x08}, {0x62, 0x08}, {0x63, 0x08}, {0x64, 0x2f},
- {0x8c, 0x3f}, {0x8d, 0x3f}, {0x8e, 0x3f},
- {0x8f, 0x3f}, {0xc4, 0xff}, {0xc5, 0xff}, {0xc6, 0xff}, {0xc7, 0xff},
- {0xc8, 0x00}, {0xc9, 0x00}, {0xca, 0x80}, {0xcb, 0x00},
-
- /* PAGE 0: */
- {0x5e, 0x00}, {0x9f, 0x03}
- };
-
-
-static u8 ZEBRA_AGC[] = {
- 0,
- 0x7E, 0x7E, 0x7E, 0x7E, 0x7D, 0x7C, 0x7B, 0x7A, 0x79, 0x78, 0x77, 0x76,
- 0x75, 0x74, 0x73, 0x72, 0x71, 0x70, 0x6F, 0x6E, 0x6D, 0x6C, 0x6B, 0x6A,
- 0x69, 0x68, 0x67, 0x66, 0x65, 0x64, 0x63, 0x62, 0x48, 0x47, 0x46, 0x45,
- 0x44, 0x29, 0x28, 0x27, 0x26, 0x25, 0x24, 0x23, 0x22, 0x21, 0x08, 0x07,
- 0x06, 0x05, 0x04, 0x03, 0x02, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
- 0x00, 0x00, 0x00, 0x00, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f, 0x0f,
- 0x0f, 0x0f, 0x10, 0x11, 0x12, 0x13, 0x15, 0x16, 0x17, 0x17, 0x18, 0x18,
- 0x19, 0x1a, 0x1a, 0x1b, 0x1b, 0x1c, 0x1c, 0x1d, 0x1d, 0x1d, 0x1e, 0x1e,
- 0x1f, 0x1f, 0x1f, 0x20, 0x20, 0x20, 0x20, 0x21, 0x21, 0x21, 0x22, 0x22,
- 0x22, 0x23, 0x23, 0x24, 0x24, 0x25, 0x25, 0x25, 0x26, 0x26, 0x27, 0x27,
- 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F, 0x2F
- };
-
-static u32 ZEBRA_RF_RX_GAIN_TABLE[] = {
- 0x0096, 0x0076, 0x0056, 0x0036, 0x0016, 0x01f6, 0x01d6, 0x01b6,
- 0x0196, 0x0176, 0x00F7, 0x00D7, 0x00B7, 0x0097, 0x0077, 0x0057,
- 0x0037, 0x00FB, 0x00DB, 0x00BB, 0x00FF, 0x00E3, 0x00C3, 0x00A3,
- 0x0083, 0x0063, 0x0043, 0x0023, 0x0003, 0x01E3, 0x01C3, 0x01A3,
- 0x0183, 0x0163, 0x0143, 0x0123, 0x0103
- };
-
-static u8 OFDM_CONFIG[] = {
- /* OFDM reg0x06[7:0]=0xFF: Enable power saving mode in RX */
- /* OFDM reg0x3C[4]=1'b1: Enable RX power saving mode */
- /* ofdm 0x3a = 0x7b ,(original : 0xfb) For ECS shielding room TP test */
- /* 0x00 */
- 0x10, 0x0F, 0x0A, 0x0C, 0x14, 0xFA, 0xFF, 0x50,
- 0x00, 0x50, 0x00, 0x00, 0x00, 0x5C, 0x00, 0x00,
- /* 0x10 */
- 0x40, 0x00, 0x40, 0x00, 0x00, 0x00, 0xA8, 0x26,
- 0x32, 0x33, 0x06, 0xA5, 0x6F, 0x55, 0xC8, 0xBB,
- /* 0x20 */
- 0x0A, 0xE1, 0x2C, 0x4A, 0x86, 0x83, 0x34, 0x00,
- 0x4F, 0x24, 0x6F, 0xC2, 0x03, 0x40, 0x80, 0x00,
- /* 0x30 */
- 0xC0, 0xC1, 0x58, 0xF1, 0x00, 0xC4, 0x90, 0x3e,
- 0xD8, 0x3C, 0x7B, 0x10, 0x10
- };
-
- /*---------------------------------------------------------------
- * Hardware IO
- * the code is ported from Windows source code
- *---------------------------------------------------------------
- */
-
-static u8 PlatformIORead1Byte(struct net_device *dev, u32 offset)
-{
- return read_nic_byte(dev, offset);
-}
-
-static void PlatformIOWrite1Byte(struct net_device *dev, u32 offset, u8 data)
-{
- write_nic_byte(dev, offset, data);
- /*
- * To make sure write operation is completed,
- * 2005.11.09, by rcnjko.
- */
- read_nic_byte(dev, offset);
-}
-
-static void PlatformIOWrite2Byte(struct net_device *dev, u32 offset, u16 data)
-{
- write_nic_word(dev, offset, data);
- /*
- * To make sure write operation is completed,
- * 2005.11.09, by rcnjko.
- */
- read_nic_word(dev, offset);
-}
-
-static void PlatformIOWrite4Byte(struct net_device *dev, u32 offset, u32 data)
-{
- if (offset == PhyAddr) {
- /* For Base Band configuration. */
- unsigned char cmdByte;
- unsigned long dataBytes;
- unsigned char idx;
- u8 u1bTmp;
-
- cmdByte = (u8)(data & 0x000000ff);
- dataBytes = data>>8;
-
- /*
- * 071010, rcnjko:
- * The critical section is only BB read/write race
- * condition. Assumption:
- * 1. We assume NO one will access BB at DIRQL, otherwise,
- * system will crash for
- * acquiring the spinlock in such context.
- * 2. PlatformIOWrite4Byte() MUST NOT be recursive.
- */
- /* NdisAcquireSpinLock( &(pDevice->IoSpinLock) ); */
-
- for (idx = 0; idx < 30; idx++) {
- /* Make sure command bit is clear before access it. */
- u1bTmp = PlatformIORead1Byte(dev, PhyAddr);
- if ((u1bTmp & BIT7) == 0)
- break;
- else
- mdelay(10);
- }
-
- for (idx = 0; idx < 3; idx++)
- PlatformIOWrite1Byte(dev, offset+1+idx,
- ((u8 *)&dataBytes)[idx]);
-
- write_nic_byte(dev, offset, cmdByte);
-
- /* NdisReleaseSpinLock( &(pDevice->IoSpinLock) ); */
- } else {
- write_nic_dword(dev, offset, data);
- /*
- * To make sure write operation is completed, 2005.11.09,
- * by rcnjko.
- */
- read_nic_dword(dev, offset);
- }
-}
-
-static void SetOutputEnableOfRfPins(struct net_device *dev)
-{
- write_nic_word(dev, RFPinsEnable, 0x1bff);
-}
-
-static bool HwHSSIThreeWire(struct net_device *dev,
- u8 *pDataBuf,
- bool write)
-{
- u8 TryCnt;
- u8 u1bTmp;
-
- /* Check if WE and RE are cleared. */
- for (TryCnt = 0; TryCnt < TC_3W_POLL_MAX_TRY_CNT; TryCnt++) {
- u1bTmp = read_nic_byte(dev, SW_3W_CMD1);
- if ((u1bTmp & (SW_3W_CMD1_RE|SW_3W_CMD1_WE)) == 0)
- break;
-
- udelay(10);
- }
- if (TryCnt == TC_3W_POLL_MAX_TRY_CNT) {
- netdev_err(dev,
- "HwThreeWire(): CmdReg: %#X RE|WE bits are not clear!!\n",
- u1bTmp);
- return false;
- }
-
- /* RTL8187S HSSI Read/Write Function */
- u1bTmp = read_nic_byte(dev, RF_SW_CONFIG);
- u1bTmp |= RF_SW_CFG_SI; /* reg08[1]=1 Serial Interface(SI) */
- write_nic_byte(dev, RF_SW_CONFIG, u1bTmp);
-
- /* jong: HW SI read must set reg84[3]=0. */
- u1bTmp = read_nic_byte(dev, RFPinsSelect);
- u1bTmp &= ~BIT3;
- write_nic_byte(dev, RFPinsSelect, u1bTmp);
- /* Fill up data buffer for write operation. */
-
- /* SI - reg274[3:0] : RF register's Address */
- if (write)
- write_nic_word(dev, SW_3W_DB0, *((u16 *)pDataBuf));
- else
- write_nic_word(dev, SW_3W_DB0, *((u16 *)pDataBuf));
-
- /* Set up command: WE or RE. */
- if (write)
- write_nic_byte(dev, SW_3W_CMD1, SW_3W_CMD1_WE);
- else
- write_nic_byte(dev, SW_3W_CMD1, SW_3W_CMD1_RE);
-
-
- /* Check if DONE is set. */
- for (TryCnt = 0; TryCnt < TC_3W_POLL_MAX_TRY_CNT; TryCnt++) {
- u1bTmp = read_nic_byte(dev, SW_3W_CMD1);
- if (u1bTmp & SW_3W_CMD1_DONE)
- break;
-
- udelay(10);
- }
-
- write_nic_byte(dev, SW_3W_CMD1, 0);
-
- /* Read back data for read operation. */
- if (!write) {
- /* Serial Interface : reg363_362[11:0] */
- *((u16 *)pDataBuf) = read_nic_word(dev, SI_DATA_READ);
- *((u16 *)pDataBuf) &= 0x0FFF;
- }
-
- return true;
-}
-
-void RF_WriteReg(struct net_device *dev, u8 offset, u16 data)
-{
- u16 reg = (data << 4) | (offset & 0x0f);
- HwHSSIThreeWire(dev, (u8 *)&reg, true);
-}
-
-u16 RF_ReadReg(struct net_device *dev, u8 offset)
-{
- u16 reg = offset & 0x0f;
- HwHSSIThreeWire(dev, (u8 *)&reg, false);
- return reg;
-}
-
-static u8 ReadBBPortUchar(struct net_device *dev, u32 addr)
-{
- PlatformIOWrite4Byte(dev, PhyAddr, addr & 0xffffff7f);
- return PlatformIORead1Byte(dev, PhyDataR);
-}
-
-/* by Owen on 04/07/14 for writing BB register successfully */
-static void WriteBBPortUchar(struct net_device *dev, u32 Data)
-{
- PlatformIOWrite4Byte(dev, PhyAddr, Data);
- ReadBBPortUchar(dev, Data);
-}
-
-/*
- * Description:
- * Perform Antenna settings with antenna diversity on 87SE.
- * Created by Roger, 2008.01.25.
- */
-bool SetAntennaConfig87SE(struct net_device *dev,
- u8 DefaultAnt, /* 0: Main, 1: Aux. */
- bool bAntDiversity) /* 1:Enable, 0: Disable. */
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- bool bAntennaSwitched = true;
- /* 0x00 = disabled, 0x80 = enabled */
- u8 ant_diversity_offset = 0x00;
-
- /*
- * printk("SetAntennaConfig87SE(): DefaultAnt(%d), bAntDiversity(%d)\n",
- * DefaultAnt, bAntDiversity);
- */
-
- /* Threshold for antenna diversity. */
- write_phy_cck(dev, 0x0c, 0x09); /* Reg0c : 09 */
-
- if (bAntDiversity) /* Enable Antenna Diversity. */
- ant_diversity_offset = 0x80;
-
- if (DefaultAnt == 1) { /* aux Antenna */
- /* Mac register, aux antenna */
- write_nic_byte(dev, ANTSEL, 0x00);
-
- /* Config CCK RX antenna. */
- write_phy_cck(dev, 0x11, 0xbb); /* Reg11 : bb */
-
- /* Reg01 : 47 | ant_diversity_offset */
- write_phy_cck(dev, 0x01, 0x47|ant_diversity_offset);
-
- /* Config OFDM RX antenna. */
- write_phy_ofdm(dev, 0x0D, 0x54); /* Reg0d : 54 */
- /* Reg18 : 32 */
- write_phy_ofdm(dev, 0x18, 0x32|ant_diversity_offset);
- } else { /* main Antenna */
- /* Mac register, main antenna */
- write_nic_byte(dev, ANTSEL, 0x03);
-
- /* Config CCK RX antenna. */
- write_phy_cck(dev, 0x11, 0x9b); /* Reg11 : 9b */
- /* Reg01 : 47 */
- write_phy_cck(dev, 0x01, 0x47|ant_diversity_offset);
-
- /* Config OFDM RX antenna. */
- write_phy_ofdm(dev, 0x0D, 0x5c); /* Reg0d : 5c */
- /*Reg18 : 32 */
- write_phy_ofdm(dev, 0x18, 0x32|ant_diversity_offset);
- }
- priv->CurrAntennaIndex = DefaultAnt; /* Update default settings. */
- return bAntennaSwitched;
-}
-/*
- *--------------------------------------------------------------
- * Hardware Initialization.
- * the code is ported from Windows source code
- *--------------------------------------------------------------
- */
-
-static void ZEBRA_Config_85BASIC_HardCode(struct net_device *dev)
-{
-
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- u32 i;
- u32 addr, data;
- u32 u4bRegOffset, u4bRegValue;
- u16 u4bRF23, u4bRF24;
- u8 u1b24E;
- int d_cut = 0;
-
-
-/*
- *===========================================================================
- * 87S_PCIE :: RADIOCFG.TXT
- *===========================================================================
- */
-
-
- /* Page1 : reg16-reg30 */
- RF_WriteReg(dev, 0x00, 0x013f); mdelay(1); /* switch to page1 */
- u4bRF23 = RF_ReadReg(dev, 0x08); mdelay(1);
- u4bRF24 = RF_ReadReg(dev, 0x09); mdelay(1);
-
- if (u4bRF23 == 0x818 && u4bRF24 == 0x70C) {
- d_cut = 1;
- netdev_info(dev, "card type changed from C- to D-cut\n");
- }
-
- /* Page0 : reg0-reg15 */
-
- RF_WriteReg(dev, 0x00, 0x009f); mdelay(1);/* 1 */
- RF_WriteReg(dev, 0x01, 0x06e0); mdelay(1);
- RF_WriteReg(dev, 0x02, 0x004d); mdelay(1);/* 2 */
- RF_WriteReg(dev, 0x03, 0x07f1); mdelay(1);/* 3 */
- RF_WriteReg(dev, 0x04, 0x0975); mdelay(1);
- RF_WriteReg(dev, 0x05, 0x0c72); mdelay(1);
- RF_WriteReg(dev, 0x06, 0x0ae6); mdelay(1);
- RF_WriteReg(dev, 0x07, 0x00ca); mdelay(1);
- RF_WriteReg(dev, 0x08, 0x0e1c); mdelay(1);
- RF_WriteReg(dev, 0x09, 0x02f0); mdelay(1);
- RF_WriteReg(dev, 0x0a, 0x09d0); mdelay(1);
- RF_WriteReg(dev, 0x0b, 0x01ba); mdelay(1);
- RF_WriteReg(dev, 0x0c, 0x0640); mdelay(1);
- RF_WriteReg(dev, 0x0d, 0x08df); mdelay(1);
- RF_WriteReg(dev, 0x0e, 0x0020); mdelay(1);
- RF_WriteReg(dev, 0x0f, 0x0990); mdelay(1);
-
- /* Page1 : reg16-reg30 */
- RF_WriteReg(dev, 0x00, 0x013f); mdelay(1);
- RF_WriteReg(dev, 0x03, 0x0806); mdelay(1);
- RF_WriteReg(dev, 0x04, 0x03a7); mdelay(1);
- RF_WriteReg(dev, 0x05, 0x059b); mdelay(1);
- RF_WriteReg(dev, 0x06, 0x0081); mdelay(1);
- RF_WriteReg(dev, 0x07, 0x01A0); mdelay(1);
-/*
- * Don't write RF23/RF24 to make a difference between 87S C cut and D cut.
- * asked by SD3 stevenl.
- */
- RF_WriteReg(dev, 0x0a, 0x0001); mdelay(1);
- RF_WriteReg(dev, 0x0b, 0x0418); mdelay(1);
-
- if (d_cut) {
- RF_WriteReg(dev, 0x0c, 0x0fbe); mdelay(1);
- RF_WriteReg(dev, 0x0d, 0x0008); mdelay(1);
- /* RX LO buffer */
- RF_WriteReg(dev, 0x0e, 0x0807); mdelay(1);
- } else {
- RF_WriteReg(dev, 0x0c, 0x0fbe); mdelay(1);
- RF_WriteReg(dev, 0x0d, 0x0008); mdelay(1);
- /* RX LO buffer */
- RF_WriteReg(dev, 0x0e, 0x0806); mdelay(1);
- }
-
- RF_WriteReg(dev, 0x0f, 0x0acc); mdelay(1);
- RF_WriteReg(dev, 0x00, 0x01d7); mdelay(1); /* 6 */
- RF_WriteReg(dev, 0x03, 0x0e00); mdelay(1);
- RF_WriteReg(dev, 0x04, 0x0e50); mdelay(1);
-
- for (i = 0; i <= 36; i++) {
- RF_WriteReg(dev, 0x01, i); mdelay(1);
- RF_WriteReg(dev, 0x02, ZEBRA_RF_RX_GAIN_TABLE[i]); mdelay(1);
- }
-
- RF_WriteReg(dev, 0x05, 0x0203); mdelay(1); /* 203, 343 */
- RF_WriteReg(dev, 0x06, 0x0200); mdelay(1); /* 400 */
- /* switch to reg16-reg30, and HSSI disable 137 */
- RF_WriteReg(dev, 0x00, 0x0137); mdelay(1);
- mdelay(10); /* Deay 10 ms. */ /* 0xfd */
-
- /* Z4 synthesizer loop filter setting, 392 */
- RF_WriteReg(dev, 0x0d, 0x0008); mdelay(1);
- mdelay(10); /* Deay 10 ms. */ /* 0xfd */
-
- /* switch to reg0-reg15, and HSSI disable */
- RF_WriteReg(dev, 0x00, 0x0037); mdelay(1);
- mdelay(10); /* Deay 10 ms. */ /* 0xfd */
-
- /* CBC on, Tx Rx disable, High gain */
- RF_WriteReg(dev, 0x04, 0x0160); mdelay(1);
- mdelay(10); /* Deay 10 ms. */ /* 0xfd */
-
- /* Z4 setted channel 1 */
- RF_WriteReg(dev, 0x07, 0x0080); mdelay(1);
- mdelay(10); /* Deay 10 ms. */ /* 0xfd */
-
- RF_WriteReg(dev, 0x02, 0x088D); mdelay(1); /* LC calibration */
- mdelay(200); /* Deay 200 ms. */ /* 0xfd */
- mdelay(10); /* Deay 10 ms. */ /* 0xfd */
- mdelay(10); /* Deay 10 ms. */ /* 0xfd */
-
- /* switch to reg16-reg30 137, and HSSI disable 137 */
- RF_WriteReg(dev, 0x00, 0x0137); mdelay(1);
- mdelay(10); /* Deay 10 ms. */ /* 0xfd */
-
- RF_WriteReg(dev, 0x07, 0x0000); mdelay(1);
- RF_WriteReg(dev, 0x07, 0x0180); mdelay(1);
- RF_WriteReg(dev, 0x07, 0x0220); mdelay(1);
- RF_WriteReg(dev, 0x07, 0x03E0); mdelay(1);
-
- /* DAC calibration off 20070702 */
- RF_WriteReg(dev, 0x06, 0x00c1); mdelay(1);
- RF_WriteReg(dev, 0x0a, 0x0001); mdelay(1);
- /* For crystal calibration, added by Roger, 2007.12.11. */
- if (priv->bXtalCalibration) { /* reg 30. */
- /*
- * enable crystal calibration.
- * RF Reg[30], (1)Xin:[12:9], Xout:[8:5], addr[4:0].
- * (2)PA Pwr delay timer[15:14], default: 2.4us,
- * set BIT15=0
- * (3)RF signal on/off when calibration[13], default: on,
- * set BIT13=0.
- * So we should minus 4 BITs offset.
- */
- RF_WriteReg(dev, 0x0f, (priv->XtalCal_Xin<<5) |
- (priv->XtalCal_Xout<<1) | BIT11 | BIT9); mdelay(1);
- netdev_info(dev, "ZEBRA_Config_85BASIC_HardCode(): (%02x)\n",
- (priv->XtalCal_Xin<<5) | (priv->XtalCal_Xout<<1) |
- BIT11 | BIT9);
- } else {
- /* using default value. Xin=6, Xout=6. */
- RF_WriteReg(dev, 0x0f, 0x0acc); mdelay(1);
- }
- /* switch to reg0-reg15, and HSSI enable */
- RF_WriteReg(dev, 0x00, 0x00bf); mdelay(1);
- /* Rx BB start calibration, 00c//+edward */
- RF_WriteReg(dev, 0x0d, 0x08df); mdelay(1);
- /* temperature meter off */
- RF_WriteReg(dev, 0x02, 0x004d); mdelay(1);
- RF_WriteReg(dev, 0x04, 0x0975); mdelay(1); /* Rx mode */
- mdelay(10); /* Deay 10 ms.*/ /* 0xfe */
- mdelay(10); /* Deay 10 ms.*/ /* 0xfe */
- mdelay(10); /* Deay 10 ms.*/ /* 0xfe */
- /* Rx mode*/ /*+edward */
- RF_WriteReg(dev, 0x00, 0x0197); mdelay(1);
- /* Rx mode*/ /*+edward */
- RF_WriteReg(dev, 0x05, 0x05ab); mdelay(1);
- /* Rx mode*/ /*+edward */
- RF_WriteReg(dev, 0x00, 0x009f); mdelay(1);
- /* Rx mode*/ /*+edward */
- RF_WriteReg(dev, 0x01, 0x0000); mdelay(1);
- /* Rx mode*/ /*+edward */
- RF_WriteReg(dev, 0x02, 0x0000); mdelay(1);
- /* power save parameters. */
- u1b24E = read_nic_byte(dev, 0x24E);
- write_nic_byte(dev, 0x24E, (u1b24E & (~(BIT5|BIT6))));
-
- /*======================================================================
- *
- *======================================================================
- * CCKCONF.TXT
- *======================================================================
- *
- * [POWER SAVE] Power Saving Parameters by jong. 2007-11-27
- * CCK reg0x00[7]=1'b1 :power saving for TX (default)
- * CCK reg0x00[6]=1'b1: power saving for RX (default)
- * CCK reg0x06[4]=1'b1: turn off channel estimation related
- * circuits if not doing channel estimation.
- * CCK reg0x06[3]=1'b1: turn off unused circuits before cca = 1
- * CCK reg0x06[2]=1'b1: turn off cck's circuit if macrst =0
- */
-
- write_phy_cck(dev, 0x00, 0xc8);
- write_phy_cck(dev, 0x06, 0x1c);
- write_phy_cck(dev, 0x10, 0x78);
- write_phy_cck(dev, 0x2e, 0xd0);
- write_phy_cck(dev, 0x2f, 0x06);
- write_phy_cck(dev, 0x01, 0x46);
-
- /* power control */
- write_nic_byte(dev, CCK_TXAGC, 0x10);
- write_nic_byte(dev, OFDM_TXAGC, 0x1B);
- write_nic_byte(dev, ANTSEL, 0x03);
-
-
-
- /*
- *======================================================================
- * AGC.txt
- *======================================================================
- */
-
- write_phy_ofdm(dev, 0x00, 0x12);
-
- for (i = 0; i < 128; i++) {
-
- data = ZEBRA_AGC[i+1];
- data = data << 8;
- data = data | 0x0000008F;
-
- addr = i + 0x80; /* enable writing AGC table */
- addr = addr << 8;
- addr = addr | 0x0000008E;
-
- WriteBBPortUchar(dev, data);
- WriteBBPortUchar(dev, addr);
- WriteBBPortUchar(dev, 0x0000008E);
- }
-
- PlatformIOWrite4Byte(dev, PhyAddr, 0x00001080); /* Annie, 2006-05-05 */
-
- /*
- *======================================================================
- *
- *======================================================================
- * OFDMCONF.TXT
- *======================================================================
- */
-
- for (i = 0; i < 60; i++) {
- u4bRegOffset = i;
- u4bRegValue = OFDM_CONFIG[i];
-
- WriteBBPortUchar(dev,
- (0x00000080 |
- (u4bRegOffset & 0x7f) |
- ((u4bRegValue & 0xff) << 8)));
- }
-
- /*
- *======================================================================
- * by amy for antenna
- *======================================================================
- */
- /*
- * Config Sw/Hw Combinational Antenna Diversity. Added by Roger,
- * 2008.02.26.
- */
- SetAntennaConfig87SE(dev, priv->bDefaultAntenna1,
- priv->bSwAntennaDiverity);
-}
-
-
-void UpdateInitialGain(struct net_device *dev)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
- /* lzm add 080826 */
- if (priv->eRFPowerState != RF_ON) {
- /* Don't access BB/RF under disable PLL situation.
- * RT_TRACE(COMP_DIG, DBG_LOUD, ("UpdateInitialGain -
- * pHalData->eRFPowerState!=RF_ON\n"));
- * Back to the original state
- */
- priv->InitialGain = priv->InitialGainBackUp;
- return;
- }
-
- switch (priv->InitialGain) {
- case 1: /* m861dBm */
- write_phy_ofdm(dev, 0x17, 0x26); mdelay(1);
- write_phy_ofdm(dev, 0x24, 0x86); mdelay(1);
- write_phy_ofdm(dev, 0x05, 0xfa); mdelay(1);
- break;
-
- case 2: /* m862dBm */
- write_phy_ofdm(dev, 0x17, 0x36); mdelay(1);
- write_phy_ofdm(dev, 0x24, 0x86); mdelay(1);
- write_phy_ofdm(dev, 0x05, 0xfa); mdelay(1);
- break;
-
- case 3: /* m863dBm */
- write_phy_ofdm(dev, 0x17, 0x36); mdelay(1);
- write_phy_ofdm(dev, 0x24, 0x86); mdelay(1);
- write_phy_ofdm(dev, 0x05, 0xfb); mdelay(1);
- break;
-
- case 4: /* m864dBm */
- write_phy_ofdm(dev, 0x17, 0x46); mdelay(1);
- write_phy_ofdm(dev, 0x24, 0x86); mdelay(1);
- write_phy_ofdm(dev, 0x05, 0xfb); mdelay(1);
- break;
-
- case 5: /* m82dBm */
- write_phy_ofdm(dev, 0x17, 0x46); mdelay(1);
- write_phy_ofdm(dev, 0x24, 0x96); mdelay(1);
- write_phy_ofdm(dev, 0x05, 0xfb); mdelay(1);
- break;
-
- case 6: /* m78dBm */
- write_phy_ofdm(dev, 0x17, 0x56); mdelay(1);
- write_phy_ofdm(dev, 0x24, 0x96); mdelay(1);
- write_phy_ofdm(dev, 0x05, 0xfc); mdelay(1);
- break;
-
- case 7: /* m74dBm */
- write_phy_ofdm(dev, 0x17, 0x56); mdelay(1);
- write_phy_ofdm(dev, 0x24, 0xa6); mdelay(1);
- write_phy_ofdm(dev, 0x05, 0xfc); mdelay(1);
- break;
-
- case 8:
- write_phy_ofdm(dev, 0x17, 0x66); mdelay(1);
- write_phy_ofdm(dev, 0x24, 0xb6); mdelay(1);
- write_phy_ofdm(dev, 0x05, 0xfc); mdelay(1);
- break;
-
- default: /* MP */
- write_phy_ofdm(dev, 0x17, 0x26); mdelay(1);
- write_phy_ofdm(dev, 0x24, 0x86); mdelay(1);
- write_phy_ofdm(dev, 0x05, 0xfa); mdelay(1);
- break;
- }
-}
-/*
- * Description:
- * Tx Power tracking mechanism routine on 87SE.
- * Created by Roger, 2007.12.11.
- */
-static void InitTxPwrTracking87SE(struct net_device *dev)
-{
- u32 u4bRfReg;
-
- u4bRfReg = RF_ReadReg(dev, 0x02);
-
- /* Enable Thermal meter indication. */
- RF_WriteReg(dev, 0x02, u4bRfReg|PWR_METER_EN); mdelay(1);
-}
-
-static void PhyConfig8185(struct net_device *dev)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- write_nic_dword(dev, RCR, priv->ReceiveConfig);
- priv->RFProgType = read_nic_byte(dev, CONFIG4) & 0x03;
- /* RF config */
- ZEBRA_Config_85BASIC_HardCode(dev);
- /* Set default initial gain state to 4, approved by SD3 DZ, by Bruce,
- * 2007-06-06.
- */
- if (priv->bDigMechanism) {
- if (priv->InitialGain == 0)
- priv->InitialGain = 4;
- }
-
- /*
- * Enable thermal meter indication to implement TxPower tracking
- * on 87SE. We initialize thermal meter here to avoid unsuccessful
- * configuration. Added by Roger, 2007.12.11.
- */
- if (priv->bTxPowerTrack)
- InitTxPwrTracking87SE(dev);
-
- priv->InitialGainBackUp = priv->InitialGain;
- UpdateInitialGain(dev);
-
- return;
-}
-
-static void HwConfigureRTL8185(struct net_device *dev)
-{
- /*
- * RTL8185_TODO: Determine Retrylimit, TxAGC,
- * AutoRateFallback control.
- */
- u8 bUNIVERSAL_CONTROL_RL = 0;
- u8 bUNIVERSAL_CONTROL_AGC = 1;
- u8 bUNIVERSAL_CONTROL_ANT = 1;
- u8 bAUTO_RATE_FALLBACK_CTL = 1;
- u8 val8;
- write_nic_word(dev, BRSR, 0x0fff);
- /* Retry limit */
- val8 = read_nic_byte(dev, CW_CONF);
-
- if (bUNIVERSAL_CONTROL_RL)
- val8 = val8 & 0xfd;
- else
- val8 = val8 | 0x02;
-
- write_nic_byte(dev, CW_CONF, val8);
-
- /* Tx AGC */
- val8 = read_nic_byte(dev, TXAGC_CTL);
- if (bUNIVERSAL_CONTROL_AGC) {
- write_nic_byte(dev, CCK_TXAGC, 128);
- write_nic_byte(dev, OFDM_TXAGC, 128);
- val8 = val8 & 0xfe;
- } else {
- val8 = val8 | 0x01;
- }
-
-
- write_nic_byte(dev, TXAGC_CTL, val8);
-
- /* Tx Antenna including Feedback control */
- val8 = read_nic_byte(dev, TXAGC_CTL);
-
- if (bUNIVERSAL_CONTROL_ANT) {
- write_nic_byte(dev, ANTSEL, 0x00);
- val8 = val8 & 0xfd;
- } else {
- val8 = val8 & (val8|0x02); /* xiong-2006-11-15 */
- }
-
- write_nic_byte(dev, TXAGC_CTL, val8);
-
- /* Auto Rate fallback control */
- val8 = read_nic_byte(dev, RATE_FALLBACK);
- val8 &= 0x7c;
- if (bAUTO_RATE_FALLBACK_CTL) {
- val8 |= RATE_FALLBACK_CTL_ENABLE | RATE_FALLBACK_CTL_AUTO_STEP1;
-
- /* <RJ_TODO_8185B> We shall set up the ARFR according
- * to user's setting.
- */
- PlatformIOWrite2Byte(dev, ARFR, 0x0fff); /* set 1M ~ 54Mbps. */
- }
- write_nic_byte(dev, RATE_FALLBACK, val8);
-}
-
-static void MacConfig_85BASIC_HardCode(struct net_device *dev)
-{
- /*
- *======================================================================
- * MACREG.TXT
- *======================================================================
- */
- int nLinesRead = 0;
- u32 u4bRegOffset, u4bRegValue, u4bPageIndex = 0;
- int i;
-
- nLinesRead = sizeof(MAC_REG_TABLE)/2;
-
- for (i = 0; i < nLinesRead; i++) { /* nLinesRead=101 */
- u4bRegOffset = MAC_REG_TABLE[i][0];
- u4bRegValue = MAC_REG_TABLE[i][1];
-
- if (u4bRegOffset == 0x5e)
- u4bPageIndex = u4bRegValue;
- else
- u4bRegOffset |= (u4bPageIndex << 8);
-
- write_nic_byte(dev, u4bRegOffset, (u8)u4bRegValue);
- }
- /* ================================================================= */
-}
-
-static void MacConfig_85BASIC(struct net_device *dev)
-{
-
- u8 u1DA;
- MacConfig_85BASIC_HardCode(dev);
-
- /* ================================================================= */
-
- /* Follow TID_AC_MAP of WMac. */
- write_nic_word(dev, TID_AC_MAP, 0xfa50);
-
- /* Interrupt Migration, Jong suggested we use set 0x0000 first,
- * 2005.12.14, by rcnjko.
- */
- write_nic_word(dev, IntMig, 0x0000);
-
- /* Prevent TPC to cause CRC error. Added by Annie, 2006-06-10. */
- PlatformIOWrite4Byte(dev, 0x1F0, 0x00000000);
- PlatformIOWrite4Byte(dev, 0x1F4, 0x00000000);
- PlatformIOWrite1Byte(dev, 0x1F8, 0x00);
-
- /* Asked for by SD3 CM Lin, 2006.06.27, by rcnjko. */
-
- /*
- * power save parameter based on
- * "87SE power save parameters 20071127.doc", as follow.
- */
-
- /* Enable DA10 TX power saving */
- u1DA = read_nic_byte(dev, PHYPR);
- write_nic_byte(dev, PHYPR, (u1DA | BIT2));
-
- /* POWER: */
- write_nic_word(dev, 0x360, 0x1000);
- write_nic_word(dev, 0x362, 0x1000);
-
- /* AFE. */
- write_nic_word(dev, 0x370, 0x0560);
- write_nic_word(dev, 0x372, 0x0560);
- write_nic_word(dev, 0x374, 0x0DA4);
- write_nic_word(dev, 0x376, 0x0DA4);
- write_nic_word(dev, 0x378, 0x0560);
- write_nic_word(dev, 0x37A, 0x0560);
- write_nic_word(dev, 0x37C, 0x00EC);
- write_nic_word(dev, 0x37E, 0x00EC); /* +edward */
- write_nic_byte(dev, 0x24E, 0x01);
-}
-
-static u8 GetSupportedWirelessMode8185(struct net_device *dev)
-{
- return WIRELESS_MODE_B | WIRELESS_MODE_G;
-}
-
-static void
-ActUpdateChannelAccessSetting(struct net_device *dev,
- enum wireless_mode mode,
- struct chnl_access_setting *chnl_access_setting)
-{
- AC_CODING eACI;
-
- /*
- * <RJ_TODO_8185B>
- * TODO: We still don't know how to set up these registers,
- * just follow WMAC to verify 8185B FPAG.
- *
- * <RJ_TODO_8185B>
- * Jong said CWmin/CWmax register are not functional in 8185B,
- * so we shall fill channel access realted register into AC
- * parameter registers,
- * even in nQBss.
- */
-
- /* Suggested by Jong, 2005.12.08. */
- chnl_access_setting->sifs_timer = 0x22;
- chnl_access_setting->difs_timer = 0x1C; /* 2006.06.02, by rcnjko. */
- chnl_access_setting->slot_time_timer = 9; /* 2006.06.02, by rcnjko. */
- /*
- * Suggested by wcchu, it is the default value of EIFS register,
- * 2005.12.08.
- */
- chnl_access_setting->eifs_timer = 0x5B;
- chnl_access_setting->cwmin_index = 3; /* 2006.06.02, by rcnjko. */
- chnl_access_setting->cwmax_index = 7; /* 2006.06.02, by rcnjko. */
-
- write_nic_byte(dev, SIFS, chnl_access_setting->sifs_timer);
- /*
- * Rewrited from directly use PlatformEFIOWrite1Byte(),
- * by Annie, 2006-03-29.
- */
- write_nic_byte(dev, SLOT, chnl_access_setting->slot_time_timer);
-
- write_nic_byte(dev, EIFS, chnl_access_setting->eifs_timer);
-
- /*
- * <RJ_EXPR_QOS> Suggested by wcchu, it is the default value of EIFS
- * register, 2005.12.08.
- */
- write_nic_byte(dev, AckTimeOutReg, 0x5B);
-
- for (eACI = 0; eACI < AC_MAX; eACI++)
- write_nic_byte(dev, ACM_CONTROL, 0);
-}
-
-static void ActSetWirelessMode8185(struct net_device *dev, u8 btWirelessMode)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- struct ieee80211_device *ieee = priv->ieee80211;
- u8 btSupportedWirelessMode = GetSupportedWirelessMode8185(dev);
-
- if ((btWirelessMode & btSupportedWirelessMode) == 0) {
- /*
- * Don't switch to unsupported wireless mode, 2006.02.15,
- * by rcnjko.
- */
- DMESGW("ActSetWirelessMode8185(): WirelessMode(%d) is not supported (%d)!\n",
- btWirelessMode, btSupportedWirelessMode);
- return;
- }
-
- /* 1. Assign wireless mode to switch if necessary. */
- if (btWirelessMode == WIRELESS_MODE_AUTO) {
- if ((btSupportedWirelessMode & WIRELESS_MODE_A)) {
- btWirelessMode = WIRELESS_MODE_A;
- } else if (btSupportedWirelessMode & WIRELESS_MODE_G) {
- btWirelessMode = WIRELESS_MODE_G;
-
- } else if ((btSupportedWirelessMode & WIRELESS_MODE_B)) {
- btWirelessMode = WIRELESS_MODE_B;
- } else {
- DMESGW("ActSetWirelessMode8185(): No valid wireless mode supported, btSupportedWirelessMode(%x)!!!\n",
- btSupportedWirelessMode);
- btWirelessMode = WIRELESS_MODE_B;
- }
- }
-
- /*
- * 2. Swtich band: RF or BB specific actions,
- * for example, refresh tables in omc8255, or change initial gain if
- * necessary. Nothing to do for Zebra to switch band. Update current
- * wireless mode if we switch to specified band successfully.
- */
-
- ieee->mode = (enum wireless_mode)btWirelessMode;
-
- /* 3. Change related setting. */
- if (ieee->mode == WIRELESS_MODE_A)
- DMESG("WIRELESS_MODE_A\n");
- else if (ieee->mode == WIRELESS_MODE_B)
- DMESG("WIRELESS_MODE_B\n");
- else if (ieee->mode == WIRELESS_MODE_G)
- DMESG("WIRELESS_MODE_G\n");
-
- ActUpdateChannelAccessSetting(dev, ieee->mode,
- &priv->ChannelAccessSetting);
-}
-
-void rtl8185b_irq_enable(struct net_device *dev)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
- priv->irq_enabled = 1;
- write_nic_dword(dev, IMR, priv->IntrMask);
-}
-
-static void MgntDisconnectIBSS(struct net_device *dev)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- u8 i;
-
- for (i = 0; i < 6; i++)
- priv->ieee80211->current_network.bssid[i] = 0x55;
-
-
-
- priv->ieee80211->state = IEEE80211_NOLINK;
- /*
- * Stop Beacon.
- *
- * Vista add a Adhoc profile, HW radio off until
- * OID_DOT11_RESET_REQUEST Driver would set MSR=NO_LINK,
- * then HW Radio ON, MgntQueue Stuck. Because Bcn DMA isn't
- * complete, mgnt queue would stuck until Bcn packet send.
- *
- * Disable Beacon Queue Own bit, suggested by jong
- */
- ieee80211_stop_send_beacons(priv->ieee80211);
-
- priv->ieee80211->link_change(dev);
- notify_wx_assoc_event(priv->ieee80211);
-}
-
-static void MlmeDisassociateRequest(struct net_device *dev, u8 *asSta, u8 asRsn)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- u8 i;
-
- SendDisassociation(priv->ieee80211, asSta, asRsn);
-
- if (memcmp(priv->ieee80211->current_network.bssid, asSta, 6) == 0) {
- /* ShuChen TODO: change media status. */
-
- for (i = 0; i < 6; i++)
- priv->ieee80211->current_network.bssid[i] = 0x22;
-
- ieee80211_disassociate(priv->ieee80211);
- }
-}
-
-static void MgntDisconnectAP(struct net_device *dev, u8 asRsn)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
- /*
- * Commented out by rcnjko, 2005.01.27:
- * I move SecClearAllKeys() to MgntActSet_802_11_DISASSOCIATE().
- *
- * 2004/09/15, kcwu, the key should be cleared, or the new
- * handshaking will not success
- *
- * In WPA WPA2 need to Clear all key ... because new key will set
- * after new handshaking. 2004.10.11, by rcnjko.
- */
- MlmeDisassociateRequest(dev, priv->ieee80211->current_network.bssid,
- asRsn);
-
- priv->ieee80211->state = IEEE80211_NOLINK;
-}
-
-static bool MgntDisconnect(struct net_device *dev, u8 asRsn)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- /*
- * Schedule an workitem to wake up for ps mode, 070109, by rcnjko.
- */
-
- if (IS_DOT11D_ENABLE(priv->ieee80211))
- Dot11d_Reset(priv->ieee80211);
- /* In adhoc mode, update beacon frame. */
- if (priv->ieee80211->state == IEEE80211_LINKED) {
- if (priv->ieee80211->iw_mode == IW_MODE_ADHOC)
- MgntDisconnectIBSS(dev);
-
- if (priv->ieee80211->iw_mode == IW_MODE_INFRA) {
- /*
- * We clear key here instead of MgntDisconnectAP()
- * because that MgntActSet_802_11_DISASSOCIATE()
- * is an interface called by OS, e.g.
- * OID_802_11_DISASSOCIATE in Windows while as
- * MgntDisconnectAP() is used to handle
- * disassociation related things to AP, e.g. send
- * Disassoc frame to AP. 2005.01.27, by rcnjko.
- */
- MgntDisconnectAP(dev, asRsn);
- }
- /* Indicate Disconnect, 2005.02.23, by rcnjko. */
- }
- return true;
-}
-/*
- * Description:
- * Chang RF Power State.
- * Note that, only MgntActSet_RF_State() is allowed to set
- * HW_VAR_RF_STATE.
- *
- * Assumption:
- * PASSIVE LEVEL.
- */
-static bool SetRFPowerState(struct net_device *dev,
- enum rt_rf_power_state eRFPowerState)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- bool bResult = false;
-
- if (eRFPowerState == priv->eRFPowerState)
- return bResult;
-
- bResult = SetZebraRFPowerState8185(dev, eRFPowerState);
-
- return bResult;
-}
-
-bool MgntActSet_RF_State(struct net_device *dev, enum rt_rf_power_state StateToSet,
- u32 ChangeSource)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- bool bActionAllowed = false;
- bool bConnectBySSID = false;
- enum rt_rf_power_state rtState;
- u16 RFWaitCounter = 0;
- unsigned long flag;
- /*
- * Prevent the race condition of RF state change. By Bruce,
- * 2007-11-28. Only one thread can change the RF state at one time,
- * and others should wait to be executed.
- */
- while (true) {
- spin_lock_irqsave(&priv->rf_ps_lock, flag);
- if (priv->RFChangeInProgress) {
- spin_unlock_irqrestore(&priv->rf_ps_lock, flag);
- /* Set RF after the previous action is done. */
- while (priv->RFChangeInProgress) {
- RFWaitCounter++;
- udelay(1000); /* 1 ms */
-
- /*
- * Wait too long, return FALSE to avoid
- * to be stuck here.
- */
- if (RFWaitCounter > 1000) { /* 1sec */
- netdev_info(dev, "MgntActSet_RF_State(): Wait too long to set RF\n");
- /* TODO: Reset RF state? */
- return false;
- }
- }
- } else {
- priv->RFChangeInProgress = true;
- spin_unlock_irqrestore(&priv->rf_ps_lock, flag);
- break;
- }
- }
- rtState = priv->eRFPowerState;
-
- switch (StateToSet) {
- case RF_ON:
- /*
- * Turn On RF no matter the IPS setting because we need to
- * update the RF state to Ndis under Vista, or the Windows
- * does not allow the driver to perform site survey any
- * more. By Bruce, 2007-10-02.
- */
- priv->RfOffReason &= (~ChangeSource);
-
- if (!priv->RfOffReason) {
- priv->RfOffReason = 0;
- bActionAllowed = true;
-
- if (rtState == RF_OFF &&
- ChangeSource >= RF_CHANGE_BY_HW)
- bConnectBySSID = true;
- }
- break;
-
- case RF_OFF:
- /* 070125, rcnjko: we always keep connected in AP mode. */
-
- if (priv->RfOffReason > RF_CHANGE_BY_IPS) {
- /*
- * 060808, Annie:
- * Disconnect to current BSS when radio off.
- * Asked by QuanTa.
- *
- * Calling MgntDisconnect() instead of
- * MgntActSet_802_11_DISASSOCIATE(), because
- * we do NOT need to set ssid to dummy ones.
- */
- MgntDisconnect(dev, disas_lv_ss);
- /*
- * Clear content of bssDesc[] and bssDesc4Query[]
- * to avoid reporting old bss to UI.
- */
- }
-
- priv->RfOffReason |= ChangeSource;
- bActionAllowed = true;
- break;
- case RF_SLEEP:
- priv->RfOffReason |= ChangeSource;
- bActionAllowed = true;
- break;
- default:
- break;
- }
-
- if (bActionAllowed) {
- /* Config HW to the specified mode. */
- SetRFPowerState(dev, StateToSet);
- }
-
- /* Release RF spinlock */
- spin_lock_irqsave(&priv->rf_ps_lock, flag);
- priv->RFChangeInProgress = false;
- spin_unlock_irqrestore(&priv->rf_ps_lock, flag);
- return bActionAllowed;
-}
-
-static void InactivePowerSave(struct net_device *dev)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- /*
- * This flag "bSwRfProcessing", indicates the status of IPS
- * procedure, should be set if the IPS workitem is really
- * scheduled. The old code, sets this flag before scheduling the
- * IPS workitem and however, at the same time the previous IPS
- * workitem did not end yet, fails to schedule the current
- * workitem. Thus, bSwRfProcessing blocks the IPS procedure of
- * switching RF.
- */
- priv->bSwRfProcessing = true;
-
- MgntActSet_RF_State(dev, priv->eInactivePowerState, RF_CHANGE_BY_IPS);
-
- /*
- * To solve CAM values miss in RF OFF, rewrite CAM values after
- * RF ON. By Bruce, 2007-09-20.
- */
-
- priv->bSwRfProcessing = false;
-}
-
-/*
- * Description:
- * Enter the inactive power save mode. RF will be off
- */
-void IPSEnter(struct net_device *dev)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- enum rt_rf_power_state rtState;
- if (priv->bInactivePs) {
- rtState = priv->eRFPowerState;
-
- /*
- * Do not enter IPS in the following conditions:
- * (1) RF is already OFF or
- * Sleep (2) bSwRfProcessing (indicates the IPS is still
- * under going) (3) Connected (only disconnected can
- * trigger IPS)(4) IBSS (send Beacon)
- * (5) AP mode (send Beacon)
- */
- if (rtState == RF_ON && !priv->bSwRfProcessing
- && (priv->ieee80211->state != IEEE80211_LINKED)) {
- priv->eInactivePowerState = RF_OFF;
- InactivePowerSave(dev);
- }
- }
-}
-void IPSLeave(struct net_device *dev)
-{
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
- enum rt_rf_power_state rtState;
- if (priv->bInactivePs) {
- rtState = priv->eRFPowerState;
- if ((rtState == RF_OFF || rtState == RF_SLEEP) &&
- !priv->bSwRfProcessing
- && priv->RfOffReason <= RF_CHANGE_BY_IPS) {
- priv->eInactivePowerState = RF_ON;
- InactivePowerSave(dev);
- }
- }
-}
-
-void rtl8185b_adapter_start(struct net_device *dev)
-{
- struct r8180_priv *priv = ieee80211_priv(dev);
- struct ieee80211_device *ieee = priv->ieee80211;
-
- u8 SupportedWirelessMode;
- u8 InitWirelessMode;
- u8 bInvalidWirelessMode = 0;
- u8 tmpu8;
- u8 btCR9346;
- u8 TmpU1b;
- u8 btPSR;
-
- write_nic_byte(dev, 0x24e, (BIT5|BIT6|BIT0));
- rtl8180_reset(dev);
-
- priv->dma_poll_mask = 0;
- priv->dma_poll_stop_mask = 0;
-
- HwConfigureRTL8185(dev);
- write_nic_dword(dev, MAC0, ((u32 *)dev->dev_addr)[0]);
- write_nic_word(dev, MAC4, ((u32 *)dev->dev_addr)[1] & 0xffff);
- /* default network type to 'No Link' */
- write_nic_byte(dev, MSR, read_nic_byte(dev, MSR) & 0xf3);
- write_nic_word(dev, BcnItv, 100);
- write_nic_word(dev, AtimWnd, 2);
- PlatformIOWrite2Byte(dev, FEMR, 0xFFFF);
- write_nic_byte(dev, WPA_CONFIG, 0);
- MacConfig_85BASIC(dev);
- /* Override the RFSW_CTRL (MAC offset 0x272-0x273), 2006.06.07,
- * by rcnjko.
- */
- /* BT_DEMO_BOARD type */
- PlatformIOWrite2Byte(dev, RFSW_CTRL, 0x569a);
-
- /*
- *---------------------------------------------------------------------
- * Set up PHY related.
- *---------------------------------------------------------------------
- */
- /* Enable Config3.PARAM_En to revise AnaaParm. */
- write_nic_byte(dev, CR9346, 0xc0); /* enable config register write */
- tmpu8 = read_nic_byte(dev, CONFIG3);
- write_nic_byte(dev, CONFIG3, (tmpu8 | CONFIG3_PARM_En));
- /* Turn on Analog power. */
- /* Asked for by William, otherwise, MAC 3-wire can't work,
- * 2006.06.27, by rcnjko.
- */
- write_nic_dword(dev, ANAPARAM2, ANAPARM2_ASIC_ON);
- write_nic_dword(dev, ANAPARAM, ANAPARM_ASIC_ON);
- write_nic_word(dev, ANAPARAM3, 0x0010);
-
- write_nic_byte(dev, CONFIG3, tmpu8);
- write_nic_byte(dev, CR9346, 0x00);
- /* enable EEM0 and EEM1 in 9346CR */
- btCR9346 = read_nic_byte(dev, CR9346);
- write_nic_byte(dev, CR9346, (btCR9346 | 0xC0));
-
- /* B cut use LED1 to control HW RF on/off */
- TmpU1b = read_nic_byte(dev, CONFIG5);
- TmpU1b = TmpU1b & ~BIT3;
- write_nic_byte(dev, CONFIG5, TmpU1b);
-
- /* disable EEM0 and EEM1 in 9346CR */
- btCR9346 &= ~(0xC0);
- write_nic_byte(dev, CR9346, btCR9346);
-
- /* Enable Led (suggested by Jong) */
- /* B-cut RF Radio on/off 5e[3]=0 */
- btPSR = read_nic_byte(dev, PSR);
- write_nic_byte(dev, PSR, (btPSR | BIT3));
- /* setup initial timing for RFE. */
- write_nic_word(dev, RFPinsOutput, 0x0480);
- SetOutputEnableOfRfPins(dev);
- write_nic_word(dev, RFPinsSelect, 0x2488);
-
- /* PHY config. */
- PhyConfig8185(dev);
-
- /*
- * We assume RegWirelessMode has already been initialized before,
- * however, we has to validate the wireless mode here and provide a
- * reasonable initialized value if necessary. 2005.01.13,
- * by rcnjko.
- */
- SupportedWirelessMode = GetSupportedWirelessMode8185(dev);
- if ((ieee->mode != WIRELESS_MODE_B) &&
- (ieee->mode != WIRELESS_MODE_G) &&
- (ieee->mode != WIRELESS_MODE_A) &&
- (ieee->mode != WIRELESS_MODE_AUTO)) {
- /* It should be one of B, G, A, or AUTO. */
- bInvalidWirelessMode = 1;
- } else {
- /* One of B, G, A, or AUTO. */
- /* Check if the wireless mode is supported by RF. */
- if ((ieee->mode != WIRELESS_MODE_AUTO) &&
- (ieee->mode & SupportedWirelessMode) == 0) {
- bInvalidWirelessMode = 1;
- }
- }
-
- if (bInvalidWirelessMode || ieee->mode == WIRELESS_MODE_AUTO) {
- /* Auto or other invalid value. */
- /* Assigne a wireless mode to initialize. */
- if ((SupportedWirelessMode & WIRELESS_MODE_A)) {
- InitWirelessMode = WIRELESS_MODE_A;
- } else if ((SupportedWirelessMode & WIRELESS_MODE_G)) {
- InitWirelessMode = WIRELESS_MODE_G;
- } else if ((SupportedWirelessMode & WIRELESS_MODE_B)) {
- InitWirelessMode = WIRELESS_MODE_B;
- } else {
- DMESGW("InitializeAdapter8185(): No valid wireless mode supported, SupportedWirelessMode(%x)!!!\n",
- SupportedWirelessMode);
- InitWirelessMode = WIRELESS_MODE_B;
- }
-
- /* Initialize RegWirelessMode if it is not a valid one. */
- if (bInvalidWirelessMode)
- ieee->mode = (enum wireless_mode)InitWirelessMode;
-
- } else {
- /* One of B, G, A. */
- InitWirelessMode = ieee->mode;
- }
- priv->eRFPowerState = RF_OFF;
- priv->RfOffReason = 0;
- {
- MgntActSet_RF_State(dev, RF_ON, 0);
- }
- /*
- * If inactive power mode is enabled, disable rf while in
- * disconnected state.
- */
- if (priv->bInactivePs)
- MgntActSet_RF_State(dev , RF_OFF, RF_CHANGE_BY_IPS);
-
- ActSetWirelessMode8185(dev, (u8)(InitWirelessMode));
-
- /* ----------------------------------------------------------------- */
-
- rtl8185b_irq_enable(dev);
-
- netif_start_queue(dev);
-}
-
-void rtl8185b_rx_enable(struct net_device *dev)
-{
- u8 cmd;
- /* for now we accept data, management & ctl frame*/
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
-
- if (dev->flags & IFF_PROMISC)
- DMESG("NIC in promisc mode");
-
- if (priv->ieee80211->iw_mode == IW_MODE_MONITOR || dev->flags &
- IFF_PROMISC) {
- priv->ReceiveConfig = priv->ReceiveConfig & (~RCR_APM);
- priv->ReceiveConfig = priv->ReceiveConfig | RCR_AAP;
- }
-
- if (priv->ieee80211->iw_mode == IW_MODE_MONITOR)
- priv->ReceiveConfig = priv->ReceiveConfig | RCR_ACF |
- RCR_APWRMGT | RCR_AICV;
-
-
- if (priv->crcmon == 1 && priv->ieee80211->iw_mode == IW_MODE_MONITOR)
- priv->ReceiveConfig = priv->ReceiveConfig | RCR_ACRC32;
-
- write_nic_dword(dev, RCR, priv->ReceiveConfig);
-
- fix_rx_fifo(dev);
-
- cmd = read_nic_byte(dev, CMD);
- write_nic_byte(dev, CMD, cmd | (1<<CMD_RX_ENABLE_SHIFT));
-
-}
-
-void rtl8185b_tx_enable(struct net_device *dev)
-{
- u8 cmd;
- u8 byte;
- struct r8180_priv *priv = (struct r8180_priv *)ieee80211_priv(dev);
-
- write_nic_dword(dev, TCR, priv->TransmitConfig);
- byte = read_nic_byte(dev, MSR);
- byte |= MSR_LINK_ENEDCA;
- write_nic_byte(dev, MSR, byte);
-
- fix_tx_fifo(dev);
-
- cmd = read_nic_byte(dev, CMD);
- write_nic_byte(dev, CMD, cmd | (1<<CMD_TX_ENABLE_SHIFT));
-}
-
diff --git a/drivers/staging/rtl8188eu/core/rtw_recv.c b/drivers/staging/rtl8188eu/core/rtw_recv.c
index 636ec55..e305d43 100644
--- a/drivers/staging/rtl8188eu/core/rtw_recv.c
+++ b/drivers/staging/rtl8188eu/core/rtw_recv.c
@@ -545,20 +545,18 @@ static struct recv_frame *decryptor(struct adapter *padapter,
static struct recv_frame *portctrl(struct adapter *adapter,
struct recv_frame *precv_frame)
{
- u8 *psta_addr = NULL, *ptr;
+ u8 *psta_addr, *ptr;
uint auth_alg;
struct recv_frame *pfhdr;
struct sta_info *psta;
struct sta_priv *pstapriv;
struct recv_frame *prtnframe;
- u16 ether_type = 0;
+ u16 ether_type;
u16 eapol_type = 0x888e;/* for Funia BD's WPA issue */
struct rx_pkt_attrib *pattrib;
- __be16 be_tmp;
pstapriv = &adapter->stapriv;
- psta = rtw_get_stainfo(pstapriv, psta_addr);
auth_alg = adapter->securitypriv.dot11AuthAlgrthm;
@@ -566,24 +564,23 @@ static struct recv_frame *portctrl(struct adapter *adapter,
pfhdr = precv_frame;
pattrib = &pfhdr->attrib;
psta_addr = pattrib->ta;
+ psta = rtw_get_stainfo(pstapriv, psta_addr);
prtnframe = NULL;
RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("########portctrl:adapter->securitypriv.dot11AuthAlgrthm=%d\n", adapter->securitypriv.dot11AuthAlgrthm));
if (auth_alg == 2) {
+ /* get ether_type */
+ ptr = ptr + pfhdr->attrib.hdrlen + LLC_HEADER_SIZE;
+ memcpy(&ether_type, ptr, 2);
+ ether_type = ntohs((unsigned short)ether_type);
+
if ((psta != NULL) && (psta->ieee8021x_blocked)) {
/* blocked */
/* only accept EAPOL frame */
RT_TRACE(_module_rtl871x_recv_c_, _drv_info_, ("########portctrl:psta->ieee8021x_blocked==1\n"));
- prtnframe = precv_frame;
-
- /* get ether_type */
- ptr = ptr+pfhdr->attrib.hdrlen+pfhdr->attrib.iv_len+LLC_HEADER_SIZE;
- memcpy(&be_tmp, ptr, 2);
- ether_type = ntohs(be_tmp);
-
if (ether_type == eapol_type) {
prtnframe = precv_frame;
} else {
diff --git a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
index 2636e7f..cf30a08 100644
--- a/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
+++ b/drivers/staging/rtl8188eu/os_dep/ioctl_linux.c
@@ -359,7 +359,7 @@ static char *translate_scan(struct adapter *padapter,
if (wpa_len > 0) {
p = buf;
_rtw_memset(buf, 0, MAX_WPA_IE_LEN);
- p += sprintf(p, "wpa_ie =");
+ p += sprintf(p, "wpa_ie=");
for (i = 0; i < wpa_len; i++)
p += sprintf(p, "%02x", wpa_ie[i]);
@@ -376,7 +376,7 @@ static char *translate_scan(struct adapter *padapter,
if (rsn_len > 0) {
p = buf;
_rtw_memset(buf, 0, MAX_WPA_IE_LEN);
- p += sprintf(p, "rsn_ie =");
+ 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));
@@ -2899,7 +2899,7 @@ static int rtw_p2p_get_status(struct net_device *dev,
/* 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));
+ sprintf(extra, "\n\nStatus=%.2d\n", rtw_p2p_state(pwdinfo));
wrqu->data.length = strlen(extra);
return ret;
@@ -2918,7 +2918,7 @@ static int rtw_p2p_get_req_cm(struct net_device *dev,
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);
+ 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;
}
@@ -2935,7 +2935,7 @@ static int rtw_p2p_get_role(struct net_device *dev,
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));
+ sprintf(extra, "\n\nRole=%.2d\n", rtw_p2p_role(pwdinfo));
wrqu->data.length = strlen(extra);
return ret;
}
@@ -3022,7 +3022,7 @@ static int rtw_p2p_get_op_ch(struct net_device *dev,
DBG_88E("[%s] Op_ch = %02x\n", __func__, pwdinfo->operating_channel);
- sprintf(extra, "\n\nOp_ch =%.2d\n", pwdinfo->operating_channel);
+ sprintf(extra, "\n\nOp_ch=%.2d\n", pwdinfo->operating_channel);
wrqu->data.length = strlen(extra);
return ret;
}
@@ -3043,7 +3043,7 @@ static int rtw_p2p_get_wps_configmethod(struct net_device *dev,
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 */
+ /* 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 */
@@ -3079,7 +3079,7 @@ static int rtw_p2p_get_wps_configmethod(struct net_device *dev,
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);
+ sprintf(attr_content_str, "\n\nM=%.4d", attr_content);
blnMatch = 1;
}
}
@@ -3091,7 +3091,7 @@ static int rtw_p2p_get_wps_configmethod(struct net_device *dev,
spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
if (!blnMatch)
- sprintf(attr_content_str, "\n\nM = 0000");
+ sprintf(attr_content_str, "\n\nM=0000");
if (copy_to_user(wrqu->data.pointer, attr_content_str, 6 + 17))
return -EFAULT;
@@ -3172,9 +3172,9 @@ static int rtw_p2p_get_go_device_address(struct net_device *dev,
spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
if (!blnMatch)
- snprintf(go_devadd_str, sizeof(go_devadd_str), "\n\ndev_add = NULL");
+ 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",
+ 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)))
@@ -3198,7 +3198,7 @@ static int rtw_p2p_get_device_type(struct net_device *dev,
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 */
+ 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. */
@@ -3239,7 +3239,7 @@ static int rtw_p2p_get_device_type(struct net_device *dev,
memcpy(&be_tmp, dev_type, 2);
type = be16_to_cpu(be_tmp);
- sprintf(dev_type_str, "\n\nN =%.2d", type);
+ sprintf(dev_type_str, "\n\nN=%.2d", type);
blnMatch = 1;
}
}
@@ -3252,7 +3252,7 @@ static int rtw_p2p_get_device_type(struct net_device *dev,
spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
if (!blnMatch)
- sprintf(dev_type_str, "\n\nN = 00");
+ sprintf(dev_type_str, "\n\nN=00");
if (copy_to_user(wrqu->data.pointer, dev_type_str, 9 + 17)) {
return -EFAULT;
@@ -3277,7 +3277,7 @@ static int rtw_p2p_get_device_name(struct net_device *dev,
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 */
+ 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. */
@@ -3310,7 +3310,7 @@ static int rtw_p2p_get_device_name(struct net_device *dev,
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);
+ sprintf(dev_name_str, "\n\nN=%s", dev_name);
blnMatch = 1;
}
}
@@ -3323,7 +3323,7 @@ static int rtw_p2p_get_device_name(struct net_device *dev,
spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
if (!blnMatch)
- sprintf(dev_name_str, "\n\nN = 0000");
+ 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;
@@ -3349,7 +3349,7 @@ static int rtw_p2p_get_invitation_procedure(struct net_device *dev,
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 */
+ /* +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. */
@@ -3397,12 +3397,12 @@ static int rtw_p2p_get_invitation_procedure(struct net_device *dev,
spin_unlock_bh(&pmlmepriv->scanned_queue.lock);
if (!blnMatch) {
- sprintf(inv_proc_str, "\nIP =-1");
+ sprintf(inv_proc_str, "\nIP=-1");
} else {
if (attr_content[0] & 0x20)
- sprintf(inv_proc_str, "\nIP = 1");
+ sprintf(inv_proc_str, "\nIP=1");
else
- sprintf(inv_proc_str, "\nIP = 0");
+ sprintf(inv_proc_str, "\nIP=0");
}
if (copy_to_user(wrqu->data.pointer, inv_proc_str, 8 + 17))
return -EFAULT;
@@ -3512,7 +3512,7 @@ static int rtw_p2p_invite_req(struct net_device *dev,
/* 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" */
+ /* 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);
@@ -3805,48 +3805,48 @@ static int rtw_p2p_set(struct net_device *dev,
#ifdef CONFIG_88EU_P2P
DBG_88E("[%s] extra = %s\n", __func__, extra);
- if (!memcmp(extra, "enable =", 7)) {
+ if (!memcmp(extra, "enable=", 7)) {
rtw_wext_p2p_enable(dev, info, wrqu, &extra[7]);
- } else if (!memcmp(extra, "setDN =", 6)) {
+ } else if (!memcmp(extra, "setDN=", 6)) {
wrqu->data.length -= 6;
rtw_p2p_setDN(dev, info, wrqu, &extra[6]);
- } else if (!memcmp(extra, "profilefound =", 13)) {
+ } 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)) {
+ } 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)) {
+ } else if (!memcmp(extra, "nego=", 5)) {
wrqu->data.length -= 5;
rtw_p2p_connect(dev, info, wrqu, &extra[5]);
- } else if (!memcmp(extra, "intent =", 7)) {
+ } 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)) {
+ } 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)) {
+ } 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)) {
+ } 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)) {
+ } 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)) {
+ } 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)) {
+ } else if (!memcmp(extra, "persistent=", 11)) {
wrqu->data.length -= 11;
rtw_p2p_set_persistent(dev, info, wrqu, &extra[11]);
}
@@ -3887,7 +3887,7 @@ static int rtw_p2p_get(struct net_device *dev,
"group_id", 8)) {
rtw_p2p_get_groupid(dev, info, wrqu, extra);
} else if (!memcmp((__force const char *)wrqu->data.pointer,
- "peer_deva_inv", 9)) {
+ "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,
@@ -6920,7 +6920,7 @@ static int rtw_mp_ctx(struct net_device *dev,
DBG_88E("%s: in =%s\n", __func__, extra);
- countPkTx = strncmp(extra, "count =", 5); /* strncmp true is 0 */
+ 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);
@@ -7044,7 +7044,7 @@ static int rtw_mp_arx(struct net_device *dev,
DBG_88E("%s: %s\n", __func__, input);
bStartRx = (strncmp(input, "start", 5) == 0) ? 1 : 0; /* strncmp true is 0 */
- bStopRx = (strncmp(input, "stop", 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) {
diff --git a/drivers/staging/rtl8712/rtl871x_recv.c b/drivers/staging/rtl8712/rtl871x_recv.c
index 23ec684..274c359 100644
--- a/drivers/staging/rtl8712/rtl871x_recv.c
+++ b/drivers/staging/rtl8712/rtl871x_recv.c
@@ -254,7 +254,7 @@ union recv_frame *r8712_portctrl(struct _adapter *adapter,
struct sta_info *psta;
struct sta_priv *pstapriv;
union recv_frame *prtnframe;
- u16 ether_type = 0;
+ u16 ether_type;
pstapriv = &adapter->stapriv;
ptr = get_recvframe_data(precv_frame);
@@ -263,15 +263,14 @@ union recv_frame *r8712_portctrl(struct _adapter *adapter,
psta = r8712_get_stainfo(pstapriv, psta_addr);
auth_alg = adapter->securitypriv.AuthAlgrthm;
if (auth_alg == 2) {
+ /* get ether_type */
+ ptr = ptr + pfhdr->attrib.hdrlen + LLC_HEADER_SIZE;
+ memcpy(&ether_type, ptr, 2);
+ ether_type = ntohs((unsigned short)ether_type);
+
if ((psta != NULL) && (psta->ieee8021x_blocked)) {
/* blocked
* only accept EAPOL frame */
- prtnframe = precv_frame;
- /*get ether_type */
- ptr = ptr + pfhdr->attrib.hdrlen +
- pfhdr->attrib.iv_len + LLC_HEADER_SIZE;
- memcpy(&ether_type, ptr, 2);
- ether_type = ntohs((unsigned short)ether_type);
if (ether_type == 0x888e)
prtnframe = precv_frame;
else {
diff --git a/drivers/staging/rtl8723au/core/rtw_ieee80211.c b/drivers/staging/rtl8723au/core/rtw_ieee80211.c
index 780631f..a48ab25 100644
--- a/drivers/staging/rtl8723au/core/rtw_ieee80211.c
+++ b/drivers/staging/rtl8723au/core/rtw_ieee80211.c
@@ -1496,45 +1496,23 @@ void rtw_wlan_bssid_ex_remove_p2p_attr23a(struct wlan_bssid_ex *bss_ex, u8 attr_
int rtw_get_wfd_ie(u8 *in_ie, int in_len, u8 *wfd_ie, uint *wfd_ielen)
{
int match;
- uint cnt = 0;
- u8 eid, wfd_oui[4] = {0x50, 0x6F, 0x9A, 0x0A};
+ const u8 *ie;
- match = false;
+ match = 0;
- if (in_len < 0) {
+ if (in_len < 0)
return match;
- }
-
- while (cnt < in_len)
- {
- eid = in_ie[cnt];
- if ((eid == _VENDOR_SPECIFIC_IE_) &&
- !memcmp(&in_ie[cnt+2], wfd_oui, 4)) {
- if (wfd_ie != NULL) {
- memcpy(wfd_ie, &in_ie[cnt], in_ie[cnt + 1] + 2);
-
- } else {
- if (wfd_ielen != NULL) {
- *wfd_ielen = 0;
- }
- }
-
- if (wfd_ielen != NULL) {
- *wfd_ielen = in_ie[cnt + 1] + 2;
- }
-
- cnt += in_ie[cnt + 1] + 2;
-
- match = true;
- break;
- } else {
- cnt += in_ie[cnt + 1] +2; /* goto next */
- }
- }
+ ie = cfg80211_find_vendor_ie(0x506F9A, 0x0A, in_ie, in_len);
+ if (ie && (ie[1] <= (MAX_WFD_IE_LEN - 2))) {
+ if (wfd_ie) {
+ *wfd_ielen = ie[1] + 2;
+ memcpy(wfd_ie, ie, ie[1] + 2);
+ } else
+ if (wfd_ielen)
+ *wfd_ielen = 0;
- if (match == true) {
- match = cnt;
+ match = 1;
}
return match;
diff --git a/drivers/staging/rtl8723au/core/rtw_mlme_ext.c b/drivers/staging/rtl8723au/core/rtw_mlme_ext.c
index 4c75363..1f3e8a0 100644
--- a/drivers/staging/rtl8723au/core/rtw_mlme_ext.c
+++ b/drivers/staging/rtl8723au/core/rtw_mlme_ext.c
@@ -1281,7 +1281,7 @@ unsigned int OnAssocReq23a(struct rtw_adapter *padapter, struct recv_frame *prec
u8 p2p_status_code = P2P_STATUS_SUCCESS;
u8 *p2pie;
u32 p2pielen = 0;
- u8 wfd_ie[ 128 ] = { 0x00 };
+ u8 wfd_ie[MAX_WFD_IE_LEN] = { 0x00 };
u32 wfd_ielen = 0;
#endif /* CONFIG_8723AU_P2P */
diff --git a/drivers/staging/rtl8723au/core/rtw_p2p.c b/drivers/staging/rtl8723au/core/rtw_p2p.c
index 27a6cc7..1a961e3 100644
--- a/drivers/staging/rtl8723au/core/rtw_p2p.c
+++ b/drivers/staging/rtl8723au/core/rtw_p2p.c
@@ -2535,7 +2535,7 @@ u8 process_p2p_group_negotation_req23a(struct wifidirect_info *pwdinfo, u8 *pfra
u16 wps_devicepassword_id = 0x0000;
uint wps_devicepassword_id_len = 0;
#ifdef CONFIG_8723AU_P2P
- u8 wfd_ie[ 128 ] = { 0x00 };
+ u8 wfd_ie[MAX_WFD_IE_LEN] = { 0x00 };
u32 wfd_ielen = 0;
#endif /* CONFIG_8723AU_P2P */
@@ -2741,7 +2741,7 @@ u8 process_p2p_group_negotation_resp23a(struct wifidirect_info *pwdinfo, u8 *pfr
u32 ies_len;
u8 * p2p_ie;
#ifdef CONFIG_8723AU_P2P
- u8 wfd_ie[ 128 ] = { 0x00 };
+ u8 wfd_ie[MAX_WFD_IE_LEN] = { 0x00 };
u32 wfd_ielen = 0;
#endif /* CONFIG_8723AU_P2P */
diff --git a/drivers/staging/rtl8723au/core/rtw_wlan_util.c b/drivers/staging/rtl8723au/core/rtw_wlan_util.c
index 0dfcfbc..99d81e6 100644
--- a/drivers/staging/rtl8723au/core/rtw_wlan_util.c
+++ b/drivers/staging/rtl8723au/core/rtw_wlan_util.c
@@ -570,7 +570,7 @@ void flush_all_cam_entry23a(struct rtw_adapter *padapter)
int WFD_info_handler(struct rtw_adapter *padapter, struct ndis_802_11_var_ies * pIE)
{
struct wifidirect_info *pwdinfo;
- u8 wfd_ie[128] = {0x00};
+ u8 wfd_ie[MAX_WFD_IE_LEN] = {0x00};
u32 wfd_ielen = 0;
pwdinfo = &padapter->wdinfo;
@@ -681,7 +681,7 @@ void WMMOnAssocRsp23a(struct rtw_adapter *padapter)
inx[0] = 0; inx[1] = 1; inx[2] = 2; inx[3] = 3;
if (pregpriv->wifi_spec == 1) {
- u32 j, tmp, change_inx;
+ u32 j, tmp, change_inx = false;
/* entry indx: 0->vo, 1->vi, 2->be, 3->bk. */
for (i = 0; i < 4; i++) {
diff --git a/drivers/staging/rtl8821ae/base.c b/drivers/staging/rtl8821ae/base.c
index e5073fe..a4c9cc4 100644
--- a/drivers/staging/rtl8821ae/base.c
+++ b/drivers/staging/rtl8821ae/base.c
@@ -388,7 +388,7 @@ static void _rtl_init_mac80211(struct ieee80211_hw *hw)
}
-static void _rtl_init_deferred_work(struct ieee80211_hw *hw)
+static int _rtl_init_deferred_work(struct ieee80211_hw *hw)
{
struct rtl_priv *rtlpriv = rtl_priv(hw);
@@ -410,6 +410,9 @@ static void _rtl_init_deferred_work(struct ieee80211_hw *hw)
rtlpriv->works.rtl_wq = create_workqueue(rtlpriv->cfg->name);
#endif
/*<delete in kernel end>*/
+ if (!rtlpriv->works.rtl_wq)
+ return -ENOMEM;
+
INIT_DELAYED_WORK(&rtlpriv->works.watchdog_wq,
(void *)rtl_watchdog_wq_callback);
INIT_DELAYED_WORK(&rtlpriv->works.ips_nic_off_wq,
@@ -421,6 +424,8 @@ static void _rtl_init_deferred_work(struct ieee80211_hw *hw)
INIT_DELAYED_WORK(&rtlpriv->works.fwevt_wq,
(void *)rtl_fwevt_wq_callback);
+ return 0;
+
}
void rtl_deinit_deferred_work(struct ieee80211_hw *hw)
@@ -519,7 +524,8 @@ int rtl_init_core(struct ieee80211_hw *hw)
INIT_LIST_HEAD(&rtlpriv->entry_list);
/* <6> init deferred work */
- _rtl_init_deferred_work(hw);
+ if (_rtl_init_deferred_work(hw))
+ return 1;
/* <7> */
#ifdef VIF_TODO
diff --git a/drivers/staging/speakup/main.c b/drivers/staging/speakup/main.c
index ef5933b..3b6e535 100644
--- a/drivers/staging/speakup/main.c
+++ b/drivers/staging/speakup/main.c
@@ -1855,8 +1855,9 @@ static int handle_goto(struct vc_data *vc, u_char type, u_char ch, u_short key)
{
static u_char goto_buf[8];
static int num;
- int maxlen, go_pos;
+ int maxlen;
char *cp;
+
if (type == KT_SPKUP && ch == SPEAKUP_GOTO)
goto do_goto;
if (type == KT_LATIN && ch == '\n')
@@ -1891,25 +1892,24 @@ oops:
spk_special_handler = NULL;
return 1;
}
- go_pos = kstrtol(goto_buf, 10, (long *)&cp);
- goto_pos = (u_long) go_pos;
+
+ goto_pos = simple_strtoul(goto_buf, &cp, 10);
+
if (*cp == 'x') {
if (*goto_buf < '0')
goto_pos += spk_x;
- else
+ else if (goto_pos > 0)
goto_pos--;
- if (goto_pos < 0)
- goto_pos = 0;
+
if (goto_pos >= vc->vc_cols)
goto_pos = vc->vc_cols - 1;
goto_x = 1;
} else {
if (*goto_buf < '0')
goto_pos += spk_y;
- else
+ else if (goto_pos > 0)
goto_pos--;
- if (goto_pos < 0)
- goto_pos = 0;
+
if (goto_pos >= vc->vc_rows)
goto_pos = vc->vc_rows - 1;
goto_x = 0;
diff --git a/drivers/staging/unisys/uislib/uislib.c b/drivers/staging/unisys/uislib/uislib.c
index 8ea9c46..3152a21 100644
--- a/drivers/staging/unisys/uislib/uislib.c
+++ b/drivers/staging/unisys/uislib/uislib.c
@@ -381,17 +381,17 @@ create_bus(CONTROLVM_MESSAGE *msg, char *buf)
cmd.add_vbus.busTypeGuid = msg->cmd.createBus.busDataTypeGuid;
cmd.add_vbus.busInstGuid = msg->cmd.createBus.busInstGuid;
if (!VirtControlChanFunc) {
- kfree(bus);
LOGERR("CONTROLVM_BUS_CREATE Failed: virtpci callback not registered.");
POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, bus->busNo,
POSTCODE_SEVERITY_ERR);
+ kfree(bus);
return CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_FAILURE;
}
if (!VirtControlChanFunc(&cmd)) {
- kfree(bus);
LOGERR("CONTROLVM_BUS_CREATE Failed: virtpci GUEST_ADD_VBUS returned error.");
POSTCODE_LINUX_3(BUS_CREATE_FAILURE_PC, bus->busNo,
POSTCODE_SEVERITY_ERR);
+ kfree(bus);
return
CONTROLVM_RESP_ERROR_VIRTPCI_DRIVER_CALLBACK_ERROR;
}
diff --git a/drivers/staging/unisys/visorchipset/visorchipset.h b/drivers/staging/unisys/visorchipset/visorchipset.h
index d4bf203..d95825d 100644
--- a/drivers/staging/unisys/visorchipset/visorchipset.h
+++ b/drivers/staging/unisys/visorchipset/visorchipset.h
@@ -104,9 +104,9 @@ finddevice(struct list_head *list, U32 busNo, U32 devNo)
static inline void delbusdevices(struct list_head *list, U32 busNo)
{
- VISORCHIPSET_DEVICE_INFO *p;
+ VISORCHIPSET_DEVICE_INFO *p, *tmp;
- list_for_each_entry(p, list, entry) {
+ list_for_each_entry_safe(p, tmp, list, entry) {
if (p->busNo == busNo) {
list_del(&p->entry);
kfree(p);
diff --git a/drivers/staging/unisys/visorchipset/visorchipset_main.c b/drivers/staging/unisys/visorchipset/visorchipset_main.c
index 257c6e5..c475e25 100644
--- a/drivers/staging/unisys/visorchipset/visorchipset_main.c
+++ b/drivers/staging/unisys/visorchipset/visorchipset_main.c
@@ -605,16 +605,16 @@ EXPORT_SYMBOL_GPL(visorchipset_register_busdev_client);
static void
cleanup_controlvm_structures(void)
{
- VISORCHIPSET_BUS_INFO *bi;
- VISORCHIPSET_DEVICE_INFO *di;
+ VISORCHIPSET_BUS_INFO *bi, *tmp_bi;
+ VISORCHIPSET_DEVICE_INFO *di, *tmp_di;
- list_for_each_entry(bi, &BusInfoList, entry) {
+ list_for_each_entry_safe(bi, tmp_bi, &BusInfoList, entry) {
busInfo_clear(bi);
list_del(&bi->entry);
kfree(bi);
}
- list_for_each_entry(di, &DevInfoList, entry) {
+ list_for_each_entry_safe(di, tmp_di, &DevInfoList, entry) {
devInfo_clear(di);
list_del(&di->entry);
kfree(di);
diff --git a/drivers/staging/usbip/userspace/libsrc/usbip_host_driver.c b/drivers/staging/usbip/userspace/libsrc/usbip_host_driver.c
index c5bf60b..92caef7 100644
--- a/drivers/staging/usbip/userspace/libsrc/usbip_host_driver.c
+++ b/drivers/staging/usbip/userspace/libsrc/usbip_host_driver.c
@@ -118,6 +118,7 @@ static int refresh_exported_devices(void)
struct udev_list_entry *devices, *dev_list_entry;
struct udev_device *dev;
const char *path;
+ const char *driver;
enumerate = udev_enumerate_new(udev_context);
udev_enumerate_add_match_subsystem(enumerate, "usb");
@@ -128,10 +129,12 @@ static int refresh_exported_devices(void)
udev_list_entry_foreach(dev_list_entry, devices) {
path = udev_list_entry_get_name(dev_list_entry);
dev = udev_device_new_from_syspath(udev_context, path);
+ if (dev == NULL)
+ continue;
/* Check whether device uses usbip-host driver. */
- if (!strcmp(udev_device_get_driver(dev),
- USBIP_HOST_DRV_NAME)) {
+ driver = udev_device_get_driver(dev);
+ if (driver != NULL && !strcmp(driver, USBIP_HOST_DRV_NAME)) {
edev = usbip_exported_device_new(path);
if (!edev) {
dbg("usbip_exported_device_new failed");
diff --git a/drivers/staging/usbip/vhci_sysfs.c b/drivers/staging/usbip/vhci_sysfs.c
index 47bddcd..211f43f 100644
--- a/drivers/staging/usbip/vhci_sysfs.c
+++ b/drivers/staging/usbip/vhci_sysfs.c
@@ -184,7 +184,7 @@ static ssize_t store_attach(struct device *dev, struct device_attribute *attr,
* @devid: unique device identifier in a remote host
* @speed: usb device speed in a remote host
*/
- if (sscanf(buf, "%u %u %u %u", &rhport, &sockfd, &devid, &speed) != 1)
+ if (sscanf(buf, "%u %u %u %u", &rhport, &sockfd, &devid, &speed) != 4)
return -EINVAL;
usbip_dbg_vhci_sysfs("rhport(%u) sockfd(%u) devid(%u) speed(%u)\n",
diff --git a/drivers/staging/vme/devices/vme_user.c b/drivers/staging/vme/devices/vme_user.c
index 7927927..ffb4eee 100644
--- a/drivers/staging/vme/devices/vme_user.c
+++ b/drivers/staging/vme/devices/vme_user.c
@@ -776,7 +776,8 @@ static int vme_user_probe(struct vme_dev *vdev)
image[i].kern_buf = kmalloc(image[i].size_buf, GFP_KERNEL);
if (image[i].kern_buf == NULL) {
err = -ENOMEM;
- goto err_master_buf;
+ vme_master_free(image[i].resource);
+ goto err_master;
}
}
@@ -819,8 +820,6 @@ static int vme_user_probe(struct vme_dev *vdev)
return 0;
- /* Ensure counter set correcty to destroy all sysfs devices */
- i = VME_DEVS;
err_sysfs:
while (i > 0) {
i--;
@@ -830,12 +829,10 @@ err_sysfs:
/* Ensure counter set correcty to unalloc all master windows */
i = MASTER_MAX + 1;
-err_master_buf:
- for (i = MASTER_MINOR; i < (MASTER_MAX + 1); i++)
- kfree(image[i].kern_buf);
err_master:
while (i > MASTER_MINOR) {
i--;
+ kfree(image[i].kern_buf);
vme_master_free(image[i].resource);
}
diff --git a/drivers/staging/xgifb/vb_def.h b/drivers/staging/xgifb/vb_def.h
index 5c739be..949f0e5 100644
--- a/drivers/staging/xgifb/vb_def.h
+++ b/drivers/staging/xgifb/vb_def.h
@@ -1,6 +1,6 @@
#ifndef _VB_DEF_
#define _VB_DEF_
-#include "../../video/sis/initdef.h"
+#include "../../video/fbdev/sis/initdef.h"
#define VB_XGI301C 0x0020 /* for 301C */
diff --git a/drivers/staging/xgifb/vb_struct.h b/drivers/staging/xgifb/vb_struct.h
index c08ff5b..0d27594 100644
--- a/drivers/staging/xgifb/vb_struct.h
+++ b/drivers/staging/xgifb/vb_struct.h
@@ -1,6 +1,6 @@
#ifndef _VB_STRUCT_
#define _VB_STRUCT_
-#include "../../video/sis/vstruct.h"
+#include "../../video/fbdev/sis/vstruct.h"
struct XGI_LVDSCRT1HDataStruct {
unsigned char Reg[8];
diff --git a/drivers/staging/xgifb/vgatypes.h b/drivers/staging/xgifb/vgatypes.h
index ddf7776..2643514 100644
--- a/drivers/staging/xgifb/vgatypes.h
+++ b/drivers/staging/xgifb/vgatypes.h
@@ -2,8 +2,8 @@
#define _VGATYPES_
#include <linux/fb.h> /* for struct fb_var_screeninfo for sis.h */
-#include "../../video/sis/vgatypes.h"
-#include "../../video/sis/sis.h" /* for LCD_TYPE */
+#include "../../video/fbdev/sis/vgatypes.h"
+#include "../../video/fbdev/sis/sis.h" /* for LCD_TYPE */
#ifndef XGI_VB_CHIP_TYPE
enum XGI_VB_CHIP_TYPE {
diff --git a/drivers/tty/serial/Kconfig b/drivers/tty/serial/Kconfig
index 2e6d8dd..5d9b01a 100644
--- a/drivers/tty/serial/Kconfig
+++ b/drivers/tty/serial/Kconfig
@@ -1226,6 +1226,7 @@ config SERIAL_BFIN_SPORT3_UART_CTSRTS
config SERIAL_TIMBERDALE
tristate "Support for timberdale UART"
select SERIAL_CORE
+ depends on X86_32 || COMPILE_TEST
---help---
Add support for UART controller on timberdale.
diff --git a/drivers/tty/serial/amba-pl011.c b/drivers/tty/serial/amba-pl011.c
index d4eda24..dacf0a0 100644
--- a/drivers/tty/serial/amba-pl011.c
+++ b/drivers/tty/serial/amba-pl011.c
@@ -318,7 +318,7 @@ static void pl011_dma_probe_initcall(struct device *dev, struct uart_amba_port *
.src_addr = uap->port.mapbase + UART01x_DR,
.src_addr_width = DMA_SLAVE_BUSWIDTH_1_BYTE,
.direction = DMA_DEV_TO_MEM,
- .src_maxburst = uap->fifosize >> 1,
+ .src_maxburst = uap->fifosize >> 2,
.device_fc = false,
};
@@ -2176,6 +2176,7 @@ static int pl011_probe(struct amba_device *dev, const struct amba_id *id)
static int pl011_remove(struct amba_device *dev)
{
struct uart_amba_port *uap = amba_get_drvdata(dev);
+ bool busy = false;
int i;
uart_remove_one_port(&amba_reg, &uap->port);
@@ -2183,9 +2184,12 @@ static int pl011_remove(struct amba_device *dev)
for (i = 0; i < ARRAY_SIZE(amba_ports); i++)
if (amba_ports[i] == uap)
amba_ports[i] = NULL;
+ else if (amba_ports[i])
+ busy = true;
pl011_dma_remove(uap);
- uart_unregister_driver(&amba_reg);
+ if (!busy)
+ uart_unregister_driver(&amba_reg);
return 0;
}
diff --git a/drivers/tty/serial/clps711x.c b/drivers/tty/serial/clps711x.c
index 5e6fdb1..14aaea0 100644
--- a/drivers/tty/serial/clps711x.c
+++ b/drivers/tty/serial/clps711x.c
@@ -368,16 +368,12 @@ static const struct uart_ops uart_clps711x_ops = {
static void uart_clps711x_console_putchar(struct uart_port *port, int ch)
{
struct clps711x_port *s = dev_get_drvdata(port->dev);
+ u32 sysflg = 0;
/* Wait for FIFO is not full */
- while (1) {
- u32 sysflg = 0;
-
+ do {
regmap_read(s->syscon, SYSFLG_OFFSET, &sysflg);
- if (!(sysflg & SYSFLG_UTXFF))
- break;
- cond_resched();
- }
+ } while (sysflg & SYSFLG_UTXFF);
writew(ch, port->membase + UARTDR_OFFSET);
}
@@ -387,18 +383,14 @@ static void uart_clps711x_console_write(struct console *co, const char *c,
{
struct uart_port *port = clps711x_uart.state[co->index].uart_port;
struct clps711x_port *s = dev_get_drvdata(port->dev);
+ u32 sysflg = 0;
uart_console_write(port, c, n, uart_clps711x_console_putchar);
/* Wait for transmitter to become empty */
- while (1) {
- u32 sysflg = 0;
-
+ do {
regmap_read(s->syscon, SYSFLG_OFFSET, &sysflg);
- if (!(sysflg & SYSFLG_UBUSY))
- break;
- cond_resched();
- }
+ } while (sysflg & SYSFLG_UBUSY);
}
static int uart_clps711x_console_setup(struct console *co, char *options)
diff --git a/drivers/tty/serial/efm32-uart.c b/drivers/tty/serial/efm32-uart.c
index 028582e..c167a71 100644
--- a/drivers/tty/serial/efm32-uart.c
+++ b/drivers/tty/serial/efm32-uart.c
@@ -798,6 +798,9 @@ static int efm32_uart_remove(struct platform_device *pdev)
static const struct of_device_id efm32_uart_dt_ids[] = {
{
+ .compatible = "energymicro,efm32-uart",
+ }, {
+ /* doesn't follow the "vendor,device" scheme, don't use */
.compatible = "efm32,uart",
}, {
/* sentinel */
diff --git a/drivers/tty/serial/omap-serial.c b/drivers/tty/serial/omap-serial.c
index dd8b1a5..08b6b94 100644
--- a/drivers/tty/serial/omap-serial.c
+++ b/drivers/tty/serial/omap-serial.c
@@ -225,14 +225,19 @@ static inline void serial_omap_enable_wakeirq(struct uart_omap_port *up,
if (enable)
enable_irq(up->wakeirq);
else
- disable_irq(up->wakeirq);
+ disable_irq_nosync(up->wakeirq);
}
static void serial_omap_enable_wakeup(struct uart_omap_port *up, bool enable)
{
struct omap_uart_port_info *pdata = dev_get_platdata(up->dev);
+ if (enable == up->wakeups_enabled)
+ return;
+
serial_omap_enable_wakeirq(up, enable);
+ up->wakeups_enabled = enable;
+
if (!pdata || !pdata->enable_wakeup)
return;
@@ -1495,6 +1500,11 @@ static int serial_omap_suspend(struct device *dev)
uart_suspend_port(&serial_omap_reg, &up->port);
flush_work(&up->qos_work);
+ if (device_may_wakeup(dev))
+ serial_omap_enable_wakeup(up, true);
+ else
+ serial_omap_enable_wakeup(up, false);
+
return 0;
}
@@ -1502,6 +1512,9 @@ static int serial_omap_resume(struct device *dev)
{
struct uart_omap_port *up = dev_get_drvdata(dev);
+ if (device_may_wakeup(dev))
+ serial_omap_enable_wakeup(up, false);
+
uart_resume_port(&serial_omap_reg, &up->port);
return 0;
@@ -1789,6 +1802,7 @@ static int serial_omap_remove(struct platform_device *dev)
pm_runtime_disable(up->dev);
uart_remove_one_port(&serial_omap_reg, &up->port);
pm_qos_remove_request(&up->pm_qos_request);
+ device_init_wakeup(&dev->dev, false);
return 0;
}
@@ -1877,17 +1891,7 @@ static int serial_omap_runtime_suspend(struct device *dev)
up->context_loss_cnt = serial_omap_get_context_loss_count(up);
- if (device_may_wakeup(dev)) {
- if (!up->wakeups_enabled) {
- serial_omap_enable_wakeup(up, true);
- up->wakeups_enabled = true;
- }
- } else {
- if (up->wakeups_enabled) {
- serial_omap_enable_wakeup(up, false);
- up->wakeups_enabled = false;
- }
- }
+ serial_omap_enable_wakeup(up, true);
up->latency = PM_QOS_CPU_DMA_LAT_DEFAULT_VALUE;
schedule_work(&up->qos_work);
@@ -1901,6 +1905,8 @@ static int serial_omap_runtime_resume(struct device *dev)
int loss_cnt = serial_omap_get_context_loss_count(up);
+ serial_omap_enable_wakeup(up, false);
+
if (loss_cnt < 0) {
dev_dbg(dev, "serial_omap_get_context_loss_count failed : %d\n",
loss_cnt);
diff --git a/drivers/tty/serial/serial_core.c b/drivers/tty/serial/serial_core.c
index 2cf5649..f26834d2 100644
--- a/drivers/tty/serial/serial_core.c
+++ b/drivers/tty/serial/serial_core.c
@@ -89,8 +89,7 @@ static void __uart_start(struct tty_struct *tty)
struct uart_state *state = tty->driver_data;
struct uart_port *port = state->uart_port;
- if (!uart_circ_empty(&state->xmit) && state->xmit.buf &&
- !tty->stopped && !tty->hw_stopped)
+ if (!tty->stopped && !tty->hw_stopped)
port->ops->start_tx(port);
}
@@ -1452,6 +1451,8 @@ static void uart_hangup(struct tty_struct *tty)
clear_bit(ASYNCB_NORMAL_ACTIVE, &port->flags);
spin_unlock_irqrestore(&port->lock, flags);
tty_port_tty_set(port, NULL);
+ if (!uart_console(state->uart_port))
+ uart_change_pm(state, UART_PM_STATE_OFF);
wake_up_interruptible(&port->open_wait);
wake_up_interruptible(&port->delta_msr_wait);
}
diff --git a/drivers/tty/serial/st-asc.c b/drivers/tty/serial/st-asc.c
index 21e6e84..dd3a96e 100644
--- a/drivers/tty/serial/st-asc.c
+++ b/drivers/tty/serial/st-asc.c
@@ -295,7 +295,7 @@ static void asc_receive_chars(struct uart_port *port)
status & ASC_STA_OE) {
if (c & ASC_RXBUF_FE) {
- if (c == ASC_RXBUF_FE) {
+ if (c == (ASC_RXBUF_FE | ASC_RXBUF_DUMMY_RX)) {
port->icount.brk++;
if (uart_handle_break(port))
continue;
@@ -325,7 +325,7 @@ static void asc_receive_chars(struct uart_port *port)
flag = TTY_FRAME;
}
- if (uart_handle_sysrq_char(port, c))
+ if (uart_handle_sysrq_char(port, c & 0xff))
continue;
uart_insert_char(port, c, ASC_RXBUF_DUMMY_OE, c & 0xff, flag);
diff --git a/drivers/tty/tty_io.c b/drivers/tty/tty_io.c
index d3448a9..3411071 100644
--- a/drivers/tty/tty_io.c
+++ b/drivers/tty/tty_io.c
@@ -878,9 +878,8 @@ void disassociate_ctty(int on_exit)
spin_lock_irq(&current->sighand->siglock);
put_pid(current->signal->tty_old_pgrp);
current->signal->tty_old_pgrp = NULL;
- spin_unlock_irq(&current->sighand->siglock);
- tty = get_current_tty();
+ tty = tty_kref_get(current->signal->tty);
if (tty) {
unsigned long flags;
spin_lock_irqsave(&tty->ctrl_lock, flags);
@@ -897,6 +896,7 @@ void disassociate_ctty(int on_exit)
#endif
}
+ spin_unlock_irq(&current->sighand->siglock);
/* Now clear signal->tty under the lock */
read_lock(&tasklist_lock);
session_clear_tty(task_session(current));
diff --git a/drivers/usb/class/cdc-acm.c b/drivers/usb/class/cdc-acm.c
index 900f7ff..904efb6 100644
--- a/drivers/usb/class/cdc-acm.c
+++ b/drivers/usb/class/cdc-acm.c
@@ -518,13 +518,16 @@ static int acm_port_activate(struct tty_port *port, struct tty_struct *tty)
if (usb_submit_urb(acm->ctrlurb, GFP_KERNEL)) {
dev_err(&acm->control->dev,
"%s - usb_submit_urb(ctrl irq) failed\n", __func__);
+ usb_autopm_put_interface(acm->control);
goto error_submit_urb;
}
acm->ctrlout = ACM_CTRL_DTR | ACM_CTRL_RTS;
if (acm_set_control(acm, acm->ctrlout) < 0 &&
- (acm->ctrl_caps & USB_CDC_CAP_LINE))
+ (acm->ctrl_caps & USB_CDC_CAP_LINE)) {
+ usb_autopm_put_interface(acm->control);
goto error_set_control;
+ }
usb_autopm_put_interface(acm->control);
@@ -549,7 +552,6 @@ error_submit_read_urbs:
error_set_control:
usb_kill_urb(acm->ctrlurb);
error_submit_urb:
- usb_autopm_put_interface(acm->control);
error_get_interface:
disconnected:
mutex_unlock(&acm->mutex);
@@ -1652,13 +1654,27 @@ static const struct usb_device_id acm_ids[] = {
},
/* Motorola H24 HSPA module: */
{ USB_DEVICE(0x22b8, 0x2d91) }, /* modem */
- { USB_DEVICE(0x22b8, 0x2d92) }, /* modem + diagnostics */
- { USB_DEVICE(0x22b8, 0x2d93) }, /* modem + AT port */
- { USB_DEVICE(0x22b8, 0x2d95) }, /* modem + AT port + diagnostics */
- { USB_DEVICE(0x22b8, 0x2d96) }, /* modem + NMEA */
- { USB_DEVICE(0x22b8, 0x2d97) }, /* modem + diagnostics + NMEA */
- { USB_DEVICE(0x22b8, 0x2d99) }, /* modem + AT port + NMEA */
- { USB_DEVICE(0x22b8, 0x2d9a) }, /* modem + AT port + diagnostics + NMEA */
+ { USB_DEVICE(0x22b8, 0x2d92), /* modem + diagnostics */
+ .driver_info = NO_UNION_NORMAL, /* handle only modem interface */
+ },
+ { USB_DEVICE(0x22b8, 0x2d93), /* modem + AT port */
+ .driver_info = NO_UNION_NORMAL, /* handle only modem interface */
+ },
+ { USB_DEVICE(0x22b8, 0x2d95), /* modem + AT port + diagnostics */
+ .driver_info = NO_UNION_NORMAL, /* handle only modem interface */
+ },
+ { USB_DEVICE(0x22b8, 0x2d96), /* modem + NMEA */
+ .driver_info = NO_UNION_NORMAL, /* handle only modem interface */
+ },
+ { USB_DEVICE(0x22b8, 0x2d97), /* modem + diagnostics + NMEA */
+ .driver_info = NO_UNION_NORMAL, /* handle only modem interface */
+ },
+ { USB_DEVICE(0x22b8, 0x2d99), /* modem + AT port + NMEA */
+ .driver_info = NO_UNION_NORMAL, /* handle only modem interface */
+ },
+ { USB_DEVICE(0x22b8, 0x2d9a), /* modem + AT port + diagnostics + NMEA */
+ .driver_info = NO_UNION_NORMAL, /* handle only modem interface */
+ },
{ USB_DEVICE(0x0572, 0x1329), /* Hummingbird huc56s (Conexant) */
.driver_info = NO_UNION_NORMAL, /* union descriptor misplaced on
diff --git a/drivers/usb/core/hcd-pci.c b/drivers/usb/core/hcd-pci.c
index d59d993..1f02e65 100644
--- a/drivers/usb/core/hcd-pci.c
+++ b/drivers/usb/core/hcd-pci.c
@@ -75,7 +75,7 @@ static void for_each_companion(struct pci_dev *pdev, struct usb_hcd *hcd,
PCI_SLOT(companion->devfn) != slot)
continue;
companion_hcd = pci_get_drvdata(companion);
- if (!companion_hcd)
+ if (!companion_hcd || !companion_hcd->self.root_hub)
continue;
fn(pdev, hcd, companion, companion_hcd);
}
diff --git a/drivers/usb/host/ehci-exynos.c b/drivers/usb/host/ehci-exynos.c
index d1d8c47..7f425ac 100644
--- a/drivers/usb/host/ehci-exynos.c
+++ b/drivers/usb/host/ehci-exynos.c
@@ -212,6 +212,8 @@ static int exynos_ehci_suspend(struct device *dev)
int rc;
rc = ehci_suspend(hcd, do_wakeup);
+ if (rc)
+ return rc;
if (exynos_ehci->otg)
exynos_ehci->otg->set_host(exynos_ehci->otg, &hcd->self);
diff --git a/drivers/usb/host/ehci-platform.c b/drivers/usb/host/ehci-platform.c
index b3a0e11..c7dd93a 100644
--- a/drivers/usb/host/ehci-platform.c
+++ b/drivers/usb/host/ehci-platform.c
@@ -303,6 +303,8 @@ static int ehci_platform_suspend(struct device *dev)
int ret;
ret = ehci_suspend(hcd, do_wakeup);
+ if (ret)
+ return ret;
if (pdata->power_suspend)
pdata->power_suspend(pdev);
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
index 27ac6ad..7ef00ec 100644
--- a/drivers/usb/host/ehci-tegra.c
+++ b/drivers/usb/host/ehci-tegra.c
@@ -509,8 +509,31 @@ static struct platform_driver tegra_ehci_driver = {
}
};
+static int tegra_ehci_reset(struct usb_hcd *hcd)
+{
+ struct ehci_hcd *ehci = hcd_to_ehci(hcd);
+ int retval;
+ int txfifothresh;
+
+ retval = ehci_setup(hcd);
+ if (retval)
+ return retval;
+
+ /*
+ * We should really pull this value out of tegra_ehci_soc_config, but
+ * to avoid needing access to it, make use of the fact that Tegra20 is
+ * the only one so far that needs a value of 10, and Tegra20 is the
+ * only one which doesn't set has_hostpc.
+ */
+ txfifothresh = ehci->has_hostpc ? 0x10 : 10;
+ ehci_writel(ehci, txfifothresh << 16, &ehci->regs->txfill_tuning);
+
+ return 0;
+}
+
static const struct ehci_driver_overrides tegra_overrides __initconst = {
.extra_priv_size = sizeof(struct tegra_ehci_hcd),
+ .reset = tegra_ehci_reset,
};
static int __init ehci_tegra_init(void)
diff --git a/drivers/usb/host/ohci-jz4740.c b/drivers/usb/host/ohci-jz4740.c
index af8dc1b..c2c221a 100644
--- a/drivers/usb/host/ohci-jz4740.c
+++ b/drivers/usb/host/ohci-jz4740.c
@@ -82,14 +82,14 @@ static int ohci_jz4740_hub_control(struct usb_hcd *hcd, u16 typeReq, u16 wValue,
u16 wIndex, char *buf, u16 wLength)
{
struct jz4740_ohci_hcd *jz4740_ohci = hcd_to_jz4740_hcd(hcd);
- int ret;
+ int ret = 0;
switch (typeReq) {
- case SetHubFeature:
+ case SetPortFeature:
if (wValue == USB_PORT_FEAT_POWER)
ret = ohci_jz4740_set_vbus_power(jz4740_ohci, true);
break;
- case ClearHubFeature:
+ case ClearPortFeature:
if (wValue == USB_PORT_FEAT_POWER)
ret = ohci_jz4740_set_vbus_power(jz4740_ohci, false);
break;
diff --git a/drivers/usb/serial/cp210x.c b/drivers/usb/serial/cp210x.c
index 95fa121..762e4a5 100644
--- a/drivers/usb/serial/cp210x.c
+++ b/drivers/usb/serial/cp210x.c
@@ -104,6 +104,7 @@ static const struct usb_device_id id_table[] = {
{ USB_DEVICE(0x10C4, 0x8218) }, /* Lipowsky Industrie Elektronik GmbH, HARP-1 */
{ USB_DEVICE(0x10C4, 0x822B) }, /* Modem EDGE(GSM) Comander 2 */
{ USB_DEVICE(0x10C4, 0x826B) }, /* Cygnal Integrated Products, Inc., Fasttrax GPS demonstration module */
+ { USB_DEVICE(0x10C4, 0x8281) }, /* Nanotec Plug & Drive */
{ USB_DEVICE(0x10C4, 0x8293) }, /* Telegesis ETRX2USB */
{ USB_DEVICE(0x10C4, 0x82F9) }, /* Procyon AVS */
{ USB_DEVICE(0x10C4, 0x8341) }, /* Siemens MC35PU GPRS Modem */
diff --git a/drivers/usb/serial/ftdi_sio.c b/drivers/usb/serial/ftdi_sio.c
index 44ab129..7c6e1de 100644
--- a/drivers/usb/serial/ftdi_sio.c
+++ b/drivers/usb/serial/ftdi_sio.c
@@ -909,6 +909,39 @@ static const struct usb_device_id id_table_combined[] = {
{ USB_DEVICE(FTDI_VID, FTDI_Z3X_PID) },
/* Cressi Devices */
{ USB_DEVICE(FTDI_VID, FTDI_CRESSI_PID) },
+ /* Brainboxes Devices */
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_VX_001_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_VX_012_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_VX_023_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_VX_034_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_101_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_160_1_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_160_2_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_160_3_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_160_4_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_160_5_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_160_6_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_160_7_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_160_8_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_257_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_279_1_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_279_2_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_279_3_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_279_4_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_313_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_324_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_346_1_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_346_2_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_357_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_606_1_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_606_2_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_606_3_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_701_1_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_701_2_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_842_1_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_842_2_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_842_3_PID) },
+ { USB_DEVICE(BRAINBOXES_VID, BRAINBOXES_US_842_4_PID) },
{ } /* Terminating entry */
};
diff --git a/drivers/usb/serial/ftdi_sio_ids.h b/drivers/usb/serial/ftdi_sio_ids.h
index e599fbf..993c93d 100644
--- a/drivers/usb/serial/ftdi_sio_ids.h
+++ b/drivers/usb/serial/ftdi_sio_ids.h
@@ -1326,3 +1326,40 @@
* Manufacturer: Cressi
*/
#define FTDI_CRESSI_PID 0x87d0
+
+/*
+ * Brainboxes devices
+ */
+#define BRAINBOXES_VID 0x05d1
+#define BRAINBOXES_VX_001_PID 0x1001 /* VX-001 ExpressCard 1 Port RS232 */
+#define BRAINBOXES_VX_012_PID 0x1002 /* VX-012 ExpressCard 2 Port RS232 */
+#define BRAINBOXES_VX_023_PID 0x1003 /* VX-023 ExpressCard 1 Port RS422/485 */
+#define BRAINBOXES_VX_034_PID 0x1004 /* VX-034 ExpressCard 2 Port RS422/485 */
+#define BRAINBOXES_US_101_PID 0x1011 /* US-101 1xRS232 */
+#define BRAINBOXES_US_324_PID 0x1013 /* US-324 1xRS422/485 1Mbaud */
+#define BRAINBOXES_US_606_1_PID 0x2001 /* US-606 6 Port RS232 Serial Port 1 and 2 */
+#define BRAINBOXES_US_606_2_PID 0x2002 /* US-606 6 Port RS232 Serial Port 3 and 4 */
+#define BRAINBOXES_US_606_3_PID 0x2003 /* US-606 6 Port RS232 Serial Port 4 and 6 */
+#define BRAINBOXES_US_701_1_PID 0x2011 /* US-701 4xRS232 1Mbaud Port 1 and 2 */
+#define BRAINBOXES_US_701_2_PID 0x2012 /* US-701 4xRS422 1Mbaud Port 3 and 4 */
+#define BRAINBOXES_US_279_1_PID 0x2021 /* US-279 8xRS422 1Mbaud Port 1 and 2 */
+#define BRAINBOXES_US_279_2_PID 0x2022 /* US-279 8xRS422 1Mbaud Port 3 and 4 */
+#define BRAINBOXES_US_279_3_PID 0x2023 /* US-279 8xRS422 1Mbaud Port 5 and 6 */
+#define BRAINBOXES_US_279_4_PID 0x2024 /* US-279 8xRS422 1Mbaud Port 7 and 8 */
+#define BRAINBOXES_US_346_1_PID 0x3011 /* US-346 4xRS422/485 1Mbaud Port 1 and 2 */
+#define BRAINBOXES_US_346_2_PID 0x3012 /* US-346 4xRS422/485 1Mbaud Port 3 and 4 */
+#define BRAINBOXES_US_257_PID 0x5001 /* US-257 2xRS232 1Mbaud */
+#define BRAINBOXES_US_313_PID 0x6001 /* US-313 2xRS422/485 1Mbaud */
+#define BRAINBOXES_US_357_PID 0x7001 /* US_357 1xRS232/422/485 */
+#define BRAINBOXES_US_842_1_PID 0x8001 /* US-842 8xRS422/485 1Mbaud Port 1 and 2 */
+#define BRAINBOXES_US_842_2_PID 0x8002 /* US-842 8xRS422/485 1Mbaud Port 3 and 4 */
+#define BRAINBOXES_US_842_3_PID 0x8003 /* US-842 8xRS422/485 1Mbaud Port 5 and 6 */
+#define BRAINBOXES_US_842_4_PID 0x8004 /* US-842 8xRS422/485 1Mbaud Port 7 and 8 */
+#define BRAINBOXES_US_160_1_PID 0x9001 /* US-160 16xRS232 1Mbaud Port 1 and 2 */
+#define BRAINBOXES_US_160_2_PID 0x9002 /* US-160 16xRS232 1Mbaud Port 3 and 4 */
+#define BRAINBOXES_US_160_3_PID 0x9003 /* US-160 16xRS232 1Mbaud Port 5 and 6 */
+#define BRAINBOXES_US_160_4_PID 0x9004 /* US-160 16xRS232 1Mbaud Port 7 and 8 */
+#define BRAINBOXES_US_160_5_PID 0x9005 /* US-160 16xRS232 1Mbaud Port 9 and 10 */
+#define BRAINBOXES_US_160_6_PID 0x9006 /* US-160 16xRS232 1Mbaud Port 11 and 12 */
+#define BRAINBOXES_US_160_7_PID 0x9007 /* US-160 16xRS232 1Mbaud Port 13 and 14 */
+#define BRAINBOXES_US_160_8_PID 0x9008 /* US-160 16xRS232 1Mbaud Port 15 and 16 */
diff --git a/drivers/usb/serial/option.c b/drivers/usb/serial/option.c
index 68fc9fe..367c7f0 100644
--- a/drivers/usb/serial/option.c
+++ b/drivers/usb/serial/option.c
@@ -243,6 +243,7 @@ static void option_instat_callback(struct urb *urb);
#define TELIT_PRODUCT_CC864_DUAL 0x1005
#define TELIT_PRODUCT_CC864_SINGLE 0x1006
#define TELIT_PRODUCT_DE910_DUAL 0x1010
+#define TELIT_PRODUCT_UE910_V2 0x1012
#define TELIT_PRODUCT_LE920 0x1200
/* ZTE PRODUCTS */
@@ -1041,6 +1042,7 @@ static const struct usb_device_id option_ids[] = {
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_CC864_DUAL) },
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_CC864_SINGLE) },
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_DE910_DUAL) },
+ { USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_UE910_V2) },
{ USB_DEVICE(TELIT_VENDOR_ID, TELIT_PRODUCT_LE920),
.driver_info = (kernel_ulong_t)&telit_le920_blacklist },
{ USB_DEVICE_AND_INTERFACE_INFO(ZTE_VENDOR_ID, ZTE_PRODUCT_MF622, 0xff, 0xff, 0xff) }, /* ZTE WCDMA products */
diff --git a/drivers/usb/serial/pl2303.c b/drivers/usb/serial/pl2303.c
index 2e22fc2..b3d5a35 100644
--- a/drivers/usb/serial/pl2303.c
+++ b/drivers/usb/serial/pl2303.c
@@ -83,6 +83,9 @@ static const struct usb_device_id id_table[] = {
{ USB_DEVICE(YCCABLE_VENDOR_ID, YCCABLE_PRODUCT_ID) },
{ USB_DEVICE(SUPERIAL_VENDOR_ID, SUPERIAL_PRODUCT_ID) },
{ USB_DEVICE(HP_VENDOR_ID, HP_LD220_PRODUCT_ID) },
+ { USB_DEVICE(HP_VENDOR_ID, HP_LD960_PRODUCT_ID) },
+ { USB_DEVICE(HP_VENDOR_ID, HP_LCM220_PRODUCT_ID) },
+ { USB_DEVICE(HP_VENDOR_ID, HP_LCM960_PRODUCT_ID) },
{ USB_DEVICE(CRESSI_VENDOR_ID, CRESSI_EDY_PRODUCT_ID) },
{ USB_DEVICE(ZEAGLE_VENDOR_ID, ZEAGLE_N2ITION3_PRODUCT_ID) },
{ USB_DEVICE(SONY_VENDOR_ID, SONY_QN3USB_PRODUCT_ID) },
diff --git a/drivers/usb/serial/pl2303.h b/drivers/usb/serial/pl2303.h
index c38b8c0..42bc082 100644
--- a/drivers/usb/serial/pl2303.h
+++ b/drivers/usb/serial/pl2303.h
@@ -121,8 +121,11 @@
#define SUPERIAL_VENDOR_ID 0x5372
#define SUPERIAL_PRODUCT_ID 0x2303
-/* Hewlett-Packard LD220-HP POS Pole Display */
+/* Hewlett-Packard POS Pole Displays */
#define HP_VENDOR_ID 0x03f0
+#define HP_LD960_PRODUCT_ID 0x0b39
+#define HP_LCM220_PRODUCT_ID 0x3139
+#define HP_LCM960_PRODUCT_ID 0x3239
#define HP_LD220_PRODUCT_ID 0x3524
/* Cressi Edy (diving computer) PC interface */
diff --git a/drivers/usb/serial/sierra.c b/drivers/usb/serial/sierra.c
index a9eb6221..6b192e6 100644
--- a/drivers/usb/serial/sierra.c
+++ b/drivers/usb/serial/sierra.c
@@ -291,7 +291,6 @@ static const struct usb_device_id id_table[] = {
{ USB_DEVICE(0x0f3d, 0x68A3), /* Airprime/Sierra Wireless Direct IP modems */
.driver_info = (kernel_ulong_t)&direct_ip_interface_blacklist
},
- { USB_DEVICE(0x413C, 0x08133) }, /* Dell Computer Corp. Wireless 5720 VZW Mobile Broadband (EVDO Rev-A) Minicard GPS Port */
{ }
};
diff --git a/drivers/usb/serial/usb_wwan.c b/drivers/usb/serial/usb_wwan.c
index 640fe01..b078440 100644
--- a/drivers/usb/serial/usb_wwan.c
+++ b/drivers/usb/serial/usb_wwan.c
@@ -466,6 +466,9 @@ int usb_wwan_port_probe(struct usb_serial_port *port)
int err;
int i;
+ if (!port->bulk_in_size || !port->bulk_out_size)
+ return -ENODEV;
+
portdata = kzalloc(sizeof(*portdata), GFP_KERNEL);
if (!portdata)
return -ENOMEM;
@@ -473,9 +476,6 @@ int usb_wwan_port_probe(struct usb_serial_port *port)
init_usb_anchor(&portdata->delayed);
for (i = 0; i < N_IN_URB; i++) {
- if (!port->bulk_in_size)
- break;
-
buffer = (u8 *)__get_free_page(GFP_KERNEL);
if (!buffer)
goto bail_out_error;
@@ -489,9 +489,6 @@ int usb_wwan_port_probe(struct usb_serial_port *port)
}
for (i = 0; i < N_OUT_URB; i++) {
- if (!port->bulk_out_size)
- break;
-
buffer = kmalloc(OUT_BUFLEN, GFP_KERNEL);
if (!buffer)
goto bail_out_error2;
diff --git a/drivers/usb/storage/uas.c b/drivers/usb/storage/uas.c
index a7ac97c..511b229 100644
--- a/drivers/usb/storage/uas.c
+++ b/drivers/usb/storage/uas.c
@@ -137,7 +137,7 @@ static void uas_do_work(struct work_struct *work)
if (!(cmdinfo->state & IS_IN_WORK_LIST))
continue;
- err = uas_submit_urbs(cmnd, cmnd->device->hostdata, GFP_NOIO);
+ err = uas_submit_urbs(cmnd, cmnd->device->hostdata, GFP_ATOMIC);
if (!err)
cmdinfo->state &= ~IS_IN_WORK_LIST;
else
@@ -803,7 +803,7 @@ static int uas_eh_task_mgmt(struct scsi_cmnd *cmnd,
devinfo->running_task = 1;
memset(&devinfo->response, 0, sizeof(devinfo->response));
- sense_urb = uas_submit_sense_urb(cmnd, GFP_NOIO,
+ sense_urb = uas_submit_sense_urb(cmnd, GFP_ATOMIC,
devinfo->use_streams ? tag : 0);
if (!sense_urb) {
shost_printk(KERN_INFO, shost,
@@ -813,7 +813,7 @@ static int uas_eh_task_mgmt(struct scsi_cmnd *cmnd,
spin_unlock_irqrestore(&devinfo->lock, flags);
return FAILED;
}
- if (uas_submit_task_urb(cmnd, GFP_NOIO, function, tag)) {
+ if (uas_submit_task_urb(cmnd, GFP_ATOMIC, function, tag)) {
shost_printk(KERN_INFO, shost,
"%s: %s: submit task mgmt urb failed\n",
__func__, fname);
@@ -1030,7 +1030,7 @@ static int uas_configure_endpoints(struct uas_dev_info *devinfo)
devinfo->use_streams = 0;
} else {
devinfo->qdepth = usb_alloc_streams(devinfo->intf, eps + 1,
- 3, 256, GFP_KERNEL);
+ 3, 256, GFP_NOIO);
if (devinfo->qdepth < 0)
return devinfo->qdepth;
devinfo->use_streams = 1;
@@ -1047,7 +1047,7 @@ static void uas_free_streams(struct uas_dev_info *devinfo)
eps[0] = usb_pipe_endpoint(udev, devinfo->status_pipe);
eps[1] = usb_pipe_endpoint(udev, devinfo->data_in_pipe);
eps[2] = usb_pipe_endpoint(udev, devinfo->data_out_pipe);
- usb_free_streams(devinfo->intf, eps, 3, GFP_KERNEL);
+ usb_free_streams(devinfo->intf, eps, 3, GFP_NOIO);
}
static int uas_probe(struct usb_interface *intf, const struct usb_device_id *id)
@@ -1096,16 +1096,17 @@ static int uas_probe(struct usb_interface *intf, const struct usb_device_id *id)
if (result)
goto free_streams;
+ usb_set_intfdata(intf, shost);
result = scsi_add_host(shost, &intf->dev);
if (result)
goto free_streams;
scsi_scan_host(shost);
- usb_set_intfdata(intf, shost);
return result;
free_streams:
uas_free_streams(devinfo);
+ usb_set_intfdata(intf, NULL);
set_alt0:
usb_set_interface(udev, intf->altsetting[0].desc.bInterfaceNumber, 0);
if (shost)
diff --git a/drivers/usb/usb-common.c b/drivers/usb/usb-common.c
index d771870a..6dfd30a 100644
--- a/drivers/usb/usb-common.c
+++ b/drivers/usb/usb-common.c
@@ -69,7 +69,7 @@ const char *usb_state_string(enum usb_device_state state)
[USB_STATE_RECONNECTING] = "reconnecting",
[USB_STATE_UNAUTHENTICATED] = "unauthenticated",
[USB_STATE_DEFAULT] = "default",
- [USB_STATE_ADDRESS] = "addresssed",
+ [USB_STATE_ADDRESS] = "addressed",
[USB_STATE_CONFIGURED] = "configured",
[USB_STATE_SUSPENDED] = "suspended",
};
diff --git a/drivers/uwb/drp.c b/drivers/uwb/drp.c
index 16ada83..1a2fd97 100644
--- a/drivers/uwb/drp.c
+++ b/drivers/uwb/drp.c
@@ -599,8 +599,11 @@ static void uwb_drp_handle_alien_drp(struct uwb_rc *rc, struct uwb_ie_drp *drp_i
/* alloc and initialize new uwb_cnflt_alien */
cnflt = kzalloc(sizeof(struct uwb_cnflt_alien), GFP_KERNEL);
- if (!cnflt)
+ if (!cnflt) {
dev_err(dev, "failed to alloc uwb_cnflt_alien struct\n");
+ return;
+ }
+
INIT_LIST_HEAD(&cnflt->rc_node);
init_timer(&cnflt->timer);
cnflt->timer.function = uwb_cnflt_timer;
diff --git a/drivers/video/Kconfig b/drivers/video/Kconfig
index 6c793bc..c7b4f0f 100644
--- a/drivers/video/Kconfig
+++ b/drivers/video/Kconfig
@@ -21,7 +21,15 @@ source "drivers/gpu/vga/Kconfig"
source "drivers/gpu/host1x/Kconfig"
+menu "Direct Rendering Manager"
source "drivers/gpu/drm/Kconfig"
+endmenu
+
+menu "Frame buffer Devices"
+source "drivers/video/fbdev/Kconfig"
+endmenu
+
+source "drivers/video/backlight/Kconfig"
config VGASTATE
tristate
@@ -33,2482 +41,14 @@ config VIDEOMODE_HELPERS
config HDMI
bool
-menuconfig FB
- tristate "Support for frame buffer devices"
- ---help---
- The frame buffer device provides an abstraction for the graphics
- hardware. It represents the frame buffer of some video hardware and
- allows application software to access the graphics hardware through
- a well-defined interface, so the software doesn't need to know
- anything about the low-level (hardware register) stuff.
-
- Frame buffer devices work identically across the different
- architectures supported by Linux and make the implementation of
- application programs easier and more portable; at this point, an X
- server exists which uses the frame buffer device exclusively.
- On several non-X86 architectures, the frame buffer device is the
- only way to use the graphics hardware.
-
- The device is accessed through special device nodes, usually located
- in the /dev directory, i.e. /dev/fb*.
-
- You need an utility program called fbset to make full use of frame
- buffer devices. Please read <file:Documentation/fb/framebuffer.txt>
- and the Framebuffer-HOWTO at
- <http://www.munted.org.uk/programming/Framebuffer-HOWTO-1.3.html> for more
- information.
-
- Say Y here and to the driver for your graphics board below if you
- are compiling a kernel for a non-x86 architecture.
-
- If you are compiling for the x86 architecture, you can say Y if you
- want to play with it, but it is not essential. Please note that
- running graphical applications that directly touch the hardware
- (e.g. an accelerated X server) and that are not frame buffer
- device-aware may cause unexpected results. If unsure, say N.
-
-config FIRMWARE_EDID
- bool "Enable firmware EDID"
- depends on FB
- default n
- ---help---
- This enables access to the EDID transferred from the firmware.
- On the i386, this is from the Video BIOS. Enable this if DDC/I2C
- transfers do not work for your driver and if you are using
- nvidiafb, i810fb or savagefb.
-
- In general, choosing Y for this option is safe. If you
- experience extremely long delays while booting before you get
- something on your display, try setting this to N. Matrox cards in
- combination with certain motherboards and monitors are known to
- suffer from this problem.
-
-config FB_DDC
- tristate
- depends on FB
- select I2C_ALGOBIT
- select I2C
- default n
-
-config FB_BOOT_VESA_SUPPORT
- bool
- depends on FB
- default n
- ---help---
- If true, at least one selected framebuffer driver can take advantage
- of VESA video modes set at an early boot stage via the vga= parameter.
-
-config FB_CFB_FILLRECT
- tristate
- depends on FB
- default n
- ---help---
- Include the cfb_fillrect function for generic software rectangle
- filling. This is used by drivers that don't provide their own
- (accelerated) version.
-
-config FB_CFB_COPYAREA
- tristate
- depends on FB
- default n
- ---help---
- Include the cfb_copyarea function for generic software area copying.
- This is used by drivers that don't provide their own (accelerated)
- version.
-
-config FB_CFB_IMAGEBLIT
- tristate
- depends on FB
- default n
- ---help---
- Include the cfb_imageblit function for generic software image
- blitting. This is used by drivers that don't provide their own
- (accelerated) version.
-
-config FB_CFB_REV_PIXELS_IN_BYTE
- bool
- depends on FB
- default n
- ---help---
- Allow generic frame-buffer functions to work on displays with 1, 2
- and 4 bits per pixel depths which has opposite order of pixels in
- byte order to bytes in long order.
-
-config FB_SYS_FILLRECT
- tristate
- depends on FB
- default n
- ---help---
- Include the sys_fillrect function for generic software rectangle
- filling. This is used by drivers that don't provide their own
- (accelerated) version and the framebuffer is in system RAM.
-
-config FB_SYS_COPYAREA
- tristate
- depends on FB
- default n
- ---help---
- Include the sys_copyarea function for generic software area copying.
- This is used by drivers that don't provide their own (accelerated)
- version and the framebuffer is in system RAM.
-
-config FB_SYS_IMAGEBLIT
- tristate
- depends on FB
- default n
- ---help---
- Include the sys_imageblit function for generic software image
- blitting. This is used by drivers that don't provide their own
- (accelerated) version and the framebuffer is in system RAM.
-
-menuconfig FB_FOREIGN_ENDIAN
- bool "Framebuffer foreign endianness support"
- depends on FB
- ---help---
- This menu will let you enable support for the framebuffers with
- non-native endianness (e.g. Little-Endian framebuffer on a
- Big-Endian machine). Most probably you don't have such hardware,
- so it's safe to say "n" here.
-
-choice
- prompt "Choice endianness support"
- depends on FB_FOREIGN_ENDIAN
-
-config FB_BOTH_ENDIAN
- bool "Support for Big- and Little-Endian framebuffers"
-
-config FB_BIG_ENDIAN
- bool "Support for Big-Endian framebuffers only"
-
-config FB_LITTLE_ENDIAN
- bool "Support for Little-Endian framebuffers only"
-
-endchoice
-
-config FB_SYS_FOPS
- tristate
- depends on FB
- default n
-
-config FB_DEFERRED_IO
- bool
- depends on FB
-
-config FB_HECUBA
- tristate
- depends on FB
- depends on FB_DEFERRED_IO
-
-config FB_SVGALIB
- tristate
- depends on FB
- default n
- ---help---
- Common utility functions useful to fbdev drivers of VGA-based
- cards.
-
-config FB_MACMODES
- tristate
- depends on FB
- default n
-
-config FB_BACKLIGHT
- bool
- depends on FB
- select BACKLIGHT_LCD_SUPPORT
- select BACKLIGHT_CLASS_DEVICE
- default n
-
-config FB_MODE_HELPERS
- bool "Enable Video Mode Handling Helpers"
- depends on FB
- default n
- ---help---
- This enables functions for handling video modes using the
- Generalized Timing Formula and the EDID parser. A few drivers rely
- on this feature such as the radeonfb, rivafb, and the i810fb. If
- your driver does not take advantage of this feature, choosing Y will
- just increase the kernel size by about 5K.
-
-config FB_TILEBLITTING
- bool "Enable Tile Blitting Support"
- depends on FB
- default n
- ---help---
- This enables tile blitting. Tile blitting is a drawing technique
- where the screen is divided into rectangular sections (tiles), whereas
- the standard blitting divides the screen into pixels. Because the
- default drawing element is a tile, drawing functions will be passed
- parameters in terms of number of tiles instead of number of pixels.
- For example, to draw a single character, instead of using bitmaps,
- an index to an array of bitmaps will be used. To clear or move a
- rectangular section of a screen, the rectangle will be described in
- terms of number of tiles in the x- and y-axis.
-
- This is particularly important to one driver, matroxfb. If
- unsure, say N.
-
-comment "Frame buffer hardware drivers"
- depends on FB
-
-config FB_GRVGA
- tristate "Aeroflex Gaisler framebuffer support"
- depends on FB && SPARC
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- ---help---
- This enables support for the SVGACTRL framebuffer in the GRLIB IP library from Aeroflex Gaisler.
-
-config FB_CIRRUS
- tristate "Cirrus Logic support"
- depends on FB && (ZORRO || PCI)
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- ---help---
- This enables support for Cirrus Logic GD542x/543x based boards on
- Amiga: SD64, Piccolo, Picasso II/II+, Picasso IV, or EGS Spectrum.
-
- If you have a PCI-based system, this enables support for these
- chips: GD-543x, GD-544x, GD-5480.
-
- Please read the file <file:Documentation/fb/cirrusfb.txt>.
-
- Say N unless you have such a graphics board or plan to get one
- before you next recompile the kernel.
-
-config FB_PM2
- tristate "Permedia2 support"
- depends on FB && ((AMIGA && BROKEN) || PCI)
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the frame buffer device driver for cards based on
- the 3D Labs Permedia, Permedia 2 and Permedia 2V chips.
- The driver was tested on the following cards:
- Diamond FireGL 1000 PRO AGP
- ELSA Gloria Synergy PCI
- Appian Jeronimo PRO (both heads) PCI
- 3DLabs Oxygen ACX aka EONtronics Picasso P2 PCI
- Techsource Raptor GFX-8P (aka Sun PGX-32) on SPARC
- ASK Graphic Blaster Exxtreme AGP
-
- To compile this driver as a module, choose M here: the
- module will be called pm2fb.
-
-config FB_PM2_FIFO_DISCONNECT
- bool "enable FIFO disconnect feature"
- depends on FB_PM2 && PCI
- help
- Support the Permedia2 FIFO disconnect feature.
-
-config FB_ARMCLCD
- tristate "ARM PrimeCell PL110 support"
- depends on ARM || ARM64 || COMPILE_TEST
- depends on FB && ARM_AMBA
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This framebuffer device driver is for the ARM PrimeCell PL110
- Colour LCD controller. ARM PrimeCells provide the building
- blocks for System on a Chip devices.
-
- If you want to compile this as a module (=code which can be
- inserted into and removed from the running kernel), say M
- here and read <file:Documentation/kbuild/modules.txt>. The module
- will be called amba-clcd.
-
-config FB_ACORN
- bool "Acorn VIDC support"
- depends on (FB = y) && ARM && ARCH_ACORN
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the frame buffer device driver for the Acorn VIDC graphics
- hardware found in Acorn RISC PCs and other ARM-based machines. If
- unsure, say N.
-
-config FB_CLPS711X
- bool "CLPS711X LCD support"
- depends on (FB = y) && ARM && ARCH_CLPS711X
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- Say Y to enable the Framebuffer driver for the CLPS7111 and
- EP7212 processors.
-
-config FB_SA1100
- bool "SA-1100 LCD support"
- depends on (FB = y) && ARM && ARCH_SA1100
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is a framebuffer device for the SA-1100 LCD Controller.
- See <http://www.linux-fbdev.org/> for information on framebuffer
- devices.
-
- If you plan to use the LCD display with your SA-1100 system, say
- Y here.
-
-config FB_IMX
- tristate "Freescale i.MX1/21/25/27 LCD support"
- depends on FB && ARCH_MXC
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select FB_MODE_HELPERS
- select VIDEOMODE_HELPERS
-
-config FB_CYBER2000
- tristate "CyberPro 2000/2010/5000 support"
- depends on FB && PCI && (BROKEN || !SPARC64)
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This enables support for the Integraphics CyberPro 20x0 and 5000
- VGA chips used in the Rebel.com Netwinder and other machines.
- Say Y if you have a NetWinder or a graphics card containing this
- device, otherwise say N.
-
-config FB_CYBER2000_DDC
- bool "DDC for CyberPro support"
- depends on FB_CYBER2000
- select FB_DDC
- default y
- help
- Say Y here if you want DDC support for your CyberPro graphics
- card. This is only I2C bus support, driver does not use EDID.
-
-config FB_CYBER2000_I2C
- bool "CyberPro 2000/2010/5000 I2C support"
- depends on FB_CYBER2000 && I2C && ARCH_NETWINDER
- select I2C_ALGOBIT
- help
- Enable support for the I2C video decoder interface on the
- Integraphics CyberPro 20x0 and 5000 VGA chips. This is used
- on the Netwinder machines for the SAA7111 video capture.
-
-config FB_APOLLO
- bool
- depends on (FB = y) && APOLLO
- default y
- select FB_CFB_FILLRECT
- select FB_CFB_IMAGEBLIT
-
-config FB_Q40
- bool
- depends on (FB = y) && Q40
- default y
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
-
-config FB_AMIGA
- tristate "Amiga native chipset support"
- depends on FB && AMIGA
- help
- This is the frame buffer device driver for the builtin graphics
- chipset found in Amigas.
-
- To compile this driver as a module, choose M here: the
- module will be called amifb.
-
-config FB_AMIGA_OCS
- bool "Amiga OCS chipset support"
- depends on FB_AMIGA
- help
- This enables support for the original Agnus and Denise video chips,
- found in the Amiga 1000 and most A500's and A2000's. If you intend
- to run Linux on any of these systems, say Y; otherwise say N.
-
-config FB_AMIGA_ECS
- bool "Amiga ECS chipset support"
- depends on FB_AMIGA
- help
- This enables support for the Enhanced Chip Set, found in later
- A500's, later A2000's, the A600, the A3000, the A3000T and CDTV. If
- you intend to run Linux on any of these systems, say Y; otherwise
- say N.
-
-config FB_AMIGA_AGA
- bool "Amiga AGA chipset support"
- depends on FB_AMIGA
- help
- This enables support for the Advanced Graphics Architecture (also
- known as the AGA or AA) Chip Set, found in the A1200, A4000, A4000T
- and CD32. If you intend to run Linux on any of these systems, say Y;
- otherwise say N.
-
-config FB_FM2
- bool "Amiga FrameMaster II/Rainbow II support"
- depends on (FB = y) && ZORRO
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the frame buffer device driver for the Amiga FrameMaster
- card from BSC (exhibited 1992 but not shipped as a CBM product).
-
-config FB_ARC
- tristate "Arc Monochrome LCD board support"
- depends on FB && X86
- select FB_SYS_FILLRECT
- select FB_SYS_COPYAREA
- select FB_SYS_IMAGEBLIT
- select FB_SYS_FOPS
- help
- This enables support for the Arc Monochrome LCD board. The board
- is based on the KS-108 lcd controller and is typically a matrix
- of 2*n chips. This driver was tested with a 128x64 panel. This
- driver supports it for use with x86 SBCs through a 16 bit GPIO
- interface (8 bit data, 8 bit control). If you anticipate using
- this driver, say Y or M; otherwise say N. You must specify the
- GPIO IO address to be used for setting control and data.
-
-config FB_ATARI
- bool "Atari native chipset support"
- depends on (FB = y) && ATARI
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the frame buffer device driver for the builtin graphics
- chipset found in Ataris.
-
-config FB_OF
- bool "Open Firmware frame buffer device support"
- depends on (FB = y) && (PPC64 || PPC_OF) && (!PPC_PSERIES || PCI)
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select FB_MACMODES
- help
- Say Y if you want support with Open Firmware for your graphics
- board.
-
-config FB_CONTROL
- bool "Apple \"control\" display support"
- depends on (FB = y) && PPC_PMAC && PPC32
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select FB_MACMODES
- help
- This driver supports a frame buffer for the graphics adapter in the
- Power Macintosh 7300 and others.
-
-config FB_PLATINUM
- bool "Apple \"platinum\" display support"
- depends on (FB = y) && PPC_PMAC && PPC32
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select FB_MACMODES
- help
- This driver supports a frame buffer for the "platinum" graphics
- adapter in some Power Macintoshes.
-
-config FB_VALKYRIE
- bool "Apple \"valkyrie\" display support"
- depends on (FB = y) && (MAC || (PPC_PMAC && PPC32))
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select FB_MACMODES
- help
- This driver supports a frame buffer for the "valkyrie" graphics
- adapter in some Power Macintoshes.
-
-config FB_CT65550
- bool "Chips 65550 display support"
- depends on (FB = y) && PPC32 && PCI
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the frame buffer device driver for the Chips & Technologies
- 65550 graphics chip in PowerBooks.
-
-config FB_ASILIANT
- bool "Asiliant (Chips) 69000 display support"
- depends on (FB = y) && PCI
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the frame buffer device driver for the Asiliant 69030 chipset
-
-config FB_IMSTT
- bool "IMS Twin Turbo display support"
- depends on (FB = y) && PCI
- select FB_CFB_IMAGEBLIT
- select FB_MACMODES if PPC
- help
- The IMS Twin Turbo is a PCI-based frame buffer card bundled with
- many Macintosh and compatible computers.
-
-config FB_VGA16
- tristate "VGA 16-color graphics support"
- depends on FB && (X86 || PPC)
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select VGASTATE
- select FONT_8x16 if FRAMEBUFFER_CONSOLE
- help
- This is the frame buffer device driver for VGA 16 color graphic
- cards. Say Y if you have such a card.
-
- To compile this driver as a module, choose M here: the
- module will be called vga16fb.
-
-config FB_BF54X_LQ043
- tristate "SHARP LQ043 TFT LCD (BF548 EZKIT)"
- depends on FB && (BF54x) && !BF542
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the framebuffer device driver for a SHARP LQ043T1DG01 TFT LCD
-
-config FB_BFIN_T350MCQB
- tristate "Varitronix COG-T350MCQB TFT LCD display (BF527 EZKIT)"
- depends on FB && BLACKFIN
- select BFIN_GPTIMERS
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the framebuffer device driver for a Varitronix VL-PS-COG-T350MCQB-01 display TFT LCD
- This display is a QVGA 320x240 24-bit RGB display interfaced by an 8-bit wide PPI
- It uses PPI[0..7] PPI_FS1, PPI_FS2 and PPI_CLK.
-
-config FB_BFIN_LQ035Q1
- tristate "SHARP LQ035Q1DH02 TFT LCD"
- depends on FB && BLACKFIN && SPI
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select BFIN_GPTIMERS
- help
- This is the framebuffer device driver for a SHARP LQ035Q1DH02 TFT display found on
- the Blackfin Landscape LCD EZ-Extender Card.
- This display is a QVGA 320x240 18-bit RGB display interfaced by an 16-bit wide PPI
- It uses PPI[0..15] PPI_FS1, PPI_FS2 and PPI_CLK.
-
- To compile this driver as a module, choose M here: the
- module will be called bfin-lq035q1-fb.
-
-config FB_BF537_LQ035
- tristate "SHARP LQ035 TFT LCD (BF537 STAMP)"
- depends on FB && (BF534 || BF536 || BF537) && I2C_BLACKFIN_TWI
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select BFIN_GPTIMERS
- help
- This is the framebuffer device for a SHARP LQ035Q7DB03 TFT LCD
- attached to a BF537.
-
- To compile this driver as a module, choose M here: the
- module will be called bf537-lq035.
-
-config FB_BFIN_7393
- tristate "Blackfin ADV7393 Video encoder"
- depends on FB && BLACKFIN
- select I2C
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the framebuffer device for a ADV7393 video encoder
- attached to a Blackfin on the PPI port.
- If your Blackfin board has a ADV7393 select Y.
-
- To compile this driver as a module, choose M here: the
- module will be called bfin_adv7393fb.
-
-choice
- prompt "Video mode support"
- depends on FB_BFIN_7393
- default NTSC
-
-config NTSC
- bool 'NTSC 720x480'
-
-config PAL
- bool 'PAL 720x576'
-
-config NTSC_640x480
- bool 'NTSC 640x480 (Experimental)'
-
-config PAL_640x480
- bool 'PAL 640x480 (Experimental)'
-
-config NTSC_YCBCR
- bool 'NTSC 720x480 YCbCR input'
-
-config PAL_YCBCR
- bool 'PAL 720x576 YCbCR input'
-
-endchoice
-
-choice
- prompt "Size of ADV7393 frame buffer memory Single/Double Size"
- depends on (FB_BFIN_7393)
- default ADV7393_1XMEM
-
-config ADV7393_1XMEM
- bool 'Single'
-
-config ADV7393_2XMEM
- bool 'Double'
-endchoice
-
-config FB_STI
- tristate "HP STI frame buffer device support"
- depends on FB && PARISC
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select STI_CONSOLE
- select VT
- default y
- ---help---
- STI refers to the HP "Standard Text Interface" which is a set of
- BIOS routines contained in a ROM chip in HP PA-RISC based machines.
- Enabling this option will implement the linux framebuffer device
- using calls to the STI BIOS routines for initialisation.
-
- If you enable this option, you will get a planar framebuffer device
- /dev/fb which will work on the most common HP graphic cards of the
- NGLE family, including the artist chips (in the 7xx and Bxxx series),
- HCRX, HCRX24, CRX, CRX24 and VisEG series.
-
- It is safe to enable this option, so you should probably say "Y".
-
-config FB_MAC
- bool "Generic Macintosh display support"
- depends on (FB = y) && MAC
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select FB_MACMODES
-
-config FB_HP300
- bool
- depends on (FB = y) && DIO
- select FB_CFB_IMAGEBLIT
- default y
-
-config FB_TGA
- tristate "TGA/SFB+ framebuffer support"
- depends on FB && (ALPHA || TC)
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select BITREVERSE
- ---help---
- This is the frame buffer device driver for generic TGA and SFB+
- graphic cards. These include DEC ZLXp-E1, -E2 and -E3 PCI cards,
- also known as PBXGA-A, -B and -C, and DEC ZLX-E1, -E2 and -E3
- TURBOchannel cards, also known as PMAGD-A, -B and -C.
-
- Due to hardware limitations ZLX-E2 and E3 cards are not supported
- for DECstation 5000/200 systems. Additionally due to firmware
- limitations these cards may cause troubles with booting DECstation
- 5000/240 and /260 systems, but are fully supported under Linux if
- you manage to get it going. ;-)
-
- Say Y if you have one of those.
-
-config FB_UVESA
- tristate "Userspace VESA VGA graphics support"
- depends on FB && CONNECTOR
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select FB_MODE_HELPERS
- help
- This is the frame buffer driver for generic VBE 2.0 compliant
- graphic cards. It can also take advantage of VBE 3.0 features,
- such as refresh rate adjustment.
-
- This driver generally provides more features than vesafb but
- requires a userspace helper application called 'v86d'. See
- <file:Documentation/fb/uvesafb.txt> for more information.
-
- If unsure, say N.
-
-config FB_VESA
- bool "VESA VGA graphics support"
- depends on (FB = y) && X86
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select FB_BOOT_VESA_SUPPORT
- help
- This is the frame buffer device driver for generic VESA 2.0
- compliant graphic cards. The older VESA 1.2 cards are not supported.
- You will get a boot time penguin logo at no additional cost. Please
- read <file:Documentation/fb/vesafb.txt>. If unsure, say Y.
-
-config FB_EFI
- bool "EFI-based Framebuffer Support"
- depends on (FB = y) && X86 && EFI
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the EFI frame buffer device driver. If the firmware on
- your platform is EFI 1.10 or UEFI 2.0, select Y to add support for
- using the EFI framebuffer as your console.
-
-config FB_N411
- tristate "N411 Apollo/Hecuba devkit support"
- depends on FB && X86 && MMU
- select FB_SYS_FILLRECT
- select FB_SYS_COPYAREA
- select FB_SYS_IMAGEBLIT
- select FB_SYS_FOPS
- select FB_DEFERRED_IO
- select FB_HECUBA
- help
- This enables support for the Apollo display controller in its
- Hecuba form using the n411 devkit.
-
-config FB_HGA
- tristate "Hercules mono graphics support"
- depends on FB && X86
- help
- Say Y here if you have a Hercules mono graphics card.
-
- To compile this driver as a module, choose M here: the
- module will be called hgafb.
-
- As this card technology is at least 25 years old,
- most people will answer N here.
-
-config FB_GBE
- bool "SGI Graphics Backend frame buffer support"
- depends on (FB = y) && SGI_IP32
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the frame buffer device driver for SGI Graphics Backend.
- This chip is used in SGI O2 and Visual Workstation 320/540.
-
-config FB_GBE_MEM
- int "Video memory size in MB"
- depends on FB_GBE
- default 4
- help
- This is the amount of memory reserved for the framebuffer,
- which can be any value between 1MB and 8MB.
-
-config FB_SBUS
- bool "SBUS and UPA framebuffers"
- depends on (FB = y) && SPARC
- help
- Say Y if you want support for SBUS or UPA based frame buffer device.
-
-config FB_BW2
- bool "BWtwo support"
- depends on (FB = y) && (SPARC && FB_SBUS)
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the frame buffer device driver for the BWtwo frame buffer.
-
-config FB_CG3
- bool "CGthree support"
- depends on (FB = y) && (SPARC && FB_SBUS)
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the frame buffer device driver for the CGthree frame buffer.
-
-config FB_CG6
- bool "CGsix (GX,TurboGX) support"
- depends on (FB = y) && (SPARC && FB_SBUS)
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the frame buffer device driver for the CGsix (GX, TurboGX)
- frame buffer.
-
-config FB_FFB
- bool "Creator/Creator3D/Elite3D support"
- depends on FB_SBUS && SPARC64
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the frame buffer device driver for the Creator, Creator3D,
- and Elite3D graphics boards.
-
-config FB_TCX
- bool "TCX (SS4/SS5 only) support"
- depends on FB_SBUS
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the frame buffer device driver for the TCX 24/8bit frame
- buffer.
-
-config FB_CG14
- bool "CGfourteen (SX) support"
- depends on FB_SBUS
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the frame buffer device driver for the CGfourteen frame
- buffer on Desktop SPARCsystems with the SX graphics option.
-
-config FB_P9100
- bool "P9100 (Sparcbook 3 only) support"
- depends on FB_SBUS
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the frame buffer device driver for the P9100 card
- supported on Sparcbook 3 machines.
-
-config FB_LEO
- bool "Leo (ZX) support"
- depends on FB_SBUS
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the frame buffer device driver for the SBUS-based Sun ZX
- (leo) frame buffer cards.
-
-config FB_IGA
- bool "IGA 168x display support"
- depends on (FB = y) && SPARC32
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the framebuffer device for the INTERGRAPHICS 1680 and
- successor frame buffer cards.
-
-config FB_XVR500
- bool "Sun XVR-500 3DLABS Wildcat support"
- depends on (FB = y) && PCI && SPARC64
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the framebuffer device for the Sun XVR-500 and similar
- graphics cards based upon the 3DLABS Wildcat chipset. The driver
- only works on sparc64 systems where the system firmware has
- mostly initialized the card already. It is treated as a
- completely dumb framebuffer device.
-
-config FB_XVR2500
- bool "Sun XVR-2500 3DLABS Wildcat support"
- depends on (FB = y) && PCI && SPARC64
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the framebuffer device for the Sun XVR-2500 and similar
- graphics cards based upon the 3DLABS Wildcat chipset. The driver
- only works on sparc64 systems where the system firmware has
- mostly initialized the card already. It is treated as a
- completely dumb framebuffer device.
-
-config FB_XVR1000
- bool "Sun XVR-1000 support"
- depends on (FB = y) && SPARC64
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the framebuffer device for the Sun XVR-1000 and similar
- graphics cards. The driver only works on sparc64 systems where
- the system firmware has mostly initialized the card already. It
- is treated as a completely dumb framebuffer device.
-
-config FB_PVR2
- tristate "NEC PowerVR 2 display support"
- depends on FB && SH_DREAMCAST
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- ---help---
- Say Y here if you have a PowerVR 2 card in your box. If you plan to
- run linux on your Dreamcast, you will have to say Y here.
- This driver may or may not work on other PowerVR 2 cards, but is
- totally untested. Use at your own risk. If unsure, say N.
-
- To compile this driver as a module, choose M here: the
- module will be called pvr2fb.
-
- You can pass several parameters to the driver at boot time or at
- module load time. The parameters look like "video=pvr2:XXX", where
- the meaning of XXX can be found at the end of the main source file
- (<file:drivers/video/pvr2fb.c>). Please see the file
- <file:Documentation/fb/pvr2fb.txt>.
-
-config FB_OPENCORES
- tristate "OpenCores VGA/LCD core 2.0 framebuffer support"
- depends on FB && HAS_DMA
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This enables support for the OpenCores VGA/LCD core.
-
- The OpenCores VGA/LCD core is typically used together with
- softcore CPUs (e.g. OpenRISC or Microblaze) or hard processor
- systems (e.g. Altera socfpga or Xilinx Zynq) on FPGAs.
-
- The source code and specification for the core is available at
- <http://opencores.org/project,vga_lcd>
-
-config FB_S1D13XXX
- tristate "Epson S1D13XXX framebuffer support"
- depends on FB
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- Support for S1D13XXX framebuffer device family (currently only
- working with S1D13806). Product specs at
- <http://vdc.epson.com/>
-
-config FB_ATMEL
- tristate "AT91/AT32 LCD Controller support"
- depends on FB && HAVE_FB_ATMEL
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select FB_MODE_HELPERS
- select VIDEOMODE_HELPERS
- help
- This enables support for the AT91/AT32 LCD Controller.
-
-config FB_INTSRAM
- bool "Frame Buffer in internal SRAM"
- depends on FB_ATMEL && ARCH_AT91SAM9261
- help
- Say Y if you want to map Frame Buffer in internal SRAM. Say N if you want
- to let frame buffer in external SDRAM.
-
-config FB_ATMEL_STN
- bool "Use a STN display with AT91/AT32 LCD Controller"
- depends on FB_ATMEL && (MACH_AT91SAM9261EK || MACH_AT91SAM9G10EK)
- default n
- help
- Say Y if you want to connect a STN LCD display to the AT91/AT32 LCD
- Controller. Say N if you want to connect a TFT.
-
- If unsure, say N.
-
-config FB_NVIDIA
- tristate "nVidia Framebuffer Support"
- depends on FB && PCI
- select FB_BACKLIGHT if FB_NVIDIA_BACKLIGHT
- select FB_MODE_HELPERS
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select BITREVERSE
- select VGASTATE
- help
- This driver supports graphics boards with the nVidia chips, TNT
- and newer. For very old chipsets, such as the RIVA128, then use
- the rivafb.
- Say Y if you have such a graphics board.
-
- To compile this driver as a module, choose M here: the
- module will be called nvidiafb.
-
-config FB_NVIDIA_I2C
- bool "Enable DDC Support"
- depends on FB_NVIDIA
- select FB_DDC
- help
- This enables I2C support for nVidia Chipsets. This is used
- only for getting EDID information from the attached display
- allowing for robust video mode handling and switching.
-
- Because fbdev-2.6 requires that drivers must be able to
- independently validate video mode parameters, you should say Y
- here.
-
-config FB_NVIDIA_DEBUG
- bool "Lots of debug output"
- depends on FB_NVIDIA
- default n
- help
- Say Y here if you want the nVidia driver to output all sorts
- of debugging information to provide to the maintainer when
- something goes wrong.
-
-config FB_NVIDIA_BACKLIGHT
- bool "Support for backlight control"
- depends on FB_NVIDIA
- default y
- help
- Say Y here if you want to control the backlight of your display.
-
-config FB_RIVA
- tristate "nVidia Riva support"
- depends on FB && PCI
- select FB_BACKLIGHT if FB_RIVA_BACKLIGHT
- select FB_MODE_HELPERS
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select BITREVERSE
- select VGASTATE
- help
- This driver supports graphics boards with the nVidia Riva/Geforce
- chips.
- Say Y if you have such a graphics board.
-
- To compile this driver as a module, choose M here: the
- module will be called rivafb.
-
-config FB_RIVA_I2C
- bool "Enable DDC Support"
- depends on FB_RIVA
- select FB_DDC
- help
- This enables I2C support for nVidia Chipsets. This is used
- only for getting EDID information from the attached display
- allowing for robust video mode handling and switching.
-
- Because fbdev-2.6 requires that drivers must be able to
- independently validate video mode parameters, you should say Y
- here.
-
-config FB_RIVA_DEBUG
- bool "Lots of debug output"
- depends on FB_RIVA
- default n
- help
- Say Y here if you want the Riva driver to output all sorts
- of debugging information to provide to the maintainer when
- something goes wrong.
-
-config FB_RIVA_BACKLIGHT
- bool "Support for backlight control"
- depends on FB_RIVA
- default y
- help
- Say Y here if you want to control the backlight of your display.
-
-config FB_I740
- tristate "Intel740 support"
- depends on FB && PCI
- select FB_MODE_HELPERS
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select VGASTATE
- select FB_DDC
- help
- This driver supports graphics cards based on Intel740 chip.
-
-config FB_I810
- tristate "Intel 810/815 support"
- depends on FB && PCI && X86_32 && AGP_INTEL
- select FB_MODE_HELPERS
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select VGASTATE
- help
- This driver supports the on-board graphics built in to the Intel 810
- and 815 chipsets. Say Y if you have and plan to use such a board.
-
- To compile this driver as a module, choose M here: the
- module will be called i810fb.
-
- For more information, please read
- <file:Documentation/fb/intel810.txt>
-
-config FB_I810_GTF
- bool "use VESA Generalized Timing Formula"
- depends on FB_I810
- help
- If you say Y, then the VESA standard, Generalized Timing Formula
- or GTF, will be used to calculate the required video timing values
- per video mode. Since the GTF allows nondiscrete timings
- (nondiscrete being a range of values as opposed to discrete being a
- set of values), you'll be able to use any combination of horizontal
- and vertical resolutions, and vertical refresh rates without having
- to specify your own timing parameters. This is especially useful
- to maximize the performance of an aging display, or if you just
- have a display with nonstandard dimensions. A VESA compliant
- monitor is recommended, but can still work with non-compliant ones.
- If you need or want this, then select this option. The timings may
- not be compliant with Intel's recommended values. Use at your own
- risk.
-
- If you say N, the driver will revert to discrete video timings
- using a set recommended by Intel in their documentation.
-
- If unsure, say N.
-
-config FB_I810_I2C
- bool "Enable DDC Support"
- depends on FB_I810 && FB_I810_GTF
- select FB_DDC
- help
-
-config FB_LE80578
- tristate "Intel LE80578 (Vermilion) support"
- depends on FB && PCI && X86
- select FB_MODE_HELPERS
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This driver supports the LE80578 (Vermilion Range) chipset
-
-config FB_CARILLO_RANCH
- tristate "Intel Carillo Ranch support"
- depends on FB_LE80578 && FB && PCI && X86
- help
- This driver supports the LE80578 (Carillo Ranch) board
-
-config FB_INTEL
- tristate "Intel 830M/845G/852GM/855GM/865G/915G/945G/945GM/965G/965GM support"
- depends on FB && PCI && X86 && AGP_INTEL && EXPERT
- select FB_MODE_HELPERS
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select FB_BOOT_VESA_SUPPORT if FB_INTEL = y
- depends on !DRM_I915
- help
- This driver supports the on-board graphics built in to the Intel
- 830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM/965G/965GM chipsets.
- Say Y if you have and plan to use such a board.
-
- To make FB_INTELFB=Y work you need to say AGP_INTEL=y too.
-
- To compile this driver as a module, choose M here: the
- module will be called intelfb.
-
- For more information, please read <file:Documentation/fb/intelfb.txt>
-
-config FB_INTEL_DEBUG
- bool "Intel driver Debug Messages"
- depends on FB_INTEL
- ---help---
- Say Y here if you want the Intel driver to output all sorts
- of debugging information to provide to the maintainer when
- something goes wrong.
-
-config FB_INTEL_I2C
- bool "DDC/I2C for Intel framebuffer support"
- depends on FB_INTEL
- select FB_DDC
- default y
- help
- Say Y here if you want DDC/I2C support for your on-board Intel graphics.
-
-config FB_MATROX
- tristate "Matrox acceleration"
- depends on FB && PCI
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select FB_TILEBLITTING
- select FB_MACMODES if PPC_PMAC
- ---help---
- Say Y here if you have a Matrox Millennium, Matrox Millennium II,
- Matrox Mystique, Matrox Mystique 220, Matrox Productiva G100, Matrox
- Mystique G200, Matrox Millennium G200, Matrox Marvel G200 video,
- Matrox G400, G450 or G550 card in your box.
-
- To compile this driver as a module, choose M here: the
- module will be called matroxfb.
-
- You can pass several parameters to the driver at boot time or at
- module load time. The parameters look like "video=matroxfb:XXX", and
- are described in <file:Documentation/fb/matroxfb.txt>.
-
-config FB_MATROX_MILLENIUM
- bool "Millennium I/II support"
- depends on FB_MATROX
- help
- Say Y here if you have a Matrox Millennium or Matrox Millennium II
- video card. If you select "Advanced lowlevel driver options" below,
- you should check 4 bpp packed pixel, 8 bpp packed pixel, 16 bpp
- packed pixel, 24 bpp packed pixel and 32 bpp packed pixel. You can
- also use font widths different from 8.
-
-config FB_MATROX_MYSTIQUE
- bool "Mystique support"
- depends on FB_MATROX
- help
- Say Y here if you have a Matrox Mystique or Matrox Mystique 220
- video card. If you select "Advanced lowlevel driver options" below,
- you should check 8 bpp packed pixel, 16 bpp packed pixel, 24 bpp
- packed pixel and 32 bpp packed pixel. You can also use font widths
- different from 8.
-
-config FB_MATROX_G
- bool "G100/G200/G400/G450/G550 support"
- depends on FB_MATROX
- ---help---
- Say Y here if you have a Matrox G100, G200, G400, G450 or G550 based
- video card. If you select "Advanced lowlevel driver options", you
- should check 8 bpp packed pixel, 16 bpp packed pixel, 24 bpp packed
- pixel and 32 bpp packed pixel. You can also use font widths
- different from 8.
-
- If you need support for G400 secondary head, you must say Y to
- "Matrox I2C support" and "G400 second head support" right below.
- G450/G550 secondary head and digital output are supported without
- additional modules.
-
- The driver starts in monitor mode. You must use the matroxset tool
- (available at <ftp://platan.vc.cvut.cz/pub/linux/matrox-latest/>) to
- swap primary and secondary head outputs, or to change output mode.
- Secondary head driver always start in 640x480 resolution and you
- must use fbset to change it.
-
- Do not forget that second head supports only 16 and 32 bpp
- packed pixels, so it is a good idea to compile them into the kernel
- too. You can use only some font widths, as the driver uses generic
- painting procedures (the secondary head does not use acceleration
- engine).
-
- G450/G550 hardware can display TV picture only from secondary CRTC,
- and it performs no scaling, so picture must have 525 or 625 lines.
-
-config FB_MATROX_I2C
- tristate "Matrox I2C support"
- depends on FB_MATROX
- select FB_DDC
- ---help---
- This drivers creates I2C buses which are needed for accessing the
- DDC (I2C) bus present on all Matroxes, an I2C bus which
- interconnects Matrox optional devices, like MGA-TVO on G200 and
- G400, and the secondary head DDC bus, present on G400 only.
-
- You can say Y or M here if you want to experiment with monitor
- detection code. You must say Y or M here if you want to use either
- second head of G400 or MGA-TVO on G200 or G400.
-
- If you compile it as module, it will create a module named
- i2c-matroxfb.
-
-config FB_MATROX_MAVEN
- tristate "G400 second head support"
- depends on FB_MATROX_G && FB_MATROX_I2C
- ---help---
- WARNING !!! This support does not work with G450 !!!
-
- Say Y or M here if you want to use a secondary head (meaning two
- monitors in parallel) on G400 or MGA-TVO add-on on G200. Secondary
- head is not compatible with accelerated XFree 3.3.x SVGA servers -
- secondary head output is blanked while you are in X. With XFree
- 3.9.17 preview you can use both heads if you use SVGA over fbdev or
- the fbdev driver on first head and the fbdev driver on second head.
-
- If you compile it as module, two modules are created,
- matroxfb_crtc2 and matroxfb_maven. Matroxfb_maven is needed for
- both G200 and G400, matroxfb_crtc2 is needed only by G400. You must
- also load i2c-matroxfb to get it to run.
-
- The driver starts in monitor mode and you must use the matroxset
- tool (available at
- <ftp://platan.vc.cvut.cz/pub/linux/matrox-latest/>) to switch it to
- PAL or NTSC or to swap primary and secondary head outputs.
- Secondary head driver also always start in 640x480 resolution, you
- must use fbset to change it.
-
- Also do not forget that second head supports only 16 and 32 bpp
- packed pixels, so it is a good idea to compile them into the kernel
- too. You can use only some font widths, as the driver uses generic
- painting procedures (the secondary head does not use acceleration
- engine).
-
-config FB_RADEON
- tristate "ATI Radeon display support"
- depends on FB && PCI
- select FB_BACKLIGHT if FB_RADEON_BACKLIGHT
- select FB_MODE_HELPERS
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select FB_MACMODES if PPC_OF
- help
- Choose this option if you want to use an ATI Radeon graphics card as
- a framebuffer device. There are both PCI and AGP versions. You
- don't need to choose this to run the Radeon in plain VGA mode.
-
- There is a product page at
- http://products.amd.com/en-us/GraphicCardResult.aspx
-
-config FB_RADEON_I2C
- bool "DDC/I2C for ATI Radeon support"
- depends on FB_RADEON
- select FB_DDC
- default y
- help
- Say Y here if you want DDC/I2C support for your Radeon board.
-
-config FB_RADEON_BACKLIGHT
- bool "Support for backlight control"
- depends on FB_RADEON
- default y
- help
- Say Y here if you want to control the backlight of your display.
-
-config FB_RADEON_DEBUG
- bool "Lots of debug output from Radeon driver"
- depends on FB_RADEON
- default n
- help
- Say Y here if you want the Radeon driver to output all sorts
- of debugging information to provide to the maintainer when
- something goes wrong.
-
-config FB_ATY128
- tristate "ATI Rage128 display support"
- depends on FB && PCI
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select FB_BACKLIGHT if FB_ATY128_BACKLIGHT
- select FB_MACMODES if PPC_PMAC
- help
- This driver supports graphics boards with the ATI Rage128 chips.
- Say Y if you have such a graphics board and read
- <file:Documentation/fb/aty128fb.txt>.
-
- To compile this driver as a module, choose M here: the
- module will be called aty128fb.
-
-config FB_ATY128_BACKLIGHT
- bool "Support for backlight control"
- depends on FB_ATY128
- default y
- help
- Say Y here if you want to control the backlight of your display.
-
-config FB_ATY
- tristate "ATI Mach64 display support" if PCI || ATARI
- depends on FB && !SPARC32
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select FB_BACKLIGHT if FB_ATY_BACKLIGHT
- select FB_MACMODES if PPC
- help
- This driver supports graphics boards with the ATI Mach64 chips.
- Say Y if you have such a graphics board.
-
- To compile this driver as a module, choose M here: the
- module will be called atyfb.
-
-config FB_ATY_CT
- bool "Mach64 CT/VT/GT/LT (incl. 3D RAGE) support"
- depends on PCI && FB_ATY
- default y if SPARC64 && PCI
- help
- Say Y here to support use of ATI's 64-bit Rage boards (or other
- boards based on the Mach64 CT, VT, GT, and LT chipsets) as a
- framebuffer device. The ATI product support page for these boards
- is at <http://support.ati.com/products/pc/mach64/mach64.html>.
-
-config FB_ATY_GENERIC_LCD
- bool "Mach64 generic LCD support"
- depends on FB_ATY_CT
- help
- Say Y if you have a laptop with an ATI Rage LT PRO, Rage Mobility,
- Rage XC, or Rage XL chipset.
-
-config FB_ATY_GX
- bool "Mach64 GX support" if PCI
- depends on FB_ATY
- default y if ATARI
- help
- Say Y here to support use of the ATI Mach64 Graphics Expression
- board (or other boards based on the Mach64 GX chipset) as a
- framebuffer device. The ATI product support page for these boards
- is at
- <http://support.ati.com/products/pc/mach64/graphics_xpression.html>.
-
-config FB_ATY_BACKLIGHT
- bool "Support for backlight control"
- depends on FB_ATY
- default y
- help
- Say Y here if you want to control the backlight of your display.
-
-config FB_S3
- tristate "S3 Trio/Virge support"
- depends on FB && PCI
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select FB_TILEBLITTING
- select FB_SVGALIB
- select VGASTATE
- select FONT_8x16 if FRAMEBUFFER_CONSOLE
- ---help---
- Driver for graphics boards with S3 Trio / S3 Virge chip.
-
-config FB_S3_DDC
- bool "DDC for S3 support"
- depends on FB_S3
- select FB_DDC
- default y
- help
- Say Y here if you want DDC support for your S3 graphics card.
-
-config FB_SAVAGE
- tristate "S3 Savage support"
- depends on FB && PCI
- select FB_MODE_HELPERS
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select VGASTATE
- help
- This driver supports notebooks and computers with S3 Savage PCI/AGP
- chips.
-
- Say Y if you have such a graphics card.
-
- To compile this driver as a module, choose M here; the module
- will be called savagefb.
-
-config FB_SAVAGE_I2C
- bool "Enable DDC2 Support"
- depends on FB_SAVAGE
- select FB_DDC
- help
- This enables I2C support for S3 Savage Chipsets. This is used
- only for getting EDID information from the attached display
- allowing for robust video mode handling and switching.
-
- Because fbdev-2.6 requires that drivers must be able to
- independently validate video mode parameters, you should say Y
- here.
-
-config FB_SAVAGE_ACCEL
- bool "Enable Console Acceleration"
- depends on FB_SAVAGE
- default n
- help
- This option will compile in console acceleration support. If
- the resulting framebuffer console has bothersome glitches, then
- choose N here.
-
-config FB_SIS
- tristate "SiS/XGI display support"
- depends on FB && PCI
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select FB_BOOT_VESA_SUPPORT if FB_SIS = y
- help
- This is the frame buffer device driver for the SiS 300, 315, 330
- and 340 series as well as XGI V3XT, V5, V8, Z7 graphics chipsets.
- Specs available at <http://www.sis.com> and <http://www.xgitech.com>.
-
- To compile this driver as a module, choose M here; the module
- will be called sisfb.
-
-config FB_SIS_300
- bool "SiS 300 series support"
- depends on FB_SIS
- help
- Say Y here to support use of the SiS 300/305, 540, 630 and 730.
-
-config FB_SIS_315
- bool "SiS 315/330/340 series and XGI support"
- depends on FB_SIS
- help
- Say Y here to support use of the SiS 315, 330 and 340 series
- (315/H/PRO, 55x, 650, 651, 740, 330, 661, 741, 760, 761) as well
- as XGI V3XT, V5, V8 and Z7.
-
-config FB_VIA
- tristate "VIA UniChrome (Pro) and Chrome9 display support"
- depends on FB && PCI && X86
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select I2C_ALGOBIT
- select I2C
- select GPIOLIB
- help
- This is the frame buffer device driver for Graphics chips of VIA
- UniChrome (Pro) Family (CLE266,PM800/CN400,P4M800CE/P4M800Pro/
- CN700/VN800,CX700/VX700,P4M890) and Chrome9 Family (K8M890,CN896
- /P4M900,VX800)
- Say Y if you have a VIA UniChrome graphics board.
-
- To compile this driver as a module, choose M here: the
- module will be called viafb.
-
-if FB_VIA
-
-config FB_VIA_DIRECT_PROCFS
- bool "direct hardware access via procfs (DEPRECATED)(DANGEROUS)"
- depends on FB_VIA
- default n
- help
- Allow direct hardware access to some output registers via procfs.
- This is dangerous but may provide the only chance to get the
- correct output device configuration.
- Its use is strongly discouraged.
-
-config FB_VIA_X_COMPATIBILITY
- bool "X server compatibility"
- depends on FB_VIA
- default n
- help
- This option reduces the functionality (power saving, ...) of the
- framebuffer to avoid negative impact on the OpenChrome X server.
- If you use any X server other than fbdev you should enable this
- otherwise it should be safe to disable it and allow using all
- features.
-
-endif
-
-config FB_NEOMAGIC
- tristate "NeoMagic display support"
- depends on FB && PCI
- select FB_MODE_HELPERS
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select VGASTATE
- help
- This driver supports notebooks with NeoMagic PCI chips.
- Say Y if you have such a graphics card.
-
- To compile this driver as a module, choose M here: the
- module will be called neofb.
-
-config FB_KYRO
- tristate "IMG Kyro support"
- depends on FB && PCI
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- Say Y here if you have a STG4000 / Kyro / PowerVR 3 based
- graphics board.
-
- To compile this driver as a module, choose M here: the
- module will be called kyrofb.
-
-config FB_3DFX
- tristate "3Dfx Banshee/Voodoo3/Voodoo5 display support"
- depends on FB && PCI
- select FB_CFB_IMAGEBLIT
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_MODE_HELPERS
- help
- This driver supports graphics boards with the 3Dfx Banshee,
- Voodoo3 or VSA-100 (aka Voodoo4/5) chips. Say Y if you have
- such a graphics board.
-
- To compile this driver as a module, choose M here: the
- module will be called tdfxfb.
-
-config FB_3DFX_ACCEL
- bool "3Dfx Acceleration functions"
- depends on FB_3DFX
- ---help---
- This will compile the 3Dfx Banshee/Voodoo3/VSA-100 frame buffer
- device driver with acceleration functions.
-
-config FB_3DFX_I2C
- bool "Enable DDC/I2C support"
- depends on FB_3DFX
- select FB_DDC
- default y
- help
- Say Y here if you want DDC/I2C support for your 3dfx Voodoo3.
-
-config FB_VOODOO1
- tristate "3Dfx Voodoo Graphics (sst1) support"
- depends on FB && PCI
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- ---help---
- Say Y here if you have a 3Dfx Voodoo Graphics (Voodoo1/sst1) or
- Voodoo2 (cvg) based graphics card.
-
- To compile this driver as a module, choose M here: the
- module will be called sstfb.
-
- WARNING: Do not use any application that uses the 3D engine
- (namely glide) while using this driver.
- Please read the <file:Documentation/fb/sstfb.txt> for supported
- options and other important info support.
-
-config FB_VT8623
- tristate "VIA VT8623 support"
- depends on FB && PCI
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select FB_TILEBLITTING
- select FB_SVGALIB
- select VGASTATE
- select FONT_8x16 if FRAMEBUFFER_CONSOLE
- ---help---
- Driver for CastleRock integrated graphics core in the
- VIA VT8623 [Apollo CLE266] chipset.
-
-config FB_TRIDENT
- tristate "Trident/CyberXXX/CyberBlade support"
- depends on FB && PCI
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- ---help---
- This is the frame buffer device driver for Trident PCI/AGP chipsets.
- Supported chipset families are TGUI 9440/96XX, 3DImage, Blade3D
- and Blade XP.
- There are also integrated versions of these chips called CyberXXXX,
- CyberImage or CyberBlade. These chips are mostly found in laptops
- but also on some motherboards including early VIA EPIA motherboards.
- For more information, read <file:Documentation/fb/tridentfb.txt>
-
- Say Y if you have such a graphics board.
-
- To compile this driver as a module, choose M here: the
- module will be called tridentfb.
-
-config FB_ARK
- tristate "ARK 2000PV support"
- depends on FB && PCI
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select FB_TILEBLITTING
- select FB_SVGALIB
- select VGASTATE
- select FONT_8x16 if FRAMEBUFFER_CONSOLE
- ---help---
- Driver for PCI graphics boards with ARK 2000PV chip
- and ICS 5342 RAMDAC.
-
-config FB_PM3
- tristate "Permedia3 support"
- depends on FB && PCI
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the frame buffer device driver for the 3DLabs Permedia3
- chipset, used in Formac ProFormance III, 3DLabs Oxygen VX1 &
- similar boards, 3DLabs Permedia3 Create!, Appian Jeronimo 2000
- and maybe other boards.
-
-config FB_CARMINE
- tristate "Fujitsu carmine frame buffer support"
- depends on FB && PCI
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the frame buffer device driver for the Fujitsu Carmine chip.
- The driver provides two independent frame buffer devices.
-
-choice
- depends on FB_CARMINE
- prompt "DRAM timing"
- default FB_CARMINE_DRAM_EVAL
-
-config FB_CARMINE_DRAM_EVAL
- bool "Eval board timings"
- help
- Use timings which work on the eval card.
-
-config CARMINE_DRAM_CUSTOM
- bool "Custom board timings"
- help
- Use custom board timings.
-endchoice
-
-config FB_AU1100
- bool "Au1100 LCD Driver"
- depends on (FB = y) && MIPS_ALCHEMY
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the framebuffer driver for the AMD Au1100 SOC. It can drive
- various panels and CRTs by passing in kernel cmd line option
- au1100fb:panel=<name>.
-
-config FB_AU1200
- bool "Au1200/Au1300 LCD Driver"
- depends on (FB = y) && MIPS_ALCHEMY
- select FB_SYS_FILLRECT
- select FB_SYS_COPYAREA
- select FB_SYS_IMAGEBLIT
- select FB_SYS_FOPS
- help
- This is the framebuffer driver for the Au1200/Au1300 SOCs.
- It can drive various panels and CRTs by passing in kernel cmd line
- option au1200fb:panel=<name>.
-
-config FB_VT8500
- bool "VIA VT8500 framebuffer support"
- depends on (FB = y) && ARM && ARCH_VT8500
- select FB_SYS_FILLRECT if (!FB_WMT_GE_ROPS)
- select FB_SYS_COPYAREA if (!FB_WMT_GE_ROPS)
- select FB_SYS_IMAGEBLIT
- select FB_MODE_HELPERS
- select VIDEOMODE_HELPERS
- help
- This is the framebuffer driver for VIA VT8500 integrated LCD
- controller.
-
-config FB_WM8505
- bool "Wondermedia WM8xxx-series frame buffer support"
- depends on (FB = y) && ARM && ARCH_VT8500
- select FB_SYS_FILLRECT if (!FB_WMT_GE_ROPS)
- select FB_SYS_COPYAREA if (!FB_WMT_GE_ROPS)
- select FB_SYS_IMAGEBLIT
- select FB_MODE_HELPERS
- select VIDEOMODE_HELPERS
- help
- This is the framebuffer driver for WonderMedia WM8xxx-series
- integrated LCD controller. This driver covers the WM8505, WM8650
- and WM8850 SoCs.
-
-config FB_WMT_GE_ROPS
- bool "VT8500/WM8xxx accelerated raster ops support"
- depends on (FB = y) && (FB_VT8500 || FB_WM8505)
- default n
- help
- This adds support for accelerated raster operations on the
- VIA VT8500 and Wondermedia 85xx series SoCs.
-
-source "drivers/video/geode/Kconfig"
-
-config FB_HIT
- tristate "HD64461 Frame Buffer support"
- depends on FB && HD64461
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This is the frame buffer device driver for the Hitachi HD64461 LCD
- frame buffer card.
-
-config FB_PMAG_AA
- bool "PMAG-AA TURBOchannel framebuffer support"
- depends on (FB = y) && TC
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- Support for the PMAG-AA TURBOchannel framebuffer card (1280x1024x1)
- used mainly in the MIPS-based DECstation series.
-
-config FB_PMAG_BA
- tristate "PMAG-BA TURBOchannel framebuffer support"
- depends on FB && TC
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- Support for the PMAG-BA TURBOchannel framebuffer card (1024x864x8)
- used mainly in the MIPS-based DECstation series.
-
-config FB_PMAGB_B
- tristate "PMAGB-B TURBOchannel framebuffer support"
- depends on FB && TC
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- Support for the PMAGB-B TURBOchannel framebuffer card used mainly
- in the MIPS-based DECstation series. The card is currently only
- supported in 1280x1024x8 mode.
-
-config FB_MAXINE
- bool "Maxine (Personal DECstation) onboard framebuffer support"
- depends on (FB = y) && MACH_DECSTATION
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- Support for the onboard framebuffer (1024x768x8) in the Personal
- DECstation series (Personal DECstation 5000/20, /25, /33, /50,
- Codename "Maxine").
-
-config FB_G364
- bool "G364 frame buffer support"
- depends on (FB = y) && (MIPS_MAGNUM_4000 || OLIVETTI_M700)
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- The G364 driver is the framebuffer used in MIPS Magnum 4000 and
- Olivetti M700-10 systems.
-
-config FB_68328
- bool "Motorola 68328 native frame buffer support"
- depends on (FB = y) && (M68328 || M68EZ328 || M68VZ328)
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- Say Y here if you want to support the built-in frame buffer of
- the Motorola 68328 CPU family.
-
-config FB_PXA168
- tristate "PXA168/910 LCD framebuffer support"
- depends on FB && (CPU_PXA168 || CPU_PXA910)
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- ---help---
- Frame buffer driver for the built-in LCD controller in the Marvell
- MMP processor.
-
-config FB_PXA
- tristate "PXA LCD framebuffer support"
- depends on FB && ARCH_PXA
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- ---help---
- Frame buffer driver for the built-in LCD controller in the Intel
- PXA2x0 processor.
-
- This driver is also available as a module ( = code which can be
- inserted and removed from the running kernel whenever you want). The
- module will be called pxafb. If you want to compile it as a module,
- say M here and read <file:Documentation/kbuild/modules.txt>.
-
- If unsure, say N.
-
-config FB_PXA_OVERLAY
- bool "Support PXA27x/PXA3xx Overlay(s) as framebuffer"
- default n
- depends on FB_PXA && (PXA27x || PXA3xx)
-
-config FB_PXA_SMARTPANEL
- bool "PXA Smartpanel LCD support"
- default n
- depends on FB_PXA
-
-config FB_PXA_PARAMETERS
- bool "PXA LCD command line parameters"
- default n
- depends on FB_PXA
- ---help---
- Enable the use of kernel command line or module parameters
- to configure the physical properties of the LCD panel when
- using the PXA LCD driver.
-
- This option allows you to override the panel parameters
- supplied by the platform in order to support multiple
- different models of flatpanel. If you will only be using a
- single model of flatpanel then you can safely leave this
- option disabled.
-
- <file:Documentation/fb/pxafb.txt> describes the available parameters.
-
-config PXA3XX_GCU
- tristate "PXA3xx 2D graphics accelerator driver"
- depends on FB_PXA
- help
- Kernelspace driver for the 2D graphics controller unit (GCU)
- found on PXA3xx processors. There is a counterpart driver in the
- DirectFB suite, see http://www.directfb.org/
-
- If you compile this as a module, it will be called pxa3xx_gcu.
-
-config FB_MBX
- tristate "2700G LCD framebuffer support"
- depends on FB && ARCH_PXA
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- ---help---
- Framebuffer driver for the Intel 2700G (Marathon) Graphics
- Accelerator
-
-config FB_MBX_DEBUG
- bool "Enable debugging info via debugfs"
- depends on FB_MBX && DEBUG_FS
- default n
- ---help---
- Enable this if you want debugging information using the debug
- filesystem (debugfs)
-
- If unsure, say N.
-
-config FB_FSL_DIU
- tristate "Freescale DIU framebuffer support"
- depends on FB && FSL_SOC
- select FB_MODE_HELPERS
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select PPC_LIB_RHEAP
- ---help---
- Framebuffer driver for the Freescale SoC DIU
-
-config FB_W100
- tristate "W100 frame buffer support"
- depends on FB && ARCH_PXA
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- ---help---
- Frame buffer driver for the w100 as found on the Sharp SL-Cxx series.
- It can also drive the w3220 chip found on iPAQ hx4700.
-
- This driver is also available as a module ( = code which can be
- inserted and removed from the running kernel whenever you want). The
- module will be called w100fb. If you want to compile it as a module,
- say M here and read <file:Documentation/kbuild/modules.txt>.
-
- If unsure, say N.
-
-config FB_SH_MOBILE_LCDC
- tristate "SuperH Mobile LCDC framebuffer support"
- depends on FB && (SUPERH || ARCH_SHMOBILE) && HAVE_CLK
- select FB_SYS_FILLRECT
- select FB_SYS_COPYAREA
- select FB_SYS_IMAGEBLIT
- select FB_SYS_FOPS
- select FB_DEFERRED_IO
- select FB_BACKLIGHT
- select SH_MIPI_DSI if SH_LCD_MIPI_DSI
- ---help---
- Frame buffer driver for the on-chip SH-Mobile LCD controller.
-
-config FB_SH_MOBILE_HDMI
- tristate "SuperH Mobile HDMI controller support"
- depends on FB_SH_MOBILE_LCDC
- select FB_MODE_HELPERS
- select SOUND
- select SND
- select SND_SOC
- ---help---
- Driver for the on-chip SH-Mobile HDMI controller.
-
-config FB_TMIO
- tristate "Toshiba Mobile IO FrameBuffer support"
- depends on FB && MFD_CORE
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- ---help---
- Frame buffer driver for the Toshiba Mobile IO integrated as found
- on the Sharp SL-6000 series
-
- This driver is also available as a module ( = code which can be
- inserted and removed from the running kernel whenever you want). The
- module will be called tmiofb. If you want to compile it as a module,
- say M here and read <file:Documentation/kbuild/modules.txt>.
-
- If unsure, say N.
-
-config FB_TMIO_ACCELL
- bool "tmiofb acceleration"
- depends on FB_TMIO
- default y
-
-config FB_S3C
- tristate "Samsung S3C framebuffer support"
- depends on FB && (CPU_S3C2416 || ARCH_S3C64XX || ARCH_S5P64X0 || \
- ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS)
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- ---help---
- Frame buffer driver for the built-in FB controller in the Samsung
- SoC line from the S3C2443 onwards, including the S3C2416, S3C2450,
- and the S3C64XX series such as the S3C6400 and S3C6410.
-
- These chips all have the same basic framebuffer design with the
- actual capabilities depending on the chip. For instance the S3C6400
- and S3C6410 support 4 hardware windows whereas the S3C24XX series
- currently only have two.
-
- Currently the support is only for the S3C6400 and S3C6410 SoCs.
-
-config FB_S3C_DEBUG_REGWRITE
- bool "Debug register writes"
- depends on FB_S3C
- ---help---
- Show all register writes via pr_debug()
-
-config FB_S3C2410
- tristate "S3C2410 LCD framebuffer support"
- depends on FB && ARCH_S3C24XX
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- ---help---
- Frame buffer driver for the built-in LCD controller in the Samsung
- S3C2410 processor.
-
- This driver is also available as a module ( = code which can be
- inserted and removed from the running kernel whenever you want). The
- module will be called s3c2410fb. If you want to compile it as a module,
- say M here and read <file:Documentation/kbuild/modules.txt>.
-
- If unsure, say N.
-config FB_S3C2410_DEBUG
- bool "S3C2410 lcd debug messages"
- depends on FB_S3C2410
- help
- Turn on debugging messages. Note that you can set/unset at run time
- through sysfs
-
-config FB_NUC900
- bool "NUC900 LCD framebuffer support"
- depends on FB && ARCH_W90X900
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- ---help---
- Frame buffer driver for the built-in LCD controller in the Nuvoton
- NUC900 processor
-
-config GPM1040A0_320X240
- bool "Giantplus Technology GPM1040A0 320x240 Color TFT LCD"
- depends on FB_NUC900
-
-config FB_SM501
- tristate "Silicon Motion SM501 framebuffer support"
- depends on FB && MFD_SM501
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- ---help---
- Frame buffer driver for the CRT and LCD controllers in the Silicon
- Motion SM501.
-
- This driver is also available as a module ( = code which can be
- inserted and removed from the running kernel whenever you want). The
- module will be called sm501fb. If you want to compile it as a module,
- say M here and read <file:Documentation/kbuild/modules.txt>.
-
- If unsure, say N.
-
-config FB_SMSCUFX
- tristate "SMSC UFX6000/7000 USB Framebuffer support"
- depends on FB && USB
- select FB_MODE_HELPERS
- select FB_SYS_FILLRECT
- select FB_SYS_COPYAREA
- select FB_SYS_IMAGEBLIT
- select FB_SYS_FOPS
- select FB_DEFERRED_IO
- ---help---
- This is a kernel framebuffer driver for SMSC UFX USB devices.
- Supports fbdev clients like xf86-video-fbdev, kdrive, fbi, and
- mplayer -vo fbdev. Supports both UFX6000 (USB 2.0) and UFX7000
- (USB 3.0) devices.
- To compile as a module, choose M here: the module name is smscufx.
-
-config FB_UDL
- tristate "Displaylink USB Framebuffer support"
- depends on FB && USB
- select FB_MODE_HELPERS
- select FB_SYS_FILLRECT
- select FB_SYS_COPYAREA
- select FB_SYS_IMAGEBLIT
- select FB_SYS_FOPS
- select FB_DEFERRED_IO
- ---help---
- This is a kernel framebuffer driver for DisplayLink USB devices.
- Supports fbdev clients like xf86-video-fbdev, kdrive, fbi, and
- mplayer -vo fbdev. Supports all USB 2.0 era DisplayLink devices.
- To compile as a module, choose M here: the module name is udlfb.
-
-config FB_IBM_GXT4500
- tristate "Framebuffer support for IBM GXT4000P/4500P/6000P/6500P adaptors"
- depends on FB && PPC
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- ---help---
- Say Y here to enable support for the IBM GXT4000P/6000P and
- GXT4500P/6500P display adaptor based on Raster Engine RC1000,
- found on some IBM System P (pSeries) machines. This driver
- doesn't use Geometry Engine GT1000.
-
-config FB_PS3
- tristate "PS3 GPU framebuffer driver"
- depends on FB && PS3_PS3AV
- select FB_SYS_FILLRECT
- select FB_SYS_COPYAREA
- select FB_SYS_IMAGEBLIT
- select FB_SYS_FOPS
- select VT_HW_CONSOLE_BINDING if FRAMEBUFFER_CONSOLE
- ---help---
- Include support for the virtual frame buffer in the PS3 platform.
-
-config FB_PS3_DEFAULT_SIZE_M
- int "PS3 default frame buffer size (in MiB)"
- depends on FB_PS3
- default 9
- ---help---
- This is the default size (in MiB) of the virtual frame buffer in
- the PS3.
- The default value can be overridden on the kernel command line
- using the "ps3fb" option (e.g. "ps3fb=9M");
-
-config FB_XILINX
- tristate "Xilinx frame buffer support"
- depends on FB && (XILINX_VIRTEX || MICROBLAZE || ARCH_ZYNQ)
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- ---help---
- Include support for the Xilinx ML300/ML403 reference design
- framebuffer. ML300 carries a 640*480 LCD display on the board,
- ML403 uses a standard DB15 VGA connector.
-
-config FB_GOLDFISH
- tristate "Goldfish Framebuffer"
- depends on FB && HAS_DMA
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- ---help---
- Framebuffer driver for Goldfish Virtual Platform
-
-config FB_COBALT
- tristate "Cobalt server LCD frame buffer support"
- depends on FB && (MIPS_COBALT || MIPS_SEAD3)
-
-config FB_SH7760
- bool "SH7760/SH7763/SH7720/SH7721 LCDC support"
- depends on FB && (CPU_SUBTYPE_SH7760 || CPU_SUBTYPE_SH7763 \
- || CPU_SUBTYPE_SH7720 || CPU_SUBTYPE_SH7721)
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- ---help---
- Support for the SH7760/SH7763/SH7720/SH7721 integrated
- (D)STN/TFT LCD Controller.
- Supports display resolutions up to 1024x1024 pixel, grayscale and
- color operation, with depths ranging from 1 bpp to 8 bpp monochrome
- and 8, 15 or 16 bpp color; 90 degrees clockwise display rotation for
- panels <= 320 pixel horizontal resolution.
-
-config FB_DA8XX
- tristate "DA8xx/OMAP-L1xx/AM335x Framebuffer support"
- depends on FB && (ARCH_DAVINCI_DA8XX || SOC_AM33XX)
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select FB_CFB_REV_PIXELS_IN_BYTE
- select FB_MODE_HELPERS
- select VIDEOMODE_HELPERS
- ---help---
- This is the frame buffer device driver for the TI LCD controller
- found on DA8xx/OMAP-L1xx/AM335x SoCs.
- If unsure, say N.
-
-config FB_VIRTUAL
- tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)"
- depends on FB
- select FB_SYS_FILLRECT
- select FB_SYS_COPYAREA
- select FB_SYS_IMAGEBLIT
- select FB_SYS_FOPS
- ---help---
- This is a `virtual' frame buffer device. It operates on a chunk of
- unswappable kernel memory instead of on the memory of a graphics
- board. This means you cannot see any output sent to this frame
- buffer device, while it does consume precious memory. The main use
- of this frame buffer device is testing and debugging the frame
- buffer subsystem. Do NOT enable it for normal systems! To protect
- the innocent, it has to be enabled explicitly at boot time using the
- kernel option `video=vfb:'.
-
- To compile this driver as a module, choose M here: the
- module will be called vfb. In order to load it, you must use
- the vfb_enable=1 option.
-
- If unsure, say N.
-
-config XEN_FBDEV_FRONTEND
- tristate "Xen virtual frame buffer support"
- depends on FB && XEN
- select FB_SYS_FILLRECT
- select FB_SYS_COPYAREA
- select FB_SYS_IMAGEBLIT
- select FB_SYS_FOPS
- select FB_DEFERRED_IO
- select INPUT_XEN_KBDDEV_FRONTEND if INPUT_MISC
- select XEN_XENBUS_FRONTEND
- default y
- help
- This driver implements the front-end of the Xen virtual
- frame buffer driver. It communicates with a back-end
- in another domain.
-
-config FB_METRONOME
- tristate "E-Ink Metronome/8track controller support"
- depends on FB
- select FB_SYS_FILLRECT
- select FB_SYS_COPYAREA
- select FB_SYS_IMAGEBLIT
- select FB_SYS_FOPS
- select FB_DEFERRED_IO
- help
- This driver implements support for the E-Ink Metronome
- controller. The pre-release name for this device was 8track
- and could also have been called by some vendors as PVI-nnnn.
-
-config FB_MB862XX
- tristate "Fujitsu MB862xx GDC support"
- depends on FB
- depends on PCI || (OF && PPC)
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- ---help---
- Frame buffer driver for Fujitsu Carmine/Coral-P(A)/Lime controllers.
-
-choice
- prompt "GDC variant"
- depends on FB_MB862XX
-
-config FB_MB862XX_PCI_GDC
- bool "Carmine/Coral-P(A) GDC"
- depends on PCI
- ---help---
- This enables framebuffer support for Fujitsu Carmine/Coral-P(A)
- PCI graphics controller devices.
-
-config FB_MB862XX_LIME
- bool "Lime GDC"
- depends on OF && PPC
- select FB_FOREIGN_ENDIAN
- select FB_LITTLE_ENDIAN
- ---help---
- Framebuffer support for Fujitsu Lime GDC on host CPU bus.
-
-endchoice
-
-config FB_MB862XX_I2C
- bool "Support I2C bus on MB862XX GDC"
- depends on FB_MB862XX && I2C
- default y
- help
- Selecting this option adds Coral-P(A)/Lime GDC I2C bus adapter
- driver to support accessing I2C devices on controller's I2C bus.
- These are usually some video decoder chips.
-
-config FB_EP93XX
- tristate "EP93XX frame buffer support"
- depends on FB && ARCH_EP93XX
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- ---help---
- Framebuffer driver for the Cirrus Logic EP93XX series of processors.
- This driver is also available as a module. The module will be called
- ep93xx-fb.
-
-config FB_PRE_INIT_FB
- bool "Don't reinitialize, use bootloader's GDC/Display configuration"
- depends on FB && FB_MB862XX_LIME
- ---help---
- Select this option if display contents should be inherited as set by
- the bootloader.
-
-config FB_MSM
- tristate "MSM Framebuffer support"
- depends on FB && ARCH_MSM
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
-
-config FB_MX3
- tristate "MX3 Framebuffer support"
- depends on FB && MX3_IPU
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- default y
- help
- This is a framebuffer device for the i.MX31 LCD Controller. So
- far only synchronous displays are supported. If you plan to use
- an LCD display with your i.MX31 system, say Y here.
-
-config FB_BROADSHEET
- tristate "E-Ink Broadsheet/Epson S1D13521 controller support"
- depends on FB
- select FB_SYS_FILLRECT
- select FB_SYS_COPYAREA
- select FB_SYS_IMAGEBLIT
- select FB_SYS_FOPS
- select FB_DEFERRED_IO
- help
- This driver implements support for the E-Ink Broadsheet
- controller. The release name for this device was Epson S1D13521
- and could also have been called by other names when coupled with
- a bridge adapter.
-
-config FB_AUO_K190X
- tristate "AUO-K190X EPD controller support"
- depends on FB
- select FB_SYS_FILLRECT
- select FB_SYS_COPYAREA
- select FB_SYS_IMAGEBLIT
- select FB_SYS_FOPS
- select FB_DEFERRED_IO
- help
- Provides support for epaper controllers from the K190X series
- of AUO. These controllers can be used to drive epaper displays
- from Sipix.
-
- This option enables the common support, shared by the individual
- controller drivers. You will also have to enable the driver
- for the controller type used in your device.
-
-config FB_AUO_K1900
- tristate "AUO-K1900 EPD controller support"
- depends on FB && FB_AUO_K190X
- help
- This driver implements support for the AUO K1900 epd-controller.
- This controller can drive Sipix epaper displays but can only do
- serial updates, reducing the number of possible frames per second.
-
-config FB_AUO_K1901
- tristate "AUO-K1901 EPD controller support"
- depends on FB && FB_AUO_K190X
- help
- This driver implements support for the AUO K1901 epd-controller.
- This controller can drive Sipix epaper displays and supports
- concurrent updates, making higher frames per second possible.
-
-config FB_JZ4740
- tristate "JZ4740 LCD framebuffer support"
- depends on FB && MACH_JZ4740
- select FB_SYS_FILLRECT
- select FB_SYS_COPYAREA
- select FB_SYS_IMAGEBLIT
- help
- Framebuffer support for the JZ4740 SoC.
-
-config FB_MXS
- tristate "MXS LCD framebuffer support"
- depends on FB && ARCH_MXS
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- select FB_MODE_HELPERS
- select VIDEOMODE_HELPERS
- help
- Framebuffer support for the MXS SoC.
-
-config FB_PUV3_UNIGFX
- tristate "PKUnity v3 Unigfx framebuffer support"
- depends on FB && UNICORE32 && ARCH_PUV3
- select FB_SYS_FILLRECT
- select FB_SYS_COPYAREA
- select FB_SYS_IMAGEBLIT
- select FB_SYS_FOPS
- help
- Choose this option if you want to use the Unigfx device as a
- framebuffer device. Without the support of PCI & AGP.
-
-config FB_HYPERV
- tristate "Microsoft Hyper-V Synthetic Video support"
- depends on FB && HYPERV
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- This framebuffer driver supports Microsoft Hyper-V Synthetic Video.
-
-config FB_SIMPLE
- bool "Simple framebuffer support"
- depends on (FB = y)
- select FB_CFB_FILLRECT
- select FB_CFB_COPYAREA
- select FB_CFB_IMAGEBLIT
- help
- Say Y if you want support for a simple frame-buffer.
-
- This driver assumes that the display hardware has been initialized
- before the kernel boots, and the kernel will simply render to the
- pre-allocated frame buffer surface.
-
- Configuration re: surface address, size, and format must be provided
- through device tree, or plain old platform data.
-
-source "drivers/video/omap/Kconfig"
-source "drivers/video/omap2/Kconfig"
-source "drivers/video/exynos/Kconfig"
-source "drivers/video/mmp/Kconfig"
-source "drivers/video/backlight/Kconfig"
-
if VT
source "drivers/video/console/Kconfig"
endif
if FB || SGI_NEWPORT_CONSOLE
source "drivers/video/logo/Kconfig"
-endif
-config FB_SH_MOBILE_MERAM
- tristate "SuperH Mobile MERAM read ahead support"
- depends on (SUPERH || ARCH_SHMOBILE)
- select GENERIC_ALLOCATOR
- ---help---
- Enable MERAM support for the SuperH controller.
-
- This will allow for caching of the framebuffer to provide more
- reliable access under heavy main memory bus traffic situations.
- Up to 4 memory channels can be configured, allowing 4 RGB or
- 2 YCbCr framebuffers to be configured.
+endif
-config FB_SSD1307
- tristate "Solomon SSD1307 framebuffer support"
- depends on FB && I2C
- depends on OF
- depends on GPIOLIB
- select FB_SYS_FOPS
- select FB_SYS_FILLRECT
- select FB_SYS_COPYAREA
- select FB_SYS_IMAGEBLIT
- select FB_DEFERRED_IO
- select PWM
- help
- This driver implements support for the Solomon SSD1307
- OLED controller over I2C.
endmenu
diff --git a/drivers/video/Makefile b/drivers/video/Makefile
index 1be26fe..9ad3c17 100644
--- a/drivers/video/Makefile
+++ b/drivers/video/Makefile
@@ -1,175 +1,11 @@
-# Makefile for the Linux video drivers.
-# 5 Aug 1999, James Simmons, <mailto:jsimmons@users.sf.net>
-# Rewritten to use lists instead of if-statements.
-
-# Each configuration option enables a list of files.
-
obj-$(CONFIG_VGASTATE) += vgastate.o
obj-$(CONFIG_HDMI) += hdmi.o
-obj-y += fb_notify.o
-obj-$(CONFIG_FB) += fb.o
-fb-y := fbmem.o fbmon.o fbcmap.o fbsysfs.o \
- modedb.o fbcvt.o
-fb-objs := $(fb-y)
obj-$(CONFIG_VT) += console/
obj-$(CONFIG_LOGO) += logo/
obj-y += backlight/
-obj-$(CONFIG_EXYNOS_VIDEO) += exynos/
-
-obj-$(CONFIG_FB_CFB_FILLRECT) += cfbfillrect.o
-obj-$(CONFIG_FB_CFB_COPYAREA) += cfbcopyarea.o
-obj-$(CONFIG_FB_CFB_IMAGEBLIT) += cfbimgblt.o
-obj-$(CONFIG_FB_SYS_FILLRECT) += sysfillrect.o
-obj-$(CONFIG_FB_SYS_COPYAREA) += syscopyarea.o
-obj-$(CONFIG_FB_SYS_IMAGEBLIT) += sysimgblt.o
-obj-$(CONFIG_FB_SYS_FOPS) += fb_sys_fops.o
-obj-$(CONFIG_FB_SVGALIB) += svgalib.o
-obj-$(CONFIG_FB_MACMODES) += macmodes.o
-obj-$(CONFIG_FB_DDC) += fb_ddc.o
-obj-$(CONFIG_FB_DEFERRED_IO) += fb_defio.o
-obj-$(CONFIG_FB_WMT_GE_ROPS) += wmt_ge_rops.o
-
-# Hardware specific drivers go first
-obj-$(CONFIG_FB_AMIGA) += amifb.o c2p_planar.o
-obj-$(CONFIG_FB_ARC) += arcfb.o
-obj-$(CONFIG_FB_CLPS711X) += clps711xfb.o
-obj-$(CONFIG_FB_CYBER2000) += cyber2000fb.o
-obj-$(CONFIG_FB_GRVGA) += grvga.o
-obj-$(CONFIG_FB_PM2) += pm2fb.o
-obj-$(CONFIG_FB_PM3) += pm3fb.o
-
-obj-$(CONFIG_FB_I740) += i740fb.o
-obj-$(CONFIG_FB_MATROX) += matrox/
-obj-$(CONFIG_FB_RIVA) += riva/
-obj-$(CONFIG_FB_NVIDIA) += nvidia/
-obj-$(CONFIG_FB_ATY) += aty/ macmodes.o
-obj-$(CONFIG_FB_ATY128) += aty/ macmodes.o
-obj-$(CONFIG_FB_RADEON) += aty/
-obj-$(CONFIG_FB_SIS) += sis/
-obj-$(CONFIG_FB_VIA) += via/
-obj-$(CONFIG_FB_KYRO) += kyro/
-obj-$(CONFIG_FB_SAVAGE) += savage/
-obj-$(CONFIG_FB_GEODE) += geode/
-obj-$(CONFIG_FB_MBX) += mbx/
-obj-$(CONFIG_FB_NEOMAGIC) += neofb.o
-obj-$(CONFIG_FB_3DFX) += tdfxfb.o
-obj-$(CONFIG_FB_CONTROL) += controlfb.o
-obj-$(CONFIG_FB_PLATINUM) += platinumfb.o
-obj-$(CONFIG_FB_VALKYRIE) += valkyriefb.o
-obj-$(CONFIG_FB_CT65550) += chipsfb.o
-obj-$(CONFIG_FB_IMSTT) += imsttfb.o
-obj-$(CONFIG_FB_FM2) += fm2fb.o
-obj-$(CONFIG_FB_VT8623) += vt8623fb.o
-obj-$(CONFIG_FB_TRIDENT) += tridentfb.o
-obj-$(CONFIG_FB_LE80578) += vermilion/
-obj-$(CONFIG_FB_S3) += s3fb.o
-obj-$(CONFIG_FB_ARK) += arkfb.o
-obj-$(CONFIG_FB_STI) += stifb.o
-obj-$(CONFIG_FB_FFB) += ffb.o sbuslib.o
-obj-$(CONFIG_FB_CG6) += cg6.o sbuslib.o
-obj-$(CONFIG_FB_CG3) += cg3.o sbuslib.o
-obj-$(CONFIG_FB_BW2) += bw2.o sbuslib.o
-obj-$(CONFIG_FB_CG14) += cg14.o sbuslib.o
-obj-$(CONFIG_FB_P9100) += p9100.o sbuslib.o
-obj-$(CONFIG_FB_TCX) += tcx.o sbuslib.o
-obj-$(CONFIG_FB_LEO) += leo.o sbuslib.o
-obj-$(CONFIG_FB_ACORN) += acornfb.o
-obj-$(CONFIG_FB_ATARI) += atafb.o c2p_iplan2.o atafb_mfb.o \
- atafb_iplan2p2.o atafb_iplan2p4.o atafb_iplan2p8.o
-obj-$(CONFIG_FB_MAC) += macfb.o
-obj-$(CONFIG_FB_HECUBA) += hecubafb.o
-obj-$(CONFIG_FB_N411) += n411.o
-obj-$(CONFIG_FB_HGA) += hgafb.o
-obj-$(CONFIG_FB_XVR500) += sunxvr500.o
-obj-$(CONFIG_FB_XVR2500) += sunxvr2500.o
-obj-$(CONFIG_FB_XVR1000) += sunxvr1000.o
-obj-$(CONFIG_FB_IGA) += igafb.o
-obj-$(CONFIG_FB_APOLLO) += dnfb.o
-obj-$(CONFIG_FB_Q40) += q40fb.o
-obj-$(CONFIG_FB_TGA) += tgafb.o
-obj-$(CONFIG_FB_HP300) += hpfb.o
-obj-$(CONFIG_FB_G364) += g364fb.o
-obj-$(CONFIG_FB_EP93XX) += ep93xx-fb.o
-obj-$(CONFIG_FB_SA1100) += sa1100fb.o
-obj-$(CONFIG_FB_HIT) += hitfb.o
-obj-$(CONFIG_FB_ATMEL) += atmel_lcdfb.o
-obj-$(CONFIG_FB_PVR2) += pvr2fb.o
-obj-$(CONFIG_FB_VOODOO1) += sstfb.o
-obj-$(CONFIG_FB_ARMCLCD) += amba-clcd.o
-obj-$(CONFIG_FB_GOLDFISH) += goldfishfb.o
-obj-$(CONFIG_FB_68328) += 68328fb.o
-obj-$(CONFIG_FB_GBE) += gbefb.o
-obj-$(CONFIG_FB_CIRRUS) += cirrusfb.o
-obj-$(CONFIG_FB_ASILIANT) += asiliantfb.o
-obj-$(CONFIG_FB_PXA) += pxafb.o
-obj-$(CONFIG_FB_PXA168) += pxa168fb.o
-obj-$(CONFIG_PXA3XX_GCU) += pxa3xx-gcu.o
-obj-$(CONFIG_MMP_DISP) += mmp/
-obj-$(CONFIG_FB_W100) += w100fb.o
-obj-$(CONFIG_FB_TMIO) += tmiofb.o
-obj-$(CONFIG_FB_AU1100) += au1100fb.o
-obj-$(CONFIG_FB_AU1200) += au1200fb.o
-obj-$(CONFIG_FB_VT8500) += vt8500lcdfb.o
-obj-$(CONFIG_FB_WM8505) += wm8505fb.o
-obj-$(CONFIG_FB_PMAG_AA) += pmag-aa-fb.o
-obj-$(CONFIG_FB_PMAG_BA) += pmag-ba-fb.o
-obj-$(CONFIG_FB_PMAGB_B) += pmagb-b-fb.o
-obj-$(CONFIG_FB_MAXINE) += maxinefb.o
-obj-$(CONFIG_FB_METRONOME) += metronomefb.o
-obj-$(CONFIG_FB_BROADSHEET) += broadsheetfb.o
-obj-$(CONFIG_FB_AUO_K190X) += auo_k190x.o
-obj-$(CONFIG_FB_AUO_K1900) += auo_k1900fb.o
-obj-$(CONFIG_FB_AUO_K1901) += auo_k1901fb.o
-obj-$(CONFIG_FB_S1D13XXX) += s1d13xxxfb.o
-obj-$(CONFIG_FB_SH7760) += sh7760fb.o
-obj-$(CONFIG_FB_IMX) += imxfb.o
-obj-$(CONFIG_FB_S3C) += s3c-fb.o
-obj-$(CONFIG_FB_S3C2410) += s3c2410fb.o
-obj-$(CONFIG_FB_FSL_DIU) += fsl-diu-fb.o
-obj-$(CONFIG_FB_COBALT) += cobalt_lcdfb.o
-obj-$(CONFIG_FB_IBM_GXT4500) += gxt4500.o
-obj-$(CONFIG_FB_PS3) += ps3fb.o
-obj-$(CONFIG_FB_SM501) += sm501fb.o
-obj-$(CONFIG_FB_UDL) += udlfb.o
-obj-$(CONFIG_FB_SMSCUFX) += smscufx.o
-obj-$(CONFIG_FB_XILINX) += xilinxfb.o
-obj-$(CONFIG_SH_MIPI_DSI) += sh_mipi_dsi.o
-obj-$(CONFIG_FB_SH_MOBILE_HDMI) += sh_mobile_hdmi.o
-obj-$(CONFIG_FB_SH_MOBILE_MERAM) += sh_mobile_meram.o
-obj-$(CONFIG_FB_SH_MOBILE_LCDC) += sh_mobile_lcdcfb.o
-obj-$(CONFIG_FB_OMAP) += omap/
-obj-y += omap2/
-obj-$(CONFIG_XEN_FBDEV_FRONTEND) += xen-fbfront.o
-obj-$(CONFIG_FB_CARMINE) += carminefb.o
-obj-$(CONFIG_FB_MB862XX) += mb862xx/
-obj-$(CONFIG_FB_MSM) += msm/
-obj-$(CONFIG_FB_NUC900) += nuc900fb.o
-obj-$(CONFIG_FB_JZ4740) += jz4740_fb.o
-obj-$(CONFIG_FB_PUV3_UNIGFX) += fb-puv3.o
-obj-$(CONFIG_FB_HYPERV) += hyperv_fb.o
-obj-$(CONFIG_FB_OPENCORES) += ocfb.o
-
-# Platform or fallback drivers go here
-obj-$(CONFIG_FB_UVESA) += uvesafb.o
-obj-$(CONFIG_FB_VESA) += vesafb.o
-obj-$(CONFIG_FB_EFI) += efifb.o
-obj-$(CONFIG_FB_VGA16) += vga16fb.o
-obj-$(CONFIG_FB_OF) += offb.o
-obj-$(CONFIG_FB_BF537_LQ035) += bf537-lq035.o
-obj-$(CONFIG_FB_BF54X_LQ043) += bf54x-lq043fb.o
-obj-$(CONFIG_FB_BFIN_LQ035Q1) += bfin-lq035q1-fb.o
-obj-$(CONFIG_FB_BFIN_T350MCQB) += bfin-t350mcqb-fb.o
-obj-$(CONFIG_FB_BFIN_7393) += bfin_adv7393fb.o
-obj-$(CONFIG_FB_MX3) += mx3fb.o
-obj-$(CONFIG_FB_DA8XX) += da8xx-fb.o
-obj-$(CONFIG_FB_MXS) += mxsfb.o
-obj-$(CONFIG_FB_SSD1307) += ssd1307fb.o
-obj-$(CONFIG_FB_SIMPLE) += simplefb.o
-
-# the test framebuffer is last
-obj-$(CONFIG_FB_VIRTUAL) += vfb.o
+obj-y += fbdev/
obj-$(CONFIG_VIDEOMODE_HELPERS) += display_timing.o videomode.o
ifeq ($(CONFIG_OF),y)
diff --git a/drivers/video/console/sticon.c b/drivers/video/console/sticon.c
index 5f65ca3..026fd12 100644
--- a/drivers/video/console/sticon.c
+++ b/drivers/video/console/sticon.c
@@ -46,7 +46,7 @@
#include <asm/io.h>
-#include "../sticore.h"
+#include "../fbdev/sticore.h"
/* switching to graphics mode */
#define BLANK 0
diff --git a/drivers/video/console/sticore.c b/drivers/video/console/sticore.c
index cecd3de..7da1ad0 100644
--- a/drivers/video/console/sticore.c
+++ b/drivers/video/console/sticore.c
@@ -28,7 +28,7 @@
#include <asm/cacheflush.h>
#include <asm/grfioctl.h>
-#include "../sticore.h"
+#include "../fbdev/sticore.h"
#define STI_DRIVERVERSION "Version 0.9b"
diff --git a/drivers/video/68328fb.c b/drivers/video/fbdev/68328fb.c
index 552258c..552258c 100644
--- a/drivers/video/68328fb.c
+++ b/drivers/video/fbdev/68328fb.c
diff --git a/drivers/video/fbdev/Kconfig b/drivers/video/fbdev/Kconfig
new file mode 100644
index 0000000..e1f4727
--- /dev/null
+++ b/drivers/video/fbdev/Kconfig
@@ -0,0 +1,2474 @@
+#
+# fbdev configuration
+#
+
+menuconfig FB
+ tristate "Support for frame buffer devices"
+ ---help---
+ The frame buffer device provides an abstraction for the graphics
+ hardware. It represents the frame buffer of some video hardware and
+ allows application software to access the graphics hardware through
+ a well-defined interface, so the software doesn't need to know
+ anything about the low-level (hardware register) stuff.
+
+ Frame buffer devices work identically across the different
+ architectures supported by Linux and make the implementation of
+ application programs easier and more portable; at this point, an X
+ server exists which uses the frame buffer device exclusively.
+ On several non-X86 architectures, the frame buffer device is the
+ only way to use the graphics hardware.
+
+ The device is accessed through special device nodes, usually located
+ in the /dev directory, i.e. /dev/fb*.
+
+ You need an utility program called fbset to make full use of frame
+ buffer devices. Please read <file:Documentation/fb/framebuffer.txt>
+ and the Framebuffer-HOWTO at
+ <http://www.munted.org.uk/programming/Framebuffer-HOWTO-1.3.html> for more
+ information.
+
+ Say Y here and to the driver for your graphics board below if you
+ are compiling a kernel for a non-x86 architecture.
+
+ If you are compiling for the x86 architecture, you can say Y if you
+ want to play with it, but it is not essential. Please note that
+ running graphical applications that directly touch the hardware
+ (e.g. an accelerated X server) and that are not frame buffer
+ device-aware may cause unexpected results. If unsure, say N.
+
+config FIRMWARE_EDID
+ bool "Enable firmware EDID"
+ depends on FB
+ default n
+ ---help---
+ This enables access to the EDID transferred from the firmware.
+ On the i386, this is from the Video BIOS. Enable this if DDC/I2C
+ transfers do not work for your driver and if you are using
+ nvidiafb, i810fb or savagefb.
+
+ In general, choosing Y for this option is safe. If you
+ experience extremely long delays while booting before you get
+ something on your display, try setting this to N. Matrox cards in
+ combination with certain motherboards and monitors are known to
+ suffer from this problem.
+
+config FB_DDC
+ tristate
+ depends on FB
+ select I2C_ALGOBIT
+ select I2C
+ default n
+
+config FB_BOOT_VESA_SUPPORT
+ bool
+ depends on FB
+ default n
+ ---help---
+ If true, at least one selected framebuffer driver can take advantage
+ of VESA video modes set at an early boot stage via the vga= parameter.
+
+config FB_CFB_FILLRECT
+ tristate
+ depends on FB
+ default n
+ ---help---
+ Include the cfb_fillrect function for generic software rectangle
+ filling. This is used by drivers that don't provide their own
+ (accelerated) version.
+
+config FB_CFB_COPYAREA
+ tristate
+ depends on FB
+ default n
+ ---help---
+ Include the cfb_copyarea function for generic software area copying.
+ This is used by drivers that don't provide their own (accelerated)
+ version.
+
+config FB_CFB_IMAGEBLIT
+ tristate
+ depends on FB
+ default n
+ ---help---
+ Include the cfb_imageblit function for generic software image
+ blitting. This is used by drivers that don't provide their own
+ (accelerated) version.
+
+config FB_CFB_REV_PIXELS_IN_BYTE
+ bool
+ depends on FB
+ default n
+ ---help---
+ Allow generic frame-buffer functions to work on displays with 1, 2
+ and 4 bits per pixel depths which has opposite order of pixels in
+ byte order to bytes in long order.
+
+config FB_SYS_FILLRECT
+ tristate
+ depends on FB
+ default n
+ ---help---
+ Include the sys_fillrect function for generic software rectangle
+ filling. This is used by drivers that don't provide their own
+ (accelerated) version and the framebuffer is in system RAM.
+
+config FB_SYS_COPYAREA
+ tristate
+ depends on FB
+ default n
+ ---help---
+ Include the sys_copyarea function for generic software area copying.
+ This is used by drivers that don't provide their own (accelerated)
+ version and the framebuffer is in system RAM.
+
+config FB_SYS_IMAGEBLIT
+ tristate
+ depends on FB
+ default n
+ ---help---
+ Include the sys_imageblit function for generic software image
+ blitting. This is used by drivers that don't provide their own
+ (accelerated) version and the framebuffer is in system RAM.
+
+menuconfig FB_FOREIGN_ENDIAN
+ bool "Framebuffer foreign endianness support"
+ depends on FB
+ ---help---
+ This menu will let you enable support for the framebuffers with
+ non-native endianness (e.g. Little-Endian framebuffer on a
+ Big-Endian machine). Most probably you don't have such hardware,
+ so it's safe to say "n" here.
+
+choice
+ prompt "Choice endianness support"
+ depends on FB_FOREIGN_ENDIAN
+
+config FB_BOTH_ENDIAN
+ bool "Support for Big- and Little-Endian framebuffers"
+
+config FB_BIG_ENDIAN
+ bool "Support for Big-Endian framebuffers only"
+
+config FB_LITTLE_ENDIAN
+ bool "Support for Little-Endian framebuffers only"
+
+endchoice
+
+config FB_SYS_FOPS
+ tristate
+ depends on FB
+ default n
+
+config FB_DEFERRED_IO
+ bool
+ depends on FB
+
+config FB_HECUBA
+ tristate
+ depends on FB
+ depends on FB_DEFERRED_IO
+
+config FB_SVGALIB
+ tristate
+ depends on FB
+ default n
+ ---help---
+ Common utility functions useful to fbdev drivers of VGA-based
+ cards.
+
+config FB_MACMODES
+ tristate
+ depends on FB
+ default n
+
+config FB_BACKLIGHT
+ bool
+ depends on FB
+ select BACKLIGHT_LCD_SUPPORT
+ select BACKLIGHT_CLASS_DEVICE
+ default n
+
+config FB_MODE_HELPERS
+ bool "Enable Video Mode Handling Helpers"
+ depends on FB
+ default n
+ ---help---
+ This enables functions for handling video modes using the
+ Generalized Timing Formula and the EDID parser. A few drivers rely
+ on this feature such as the radeonfb, rivafb, and the i810fb. If
+ your driver does not take advantage of this feature, choosing Y will
+ just increase the kernel size by about 5K.
+
+config FB_TILEBLITTING
+ bool "Enable Tile Blitting Support"
+ depends on FB
+ default n
+ ---help---
+ This enables tile blitting. Tile blitting is a drawing technique
+ where the screen is divided into rectangular sections (tiles), whereas
+ the standard blitting divides the screen into pixels. Because the
+ default drawing element is a tile, drawing functions will be passed
+ parameters in terms of number of tiles instead of number of pixels.
+ For example, to draw a single character, instead of using bitmaps,
+ an index to an array of bitmaps will be used. To clear or move a
+ rectangular section of a screen, the rectangle will be described in
+ terms of number of tiles in the x- and y-axis.
+
+ This is particularly important to one driver, matroxfb. If
+ unsure, say N.
+
+comment "Frame buffer hardware drivers"
+ depends on FB
+
+config FB_GRVGA
+ tristate "Aeroflex Gaisler framebuffer support"
+ depends on FB && SPARC
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ ---help---
+ This enables support for the SVGACTRL framebuffer in the GRLIB IP library from Aeroflex Gaisler.
+
+config FB_CIRRUS
+ tristate "Cirrus Logic support"
+ depends on FB && (ZORRO || PCI)
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ ---help---
+ This enables support for Cirrus Logic GD542x/543x based boards on
+ Amiga: SD64, Piccolo, Picasso II/II+, Picasso IV, or EGS Spectrum.
+
+ If you have a PCI-based system, this enables support for these
+ chips: GD-543x, GD-544x, GD-5480.
+
+ Please read the file <file:Documentation/fb/cirrusfb.txt>.
+
+ Say N unless you have such a graphics board or plan to get one
+ before you next recompile the kernel.
+
+config FB_PM2
+ tristate "Permedia2 support"
+ depends on FB && ((AMIGA && BROKEN) || PCI)
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the frame buffer device driver for cards based on
+ the 3D Labs Permedia, Permedia 2 and Permedia 2V chips.
+ The driver was tested on the following cards:
+ Diamond FireGL 1000 PRO AGP
+ ELSA Gloria Synergy PCI
+ Appian Jeronimo PRO (both heads) PCI
+ 3DLabs Oxygen ACX aka EONtronics Picasso P2 PCI
+ Techsource Raptor GFX-8P (aka Sun PGX-32) on SPARC
+ ASK Graphic Blaster Exxtreme AGP
+
+ To compile this driver as a module, choose M here: the
+ module will be called pm2fb.
+
+config FB_PM2_FIFO_DISCONNECT
+ bool "enable FIFO disconnect feature"
+ depends on FB_PM2 && PCI
+ help
+ Support the Permedia2 FIFO disconnect feature.
+
+config FB_ARMCLCD
+ tristate "ARM PrimeCell PL110 support"
+ depends on ARM || ARM64 || COMPILE_TEST
+ depends on FB && ARM_AMBA
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This framebuffer device driver is for the ARM PrimeCell PL110
+ Colour LCD controller. ARM PrimeCells provide the building
+ blocks for System on a Chip devices.
+
+ If you want to compile this as a module (=code which can be
+ inserted into and removed from the running kernel), say M
+ here and read <file:Documentation/kbuild/modules.txt>. The module
+ will be called amba-clcd.
+
+config FB_ACORN
+ bool "Acorn VIDC support"
+ depends on (FB = y) && ARM && ARCH_ACORN
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the frame buffer device driver for the Acorn VIDC graphics
+ hardware found in Acorn RISC PCs and other ARM-based machines. If
+ unsure, say N.
+
+config FB_CLPS711X
+ bool "CLPS711X LCD support"
+ depends on (FB = y) && ARM && ARCH_CLPS711X
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ Say Y to enable the Framebuffer driver for the CLPS7111 and
+ EP7212 processors.
+
+config FB_SA1100
+ bool "SA-1100 LCD support"
+ depends on (FB = y) && ARM && ARCH_SA1100
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is a framebuffer device for the SA-1100 LCD Controller.
+ See <http://www.linux-fbdev.org/> for information on framebuffer
+ devices.
+
+ If you plan to use the LCD display with your SA-1100 system, say
+ Y here.
+
+config FB_IMX
+ tristate "Freescale i.MX1/21/25/27 LCD support"
+ depends on FB && ARCH_MXC
+ select BACKLIGHT_LCD_SUPPORT
+ select LCD_CLASS_DEVICE
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select FB_MODE_HELPERS
+ select VIDEOMODE_HELPERS
+
+config FB_CYBER2000
+ tristate "CyberPro 2000/2010/5000 support"
+ depends on FB && PCI && (BROKEN || !SPARC64)
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This enables support for the Integraphics CyberPro 20x0 and 5000
+ VGA chips used in the Rebel.com Netwinder and other machines.
+ Say Y if you have a NetWinder or a graphics card containing this
+ device, otherwise say N.
+
+config FB_CYBER2000_DDC
+ bool "DDC for CyberPro support"
+ depends on FB_CYBER2000
+ select FB_DDC
+ default y
+ help
+ Say Y here if you want DDC support for your CyberPro graphics
+ card. This is only I2C bus support, driver does not use EDID.
+
+config FB_CYBER2000_I2C
+ bool "CyberPro 2000/2010/5000 I2C support"
+ depends on FB_CYBER2000 && I2C && ARCH_NETWINDER
+ select I2C_ALGOBIT
+ help
+ Enable support for the I2C video decoder interface on the
+ Integraphics CyberPro 20x0 and 5000 VGA chips. This is used
+ on the Netwinder machines for the SAA7111 video capture.
+
+config FB_APOLLO
+ bool
+ depends on (FB = y) && APOLLO
+ default y
+ select FB_CFB_FILLRECT
+ select FB_CFB_IMAGEBLIT
+
+config FB_Q40
+ bool
+ depends on (FB = y) && Q40
+ default y
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+
+config FB_AMIGA
+ tristate "Amiga native chipset support"
+ depends on FB && AMIGA
+ help
+ This is the frame buffer device driver for the builtin graphics
+ chipset found in Amigas.
+
+ To compile this driver as a module, choose M here: the
+ module will be called amifb.
+
+config FB_AMIGA_OCS
+ bool "Amiga OCS chipset support"
+ depends on FB_AMIGA
+ help
+ This enables support for the original Agnus and Denise video chips,
+ found in the Amiga 1000 and most A500's and A2000's. If you intend
+ to run Linux on any of these systems, say Y; otherwise say N.
+
+config FB_AMIGA_ECS
+ bool "Amiga ECS chipset support"
+ depends on FB_AMIGA
+ help
+ This enables support for the Enhanced Chip Set, found in later
+ A500's, later A2000's, the A600, the A3000, the A3000T and CDTV. If
+ you intend to run Linux on any of these systems, say Y; otherwise
+ say N.
+
+config FB_AMIGA_AGA
+ bool "Amiga AGA chipset support"
+ depends on FB_AMIGA
+ help
+ This enables support for the Advanced Graphics Architecture (also
+ known as the AGA or AA) Chip Set, found in the A1200, A4000, A4000T
+ and CD32. If you intend to run Linux on any of these systems, say Y;
+ otherwise say N.
+
+config FB_FM2
+ bool "Amiga FrameMaster II/Rainbow II support"
+ depends on (FB = y) && ZORRO
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the frame buffer device driver for the Amiga FrameMaster
+ card from BSC (exhibited 1992 but not shipped as a CBM product).
+
+config FB_ARC
+ tristate "Arc Monochrome LCD board support"
+ depends on FB && X86
+ select FB_SYS_FILLRECT
+ select FB_SYS_COPYAREA
+ select FB_SYS_IMAGEBLIT
+ select FB_SYS_FOPS
+ help
+ This enables support for the Arc Monochrome LCD board. The board
+ is based on the KS-108 lcd controller and is typically a matrix
+ of 2*n chips. This driver was tested with a 128x64 panel. This
+ driver supports it for use with x86 SBCs through a 16 bit GPIO
+ interface (8 bit data, 8 bit control). If you anticipate using
+ this driver, say Y or M; otherwise say N. You must specify the
+ GPIO IO address to be used for setting control and data.
+
+config FB_ATARI
+ bool "Atari native chipset support"
+ depends on (FB = y) && ATARI
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the frame buffer device driver for the builtin graphics
+ chipset found in Ataris.
+
+config FB_OF
+ bool "Open Firmware frame buffer device support"
+ depends on (FB = y) && (PPC64 || PPC_OF) && (!PPC_PSERIES || PCI)
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select FB_MACMODES
+ help
+ Say Y if you want support with Open Firmware for your graphics
+ board.
+
+config FB_CONTROL
+ bool "Apple \"control\" display support"
+ depends on (FB = y) && PPC_PMAC && PPC32
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select FB_MACMODES
+ help
+ This driver supports a frame buffer for the graphics adapter in the
+ Power Macintosh 7300 and others.
+
+config FB_PLATINUM
+ bool "Apple \"platinum\" display support"
+ depends on (FB = y) && PPC_PMAC && PPC32
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select FB_MACMODES
+ help
+ This driver supports a frame buffer for the "platinum" graphics
+ adapter in some Power Macintoshes.
+
+config FB_VALKYRIE
+ bool "Apple \"valkyrie\" display support"
+ depends on (FB = y) && (MAC || (PPC_PMAC && PPC32))
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select FB_MACMODES
+ help
+ This driver supports a frame buffer for the "valkyrie" graphics
+ adapter in some Power Macintoshes.
+
+config FB_CT65550
+ bool "Chips 65550 display support"
+ depends on (FB = y) && PPC32 && PCI
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the frame buffer device driver for the Chips & Technologies
+ 65550 graphics chip in PowerBooks.
+
+config FB_ASILIANT
+ bool "Asiliant (Chips) 69000 display support"
+ depends on (FB = y) && PCI
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the frame buffer device driver for the Asiliant 69030 chipset
+
+config FB_IMSTT
+ bool "IMS Twin Turbo display support"
+ depends on (FB = y) && PCI
+ select FB_CFB_IMAGEBLIT
+ select FB_MACMODES if PPC
+ help
+ The IMS Twin Turbo is a PCI-based frame buffer card bundled with
+ many Macintosh and compatible computers.
+
+config FB_VGA16
+ tristate "VGA 16-color graphics support"
+ depends on FB && (X86 || PPC)
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select VGASTATE
+ select FONT_8x16 if FRAMEBUFFER_CONSOLE
+ help
+ This is the frame buffer device driver for VGA 16 color graphic
+ cards. Say Y if you have such a card.
+
+ To compile this driver as a module, choose M here: the
+ module will be called vga16fb.
+
+config FB_BF54X_LQ043
+ tristate "SHARP LQ043 TFT LCD (BF548 EZKIT)"
+ depends on FB && (BF54x) && !BF542
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the framebuffer device driver for a SHARP LQ043T1DG01 TFT LCD
+
+config FB_BFIN_T350MCQB
+ tristate "Varitronix COG-T350MCQB TFT LCD display (BF527 EZKIT)"
+ depends on FB && BLACKFIN
+ select BFIN_GPTIMERS
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the framebuffer device driver for a Varitronix VL-PS-COG-T350MCQB-01 display TFT LCD
+ This display is a QVGA 320x240 24-bit RGB display interfaced by an 8-bit wide PPI
+ It uses PPI[0..7] PPI_FS1, PPI_FS2 and PPI_CLK.
+
+config FB_BFIN_LQ035Q1
+ tristate "SHARP LQ035Q1DH02 TFT LCD"
+ depends on FB && BLACKFIN && SPI
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select BFIN_GPTIMERS
+ help
+ This is the framebuffer device driver for a SHARP LQ035Q1DH02 TFT display found on
+ the Blackfin Landscape LCD EZ-Extender Card.
+ This display is a QVGA 320x240 18-bit RGB display interfaced by an 16-bit wide PPI
+ It uses PPI[0..15] PPI_FS1, PPI_FS2 and PPI_CLK.
+
+ To compile this driver as a module, choose M here: the
+ module will be called bfin-lq035q1-fb.
+
+config FB_BF537_LQ035
+ tristate "SHARP LQ035 TFT LCD (BF537 STAMP)"
+ depends on FB && (BF534 || BF536 || BF537) && I2C_BLACKFIN_TWI
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select BFIN_GPTIMERS
+ help
+ This is the framebuffer device for a SHARP LQ035Q7DB03 TFT LCD
+ attached to a BF537.
+
+ To compile this driver as a module, choose M here: the
+ module will be called bf537-lq035.
+
+config FB_BFIN_7393
+ tristate "Blackfin ADV7393 Video encoder"
+ depends on FB && BLACKFIN
+ select I2C
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the framebuffer device for a ADV7393 video encoder
+ attached to a Blackfin on the PPI port.
+ If your Blackfin board has a ADV7393 select Y.
+
+ To compile this driver as a module, choose M here: the
+ module will be called bfin_adv7393fb.
+
+choice
+ prompt "Video mode support"
+ depends on FB_BFIN_7393
+ default NTSC
+
+config NTSC
+ bool 'NTSC 720x480'
+
+config PAL
+ bool 'PAL 720x576'
+
+config NTSC_640x480
+ bool 'NTSC 640x480 (Experimental)'
+
+config PAL_640x480
+ bool 'PAL 640x480 (Experimental)'
+
+config NTSC_YCBCR
+ bool 'NTSC 720x480 YCbCR input'
+
+config PAL_YCBCR
+ bool 'PAL 720x576 YCbCR input'
+
+endchoice
+
+choice
+ prompt "Size of ADV7393 frame buffer memory Single/Double Size"
+ depends on (FB_BFIN_7393)
+ default ADV7393_1XMEM
+
+config ADV7393_1XMEM
+ bool 'Single'
+
+config ADV7393_2XMEM
+ bool 'Double'
+endchoice
+
+config FB_STI
+ tristate "HP STI frame buffer device support"
+ depends on FB && PARISC
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select STI_CONSOLE
+ select VT
+ default y
+ ---help---
+ STI refers to the HP "Standard Text Interface" which is a set of
+ BIOS routines contained in a ROM chip in HP PA-RISC based machines.
+ Enabling this option will implement the linux framebuffer device
+ using calls to the STI BIOS routines for initialisation.
+
+ If you enable this option, you will get a planar framebuffer device
+ /dev/fb which will work on the most common HP graphic cards of the
+ NGLE family, including the artist chips (in the 7xx and Bxxx series),
+ HCRX, HCRX24, CRX, CRX24 and VisEG series.
+
+ It is safe to enable this option, so you should probably say "Y".
+
+config FB_MAC
+ bool "Generic Macintosh display support"
+ depends on (FB = y) && MAC
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select FB_MACMODES
+
+config FB_HP300
+ bool
+ depends on (FB = y) && DIO
+ select FB_CFB_IMAGEBLIT
+ default y
+
+config FB_TGA
+ tristate "TGA/SFB+ framebuffer support"
+ depends on FB && (ALPHA || TC)
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select BITREVERSE
+ ---help---
+ This is the frame buffer device driver for generic TGA and SFB+
+ graphic cards. These include DEC ZLXp-E1, -E2 and -E3 PCI cards,
+ also known as PBXGA-A, -B and -C, and DEC ZLX-E1, -E2 and -E3
+ TURBOchannel cards, also known as PMAGD-A, -B and -C.
+
+ Due to hardware limitations ZLX-E2 and E3 cards are not supported
+ for DECstation 5000/200 systems. Additionally due to firmware
+ limitations these cards may cause troubles with booting DECstation
+ 5000/240 and /260 systems, but are fully supported under Linux if
+ you manage to get it going. ;-)
+
+ Say Y if you have one of those.
+
+config FB_UVESA
+ tristate "Userspace VESA VGA graphics support"
+ depends on FB && CONNECTOR
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select FB_MODE_HELPERS
+ help
+ This is the frame buffer driver for generic VBE 2.0 compliant
+ graphic cards. It can also take advantage of VBE 3.0 features,
+ such as refresh rate adjustment.
+
+ This driver generally provides more features than vesafb but
+ requires a userspace helper application called 'v86d'. See
+ <file:Documentation/fb/uvesafb.txt> for more information.
+
+ If unsure, say N.
+
+config FB_VESA
+ bool "VESA VGA graphics support"
+ depends on (FB = y) && X86
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select FB_BOOT_VESA_SUPPORT
+ help
+ This is the frame buffer device driver for generic VESA 2.0
+ compliant graphic cards. The older VESA 1.2 cards are not supported.
+ You will get a boot time penguin logo at no additional cost. Please
+ read <file:Documentation/fb/vesafb.txt>. If unsure, say Y.
+
+config FB_EFI
+ bool "EFI-based Framebuffer Support"
+ depends on (FB = y) && X86 && EFI
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the EFI frame buffer device driver. If the firmware on
+ your platform is EFI 1.10 or UEFI 2.0, select Y to add support for
+ using the EFI framebuffer as your console.
+
+config FB_N411
+ tristate "N411 Apollo/Hecuba devkit support"
+ depends on FB && X86 && MMU
+ select FB_SYS_FILLRECT
+ select FB_SYS_COPYAREA
+ select FB_SYS_IMAGEBLIT
+ select FB_SYS_FOPS
+ select FB_DEFERRED_IO
+ select FB_HECUBA
+ help
+ This enables support for the Apollo display controller in its
+ Hecuba form using the n411 devkit.
+
+config FB_HGA
+ tristate "Hercules mono graphics support"
+ depends on FB && X86
+ help
+ Say Y here if you have a Hercules mono graphics card.
+
+ To compile this driver as a module, choose M here: the
+ module will be called hgafb.
+
+ As this card technology is at least 25 years old,
+ most people will answer N here.
+
+config FB_GBE
+ bool "SGI Graphics Backend frame buffer support"
+ depends on (FB = y) && SGI_IP32
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the frame buffer device driver for SGI Graphics Backend.
+ This chip is used in SGI O2 and Visual Workstation 320/540.
+
+config FB_GBE_MEM
+ int "Video memory size in MB"
+ depends on FB_GBE
+ default 4
+ help
+ This is the amount of memory reserved for the framebuffer,
+ which can be any value between 1MB and 8MB.
+
+config FB_SBUS
+ bool "SBUS and UPA framebuffers"
+ depends on (FB = y) && SPARC
+ help
+ Say Y if you want support for SBUS or UPA based frame buffer device.
+
+config FB_BW2
+ bool "BWtwo support"
+ depends on (FB = y) && (SPARC && FB_SBUS)
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the frame buffer device driver for the BWtwo frame buffer.
+
+config FB_CG3
+ bool "CGthree support"
+ depends on (FB = y) && (SPARC && FB_SBUS)
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the frame buffer device driver for the CGthree frame buffer.
+
+config FB_CG6
+ bool "CGsix (GX,TurboGX) support"
+ depends on (FB = y) && (SPARC && FB_SBUS)
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the frame buffer device driver for the CGsix (GX, TurboGX)
+ frame buffer.
+
+config FB_FFB
+ bool "Creator/Creator3D/Elite3D support"
+ depends on FB_SBUS && SPARC64
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the frame buffer device driver for the Creator, Creator3D,
+ and Elite3D graphics boards.
+
+config FB_TCX
+ bool "TCX (SS4/SS5 only) support"
+ depends on FB_SBUS
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the frame buffer device driver for the TCX 24/8bit frame
+ buffer.
+
+config FB_CG14
+ bool "CGfourteen (SX) support"
+ depends on FB_SBUS
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the frame buffer device driver for the CGfourteen frame
+ buffer on Desktop SPARCsystems with the SX graphics option.
+
+config FB_P9100
+ bool "P9100 (Sparcbook 3 only) support"
+ depends on FB_SBUS
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the frame buffer device driver for the P9100 card
+ supported on Sparcbook 3 machines.
+
+config FB_LEO
+ bool "Leo (ZX) support"
+ depends on FB_SBUS
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the frame buffer device driver for the SBUS-based Sun ZX
+ (leo) frame buffer cards.
+
+config FB_IGA
+ bool "IGA 168x display support"
+ depends on (FB = y) && SPARC32
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the framebuffer device for the INTERGRAPHICS 1680 and
+ successor frame buffer cards.
+
+config FB_XVR500
+ bool "Sun XVR-500 3DLABS Wildcat support"
+ depends on (FB = y) && PCI && SPARC64
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the framebuffer device for the Sun XVR-500 and similar
+ graphics cards based upon the 3DLABS Wildcat chipset. The driver
+ only works on sparc64 systems where the system firmware has
+ mostly initialized the card already. It is treated as a
+ completely dumb framebuffer device.
+
+config FB_XVR2500
+ bool "Sun XVR-2500 3DLABS Wildcat support"
+ depends on (FB = y) && PCI && SPARC64
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the framebuffer device for the Sun XVR-2500 and similar
+ graphics cards based upon the 3DLABS Wildcat chipset. The driver
+ only works on sparc64 systems where the system firmware has
+ mostly initialized the card already. It is treated as a
+ completely dumb framebuffer device.
+
+config FB_XVR1000
+ bool "Sun XVR-1000 support"
+ depends on (FB = y) && SPARC64
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the framebuffer device for the Sun XVR-1000 and similar
+ graphics cards. The driver only works on sparc64 systems where
+ the system firmware has mostly initialized the card already. It
+ is treated as a completely dumb framebuffer device.
+
+config FB_PVR2
+ tristate "NEC PowerVR 2 display support"
+ depends on FB && SH_DREAMCAST
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ ---help---
+ Say Y here if you have a PowerVR 2 card in your box. If you plan to
+ run linux on your Dreamcast, you will have to say Y here.
+ This driver may or may not work on other PowerVR 2 cards, but is
+ totally untested. Use at your own risk. If unsure, say N.
+
+ To compile this driver as a module, choose M here: the
+ module will be called pvr2fb.
+
+ You can pass several parameters to the driver at boot time or at
+ module load time. The parameters look like "video=pvr2:XXX", where
+ the meaning of XXX can be found at the end of the main source file
+ (<file:drivers/video/pvr2fb.c>). Please see the file
+ <file:Documentation/fb/pvr2fb.txt>.
+
+config FB_OPENCORES
+ tristate "OpenCores VGA/LCD core 2.0 framebuffer support"
+ depends on FB && HAS_DMA
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This enables support for the OpenCores VGA/LCD core.
+
+ The OpenCores VGA/LCD core is typically used together with
+ softcore CPUs (e.g. OpenRISC or Microblaze) or hard processor
+ systems (e.g. Altera socfpga or Xilinx Zynq) on FPGAs.
+
+ The source code and specification for the core is available at
+ <http://opencores.org/project,vga_lcd>
+
+config FB_S1D13XXX
+ tristate "Epson S1D13XXX framebuffer support"
+ depends on FB
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ Support for S1D13XXX framebuffer device family (currently only
+ working with S1D13806). Product specs at
+ <http://vdc.epson.com/>
+
+config FB_ATMEL
+ tristate "AT91/AT32 LCD Controller support"
+ depends on FB && HAVE_FB_ATMEL
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select FB_MODE_HELPERS
+ select VIDEOMODE_HELPERS
+ help
+ This enables support for the AT91/AT32 LCD Controller.
+
+config FB_INTSRAM
+ bool "Frame Buffer in internal SRAM"
+ depends on FB_ATMEL && ARCH_AT91SAM9261
+ help
+ Say Y if you want to map Frame Buffer in internal SRAM. Say N if you want
+ to let frame buffer in external SDRAM.
+
+config FB_ATMEL_STN
+ bool "Use a STN display with AT91/AT32 LCD Controller"
+ depends on FB_ATMEL && (MACH_AT91SAM9261EK || MACH_AT91SAM9G10EK)
+ default n
+ help
+ Say Y if you want to connect a STN LCD display to the AT91/AT32 LCD
+ Controller. Say N if you want to connect a TFT.
+
+ If unsure, say N.
+
+config FB_NVIDIA
+ tristate "nVidia Framebuffer Support"
+ depends on FB && PCI
+ select FB_BACKLIGHT if FB_NVIDIA_BACKLIGHT
+ select FB_MODE_HELPERS
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select BITREVERSE
+ select VGASTATE
+ help
+ This driver supports graphics boards with the nVidia chips, TNT
+ and newer. For very old chipsets, such as the RIVA128, then use
+ the rivafb.
+ Say Y if you have such a graphics board.
+
+ To compile this driver as a module, choose M here: the
+ module will be called nvidiafb.
+
+config FB_NVIDIA_I2C
+ bool "Enable DDC Support"
+ depends on FB_NVIDIA
+ select FB_DDC
+ help
+ This enables I2C support for nVidia Chipsets. This is used
+ only for getting EDID information from the attached display
+ allowing for robust video mode handling and switching.
+
+ Because fbdev-2.6 requires that drivers must be able to
+ independently validate video mode parameters, you should say Y
+ here.
+
+config FB_NVIDIA_DEBUG
+ bool "Lots of debug output"
+ depends on FB_NVIDIA
+ default n
+ help
+ Say Y here if you want the nVidia driver to output all sorts
+ of debugging information to provide to the maintainer when
+ something goes wrong.
+
+config FB_NVIDIA_BACKLIGHT
+ bool "Support for backlight control"
+ depends on FB_NVIDIA
+ default y
+ help
+ Say Y here if you want to control the backlight of your display.
+
+config FB_RIVA
+ tristate "nVidia Riva support"
+ depends on FB && PCI
+ select FB_BACKLIGHT if FB_RIVA_BACKLIGHT
+ select FB_MODE_HELPERS
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select BITREVERSE
+ select VGASTATE
+ help
+ This driver supports graphics boards with the nVidia Riva/Geforce
+ chips.
+ Say Y if you have such a graphics board.
+
+ To compile this driver as a module, choose M here: the
+ module will be called rivafb.
+
+config FB_RIVA_I2C
+ bool "Enable DDC Support"
+ depends on FB_RIVA
+ select FB_DDC
+ help
+ This enables I2C support for nVidia Chipsets. This is used
+ only for getting EDID information from the attached display
+ allowing for robust video mode handling and switching.
+
+ Because fbdev-2.6 requires that drivers must be able to
+ independently validate video mode parameters, you should say Y
+ here.
+
+config FB_RIVA_DEBUG
+ bool "Lots of debug output"
+ depends on FB_RIVA
+ default n
+ help
+ Say Y here if you want the Riva driver to output all sorts
+ of debugging information to provide to the maintainer when
+ something goes wrong.
+
+config FB_RIVA_BACKLIGHT
+ bool "Support for backlight control"
+ depends on FB_RIVA
+ default y
+ help
+ Say Y here if you want to control the backlight of your display.
+
+config FB_I740
+ tristate "Intel740 support"
+ depends on FB && PCI
+ select FB_MODE_HELPERS
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select VGASTATE
+ select FB_DDC
+ help
+ This driver supports graphics cards based on Intel740 chip.
+
+config FB_I810
+ tristate "Intel 810/815 support"
+ depends on FB && PCI && X86_32 && AGP_INTEL
+ select FB_MODE_HELPERS
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select VGASTATE
+ help
+ This driver supports the on-board graphics built in to the Intel 810
+ and 815 chipsets. Say Y if you have and plan to use such a board.
+
+ To compile this driver as a module, choose M here: the
+ module will be called i810fb.
+
+ For more information, please read
+ <file:Documentation/fb/intel810.txt>
+
+config FB_I810_GTF
+ bool "use VESA Generalized Timing Formula"
+ depends on FB_I810
+ help
+ If you say Y, then the VESA standard, Generalized Timing Formula
+ or GTF, will be used to calculate the required video timing values
+ per video mode. Since the GTF allows nondiscrete timings
+ (nondiscrete being a range of values as opposed to discrete being a
+ set of values), you'll be able to use any combination of horizontal
+ and vertical resolutions, and vertical refresh rates without having
+ to specify your own timing parameters. This is especially useful
+ to maximize the performance of an aging display, or if you just
+ have a display with nonstandard dimensions. A VESA compliant
+ monitor is recommended, but can still work with non-compliant ones.
+ If you need or want this, then select this option. The timings may
+ not be compliant with Intel's recommended values. Use at your own
+ risk.
+
+ If you say N, the driver will revert to discrete video timings
+ using a set recommended by Intel in their documentation.
+
+ If unsure, say N.
+
+config FB_I810_I2C
+ bool "Enable DDC Support"
+ depends on FB_I810 && FB_I810_GTF
+ select FB_DDC
+ help
+
+config FB_LE80578
+ tristate "Intel LE80578 (Vermilion) support"
+ depends on FB && PCI && X86
+ select FB_MODE_HELPERS
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This driver supports the LE80578 (Vermilion Range) chipset
+
+config FB_CARILLO_RANCH
+ tristate "Intel Carillo Ranch support"
+ depends on FB_LE80578 && FB && PCI && X86
+ help
+ This driver supports the LE80578 (Carillo Ranch) board
+
+config FB_INTEL
+ tristate "Intel 830M/845G/852GM/855GM/865G/915G/945G/945GM/965G/965GM support"
+ depends on FB && PCI && X86 && AGP_INTEL && EXPERT
+ select FB_MODE_HELPERS
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select FB_BOOT_VESA_SUPPORT if FB_INTEL = y
+ depends on !DRM_I915
+ help
+ This driver supports the on-board graphics built in to the Intel
+ 830M/845G/852GM/855GM/865G/915G/915GM/945G/945GM/965G/965GM chipsets.
+ Say Y if you have and plan to use such a board.
+
+ To make FB_INTELFB=Y work you need to say AGP_INTEL=y too.
+
+ To compile this driver as a module, choose M here: the
+ module will be called intelfb.
+
+ For more information, please read <file:Documentation/fb/intelfb.txt>
+
+config FB_INTEL_DEBUG
+ bool "Intel driver Debug Messages"
+ depends on FB_INTEL
+ ---help---
+ Say Y here if you want the Intel driver to output all sorts
+ of debugging information to provide to the maintainer when
+ something goes wrong.
+
+config FB_INTEL_I2C
+ bool "DDC/I2C for Intel framebuffer support"
+ depends on FB_INTEL
+ select FB_DDC
+ default y
+ help
+ Say Y here if you want DDC/I2C support for your on-board Intel graphics.
+
+config FB_MATROX
+ tristate "Matrox acceleration"
+ depends on FB && PCI
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select FB_TILEBLITTING
+ select FB_MACMODES if PPC_PMAC
+ ---help---
+ Say Y here if you have a Matrox Millennium, Matrox Millennium II,
+ Matrox Mystique, Matrox Mystique 220, Matrox Productiva G100, Matrox
+ Mystique G200, Matrox Millennium G200, Matrox Marvel G200 video,
+ Matrox G400, G450 or G550 card in your box.
+
+ To compile this driver as a module, choose M here: the
+ module will be called matroxfb.
+
+ You can pass several parameters to the driver at boot time or at
+ module load time. The parameters look like "video=matroxfb:XXX", and
+ are described in <file:Documentation/fb/matroxfb.txt>.
+
+config FB_MATROX_MILLENIUM
+ bool "Millennium I/II support"
+ depends on FB_MATROX
+ help
+ Say Y here if you have a Matrox Millennium or Matrox Millennium II
+ video card. If you select "Advanced lowlevel driver options" below,
+ you should check 4 bpp packed pixel, 8 bpp packed pixel, 16 bpp
+ packed pixel, 24 bpp packed pixel and 32 bpp packed pixel. You can
+ also use font widths different from 8.
+
+config FB_MATROX_MYSTIQUE
+ bool "Mystique support"
+ depends on FB_MATROX
+ help
+ Say Y here if you have a Matrox Mystique or Matrox Mystique 220
+ video card. If you select "Advanced lowlevel driver options" below,
+ you should check 8 bpp packed pixel, 16 bpp packed pixel, 24 bpp
+ packed pixel and 32 bpp packed pixel. You can also use font widths
+ different from 8.
+
+config FB_MATROX_G
+ bool "G100/G200/G400/G450/G550 support"
+ depends on FB_MATROX
+ ---help---
+ Say Y here if you have a Matrox G100, G200, G400, G450 or G550 based
+ video card. If you select "Advanced lowlevel driver options", you
+ should check 8 bpp packed pixel, 16 bpp packed pixel, 24 bpp packed
+ pixel and 32 bpp packed pixel. You can also use font widths
+ different from 8.
+
+ If you need support for G400 secondary head, you must say Y to
+ "Matrox I2C support" and "G400 second head support" right below.
+ G450/G550 secondary head and digital output are supported without
+ additional modules.
+
+ The driver starts in monitor mode. You must use the matroxset tool
+ (available at <ftp://platan.vc.cvut.cz/pub/linux/matrox-latest/>) to
+ swap primary and secondary head outputs, or to change output mode.
+ Secondary head driver always start in 640x480 resolution and you
+ must use fbset to change it.
+
+ Do not forget that second head supports only 16 and 32 bpp
+ packed pixels, so it is a good idea to compile them into the kernel
+ too. You can use only some font widths, as the driver uses generic
+ painting procedures (the secondary head does not use acceleration
+ engine).
+
+ G450/G550 hardware can display TV picture only from secondary CRTC,
+ and it performs no scaling, so picture must have 525 or 625 lines.
+
+config FB_MATROX_I2C
+ tristate "Matrox I2C support"
+ depends on FB_MATROX
+ select FB_DDC
+ ---help---
+ This drivers creates I2C buses which are needed for accessing the
+ DDC (I2C) bus present on all Matroxes, an I2C bus which
+ interconnects Matrox optional devices, like MGA-TVO on G200 and
+ G400, and the secondary head DDC bus, present on G400 only.
+
+ You can say Y or M here if you want to experiment with monitor
+ detection code. You must say Y or M here if you want to use either
+ second head of G400 or MGA-TVO on G200 or G400.
+
+ If you compile it as module, it will create a module named
+ i2c-matroxfb.
+
+config FB_MATROX_MAVEN
+ tristate "G400 second head support"
+ depends on FB_MATROX_G && FB_MATROX_I2C
+ ---help---
+ WARNING !!! This support does not work with G450 !!!
+
+ Say Y or M here if you want to use a secondary head (meaning two
+ monitors in parallel) on G400 or MGA-TVO add-on on G200. Secondary
+ head is not compatible with accelerated XFree 3.3.x SVGA servers -
+ secondary head output is blanked while you are in X. With XFree
+ 3.9.17 preview you can use both heads if you use SVGA over fbdev or
+ the fbdev driver on first head and the fbdev driver on second head.
+
+ If you compile it as module, two modules are created,
+ matroxfb_crtc2 and matroxfb_maven. Matroxfb_maven is needed for
+ both G200 and G400, matroxfb_crtc2 is needed only by G400. You must
+ also load i2c-matroxfb to get it to run.
+
+ The driver starts in monitor mode and you must use the matroxset
+ tool (available at
+ <ftp://platan.vc.cvut.cz/pub/linux/matrox-latest/>) to switch it to
+ PAL or NTSC or to swap primary and secondary head outputs.
+ Secondary head driver also always start in 640x480 resolution, you
+ must use fbset to change it.
+
+ Also do not forget that second head supports only 16 and 32 bpp
+ packed pixels, so it is a good idea to compile them into the kernel
+ too. You can use only some font widths, as the driver uses generic
+ painting procedures (the secondary head does not use acceleration
+ engine).
+
+config FB_RADEON
+ tristate "ATI Radeon display support"
+ depends on FB && PCI
+ select FB_BACKLIGHT if FB_RADEON_BACKLIGHT
+ select FB_MODE_HELPERS
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select FB_MACMODES if PPC_OF
+ help
+ Choose this option if you want to use an ATI Radeon graphics card as
+ a framebuffer device. There are both PCI and AGP versions. You
+ don't need to choose this to run the Radeon in plain VGA mode.
+
+ There is a product page at
+ http://products.amd.com/en-us/GraphicCardResult.aspx
+
+config FB_RADEON_I2C
+ bool "DDC/I2C for ATI Radeon support"
+ depends on FB_RADEON
+ select FB_DDC
+ default y
+ help
+ Say Y here if you want DDC/I2C support for your Radeon board.
+
+config FB_RADEON_BACKLIGHT
+ bool "Support for backlight control"
+ depends on FB_RADEON
+ default y
+ help
+ Say Y here if you want to control the backlight of your display.
+
+config FB_RADEON_DEBUG
+ bool "Lots of debug output from Radeon driver"
+ depends on FB_RADEON
+ default n
+ help
+ Say Y here if you want the Radeon driver to output all sorts
+ of debugging information to provide to the maintainer when
+ something goes wrong.
+
+config FB_ATY128
+ tristate "ATI Rage128 display support"
+ depends on FB && PCI
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select FB_BACKLIGHT if FB_ATY128_BACKLIGHT
+ select FB_MACMODES if PPC_PMAC
+ help
+ This driver supports graphics boards with the ATI Rage128 chips.
+ Say Y if you have such a graphics board and read
+ <file:Documentation/fb/aty128fb.txt>.
+
+ To compile this driver as a module, choose M here: the
+ module will be called aty128fb.
+
+config FB_ATY128_BACKLIGHT
+ bool "Support for backlight control"
+ depends on FB_ATY128
+ default y
+ help
+ Say Y here if you want to control the backlight of your display.
+
+config FB_ATY
+ tristate "ATI Mach64 display support" if PCI || ATARI
+ depends on FB && !SPARC32
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select FB_BACKLIGHT if FB_ATY_BACKLIGHT
+ select FB_MACMODES if PPC
+ help
+ This driver supports graphics boards with the ATI Mach64 chips.
+ Say Y if you have such a graphics board.
+
+ To compile this driver as a module, choose M here: the
+ module will be called atyfb.
+
+config FB_ATY_CT
+ bool "Mach64 CT/VT/GT/LT (incl. 3D RAGE) support"
+ depends on PCI && FB_ATY
+ default y if SPARC64 && PCI
+ help
+ Say Y here to support use of ATI's 64-bit Rage boards (or other
+ boards based on the Mach64 CT, VT, GT, and LT chipsets) as a
+ framebuffer device. The ATI product support page for these boards
+ is at <http://support.ati.com/products/pc/mach64/mach64.html>.
+
+config FB_ATY_GENERIC_LCD
+ bool "Mach64 generic LCD support"
+ depends on FB_ATY_CT
+ help
+ Say Y if you have a laptop with an ATI Rage LT PRO, Rage Mobility,
+ Rage XC, or Rage XL chipset.
+
+config FB_ATY_GX
+ bool "Mach64 GX support" if PCI
+ depends on FB_ATY
+ default y if ATARI
+ help
+ Say Y here to support use of the ATI Mach64 Graphics Expression
+ board (or other boards based on the Mach64 GX chipset) as a
+ framebuffer device. The ATI product support page for these boards
+ is at
+ <http://support.ati.com/products/pc/mach64/graphics_xpression.html>.
+
+config FB_ATY_BACKLIGHT
+ bool "Support for backlight control"
+ depends on FB_ATY
+ default y
+ help
+ Say Y here if you want to control the backlight of your display.
+
+config FB_S3
+ tristate "S3 Trio/Virge support"
+ depends on FB && PCI
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select FB_TILEBLITTING
+ select FB_SVGALIB
+ select VGASTATE
+ select FONT_8x16 if FRAMEBUFFER_CONSOLE
+ ---help---
+ Driver for graphics boards with S3 Trio / S3 Virge chip.
+
+config FB_S3_DDC
+ bool "DDC for S3 support"
+ depends on FB_S3
+ select FB_DDC
+ default y
+ help
+ Say Y here if you want DDC support for your S3 graphics card.
+
+config FB_SAVAGE
+ tristate "S3 Savage support"
+ depends on FB && PCI
+ select FB_MODE_HELPERS
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select VGASTATE
+ help
+ This driver supports notebooks and computers with S3 Savage PCI/AGP
+ chips.
+
+ Say Y if you have such a graphics card.
+
+ To compile this driver as a module, choose M here; the module
+ will be called savagefb.
+
+config FB_SAVAGE_I2C
+ bool "Enable DDC2 Support"
+ depends on FB_SAVAGE
+ select FB_DDC
+ help
+ This enables I2C support for S3 Savage Chipsets. This is used
+ only for getting EDID information from the attached display
+ allowing for robust video mode handling and switching.
+
+ Because fbdev-2.6 requires that drivers must be able to
+ independently validate video mode parameters, you should say Y
+ here.
+
+config FB_SAVAGE_ACCEL
+ bool "Enable Console Acceleration"
+ depends on FB_SAVAGE
+ default n
+ help
+ This option will compile in console acceleration support. If
+ the resulting framebuffer console has bothersome glitches, then
+ choose N here.
+
+config FB_SIS
+ tristate "SiS/XGI display support"
+ depends on FB && PCI
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select FB_BOOT_VESA_SUPPORT if FB_SIS = y
+ help
+ This is the frame buffer device driver for the SiS 300, 315, 330
+ and 340 series as well as XGI V3XT, V5, V8, Z7 graphics chipsets.
+ Specs available at <http://www.sis.com> and <http://www.xgitech.com>.
+
+ To compile this driver as a module, choose M here; the module
+ will be called sisfb.
+
+config FB_SIS_300
+ bool "SiS 300 series support"
+ depends on FB_SIS
+ help
+ Say Y here to support use of the SiS 300/305, 540, 630 and 730.
+
+config FB_SIS_315
+ bool "SiS 315/330/340 series and XGI support"
+ depends on FB_SIS
+ help
+ Say Y here to support use of the SiS 315, 330 and 340 series
+ (315/H/PRO, 55x, 650, 651, 740, 330, 661, 741, 760, 761) as well
+ as XGI V3XT, V5, V8 and Z7.
+
+config FB_VIA
+ tristate "VIA UniChrome (Pro) and Chrome9 display support"
+ depends on FB && PCI && X86
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select I2C_ALGOBIT
+ select I2C
+ select GPIOLIB
+ help
+ This is the frame buffer device driver for Graphics chips of VIA
+ UniChrome (Pro) Family (CLE266,PM800/CN400,P4M800CE/P4M800Pro/
+ CN700/VN800,CX700/VX700,P4M890) and Chrome9 Family (K8M890,CN896
+ /P4M900,VX800)
+ Say Y if you have a VIA UniChrome graphics board.
+
+ To compile this driver as a module, choose M here: the
+ module will be called viafb.
+
+if FB_VIA
+
+config FB_VIA_DIRECT_PROCFS
+ bool "direct hardware access via procfs (DEPRECATED)(DANGEROUS)"
+ depends on FB_VIA
+ default n
+ help
+ Allow direct hardware access to some output registers via procfs.
+ This is dangerous but may provide the only chance to get the
+ correct output device configuration.
+ Its use is strongly discouraged.
+
+config FB_VIA_X_COMPATIBILITY
+ bool "X server compatibility"
+ depends on FB_VIA
+ default n
+ help
+ This option reduces the functionality (power saving, ...) of the
+ framebuffer to avoid negative impact on the OpenChrome X server.
+ If you use any X server other than fbdev you should enable this
+ otherwise it should be safe to disable it and allow using all
+ features.
+
+endif
+
+config FB_NEOMAGIC
+ tristate "NeoMagic display support"
+ depends on FB && PCI
+ select FB_MODE_HELPERS
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select VGASTATE
+ help
+ This driver supports notebooks with NeoMagic PCI chips.
+ Say Y if you have such a graphics card.
+
+ To compile this driver as a module, choose M here: the
+ module will be called neofb.
+
+config FB_KYRO
+ tristate "IMG Kyro support"
+ depends on FB && PCI
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ Say Y here if you have a STG4000 / Kyro / PowerVR 3 based
+ graphics board.
+
+ To compile this driver as a module, choose M here: the
+ module will be called kyrofb.
+
+config FB_3DFX
+ tristate "3Dfx Banshee/Voodoo3/Voodoo5 display support"
+ depends on FB && PCI
+ select FB_CFB_IMAGEBLIT
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_MODE_HELPERS
+ help
+ This driver supports graphics boards with the 3Dfx Banshee,
+ Voodoo3 or VSA-100 (aka Voodoo4/5) chips. Say Y if you have
+ such a graphics board.
+
+ To compile this driver as a module, choose M here: the
+ module will be called tdfxfb.
+
+config FB_3DFX_ACCEL
+ bool "3Dfx Acceleration functions"
+ depends on FB_3DFX
+ ---help---
+ This will compile the 3Dfx Banshee/Voodoo3/VSA-100 frame buffer
+ device driver with acceleration functions.
+
+config FB_3DFX_I2C
+ bool "Enable DDC/I2C support"
+ depends on FB_3DFX
+ select FB_DDC
+ default y
+ help
+ Say Y here if you want DDC/I2C support for your 3dfx Voodoo3.
+
+config FB_VOODOO1
+ tristate "3Dfx Voodoo Graphics (sst1) support"
+ depends on FB && PCI
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ ---help---
+ Say Y here if you have a 3Dfx Voodoo Graphics (Voodoo1/sst1) or
+ Voodoo2 (cvg) based graphics card.
+
+ To compile this driver as a module, choose M here: the
+ module will be called sstfb.
+
+ WARNING: Do not use any application that uses the 3D engine
+ (namely glide) while using this driver.
+ Please read the <file:Documentation/fb/sstfb.txt> for supported
+ options and other important info support.
+
+config FB_VT8623
+ tristate "VIA VT8623 support"
+ depends on FB && PCI
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select FB_TILEBLITTING
+ select FB_SVGALIB
+ select VGASTATE
+ select FONT_8x16 if FRAMEBUFFER_CONSOLE
+ ---help---
+ Driver for CastleRock integrated graphics core in the
+ VIA VT8623 [Apollo CLE266] chipset.
+
+config FB_TRIDENT
+ tristate "Trident/CyberXXX/CyberBlade support"
+ depends on FB && PCI
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ ---help---
+ This is the frame buffer device driver for Trident PCI/AGP chipsets.
+ Supported chipset families are TGUI 9440/96XX, 3DImage, Blade3D
+ and Blade XP.
+ There are also integrated versions of these chips called CyberXXXX,
+ CyberImage or CyberBlade. These chips are mostly found in laptops
+ but also on some motherboards including early VIA EPIA motherboards.
+ For more information, read <file:Documentation/fb/tridentfb.txt>
+
+ Say Y if you have such a graphics board.
+
+ To compile this driver as a module, choose M here: the
+ module will be called tridentfb.
+
+config FB_ARK
+ tristate "ARK 2000PV support"
+ depends on FB && PCI
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select FB_TILEBLITTING
+ select FB_SVGALIB
+ select VGASTATE
+ select FONT_8x16 if FRAMEBUFFER_CONSOLE
+ ---help---
+ Driver for PCI graphics boards with ARK 2000PV chip
+ and ICS 5342 RAMDAC.
+
+config FB_PM3
+ tristate "Permedia3 support"
+ depends on FB && PCI
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the frame buffer device driver for the 3DLabs Permedia3
+ chipset, used in Formac ProFormance III, 3DLabs Oxygen VX1 &
+ similar boards, 3DLabs Permedia3 Create!, Appian Jeronimo 2000
+ and maybe other boards.
+
+config FB_CARMINE
+ tristate "Fujitsu carmine frame buffer support"
+ depends on FB && PCI
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the frame buffer device driver for the Fujitsu Carmine chip.
+ The driver provides two independent frame buffer devices.
+
+choice
+ depends on FB_CARMINE
+ prompt "DRAM timing"
+ default FB_CARMINE_DRAM_EVAL
+
+config FB_CARMINE_DRAM_EVAL
+ bool "Eval board timings"
+ help
+ Use timings which work on the eval card.
+
+config CARMINE_DRAM_CUSTOM
+ bool "Custom board timings"
+ help
+ Use custom board timings.
+endchoice
+
+config FB_AU1100
+ bool "Au1100 LCD Driver"
+ depends on (FB = y) && MIPS_ALCHEMY
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the framebuffer driver for the AMD Au1100 SOC. It can drive
+ various panels and CRTs by passing in kernel cmd line option
+ au1100fb:panel=<name>.
+
+config FB_AU1200
+ bool "Au1200/Au1300 LCD Driver"
+ depends on (FB = y) && MIPS_ALCHEMY
+ select FB_SYS_FILLRECT
+ select FB_SYS_COPYAREA
+ select FB_SYS_IMAGEBLIT
+ select FB_SYS_FOPS
+ help
+ This is the framebuffer driver for the Au1200/Au1300 SOCs.
+ It can drive various panels and CRTs by passing in kernel cmd line
+ option au1200fb:panel=<name>.
+
+config FB_VT8500
+ bool "VIA VT8500 framebuffer support"
+ depends on (FB = y) && ARM && ARCH_VT8500
+ select FB_SYS_FILLRECT if (!FB_WMT_GE_ROPS)
+ select FB_SYS_COPYAREA if (!FB_WMT_GE_ROPS)
+ select FB_SYS_IMAGEBLIT
+ select FB_MODE_HELPERS
+ select VIDEOMODE_HELPERS
+ help
+ This is the framebuffer driver for VIA VT8500 integrated LCD
+ controller.
+
+config FB_WM8505
+ bool "Wondermedia WM8xxx-series frame buffer support"
+ depends on (FB = y) && ARM && ARCH_VT8500
+ select FB_SYS_FILLRECT if (!FB_WMT_GE_ROPS)
+ select FB_SYS_COPYAREA if (!FB_WMT_GE_ROPS)
+ select FB_SYS_IMAGEBLIT
+ select FB_MODE_HELPERS
+ select VIDEOMODE_HELPERS
+ help
+ This is the framebuffer driver for WonderMedia WM8xxx-series
+ integrated LCD controller. This driver covers the WM8505, WM8650
+ and WM8850 SoCs.
+
+config FB_WMT_GE_ROPS
+ bool "VT8500/WM8xxx accelerated raster ops support"
+ depends on (FB = y) && (FB_VT8500 || FB_WM8505)
+ default n
+ help
+ This adds support for accelerated raster operations on the
+ VIA VT8500 and Wondermedia 85xx series SoCs.
+
+source "drivers/video/fbdev/geode/Kconfig"
+
+config FB_HIT
+ tristate "HD64461 Frame Buffer support"
+ depends on FB && HD64461
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This is the frame buffer device driver for the Hitachi HD64461 LCD
+ frame buffer card.
+
+config FB_PMAG_AA
+ bool "PMAG-AA TURBOchannel framebuffer support"
+ depends on (FB = y) && TC
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ Support for the PMAG-AA TURBOchannel framebuffer card (1280x1024x1)
+ used mainly in the MIPS-based DECstation series.
+
+config FB_PMAG_BA
+ tristate "PMAG-BA TURBOchannel framebuffer support"
+ depends on FB && TC
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ Support for the PMAG-BA TURBOchannel framebuffer card (1024x864x8)
+ used mainly in the MIPS-based DECstation series.
+
+config FB_PMAGB_B
+ tristate "PMAGB-B TURBOchannel framebuffer support"
+ depends on FB && TC
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ Support for the PMAGB-B TURBOchannel framebuffer card used mainly
+ in the MIPS-based DECstation series. The card is currently only
+ supported in 1280x1024x8 mode.
+
+config FB_MAXINE
+ bool "Maxine (Personal DECstation) onboard framebuffer support"
+ depends on (FB = y) && MACH_DECSTATION
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ Support for the onboard framebuffer (1024x768x8) in the Personal
+ DECstation series (Personal DECstation 5000/20, /25, /33, /50,
+ Codename "Maxine").
+
+config FB_G364
+ bool "G364 frame buffer support"
+ depends on (FB = y) && (MIPS_MAGNUM_4000 || OLIVETTI_M700)
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ The G364 driver is the framebuffer used in MIPS Magnum 4000 and
+ Olivetti M700-10 systems.
+
+config FB_68328
+ bool "Motorola 68328 native frame buffer support"
+ depends on (FB = y) && (M68328 || M68EZ328 || M68VZ328)
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ Say Y here if you want to support the built-in frame buffer of
+ the Motorola 68328 CPU family.
+
+config FB_PXA168
+ tristate "PXA168/910 LCD framebuffer support"
+ depends on FB && (CPU_PXA168 || CPU_PXA910)
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ ---help---
+ Frame buffer driver for the built-in LCD controller in the Marvell
+ MMP processor.
+
+config FB_PXA
+ tristate "PXA LCD framebuffer support"
+ depends on FB && ARCH_PXA
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ ---help---
+ Frame buffer driver for the built-in LCD controller in the Intel
+ PXA2x0 processor.
+
+ This driver is also available as a module ( = code which can be
+ inserted and removed from the running kernel whenever you want). The
+ module will be called pxafb. If you want to compile it as a module,
+ say M here and read <file:Documentation/kbuild/modules.txt>.
+
+ If unsure, say N.
+
+config FB_PXA_OVERLAY
+ bool "Support PXA27x/PXA3xx Overlay(s) as framebuffer"
+ default n
+ depends on FB_PXA && (PXA27x || PXA3xx)
+
+config FB_PXA_SMARTPANEL
+ bool "PXA Smartpanel LCD support"
+ default n
+ depends on FB_PXA
+
+config FB_PXA_PARAMETERS
+ bool "PXA LCD command line parameters"
+ default n
+ depends on FB_PXA
+ ---help---
+ Enable the use of kernel command line or module parameters
+ to configure the physical properties of the LCD panel when
+ using the PXA LCD driver.
+
+ This option allows you to override the panel parameters
+ supplied by the platform in order to support multiple
+ different models of flatpanel. If you will only be using a
+ single model of flatpanel then you can safely leave this
+ option disabled.
+
+ <file:Documentation/fb/pxafb.txt> describes the available parameters.
+
+config PXA3XX_GCU
+ tristate "PXA3xx 2D graphics accelerator driver"
+ depends on FB_PXA
+ help
+ Kernelspace driver for the 2D graphics controller unit (GCU)
+ found on PXA3xx processors. There is a counterpart driver in the
+ DirectFB suite, see http://www.directfb.org/
+
+ If you compile this as a module, it will be called pxa3xx_gcu.
+
+config FB_MBX
+ tristate "2700G LCD framebuffer support"
+ depends on FB && ARCH_PXA
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ ---help---
+ Framebuffer driver for the Intel 2700G (Marathon) Graphics
+ Accelerator
+
+config FB_MBX_DEBUG
+ bool "Enable debugging info via debugfs"
+ depends on FB_MBX && DEBUG_FS
+ default n
+ ---help---
+ Enable this if you want debugging information using the debug
+ filesystem (debugfs)
+
+ If unsure, say N.
+
+config FB_FSL_DIU
+ tristate "Freescale DIU framebuffer support"
+ depends on FB && FSL_SOC
+ select FB_MODE_HELPERS
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select PPC_LIB_RHEAP
+ ---help---
+ Framebuffer driver for the Freescale SoC DIU
+
+config FB_W100
+ tristate "W100 frame buffer support"
+ depends on FB && ARCH_PXA
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ ---help---
+ Frame buffer driver for the w100 as found on the Sharp SL-Cxx series.
+ It can also drive the w3220 chip found on iPAQ hx4700.
+
+ This driver is also available as a module ( = code which can be
+ inserted and removed from the running kernel whenever you want). The
+ module will be called w100fb. If you want to compile it as a module,
+ say M here and read <file:Documentation/kbuild/modules.txt>.
+
+ If unsure, say N.
+
+config FB_SH_MOBILE_LCDC
+ tristate "SuperH Mobile LCDC framebuffer support"
+ depends on FB && (SUPERH || ARCH_SHMOBILE) && HAVE_CLK
+ select FB_SYS_FILLRECT
+ select FB_SYS_COPYAREA
+ select FB_SYS_IMAGEBLIT
+ select FB_SYS_FOPS
+ select FB_DEFERRED_IO
+ select FB_BACKLIGHT
+ select SH_MIPI_DSI if SH_LCD_MIPI_DSI
+ ---help---
+ Frame buffer driver for the on-chip SH-Mobile LCD controller.
+
+config FB_SH_MOBILE_HDMI
+ tristate "SuperH Mobile HDMI controller support"
+ depends on FB_SH_MOBILE_LCDC
+ select FB_MODE_HELPERS
+ select SOUND
+ select SND
+ select SND_SOC
+ ---help---
+ Driver for the on-chip SH-Mobile HDMI controller.
+
+config FB_TMIO
+ tristate "Toshiba Mobile IO FrameBuffer support"
+ depends on FB && MFD_CORE
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ ---help---
+ Frame buffer driver for the Toshiba Mobile IO integrated as found
+ on the Sharp SL-6000 series
+
+ This driver is also available as a module ( = code which can be
+ inserted and removed from the running kernel whenever you want). The
+ module will be called tmiofb. If you want to compile it as a module,
+ say M here and read <file:Documentation/kbuild/modules.txt>.
+
+ If unsure, say N.
+
+config FB_TMIO_ACCELL
+ bool "tmiofb acceleration"
+ depends on FB_TMIO
+ default y
+
+config FB_S3C
+ tristate "Samsung S3C framebuffer support"
+ depends on FB && (CPU_S3C2416 || ARCH_S3C64XX || ARCH_S5P64X0 || \
+ ARCH_S5PC100 || ARCH_S5PV210 || ARCH_EXYNOS)
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ ---help---
+ Frame buffer driver for the built-in FB controller in the Samsung
+ SoC line from the S3C2443 onwards, including the S3C2416, S3C2450,
+ and the S3C64XX series such as the S3C6400 and S3C6410.
+
+ These chips all have the same basic framebuffer design with the
+ actual capabilities depending on the chip. For instance the S3C6400
+ and S3C6410 support 4 hardware windows whereas the S3C24XX series
+ currently only have two.
+
+ Currently the support is only for the S3C6400 and S3C6410 SoCs.
+
+config FB_S3C_DEBUG_REGWRITE
+ bool "Debug register writes"
+ depends on FB_S3C
+ ---help---
+ Show all register writes via pr_debug()
+
+config FB_S3C2410
+ tristate "S3C2410 LCD framebuffer support"
+ depends on FB && ARCH_S3C24XX
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ ---help---
+ Frame buffer driver for the built-in LCD controller in the Samsung
+ S3C2410 processor.
+
+ This driver is also available as a module ( = code which can be
+ inserted and removed from the running kernel whenever you want). The
+ module will be called s3c2410fb. If you want to compile it as a module,
+ say M here and read <file:Documentation/kbuild/modules.txt>.
+
+ If unsure, say N.
+config FB_S3C2410_DEBUG
+ bool "S3C2410 lcd debug messages"
+ depends on FB_S3C2410
+ help
+ Turn on debugging messages. Note that you can set/unset at run time
+ through sysfs
+
+config FB_NUC900
+ bool "NUC900 LCD framebuffer support"
+ depends on FB && ARCH_W90X900
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ ---help---
+ Frame buffer driver for the built-in LCD controller in the Nuvoton
+ NUC900 processor
+
+config GPM1040A0_320X240
+ bool "Giantplus Technology GPM1040A0 320x240 Color TFT LCD"
+ depends on FB_NUC900
+
+config FB_SM501
+ tristate "Silicon Motion SM501 framebuffer support"
+ depends on FB && MFD_SM501
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ ---help---
+ Frame buffer driver for the CRT and LCD controllers in the Silicon
+ Motion SM501.
+
+ This driver is also available as a module ( = code which can be
+ inserted and removed from the running kernel whenever you want). The
+ module will be called sm501fb. If you want to compile it as a module,
+ say M here and read <file:Documentation/kbuild/modules.txt>.
+
+ If unsure, say N.
+
+config FB_SMSCUFX
+ tristate "SMSC UFX6000/7000 USB Framebuffer support"
+ depends on FB && USB
+ select FB_MODE_HELPERS
+ select FB_SYS_FILLRECT
+ select FB_SYS_COPYAREA
+ select FB_SYS_IMAGEBLIT
+ select FB_SYS_FOPS
+ select FB_DEFERRED_IO
+ ---help---
+ This is a kernel framebuffer driver for SMSC UFX USB devices.
+ Supports fbdev clients like xf86-video-fbdev, kdrive, fbi, and
+ mplayer -vo fbdev. Supports both UFX6000 (USB 2.0) and UFX7000
+ (USB 3.0) devices.
+ To compile as a module, choose M here: the module name is smscufx.
+
+config FB_UDL
+ tristate "Displaylink USB Framebuffer support"
+ depends on FB && USB
+ select FB_MODE_HELPERS
+ select FB_SYS_FILLRECT
+ select FB_SYS_COPYAREA
+ select FB_SYS_IMAGEBLIT
+ select FB_SYS_FOPS
+ select FB_DEFERRED_IO
+ ---help---
+ This is a kernel framebuffer driver for DisplayLink USB devices.
+ Supports fbdev clients like xf86-video-fbdev, kdrive, fbi, and
+ mplayer -vo fbdev. Supports all USB 2.0 era DisplayLink devices.
+ To compile as a module, choose M here: the module name is udlfb.
+
+config FB_IBM_GXT4500
+ tristate "Framebuffer support for IBM GXT4000P/4500P/6000P/6500P adaptors"
+ depends on FB && PPC
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ ---help---
+ Say Y here to enable support for the IBM GXT4000P/6000P and
+ GXT4500P/6500P display adaptor based on Raster Engine RC1000,
+ found on some IBM System P (pSeries) machines. This driver
+ doesn't use Geometry Engine GT1000.
+
+config FB_PS3
+ tristate "PS3 GPU framebuffer driver"
+ depends on FB && PS3_PS3AV
+ select FB_SYS_FILLRECT
+ select FB_SYS_COPYAREA
+ select FB_SYS_IMAGEBLIT
+ select FB_SYS_FOPS
+ select VT_HW_CONSOLE_BINDING if FRAMEBUFFER_CONSOLE
+ ---help---
+ Include support for the virtual frame buffer in the PS3 platform.
+
+config FB_PS3_DEFAULT_SIZE_M
+ int "PS3 default frame buffer size (in MiB)"
+ depends on FB_PS3
+ default 9
+ ---help---
+ This is the default size (in MiB) of the virtual frame buffer in
+ the PS3.
+ The default value can be overridden on the kernel command line
+ using the "ps3fb" option (e.g. "ps3fb=9M");
+
+config FB_XILINX
+ tristate "Xilinx frame buffer support"
+ depends on FB && (XILINX_VIRTEX || MICROBLAZE || ARCH_ZYNQ)
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ ---help---
+ Include support for the Xilinx ML300/ML403 reference design
+ framebuffer. ML300 carries a 640*480 LCD display on the board,
+ ML403 uses a standard DB15 VGA connector.
+
+config FB_GOLDFISH
+ tristate "Goldfish Framebuffer"
+ depends on FB && HAS_DMA
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ ---help---
+ Framebuffer driver for Goldfish Virtual Platform
+
+config FB_COBALT
+ tristate "Cobalt server LCD frame buffer support"
+ depends on FB && (MIPS_COBALT || MIPS_SEAD3)
+
+config FB_SH7760
+ bool "SH7760/SH7763/SH7720/SH7721 LCDC support"
+ depends on FB && (CPU_SUBTYPE_SH7760 || CPU_SUBTYPE_SH7763 \
+ || CPU_SUBTYPE_SH7720 || CPU_SUBTYPE_SH7721)
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ ---help---
+ Support for the SH7760/SH7763/SH7720/SH7721 integrated
+ (D)STN/TFT LCD Controller.
+ Supports display resolutions up to 1024x1024 pixel, grayscale and
+ color operation, with depths ranging from 1 bpp to 8 bpp monochrome
+ and 8, 15 or 16 bpp color; 90 degrees clockwise display rotation for
+ panels <= 320 pixel horizontal resolution.
+
+config FB_DA8XX
+ tristate "DA8xx/OMAP-L1xx/AM335x Framebuffer support"
+ depends on FB && (ARCH_DAVINCI_DA8XX || SOC_AM33XX)
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select FB_CFB_REV_PIXELS_IN_BYTE
+ select FB_MODE_HELPERS
+ select VIDEOMODE_HELPERS
+ ---help---
+ This is the frame buffer device driver for the TI LCD controller
+ found on DA8xx/OMAP-L1xx/AM335x SoCs.
+ If unsure, say N.
+
+config FB_VIRTUAL
+ tristate "Virtual Frame Buffer support (ONLY FOR TESTING!)"
+ depends on FB
+ select FB_SYS_FILLRECT
+ select FB_SYS_COPYAREA
+ select FB_SYS_IMAGEBLIT
+ select FB_SYS_FOPS
+ ---help---
+ This is a `virtual' frame buffer device. It operates on a chunk of
+ unswappable kernel memory instead of on the memory of a graphics
+ board. This means you cannot see any output sent to this frame
+ buffer device, while it does consume precious memory. The main use
+ of this frame buffer device is testing and debugging the frame
+ buffer subsystem. Do NOT enable it for normal systems! To protect
+ the innocent, it has to be enabled explicitly at boot time using the
+ kernel option `video=vfb:'.
+
+ To compile this driver as a module, choose M here: the
+ module will be called vfb. In order to load it, you must use
+ the vfb_enable=1 option.
+
+ If unsure, say N.
+
+config XEN_FBDEV_FRONTEND
+ tristate "Xen virtual frame buffer support"
+ depends on FB && XEN
+ select FB_SYS_FILLRECT
+ select FB_SYS_COPYAREA
+ select FB_SYS_IMAGEBLIT
+ select FB_SYS_FOPS
+ select FB_DEFERRED_IO
+ select INPUT_XEN_KBDDEV_FRONTEND if INPUT_MISC
+ select XEN_XENBUS_FRONTEND
+ default y
+ help
+ This driver implements the front-end of the Xen virtual
+ frame buffer driver. It communicates with a back-end
+ in another domain.
+
+config FB_METRONOME
+ tristate "E-Ink Metronome/8track controller support"
+ depends on FB
+ select FB_SYS_FILLRECT
+ select FB_SYS_COPYAREA
+ select FB_SYS_IMAGEBLIT
+ select FB_SYS_FOPS
+ select FB_DEFERRED_IO
+ help
+ This driver implements support for the E-Ink Metronome
+ controller. The pre-release name for this device was 8track
+ and could also have been called by some vendors as PVI-nnnn.
+
+config FB_MB862XX
+ tristate "Fujitsu MB862xx GDC support"
+ depends on FB
+ depends on PCI || (OF && PPC)
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ ---help---
+ Frame buffer driver for Fujitsu Carmine/Coral-P(A)/Lime controllers.
+
+choice
+ prompt "GDC variant"
+ depends on FB_MB862XX
+
+config FB_MB862XX_PCI_GDC
+ bool "Carmine/Coral-P(A) GDC"
+ depends on PCI
+ ---help---
+ This enables framebuffer support for Fujitsu Carmine/Coral-P(A)
+ PCI graphics controller devices.
+
+config FB_MB862XX_LIME
+ bool "Lime GDC"
+ depends on OF && PPC
+ select FB_FOREIGN_ENDIAN
+ select FB_LITTLE_ENDIAN
+ ---help---
+ Framebuffer support for Fujitsu Lime GDC on host CPU bus.
+
+endchoice
+
+config FB_MB862XX_I2C
+ bool "Support I2C bus on MB862XX GDC"
+ depends on FB_MB862XX && I2C
+ default y
+ help
+ Selecting this option adds Coral-P(A)/Lime GDC I2C bus adapter
+ driver to support accessing I2C devices on controller's I2C bus.
+ These are usually some video decoder chips.
+
+config FB_EP93XX
+ tristate "EP93XX frame buffer support"
+ depends on FB && ARCH_EP93XX
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ ---help---
+ Framebuffer driver for the Cirrus Logic EP93XX series of processors.
+ This driver is also available as a module. The module will be called
+ ep93xx-fb.
+
+config FB_PRE_INIT_FB
+ bool "Don't reinitialize, use bootloader's GDC/Display configuration"
+ depends on FB && FB_MB862XX_LIME
+ ---help---
+ Select this option if display contents should be inherited as set by
+ the bootloader.
+
+config FB_MSM
+ tristate "MSM Framebuffer support"
+ depends on FB && ARCH_MSM
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+
+config FB_MX3
+ tristate "MX3 Framebuffer support"
+ depends on FB && MX3_IPU
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ default y
+ help
+ This is a framebuffer device for the i.MX31 LCD Controller. So
+ far only synchronous displays are supported. If you plan to use
+ an LCD display with your i.MX31 system, say Y here.
+
+config FB_BROADSHEET
+ tristate "E-Ink Broadsheet/Epson S1D13521 controller support"
+ depends on FB
+ select FB_SYS_FILLRECT
+ select FB_SYS_COPYAREA
+ select FB_SYS_IMAGEBLIT
+ select FB_SYS_FOPS
+ select FB_DEFERRED_IO
+ help
+ This driver implements support for the E-Ink Broadsheet
+ controller. The release name for this device was Epson S1D13521
+ and could also have been called by other names when coupled with
+ a bridge adapter.
+
+config FB_AUO_K190X
+ tristate "AUO-K190X EPD controller support"
+ depends on FB
+ select FB_SYS_FILLRECT
+ select FB_SYS_COPYAREA
+ select FB_SYS_IMAGEBLIT
+ select FB_SYS_FOPS
+ select FB_DEFERRED_IO
+ help
+ Provides support for epaper controllers from the K190X series
+ of AUO. These controllers can be used to drive epaper displays
+ from Sipix.
+
+ This option enables the common support, shared by the individual
+ controller drivers. You will also have to enable the driver
+ for the controller type used in your device.
+
+config FB_AUO_K1900
+ tristate "AUO-K1900 EPD controller support"
+ depends on FB && FB_AUO_K190X
+ help
+ This driver implements support for the AUO K1900 epd-controller.
+ This controller can drive Sipix epaper displays but can only do
+ serial updates, reducing the number of possible frames per second.
+
+config FB_AUO_K1901
+ tristate "AUO-K1901 EPD controller support"
+ depends on FB && FB_AUO_K190X
+ help
+ This driver implements support for the AUO K1901 epd-controller.
+ This controller can drive Sipix epaper displays and supports
+ concurrent updates, making higher frames per second possible.
+
+config FB_JZ4740
+ tristate "JZ4740 LCD framebuffer support"
+ depends on FB && MACH_JZ4740
+ select FB_SYS_FILLRECT
+ select FB_SYS_COPYAREA
+ select FB_SYS_IMAGEBLIT
+ help
+ Framebuffer support for the JZ4740 SoC.
+
+config FB_MXS
+ tristate "MXS LCD framebuffer support"
+ depends on FB && ARCH_MXS
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ select FB_MODE_HELPERS
+ select VIDEOMODE_HELPERS
+ help
+ Framebuffer support for the MXS SoC.
+
+config FB_PUV3_UNIGFX
+ tristate "PKUnity v3 Unigfx framebuffer support"
+ depends on FB && UNICORE32 && ARCH_PUV3
+ select FB_SYS_FILLRECT
+ select FB_SYS_COPYAREA
+ select FB_SYS_IMAGEBLIT
+ select FB_SYS_FOPS
+ help
+ Choose this option if you want to use the Unigfx device as a
+ framebuffer device. Without the support of PCI & AGP.
+
+config FB_HYPERV
+ tristate "Microsoft Hyper-V Synthetic Video support"
+ depends on FB && HYPERV
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ This framebuffer driver supports Microsoft Hyper-V Synthetic Video.
+
+config FB_SIMPLE
+ bool "Simple framebuffer support"
+ depends on (FB = y)
+ select FB_CFB_FILLRECT
+ select FB_CFB_COPYAREA
+ select FB_CFB_IMAGEBLIT
+ help
+ Say Y if you want support for a simple frame-buffer.
+
+ This driver assumes that the display hardware has been initialized
+ before the kernel boots, and the kernel will simply render to the
+ pre-allocated frame buffer surface.
+
+ Configuration re: surface address, size, and format must be provided
+ through device tree, or plain old platform data.
+
+source "drivers/video/fbdev/omap/Kconfig"
+source "drivers/video/fbdev/omap2/Kconfig"
+source "drivers/video/fbdev/exynos/Kconfig"
+source "drivers/video/fbdev/mmp/Kconfig"
+
+config FB_SH_MOBILE_MERAM
+ tristate "SuperH Mobile MERAM read ahead support"
+ depends on (SUPERH || ARCH_SHMOBILE)
+ select GENERIC_ALLOCATOR
+ ---help---
+ Enable MERAM support for the SuperH controller.
+
+ This will allow for caching of the framebuffer to provide more
+ reliable access under heavy main memory bus traffic situations.
+ Up to 4 memory channels can be configured, allowing 4 RGB or
+ 2 YCbCr framebuffers to be configured.
+
+config FB_SSD1307
+ tristate "Solomon SSD1307 framebuffer support"
+ depends on FB && I2C
+ depends on OF
+ depends on GPIOLIB
+ select FB_SYS_FOPS
+ select FB_SYS_FILLRECT
+ select FB_SYS_COPYAREA
+ select FB_SYS_IMAGEBLIT
+ select FB_DEFERRED_IO
+ select PWM
+ help
+ This driver implements support for the Solomon SSD1307
+ OLED controller over I2C.
diff --git a/drivers/video/fbdev/Makefile b/drivers/video/fbdev/Makefile
new file mode 100644
index 0000000..0284f2a
--- /dev/null
+++ b/drivers/video/fbdev/Makefile
@@ -0,0 +1,152 @@
+# Makefile for the Linux video drivers.
+# 5 Aug 1999, James Simmons, <mailto:jsimmons@users.sf.net>
+# Rewritten to use lists instead of if-statements.
+
+# Each configuration option enables a list of files.
+
+obj-y += core/
+
+obj-$(CONFIG_EXYNOS_VIDEO) += exynos/
+
+obj-$(CONFIG_FB_MACMODES) += macmodes.o
+obj-$(CONFIG_FB_WMT_GE_ROPS) += wmt_ge_rops.o
+
+# Hardware specific drivers go first
+obj-$(CONFIG_FB_AMIGA) += amifb.o c2p_planar.o
+obj-$(CONFIG_FB_ARC) += arcfb.o
+obj-$(CONFIG_FB_CLPS711X) += clps711xfb.o
+obj-$(CONFIG_FB_CYBER2000) += cyber2000fb.o
+obj-$(CONFIG_FB_GRVGA) += grvga.o
+obj-$(CONFIG_FB_PM2) += pm2fb.o
+obj-$(CONFIG_FB_PM3) += pm3fb.o
+
+obj-$(CONFIG_FB_I740) += i740fb.o
+obj-$(CONFIG_FB_MATROX) += matrox/
+obj-$(CONFIG_FB_RIVA) += riva/
+obj-$(CONFIG_FB_NVIDIA) += nvidia/
+obj-$(CONFIG_FB_ATY) += aty/ macmodes.o
+obj-$(CONFIG_FB_ATY128) += aty/ macmodes.o
+obj-$(CONFIG_FB_RADEON) += aty/
+obj-$(CONFIG_FB_SIS) += sis/
+obj-$(CONFIG_FB_VIA) += via/
+obj-$(CONFIG_FB_KYRO) += kyro/
+obj-$(CONFIG_FB_SAVAGE) += savage/
+obj-$(CONFIG_FB_GEODE) += geode/
+obj-$(CONFIG_FB_MBX) += mbx/
+obj-$(CONFIG_FB_NEOMAGIC) += neofb.o
+obj-$(CONFIG_FB_3DFX) += tdfxfb.o
+obj-$(CONFIG_FB_CONTROL) += controlfb.o
+obj-$(CONFIG_FB_PLATINUM) += platinumfb.o
+obj-$(CONFIG_FB_VALKYRIE) += valkyriefb.o
+obj-$(CONFIG_FB_CT65550) += chipsfb.o
+obj-$(CONFIG_FB_IMSTT) += imsttfb.o
+obj-$(CONFIG_FB_FM2) += fm2fb.o
+obj-$(CONFIG_FB_VT8623) += vt8623fb.o
+obj-$(CONFIG_FB_TRIDENT) += tridentfb.o
+obj-$(CONFIG_FB_LE80578) += vermilion/
+obj-$(CONFIG_FB_S3) += s3fb.o
+obj-$(CONFIG_FB_ARK) += arkfb.o
+obj-$(CONFIG_FB_STI) += stifb.o
+obj-$(CONFIG_FB_FFB) += ffb.o sbuslib.o
+obj-$(CONFIG_FB_CG6) += cg6.o sbuslib.o
+obj-$(CONFIG_FB_CG3) += cg3.o sbuslib.o
+obj-$(CONFIG_FB_BW2) += bw2.o sbuslib.o
+obj-$(CONFIG_FB_CG14) += cg14.o sbuslib.o
+obj-$(CONFIG_FB_P9100) += p9100.o sbuslib.o
+obj-$(CONFIG_FB_TCX) += tcx.o sbuslib.o
+obj-$(CONFIG_FB_LEO) += leo.o sbuslib.o
+obj-$(CONFIG_FB_ACORN) += acornfb.o
+obj-$(CONFIG_FB_ATARI) += atafb.o c2p_iplan2.o atafb_mfb.o \
+ atafb_iplan2p2.o atafb_iplan2p4.o atafb_iplan2p8.o
+obj-$(CONFIG_FB_MAC) += macfb.o
+obj-$(CONFIG_FB_HECUBA) += hecubafb.o
+obj-$(CONFIG_FB_N411) += n411.o
+obj-$(CONFIG_FB_HGA) += hgafb.o
+obj-$(CONFIG_FB_XVR500) += sunxvr500.o
+obj-$(CONFIG_FB_XVR2500) += sunxvr2500.o
+obj-$(CONFIG_FB_XVR1000) += sunxvr1000.o
+obj-$(CONFIG_FB_IGA) += igafb.o
+obj-$(CONFIG_FB_APOLLO) += dnfb.o
+obj-$(CONFIG_FB_Q40) += q40fb.o
+obj-$(CONFIG_FB_TGA) += tgafb.o
+obj-$(CONFIG_FB_HP300) += hpfb.o
+obj-$(CONFIG_FB_G364) += g364fb.o
+obj-$(CONFIG_FB_EP93XX) += ep93xx-fb.o
+obj-$(CONFIG_FB_SA1100) += sa1100fb.o
+obj-$(CONFIG_FB_HIT) += hitfb.o
+obj-$(CONFIG_FB_ATMEL) += atmel_lcdfb.o
+obj-$(CONFIG_FB_PVR2) += pvr2fb.o
+obj-$(CONFIG_FB_VOODOO1) += sstfb.o
+obj-$(CONFIG_FB_ARMCLCD) += amba-clcd.o
+obj-$(CONFIG_FB_GOLDFISH) += goldfishfb.o
+obj-$(CONFIG_FB_68328) += 68328fb.o
+obj-$(CONFIG_FB_GBE) += gbefb.o
+obj-$(CONFIG_FB_CIRRUS) += cirrusfb.o
+obj-$(CONFIG_FB_ASILIANT) += asiliantfb.o
+obj-$(CONFIG_FB_PXA) += pxafb.o
+obj-$(CONFIG_FB_PXA168) += pxa168fb.o
+obj-$(CONFIG_PXA3XX_GCU) += pxa3xx-gcu.o
+obj-$(CONFIG_MMP_DISP) += mmp/
+obj-$(CONFIG_FB_W100) += w100fb.o
+obj-$(CONFIG_FB_TMIO) += tmiofb.o
+obj-$(CONFIG_FB_AU1100) += au1100fb.o
+obj-$(CONFIG_FB_AU1200) += au1200fb.o
+obj-$(CONFIG_FB_VT8500) += vt8500lcdfb.o
+obj-$(CONFIG_FB_WM8505) += wm8505fb.o
+obj-$(CONFIG_FB_PMAG_AA) += pmag-aa-fb.o
+obj-$(CONFIG_FB_PMAG_BA) += pmag-ba-fb.o
+obj-$(CONFIG_FB_PMAGB_B) += pmagb-b-fb.o
+obj-$(CONFIG_FB_MAXINE) += maxinefb.o
+obj-$(CONFIG_FB_METRONOME) += metronomefb.o
+obj-$(CONFIG_FB_BROADSHEET) += broadsheetfb.o
+obj-$(CONFIG_FB_AUO_K190X) += auo_k190x.o
+obj-$(CONFIG_FB_AUO_K1900) += auo_k1900fb.o
+obj-$(CONFIG_FB_AUO_K1901) += auo_k1901fb.o
+obj-$(CONFIG_FB_S1D13XXX) += s1d13xxxfb.o
+obj-$(CONFIG_FB_SH7760) += sh7760fb.o
+obj-$(CONFIG_FB_IMX) += imxfb.o
+obj-$(CONFIG_FB_S3C) += s3c-fb.o
+obj-$(CONFIG_FB_S3C2410) += s3c2410fb.o
+obj-$(CONFIG_FB_FSL_DIU) += fsl-diu-fb.o
+obj-$(CONFIG_FB_COBALT) += cobalt_lcdfb.o
+obj-$(CONFIG_FB_IBM_GXT4500) += gxt4500.o
+obj-$(CONFIG_FB_PS3) += ps3fb.o
+obj-$(CONFIG_FB_SM501) += sm501fb.o
+obj-$(CONFIG_FB_UDL) += udlfb.o
+obj-$(CONFIG_FB_SMSCUFX) += smscufx.o
+obj-$(CONFIG_FB_XILINX) += xilinxfb.o
+obj-$(CONFIG_SH_MIPI_DSI) += sh_mipi_dsi.o
+obj-$(CONFIG_FB_SH_MOBILE_HDMI) += sh_mobile_hdmi.o
+obj-$(CONFIG_FB_SH_MOBILE_MERAM) += sh_mobile_meram.o
+obj-$(CONFIG_FB_SH_MOBILE_LCDC) += sh_mobile_lcdcfb.o
+obj-$(CONFIG_FB_OMAP) += omap/
+obj-y += omap2/
+obj-$(CONFIG_XEN_FBDEV_FRONTEND) += xen-fbfront.o
+obj-$(CONFIG_FB_CARMINE) += carminefb.o
+obj-$(CONFIG_FB_MB862XX) += mb862xx/
+obj-$(CONFIG_FB_MSM) += msm/
+obj-$(CONFIG_FB_NUC900) += nuc900fb.o
+obj-$(CONFIG_FB_JZ4740) += jz4740_fb.o
+obj-$(CONFIG_FB_PUV3_UNIGFX) += fb-puv3.o
+obj-$(CONFIG_FB_HYPERV) += hyperv_fb.o
+obj-$(CONFIG_FB_OPENCORES) += ocfb.o
+
+# Platform or fallback drivers go here
+obj-$(CONFIG_FB_UVESA) += uvesafb.o
+obj-$(CONFIG_FB_VESA) += vesafb.o
+obj-$(CONFIG_FB_EFI) += efifb.o
+obj-$(CONFIG_FB_VGA16) += vga16fb.o
+obj-$(CONFIG_FB_OF) += offb.o
+obj-$(CONFIG_FB_BF537_LQ035) += bf537-lq035.o
+obj-$(CONFIG_FB_BF54X_LQ043) += bf54x-lq043fb.o
+obj-$(CONFIG_FB_BFIN_LQ035Q1) += bfin-lq035q1-fb.o
+obj-$(CONFIG_FB_BFIN_T350MCQB) += bfin-t350mcqb-fb.o
+obj-$(CONFIG_FB_BFIN_7393) += bfin_adv7393fb.o
+obj-$(CONFIG_FB_MX3) += mx3fb.o
+obj-$(CONFIG_FB_DA8XX) += da8xx-fb.o
+obj-$(CONFIG_FB_MXS) += mxsfb.o
+obj-$(CONFIG_FB_SSD1307) += ssd1307fb.o
+obj-$(CONFIG_FB_SIMPLE) += simplefb.o
+
+# the test framebuffer is last
+obj-$(CONFIG_FB_VIRTUAL) += vfb.o
diff --git a/drivers/video/acornfb.c b/drivers/video/fbdev/acornfb.c
index a305cae..a305cae 100644
--- a/drivers/video/acornfb.c
+++ b/drivers/video/fbdev/acornfb.c
diff --git a/drivers/video/acornfb.h b/drivers/video/fbdev/acornfb.h
index 175c8ff..175c8ff 100644
--- a/drivers/video/acornfb.h
+++ b/drivers/video/fbdev/acornfb.h
diff --git a/drivers/video/amba-clcd.c b/drivers/video/fbdev/amba-clcd.c
index 14d6b37..14d6b37 100644
--- a/drivers/video/amba-clcd.c
+++ b/drivers/video/fbdev/amba-clcd.c
diff --git a/drivers/video/amifb.c b/drivers/video/fbdev/amifb.c
index 518f790..518f790 100644
--- a/drivers/video/amifb.c
+++ b/drivers/video/fbdev/amifb.c
diff --git a/drivers/video/arcfb.c b/drivers/video/fbdev/arcfb.c
index 1b0b233..1b0b233 100644
--- a/drivers/video/arcfb.c
+++ b/drivers/video/fbdev/arcfb.c
diff --git a/drivers/video/arkfb.c b/drivers/video/fbdev/arkfb.c
index adc4ea2..adc4ea2 100644
--- a/drivers/video/arkfb.c
+++ b/drivers/video/fbdev/arkfb.c
diff --git a/drivers/video/asiliantfb.c b/drivers/video/fbdev/asiliantfb.c
index 7e8ddf0..7e8ddf0 100644
--- a/drivers/video/asiliantfb.c
+++ b/drivers/video/fbdev/asiliantfb.c
diff --git a/drivers/video/atafb.c b/drivers/video/fbdev/atafb.c
index e21d1f5..e21d1f5 100644
--- a/drivers/video/atafb.c
+++ b/drivers/video/fbdev/atafb.c
diff --git a/drivers/video/atafb.h b/drivers/video/fbdev/atafb.h
index 014e059..014e059 100644
--- a/drivers/video/atafb.h
+++ b/drivers/video/fbdev/atafb.h
diff --git a/drivers/video/atafb_iplan2p2.c b/drivers/video/fbdev/atafb_iplan2p2.c
index 8cc9c50..8cc9c50 100644
--- a/drivers/video/atafb_iplan2p2.c
+++ b/drivers/video/fbdev/atafb_iplan2p2.c
diff --git a/drivers/video/atafb_iplan2p4.c b/drivers/video/fbdev/atafb_iplan2p4.c
index bee0d89..bee0d89 100644
--- a/drivers/video/atafb_iplan2p4.c
+++ b/drivers/video/fbdev/atafb_iplan2p4.c
diff --git a/drivers/video/atafb_iplan2p8.c b/drivers/video/fbdev/atafb_iplan2p8.c
index 356fb52..356fb52 100644
--- a/drivers/video/atafb_iplan2p8.c
+++ b/drivers/video/fbdev/atafb_iplan2p8.c
diff --git a/drivers/video/atafb_mfb.c b/drivers/video/fbdev/atafb_mfb.c
index 6a352d6..6a352d6 100644
--- a/drivers/video/atafb_mfb.c
+++ b/drivers/video/fbdev/atafb_mfb.c
diff --git a/drivers/video/atafb_utils.h b/drivers/video/fbdev/atafb_utils.h
index ac9e19d..ac9e19d 100644
--- a/drivers/video/atafb_utils.h
+++ b/drivers/video/fbdev/atafb_utils.h
diff --git a/drivers/video/atmel_lcdfb.c b/drivers/video/fbdev/atmel_lcdfb.c
index e683b6e..e683b6e 100644
--- a/drivers/video/atmel_lcdfb.c
+++ b/drivers/video/fbdev/atmel_lcdfb.c
diff --git a/drivers/video/aty/Makefile b/drivers/video/fbdev/aty/Makefile
index a6cc0e9..a6cc0e9 100644
--- a/drivers/video/aty/Makefile
+++ b/drivers/video/fbdev/aty/Makefile
diff --git a/drivers/video/aty/ati_ids.h b/drivers/video/fbdev/aty/ati_ids.h
index 3e9d28b..3e9d28b 100644
--- a/drivers/video/aty/ati_ids.h
+++ b/drivers/video/fbdev/aty/ati_ids.h
diff --git a/drivers/video/aty/aty128fb.c b/drivers/video/fbdev/aty/aty128fb.c
index 52108be..52108be 100644
--- a/drivers/video/aty/aty128fb.c
+++ b/drivers/video/fbdev/aty/aty128fb.c
diff --git a/drivers/video/aty/atyfb.h b/drivers/video/fbdev/aty/atyfb.h
index 1f39a62..1f39a62 100644
--- a/drivers/video/aty/atyfb.h
+++ b/drivers/video/fbdev/aty/atyfb.h
diff --git a/drivers/video/aty/atyfb_base.c b/drivers/video/fbdev/aty/atyfb_base.c
index c3d0074..c3d0074 100644
--- a/drivers/video/aty/atyfb_base.c
+++ b/drivers/video/fbdev/aty/atyfb_base.c
diff --git a/drivers/video/aty/mach64_accel.c b/drivers/video/fbdev/aty/mach64_accel.c
index 182bd68..182bd68 100644
--- a/drivers/video/aty/mach64_accel.c
+++ b/drivers/video/fbdev/aty/mach64_accel.c
diff --git a/drivers/video/aty/mach64_ct.c b/drivers/video/fbdev/aty/mach64_ct.c
index 51f29d6..51f29d6 100644
--- a/drivers/video/aty/mach64_ct.c
+++ b/drivers/video/fbdev/aty/mach64_ct.c
diff --git a/drivers/video/aty/mach64_cursor.c b/drivers/video/fbdev/aty/mach64_cursor.c
index 0fe02e2..2fa0317 100644
--- a/drivers/video/aty/mach64_cursor.c
+++ b/drivers/video/fbdev/aty/mach64_cursor.c
@@ -5,7 +5,7 @@
#include <linux/fb.h>
#include <linux/init.h>
#include <linux/string.h>
-#include "../fb_draw.h"
+#include "../core/fb_draw.h"
#include <asm/io.h>
diff --git a/drivers/video/aty/mach64_gx.c b/drivers/video/fbdev/aty/mach64_gx.c
index 10c988a..10c988a 100644
--- a/drivers/video/aty/mach64_gx.c
+++ b/drivers/video/fbdev/aty/mach64_gx.c
diff --git a/drivers/video/aty/radeon_accel.c b/drivers/video/fbdev/aty/radeon_accel.c
index a469a3d..a469a3d 100644
--- a/drivers/video/aty/radeon_accel.c
+++ b/drivers/video/fbdev/aty/radeon_accel.c
diff --git a/drivers/video/aty/radeon_backlight.c b/drivers/video/fbdev/aty/radeon_backlight.c
index db572df..db572df 100644
--- a/drivers/video/aty/radeon_backlight.c
+++ b/drivers/video/fbdev/aty/radeon_backlight.c
diff --git a/drivers/video/aty/radeon_base.c b/drivers/video/fbdev/aty/radeon_base.c
index 26d80a4..26d80a4 100644
--- a/drivers/video/aty/radeon_base.c
+++ b/drivers/video/fbdev/aty/radeon_base.c
diff --git a/drivers/video/aty/radeon_i2c.c b/drivers/video/fbdev/aty/radeon_i2c.c
index ab1d0fd..ab1d0fd 100644
--- a/drivers/video/aty/radeon_i2c.c
+++ b/drivers/video/fbdev/aty/radeon_i2c.c
diff --git a/drivers/video/aty/radeon_monitor.c b/drivers/video/fbdev/aty/radeon_monitor.c
index bc078d5..bc078d5 100644
--- a/drivers/video/aty/radeon_monitor.c
+++ b/drivers/video/fbdev/aty/radeon_monitor.c
diff --git a/drivers/video/aty/radeon_pm.c b/drivers/video/fbdev/aty/radeon_pm.c
index 46a12f1..46a12f1 100644
--- a/drivers/video/aty/radeon_pm.c
+++ b/drivers/video/fbdev/aty/radeon_pm.c
diff --git a/drivers/video/aty/radeonfb.h b/drivers/video/fbdev/aty/radeonfb.h
index cb84604..cb84604 100644
--- a/drivers/video/aty/radeonfb.h
+++ b/drivers/video/fbdev/aty/radeonfb.h
diff --git a/drivers/video/au1100fb.c b/drivers/video/fbdev/au1100fb.c
index 372d4ae..372d4ae 100644
--- a/drivers/video/au1100fb.c
+++ b/drivers/video/fbdev/au1100fb.c
diff --git a/drivers/video/au1100fb.h b/drivers/video/fbdev/au1100fb.h
index 12d9642d..12d9642d 100644
--- a/drivers/video/au1100fb.h
+++ b/drivers/video/fbdev/au1100fb.h
diff --git a/drivers/video/au1200fb.c b/drivers/video/fbdev/au1200fb.c
index 4cfba78..4cfba78 100644
--- a/drivers/video/au1200fb.c
+++ b/drivers/video/fbdev/au1200fb.c
diff --git a/drivers/video/au1200fb.h b/drivers/video/fbdev/au1200fb.h
index e267271..e267271 100644
--- a/drivers/video/au1200fb.h
+++ b/drivers/video/fbdev/au1200fb.h
diff --git a/drivers/video/auo_k1900fb.c b/drivers/video/fbdev/auo_k1900fb.c
index f5b668e..f5b668e 100644
--- a/drivers/video/auo_k1900fb.c
+++ b/drivers/video/fbdev/auo_k1900fb.c
diff --git a/drivers/video/auo_k1901fb.c b/drivers/video/fbdev/auo_k1901fb.c
index 12b9adc..12b9adc 100644
--- a/drivers/video/auo_k1901fb.c
+++ b/drivers/video/fbdev/auo_k1901fb.c
diff --git a/drivers/video/auo_k190x.c b/drivers/video/fbdev/auo_k190x.c
index 8d2499d..8d2499d 100644
--- a/drivers/video/auo_k190x.c
+++ b/drivers/video/fbdev/auo_k190x.c
diff --git a/drivers/video/auo_k190x.h b/drivers/video/fbdev/auo_k190x.h
index e35af1f..e35af1f 100644
--- a/drivers/video/auo_k190x.h
+++ b/drivers/video/fbdev/auo_k190x.h
diff --git a/drivers/video/bf537-lq035.c b/drivers/video/fbdev/bf537-lq035.c
index a82d257..a82d257 100644
--- a/drivers/video/bf537-lq035.c
+++ b/drivers/video/fbdev/bf537-lq035.c
diff --git a/drivers/video/bf54x-lq043fb.c b/drivers/video/fbdev/bf54x-lq043fb.c
index 42b8f9d..e2c42ad 100644
--- a/drivers/video/bf54x-lq043fb.c
+++ b/drivers/video/fbdev/bf54x-lq043fb.c
@@ -49,13 +49,13 @@
#include <linux/spinlock.h>
#include <linux/dma-mapping.h>
#include <linux/platform_device.h>
+#include <linux/gpio.h>
#include <asm/blackfin.h>
#include <asm/irq.h>
#include <asm/dpmc.h>
#include <asm/dma-mapping.h>
#include <asm/dma.h>
-#include <asm/gpio.h>
#include <asm/portmux.h>
#include <mach/bf54x-lq043.h>
diff --git a/drivers/video/bfin-lq035q1-fb.c b/drivers/video/fbdev/bfin-lq035q1-fb.c
index b594a58..b594a58 100644
--- a/drivers/video/bfin-lq035q1-fb.c
+++ b/drivers/video/fbdev/bfin-lq035q1-fb.c
diff --git a/drivers/video/bfin-t350mcqb-fb.c b/drivers/video/fbdev/bfin-t350mcqb-fb.c
index b5cf130..b5cf130 100644
--- a/drivers/video/bfin-t350mcqb-fb.c
+++ b/drivers/video/fbdev/bfin-t350mcqb-fb.c
diff --git a/drivers/video/bfin_adv7393fb.c b/drivers/video/fbdev/bfin_adv7393fb.c
index a54f7f7..a54f7f7 100644
--- a/drivers/video/bfin_adv7393fb.c
+++ b/drivers/video/fbdev/bfin_adv7393fb.c
diff --git a/drivers/video/bfin_adv7393fb.h b/drivers/video/fbdev/bfin_adv7393fb.h
index cd591b5..cd591b5 100644
--- a/drivers/video/bfin_adv7393fb.h
+++ b/drivers/video/fbdev/bfin_adv7393fb.h
diff --git a/drivers/video/broadsheetfb.c b/drivers/video/fbdev/broadsheetfb.c
index 8556264..8556264 100644
--- a/drivers/video/broadsheetfb.c
+++ b/drivers/video/fbdev/broadsheetfb.c
diff --git a/drivers/video/bt431.h b/drivers/video/fbdev/bt431.h
index 04e0cfb..04e0cfb 100644
--- a/drivers/video/bt431.h
+++ b/drivers/video/fbdev/bt431.h
diff --git a/drivers/video/bt455.h b/drivers/video/fbdev/bt455.h
index 80f61b0..80f61b0 100644
--- a/drivers/video/bt455.h
+++ b/drivers/video/fbdev/bt455.h
diff --git a/drivers/video/bw2.c b/drivers/video/fbdev/bw2.c
index bc123d6..bc123d6 100644
--- a/drivers/video/bw2.c
+++ b/drivers/video/fbdev/bw2.c
diff --git a/drivers/video/c2p.h b/drivers/video/fbdev/c2p.h
index 6c38d40..6c38d40 100644
--- a/drivers/video/c2p.h
+++ b/drivers/video/fbdev/c2p.h
diff --git a/drivers/video/c2p_core.h b/drivers/video/fbdev/c2p_core.h
index e1035a8..e1035a8 100644
--- a/drivers/video/c2p_core.h
+++ b/drivers/video/fbdev/c2p_core.h
diff --git a/drivers/video/c2p_iplan2.c b/drivers/video/fbdev/c2p_iplan2.c
index 19156dc..19156dc 100644
--- a/drivers/video/c2p_iplan2.c
+++ b/drivers/video/fbdev/c2p_iplan2.c
diff --git a/drivers/video/c2p_planar.c b/drivers/video/fbdev/c2p_planar.c
index ec7ac85..ec7ac85 100644
--- a/drivers/video/c2p_planar.c
+++ b/drivers/video/fbdev/c2p_planar.c
diff --git a/drivers/video/carminefb.c b/drivers/video/fbdev/carminefb.c
index 65f7c15..65f7c15 100644
--- a/drivers/video/carminefb.c
+++ b/drivers/video/fbdev/carminefb.c
diff --git a/drivers/video/carminefb.h b/drivers/video/fbdev/carminefb.h
index 05306de..05306de 100644
--- a/drivers/video/carminefb.h
+++ b/drivers/video/fbdev/carminefb.h
diff --git a/drivers/video/carminefb_regs.h b/drivers/video/fbdev/carminefb_regs.h
index 0452156..0452156 100644
--- a/drivers/video/carminefb_regs.h
+++ b/drivers/video/fbdev/carminefb_regs.h
diff --git a/drivers/video/cg14.c b/drivers/video/fbdev/cg14.c
index c79745b..c79745b 100644
--- a/drivers/video/cg14.c
+++ b/drivers/video/fbdev/cg14.c
diff --git a/drivers/video/cg3.c b/drivers/video/fbdev/cg3.c
index 64a89d5..64a89d5 100644
--- a/drivers/video/cg3.c
+++ b/drivers/video/fbdev/cg3.c
diff --git a/drivers/video/cg6.c b/drivers/video/fbdev/cg6.c
index 70781fe..70781fe 100644
--- a/drivers/video/cg6.c
+++ b/drivers/video/fbdev/cg6.c
diff --git a/drivers/video/chipsfb.c b/drivers/video/fbdev/chipsfb.c
index 206a66b..206a66b 100644
--- a/drivers/video/chipsfb.c
+++ b/drivers/video/fbdev/chipsfb.c
diff --git a/drivers/video/cirrusfb.c b/drivers/video/fbdev/cirrusfb.c
index d992aa5..d992aa5 100644
--- a/drivers/video/cirrusfb.c
+++ b/drivers/video/fbdev/cirrusfb.c
diff --git a/drivers/video/clps711xfb.c b/drivers/video/fbdev/clps711xfb.c
index f009806..f009806 100644
--- a/drivers/video/clps711xfb.c
+++ b/drivers/video/fbdev/clps711xfb.c
diff --git a/drivers/video/cobalt_lcdfb.c b/drivers/video/fbdev/cobalt_lcdfb.c
index d5533f4..d5533f4 100644
--- a/drivers/video/cobalt_lcdfb.c
+++ b/drivers/video/fbdev/cobalt_lcdfb.c
diff --git a/drivers/video/controlfb.c b/drivers/video/fbdev/controlfb.c
index fdadef9..fdadef9 100644
--- a/drivers/video/controlfb.c
+++ b/drivers/video/fbdev/controlfb.c
diff --git a/drivers/video/controlfb.h b/drivers/video/fbdev/controlfb.h
index 6026c60..6026c60 100644
--- a/drivers/video/controlfb.h
+++ b/drivers/video/fbdev/controlfb.h
diff --git a/drivers/video/fbdev/core/Makefile b/drivers/video/fbdev/core/Makefile
new file mode 100644
index 0000000..fa30653
--- /dev/null
+++ b/drivers/video/fbdev/core/Makefile
@@ -0,0 +1,16 @@
+obj-y += fb_notify.o
+obj-$(CONFIG_FB) += fb.o
+fb-y := fbmem.o fbmon.o fbcmap.o fbsysfs.o \
+ modedb.o fbcvt.o
+fb-objs := $(fb-y)
+
+obj-$(CONFIG_FB_CFB_FILLRECT) += cfbfillrect.o
+obj-$(CONFIG_FB_CFB_COPYAREA) += cfbcopyarea.o
+obj-$(CONFIG_FB_CFB_IMAGEBLIT) += cfbimgblt.o
+obj-$(CONFIG_FB_SYS_FILLRECT) += sysfillrect.o
+obj-$(CONFIG_FB_SYS_COPYAREA) += syscopyarea.o
+obj-$(CONFIG_FB_SYS_IMAGEBLIT) += sysimgblt.o
+obj-$(CONFIG_FB_SYS_FOPS) += fb_sys_fops.o
+obj-$(CONFIG_FB_SVGALIB) += svgalib.o
+obj-$(CONFIG_FB_DDC) += fb_ddc.o
+obj-$(CONFIG_FB_DEFERRED_IO) += fb_defio.o
diff --git a/drivers/video/cfbcopyarea.c b/drivers/video/fbdev/core/cfbcopyarea.c
index bcb5723..bcb5723 100644
--- a/drivers/video/cfbcopyarea.c
+++ b/drivers/video/fbdev/core/cfbcopyarea.c
diff --git a/drivers/video/cfbfillrect.c b/drivers/video/fbdev/core/cfbfillrect.c
index ba9f58b..ba9f58b 100644
--- a/drivers/video/cfbfillrect.c
+++ b/drivers/video/fbdev/core/cfbfillrect.c
diff --git a/drivers/video/cfbimgblt.c b/drivers/video/fbdev/core/cfbimgblt.c
index a2bb276..a2bb276 100644
--- a/drivers/video/cfbimgblt.c
+++ b/drivers/video/fbdev/core/cfbimgblt.c
diff --git a/drivers/video/fb_ddc.c b/drivers/video/fbdev/core/fb_ddc.c
index 2b106f0..94322cc 100644
--- a/drivers/video/fb_ddc.c
+++ b/drivers/video/fbdev/core/fb_ddc.c
@@ -15,7 +15,7 @@
#include <linux/i2c-algo-bit.h>
#include <linux/slab.h>
-#include "edid.h"
+#include "../edid.h"
#define DDC_ADDR 0x50
diff --git a/drivers/video/fb_defio.c b/drivers/video/fbdev/core/fb_defio.c
index 900aa4e..900aa4e 100644
--- a/drivers/video/fb_defio.c
+++ b/drivers/video/fbdev/core/fb_defio.c
diff --git a/drivers/video/fb_draw.h b/drivers/video/fbdev/core/fb_draw.h
index 624ee11..624ee11 100644
--- a/drivers/video/fb_draw.h
+++ b/drivers/video/fbdev/core/fb_draw.h
diff --git a/drivers/video/fb_notify.c b/drivers/video/fbdev/core/fb_notify.c
index 74c2da5..74c2da5 100644
--- a/drivers/video/fb_notify.c
+++ b/drivers/video/fbdev/core/fb_notify.c
diff --git a/drivers/video/fb_sys_fops.c b/drivers/video/fbdev/core/fb_sys_fops.c
index ff275d7..ff275d7 100644
--- a/drivers/video/fb_sys_fops.c
+++ b/drivers/video/fbdev/core/fb_sys_fops.c
diff --git a/drivers/video/fbcmap.c b/drivers/video/fbdev/core/fbcmap.c
index f89245b..f89245b 100644
--- a/drivers/video/fbcmap.c
+++ b/drivers/video/fbdev/core/fbcmap.c
diff --git a/drivers/video/fbcvt.c b/drivers/video/fbdev/core/fbcvt.c
index 7cb715d..7cb715d 100644
--- a/drivers/video/fbcvt.c
+++ b/drivers/video/fbdev/core/fbcvt.c
diff --git a/drivers/video/fbmem.c b/drivers/video/fbdev/core/fbmem.c
index b6d5008..b6d5008 100644
--- a/drivers/video/fbmem.c
+++ b/drivers/video/fbdev/core/fbmem.c
diff --git a/drivers/video/fbmon.c b/drivers/video/fbdev/core/fbmon.c
index 6103fa6..c204ebe 100644
--- a/drivers/video/fbmon.c
+++ b/drivers/video/fbdev/core/fbmon.c
@@ -37,7 +37,7 @@
#include <asm/prom.h>
#include <asm/pci-bridge.h>
#endif
-#include "edid.h"
+#include "../edid.h"
/*
* EDID parser
diff --git a/drivers/video/fbsysfs.c b/drivers/video/fbdev/core/fbsysfs.c
index 53444ac..53444ac 100644
--- a/drivers/video/fbsysfs.c
+++ b/drivers/video/fbdev/core/fbsysfs.c
diff --git a/drivers/video/modedb.c b/drivers/video/fbdev/core/modedb.c
index a9a907c..a9a907c 100644
--- a/drivers/video/modedb.c
+++ b/drivers/video/fbdev/core/modedb.c
diff --git a/drivers/video/svgalib.c b/drivers/video/fbdev/core/svgalib.c
index 9e01322..9e01322 100644
--- a/drivers/video/svgalib.c
+++ b/drivers/video/fbdev/core/svgalib.c
diff --git a/drivers/video/syscopyarea.c b/drivers/video/fbdev/core/syscopyarea.c
index 844a32f..844a32f 100644
--- a/drivers/video/syscopyarea.c
+++ b/drivers/video/fbdev/core/syscopyarea.c
diff --git a/drivers/video/sysfillrect.c b/drivers/video/fbdev/core/sysfillrect.c
index 33ee3d3..33ee3d3 100644
--- a/drivers/video/sysfillrect.c
+++ b/drivers/video/fbdev/core/sysfillrect.c
diff --git a/drivers/video/sysimgblt.c b/drivers/video/fbdev/core/sysimgblt.c
index a4d05b1..a4d05b1 100644
--- a/drivers/video/sysimgblt.c
+++ b/drivers/video/fbdev/core/sysimgblt.c
diff --git a/drivers/video/cyber2000fb.c b/drivers/video/fbdev/cyber2000fb.c
index b0a950f..b0a950f 100644
--- a/drivers/video/cyber2000fb.c
+++ b/drivers/video/fbdev/cyber2000fb.c
diff --git a/drivers/video/cyber2000fb.h b/drivers/video/fbdev/cyber2000fb.h
index bad6910..bad6910 100644
--- a/drivers/video/cyber2000fb.h
+++ b/drivers/video/fbdev/cyber2000fb.h
diff --git a/drivers/video/da8xx-fb.c b/drivers/video/fbdev/da8xx-fb.c
index 0c0ba92..6b23508 100644
--- a/drivers/video/da8xx-fb.c
+++ b/drivers/video/fbdev/da8xx-fb.c
@@ -663,15 +663,7 @@ static int fb_setcolreg(unsigned regno, unsigned red, unsigned green,
(green << info->var.green.offset) |
(blue << info->var.blue.offset);
- switch (info->var.bits_per_pixel) {
- case 16:
- ((u16 *) (info->pseudo_palette))[regno] = v;
- break;
- case 24:
- case 32:
- ((u32 *) (info->pseudo_palette))[regno] = v;
- break;
- }
+ ((u32 *) (info->pseudo_palette))[regno] = v;
if (palette[0] != 0x4000) {
update_hw = 1;
palette[0] = 0x4000;
diff --git a/drivers/video/dnfb.c b/drivers/video/fbdev/dnfb.c
index 3526899..3526899 100644
--- a/drivers/video/dnfb.c
+++ b/drivers/video/fbdev/dnfb.c
diff --git a/drivers/video/edid.h b/drivers/video/fbdev/edid.h
index d03a232..d03a232 100644
--- a/drivers/video/edid.h
+++ b/drivers/video/fbdev/edid.h
diff --git a/drivers/video/efifb.c b/drivers/video/fbdev/efifb.c
index ae9618f..ae9618f 100644
--- a/drivers/video/efifb.c
+++ b/drivers/video/fbdev/efifb.c
diff --git a/drivers/video/ep93xx-fb.c b/drivers/video/fbdev/ep93xx-fb.c
index 35a0f53..35a0f53 100644
--- a/drivers/video/ep93xx-fb.c
+++ b/drivers/video/fbdev/ep93xx-fb.c
diff --git a/drivers/video/exynos/Kconfig b/drivers/video/fbdev/exynos/Kconfig
index fcf2d48..fcf2d48 100644
--- a/drivers/video/exynos/Kconfig
+++ b/drivers/video/fbdev/exynos/Kconfig
diff --git a/drivers/video/exynos/Makefile b/drivers/video/fbdev/exynos/Makefile
index b5b1bd2..b5b1bd2 100644
--- a/drivers/video/exynos/Makefile
+++ b/drivers/video/fbdev/exynos/Makefile
diff --git a/drivers/video/exynos/exynos_mipi_dsi.c b/drivers/video/fbdev/exynos/exynos_mipi_dsi.c
index cee9602..cee9602 100644
--- a/drivers/video/exynos/exynos_mipi_dsi.c
+++ b/drivers/video/fbdev/exynos/exynos_mipi_dsi.c
diff --git a/drivers/video/exynos/exynos_mipi_dsi_common.c b/drivers/video/fbdev/exynos/exynos_mipi_dsi_common.c
index 85edabf..85edabf 100644
--- a/drivers/video/exynos/exynos_mipi_dsi_common.c
+++ b/drivers/video/fbdev/exynos/exynos_mipi_dsi_common.c
diff --git a/drivers/video/exynos/exynos_mipi_dsi_common.h b/drivers/video/fbdev/exynos/exynos_mipi_dsi_common.h
index 4125522..4125522 100644
--- a/drivers/video/exynos/exynos_mipi_dsi_common.h
+++ b/drivers/video/fbdev/exynos/exynos_mipi_dsi_common.h
diff --git a/drivers/video/exynos/exynos_mipi_dsi_lowlevel.c b/drivers/video/fbdev/exynos/exynos_mipi_dsi_lowlevel.c
index c148d06..c148d06 100644
--- a/drivers/video/exynos/exynos_mipi_dsi_lowlevel.c
+++ b/drivers/video/fbdev/exynos/exynos_mipi_dsi_lowlevel.c
diff --git a/drivers/video/exynos/exynos_mipi_dsi_lowlevel.h b/drivers/video/fbdev/exynos/exynos_mipi_dsi_lowlevel.h
index 8546070..8546070 100644
--- a/drivers/video/exynos/exynos_mipi_dsi_lowlevel.h
+++ b/drivers/video/fbdev/exynos/exynos_mipi_dsi_lowlevel.h
diff --git a/drivers/video/exynos/exynos_mipi_dsi_regs.h b/drivers/video/fbdev/exynos/exynos_mipi_dsi_regs.h
index 4227106..4227106 100644
--- a/drivers/video/exynos/exynos_mipi_dsi_regs.h
+++ b/drivers/video/fbdev/exynos/exynos_mipi_dsi_regs.h
diff --git a/drivers/video/exynos/s6e8ax0.c b/drivers/video/fbdev/exynos/s6e8ax0.c
index 29e70ed..29e70ed 100644
--- a/drivers/video/exynos/s6e8ax0.c
+++ b/drivers/video/fbdev/exynos/s6e8ax0.c
diff --git a/drivers/video/fb-puv3.c b/drivers/video/fbdev/fb-puv3.c
index 6db9ebd..6db9ebd 100644
--- a/drivers/video/fb-puv3.c
+++ b/drivers/video/fbdev/fb-puv3.c
diff --git a/drivers/video/ffb.c b/drivers/video/fbdev/ffb.c
index 4c4ffa6..4c4ffa6 100644
--- a/drivers/video/ffb.c
+++ b/drivers/video/fbdev/ffb.c
diff --git a/drivers/video/fm2fb.c b/drivers/video/fbdev/fm2fb.c
index e69d47a..e69d47a 100644
--- a/drivers/video/fm2fb.c
+++ b/drivers/video/fbdev/fm2fb.c
diff --git a/drivers/video/fsl-diu-fb.c b/drivers/video/fbdev/fsl-diu-fb.c
index e8758b9..e8758b9 100644
--- a/drivers/video/fsl-diu-fb.c
+++ b/drivers/video/fbdev/fsl-diu-fb.c
diff --git a/drivers/video/g364fb.c b/drivers/video/fbdev/g364fb.c
index 223896c..223896c 100644
--- a/drivers/video/g364fb.c
+++ b/drivers/video/fbdev/g364fb.c
diff --git a/drivers/video/gbefb.c b/drivers/video/fbdev/gbefb.c
index 3ec65a8..3ec65a8 100644
--- a/drivers/video/gbefb.c
+++ b/drivers/video/fbdev/gbefb.c
diff --git a/drivers/video/geode/Kconfig b/drivers/video/fbdev/geode/Kconfig
index 1e85552..1e85552 100644
--- a/drivers/video/geode/Kconfig
+++ b/drivers/video/fbdev/geode/Kconfig
diff --git a/drivers/video/geode/Makefile b/drivers/video/fbdev/geode/Makefile
index 5c98da1..5c98da1 100644
--- a/drivers/video/geode/Makefile
+++ b/drivers/video/fbdev/geode/Makefile
diff --git a/drivers/video/geode/display_gx.c b/drivers/video/fbdev/geode/display_gx.c
index f0af911a0..f0af911a0 100644
--- a/drivers/video/geode/display_gx.c
+++ b/drivers/video/fbdev/geode/display_gx.c
diff --git a/drivers/video/geode/display_gx1.c b/drivers/video/fbdev/geode/display_gx1.c
index 926d53e..926d53e 100644
--- a/drivers/video/geode/display_gx1.c
+++ b/drivers/video/fbdev/geode/display_gx1.c
diff --git a/drivers/video/geode/display_gx1.h b/drivers/video/fbdev/geode/display_gx1.h
index 671c055..671c055 100644
--- a/drivers/video/geode/display_gx1.h
+++ b/drivers/video/fbdev/geode/display_gx1.h
diff --git a/drivers/video/geode/geodefb.h b/drivers/video/fbdev/geode/geodefb.h
index ae04820..ae04820 100644
--- a/drivers/video/geode/geodefb.h
+++ b/drivers/video/fbdev/geode/geodefb.h
diff --git a/drivers/video/geode/gx1fb_core.c b/drivers/video/fbdev/geode/gx1fb_core.c
index 2794ba1..2794ba1 100644
--- a/drivers/video/geode/gx1fb_core.c
+++ b/drivers/video/fbdev/geode/gx1fb_core.c
diff --git a/drivers/video/geode/gxfb.h b/drivers/video/fbdev/geode/gxfb.h
index d19e937..d19e937 100644
--- a/drivers/video/geode/gxfb.h
+++ b/drivers/video/fbdev/geode/gxfb.h
diff --git a/drivers/video/geode/gxfb_core.c b/drivers/video/fbdev/geode/gxfb_core.c
index 1790f14..1790f14 100644
--- a/drivers/video/geode/gxfb_core.c
+++ b/drivers/video/fbdev/geode/gxfb_core.c
diff --git a/drivers/video/geode/lxfb.h b/drivers/video/fbdev/geode/lxfb.h
index cfcd809..cfcd809 100644
--- a/drivers/video/geode/lxfb.h
+++ b/drivers/video/fbdev/geode/lxfb.h
diff --git a/drivers/video/geode/lxfb_core.c b/drivers/video/fbdev/geode/lxfb_core.c
index 9e1d19d..9e1d19d 100644
--- a/drivers/video/geode/lxfb_core.c
+++ b/drivers/video/fbdev/geode/lxfb_core.c
diff --git a/drivers/video/geode/lxfb_ops.c b/drivers/video/fbdev/geode/lxfb_ops.c
index 79e9abc..79e9abc 100644
--- a/drivers/video/geode/lxfb_ops.c
+++ b/drivers/video/fbdev/geode/lxfb_ops.c
diff --git a/drivers/video/geode/suspend_gx.c b/drivers/video/fbdev/geode/suspend_gx.c
index 1bb043d..1bb043d 100644
--- a/drivers/video/geode/suspend_gx.c
+++ b/drivers/video/fbdev/geode/suspend_gx.c
diff --git a/drivers/video/geode/video_cs5530.c b/drivers/video/fbdev/geode/video_cs5530.c
index 649c394..649c394 100644
--- a/drivers/video/geode/video_cs5530.c
+++ b/drivers/video/fbdev/geode/video_cs5530.c
diff --git a/drivers/video/geode/video_cs5530.h b/drivers/video/fbdev/geode/video_cs5530.h
index 56cecca..56cecca 100644
--- a/drivers/video/geode/video_cs5530.h
+++ b/drivers/video/fbdev/geode/video_cs5530.h
diff --git a/drivers/video/geode/video_gx.c b/drivers/video/fbdev/geode/video_gx.c
index 6082f65..6082f65 100644
--- a/drivers/video/geode/video_gx.c
+++ b/drivers/video/fbdev/geode/video_gx.c
diff --git a/drivers/video/goldfishfb.c b/drivers/video/fbdev/goldfishfb.c
index 7f6c9e6..7f6c9e6 100644
--- a/drivers/video/goldfishfb.c
+++ b/drivers/video/fbdev/goldfishfb.c
diff --git a/drivers/video/grvga.c b/drivers/video/fbdev/grvga.c
index c078701..c078701 100644
--- a/drivers/video/grvga.c
+++ b/drivers/video/fbdev/grvga.c
diff --git a/drivers/video/gxt4500.c b/drivers/video/fbdev/gxt4500.c
index 135d78a..135d78a 100644
--- a/drivers/video/gxt4500.c
+++ b/drivers/video/fbdev/gxt4500.c
diff --git a/drivers/video/hecubafb.c b/drivers/video/fbdev/hecubafb.c
index f64120e..f64120e 100644
--- a/drivers/video/hecubafb.c
+++ b/drivers/video/fbdev/hecubafb.c
diff --git a/drivers/video/hgafb.c b/drivers/video/fbdev/hgafb.c
index 5ff9fe2..5ff9fe2 100644
--- a/drivers/video/hgafb.c
+++ b/drivers/video/fbdev/hgafb.c
diff --git a/drivers/video/hitfb.c b/drivers/video/fbdev/hitfb.c
index a648d51..a648d51 100644
--- a/drivers/video/hitfb.c
+++ b/drivers/video/fbdev/hitfb.c
diff --git a/drivers/video/hpfb.c b/drivers/video/fbdev/hpfb.c
index a1b7e5f..a1b7e5f 100644
--- a/drivers/video/hpfb.c
+++ b/drivers/video/fbdev/hpfb.c
diff --git a/drivers/video/hyperv_fb.c b/drivers/video/fbdev/hyperv_fb.c
index e23392e..e23392e 100644
--- a/drivers/video/hyperv_fb.c
+++ b/drivers/video/fbdev/hyperv_fb.c
diff --git a/drivers/video/i740_reg.h b/drivers/video/fbdev/i740_reg.h
index 91bac76..91bac76 100644
--- a/drivers/video/i740_reg.h
+++ b/drivers/video/fbdev/i740_reg.h
diff --git a/drivers/video/i740fb.c b/drivers/video/fbdev/i740fb.c
index ca7c9df..ca7c9df 100644
--- a/drivers/video/i740fb.c
+++ b/drivers/video/fbdev/i740fb.c
diff --git a/drivers/video/i810/Makefile b/drivers/video/fbdev/i810/Makefile
index 96e08c8..96e08c8 100644
--- a/drivers/video/i810/Makefile
+++ b/drivers/video/fbdev/i810/Makefile
diff --git a/drivers/video/i810/i810-i2c.c b/drivers/video/fbdev/i810/i810-i2c.c
index 7db17d0..7db17d0 100644
--- a/drivers/video/i810/i810-i2c.c
+++ b/drivers/video/fbdev/i810/i810-i2c.c
diff --git a/drivers/video/i810/i810.h b/drivers/video/fbdev/i810/i810.h
index 1414b73..1414b73 100644
--- a/drivers/video/i810/i810.h
+++ b/drivers/video/fbdev/i810/i810.h
diff --git a/drivers/video/i810/i810_accel.c b/drivers/video/fbdev/i810/i810_accel.c
index 7672d2e..7672d2e 100644
--- a/drivers/video/i810/i810_accel.c
+++ b/drivers/video/fbdev/i810/i810_accel.c
diff --git a/drivers/video/i810/i810_dvt.c b/drivers/video/fbdev/i810/i810_dvt.c
index b4b3670..b4b3670 100644
--- a/drivers/video/i810/i810_dvt.c
+++ b/drivers/video/fbdev/i810/i810_dvt.c
diff --git a/drivers/video/i810/i810_gtf.c b/drivers/video/fbdev/i810/i810_gtf.c
index 9743d51..9743d51 100644
--- a/drivers/video/i810/i810_gtf.c
+++ b/drivers/video/fbdev/i810/i810_gtf.c
diff --git a/drivers/video/i810/i810_main.c b/drivers/video/fbdev/i810/i810_main.c
index bb674e4..bb674e4 100644
--- a/drivers/video/i810/i810_main.c
+++ b/drivers/video/fbdev/i810/i810_main.c
diff --git a/drivers/video/i810/i810_main.h b/drivers/video/fbdev/i810/i810_main.h
index a25afaa..a25afaa 100644
--- a/drivers/video/i810/i810_main.h
+++ b/drivers/video/fbdev/i810/i810_main.h
diff --git a/drivers/video/i810/i810_regs.h b/drivers/video/fbdev/i810/i810_regs.h
index 91c6bd9..91c6bd9 100644
--- a/drivers/video/i810/i810_regs.h
+++ b/drivers/video/fbdev/i810/i810_regs.h
diff --git a/drivers/video/igafb.c b/drivers/video/fbdev/igafb.c
index 486f188..486f188 100644
--- a/drivers/video/igafb.c
+++ b/drivers/video/fbdev/igafb.c
diff --git a/drivers/video/imsttfb.c b/drivers/video/fbdev/imsttfb.c
index aae10ce..aae10ce 100644
--- a/drivers/video/imsttfb.c
+++ b/drivers/video/fbdev/imsttfb.c
diff --git a/drivers/video/imxfb.c b/drivers/video/fbdev/imxfb.c
index f6e6216..f6e6216 100644
--- a/drivers/video/imxfb.c
+++ b/drivers/video/fbdev/imxfb.c
diff --git a/drivers/video/intelfb/Makefile b/drivers/video/fbdev/intelfb/Makefile
index f7d631e..f7d631e 100644
--- a/drivers/video/intelfb/Makefile
+++ b/drivers/video/fbdev/intelfb/Makefile
diff --git a/drivers/video/intelfb/intelfb.h b/drivers/video/fbdev/intelfb/intelfb.h
index 6b51175..6b51175 100644
--- a/drivers/video/intelfb/intelfb.h
+++ b/drivers/video/fbdev/intelfb/intelfb.h
diff --git a/drivers/video/intelfb/intelfb_i2c.c b/drivers/video/fbdev/intelfb/intelfb_i2c.c
index 3300bd3..3300bd3 100644
--- a/drivers/video/intelfb/intelfb_i2c.c
+++ b/drivers/video/fbdev/intelfb/intelfb_i2c.c
diff --git a/drivers/video/intelfb/intelfbdrv.c b/drivers/video/fbdev/intelfb/intelfbdrv.c
index b847d53..b847d53 100644
--- a/drivers/video/intelfb/intelfbdrv.c
+++ b/drivers/video/fbdev/intelfb/intelfbdrv.c
diff --git a/drivers/video/intelfb/intelfbhw.c b/drivers/video/fbdev/intelfb/intelfbhw.c
index fbad61d..fbad61d 100644
--- a/drivers/video/intelfb/intelfbhw.c
+++ b/drivers/video/fbdev/intelfb/intelfbhw.c
diff --git a/drivers/video/intelfb/intelfbhw.h b/drivers/video/fbdev/intelfb/intelfbhw.h
index 216ca20..216ca20 100644
--- a/drivers/video/intelfb/intelfbhw.h
+++ b/drivers/video/fbdev/intelfb/intelfbhw.h
diff --git a/drivers/video/jz4740_fb.c b/drivers/video/fbdev/jz4740_fb.c
index 87790e9..87790e9 100644
--- a/drivers/video/jz4740_fb.c
+++ b/drivers/video/fbdev/jz4740_fb.c
diff --git a/drivers/video/kyro/Makefile b/drivers/video/fbdev/kyro/Makefile
index 2fd66f5..2fd66f5 100644
--- a/drivers/video/kyro/Makefile
+++ b/drivers/video/fbdev/kyro/Makefile
diff --git a/drivers/video/kyro/STG4000InitDevice.c b/drivers/video/fbdev/kyro/STG4000InitDevice.c
index 1d3f2080..1d3f2080 100644
--- a/drivers/video/kyro/STG4000InitDevice.c
+++ b/drivers/video/fbdev/kyro/STG4000InitDevice.c
diff --git a/drivers/video/kyro/STG4000Interface.h b/drivers/video/fbdev/kyro/STG4000Interface.h
index b7c83d5..b7c83d5 100644
--- a/drivers/video/kyro/STG4000Interface.h
+++ b/drivers/video/fbdev/kyro/STG4000Interface.h
diff --git a/drivers/video/kyro/STG4000OverlayDevice.c b/drivers/video/fbdev/kyro/STG4000OverlayDevice.c
index 0aeeaa1..0aeeaa1 100644
--- a/drivers/video/kyro/STG4000OverlayDevice.c
+++ b/drivers/video/fbdev/kyro/STG4000OverlayDevice.c
diff --git a/drivers/video/kyro/STG4000Ramdac.c b/drivers/video/fbdev/kyro/STG4000Ramdac.c
index e6ad037..e6ad037 100644
--- a/drivers/video/kyro/STG4000Ramdac.c
+++ b/drivers/video/fbdev/kyro/STG4000Ramdac.c
diff --git a/drivers/video/kyro/STG4000Reg.h b/drivers/video/fbdev/kyro/STG4000Reg.h
index 50f4670..50f4670 100644
--- a/drivers/video/kyro/STG4000Reg.h
+++ b/drivers/video/fbdev/kyro/STG4000Reg.h
diff --git a/drivers/video/kyro/STG4000VTG.c b/drivers/video/fbdev/kyro/STG4000VTG.c
index bd38970..bd38970 100644
--- a/drivers/video/kyro/STG4000VTG.c
+++ b/drivers/video/fbdev/kyro/STG4000VTG.c
diff --git a/drivers/video/kyro/fbdev.c b/drivers/video/fbdev/kyro/fbdev.c
index 65041e1..65041e1 100644
--- a/drivers/video/kyro/fbdev.c
+++ b/drivers/video/fbdev/kyro/fbdev.c
diff --git a/drivers/video/leo.c b/drivers/video/fbdev/leo.c
index 2c7f7d4..2c7f7d4 100644
--- a/drivers/video/leo.c
+++ b/drivers/video/fbdev/leo.c
diff --git a/drivers/video/macfb.c b/drivers/video/fbdev/macfb.c
index cda7587..cda7587 100644
--- a/drivers/video/macfb.c
+++ b/drivers/video/fbdev/macfb.c
diff --git a/drivers/video/macmodes.c b/drivers/video/fbdev/macmodes.c
index af86c08..af86c08 100644
--- a/drivers/video/macmodes.c
+++ b/drivers/video/fbdev/macmodes.c
diff --git a/drivers/video/macmodes.h b/drivers/video/fbdev/macmodes.h
index b86ba08..b86ba08 100644
--- a/drivers/video/macmodes.h
+++ b/drivers/video/fbdev/macmodes.h
diff --git a/drivers/video/matrox/Makefile b/drivers/video/fbdev/matrox/Makefile
index f9c00eb..f9c00eb 100644
--- a/drivers/video/matrox/Makefile
+++ b/drivers/video/fbdev/matrox/Makefile
diff --git a/drivers/video/matrox/g450_pll.c b/drivers/video/fbdev/matrox/g450_pll.c
index c15f8a5..c15f8a5 100644
--- a/drivers/video/matrox/g450_pll.c
+++ b/drivers/video/fbdev/matrox/g450_pll.c
diff --git a/drivers/video/matrox/g450_pll.h b/drivers/video/fbdev/matrox/g450_pll.h
index aac615d..aac615d 100644
--- a/drivers/video/matrox/g450_pll.h
+++ b/drivers/video/fbdev/matrox/g450_pll.h
diff --git a/drivers/video/matrox/i2c-matroxfb.c b/drivers/video/fbdev/matrox/i2c-matroxfb.c
index 0fb280e..0fb280e 100644
--- a/drivers/video/matrox/i2c-matroxfb.c
+++ b/drivers/video/fbdev/matrox/i2c-matroxfb.c
diff --git a/drivers/video/matrox/matroxfb_DAC1064.c b/drivers/video/fbdev/matrox/matroxfb_DAC1064.c
index a01147f..a01147f 100644
--- a/drivers/video/matrox/matroxfb_DAC1064.c
+++ b/drivers/video/fbdev/matrox/matroxfb_DAC1064.c
diff --git a/drivers/video/matrox/matroxfb_DAC1064.h b/drivers/video/fbdev/matrox/matroxfb_DAC1064.h
index 1e6e45b..1e6e45b 100644
--- a/drivers/video/matrox/matroxfb_DAC1064.h
+++ b/drivers/video/fbdev/matrox/matroxfb_DAC1064.h
diff --git a/drivers/video/matrox/matroxfb_Ti3026.c b/drivers/video/fbdev/matrox/matroxfb_Ti3026.c
index 195ad7c..195ad7c 100644
--- a/drivers/video/matrox/matroxfb_Ti3026.c
+++ b/drivers/video/fbdev/matrox/matroxfb_Ti3026.c
diff --git a/drivers/video/matrox/matroxfb_Ti3026.h b/drivers/video/fbdev/matrox/matroxfb_Ti3026.h
index 27872aa..27872aa 100644
--- a/drivers/video/matrox/matroxfb_Ti3026.h
+++ b/drivers/video/fbdev/matrox/matroxfb_Ti3026.h
diff --git a/drivers/video/matrox/matroxfb_accel.c b/drivers/video/fbdev/matrox/matroxfb_accel.c
index 0d5cb85..0d5cb85 100644
--- a/drivers/video/matrox/matroxfb_accel.c
+++ b/drivers/video/fbdev/matrox/matroxfb_accel.c
diff --git a/drivers/video/matrox/matroxfb_accel.h b/drivers/video/fbdev/matrox/matroxfb_accel.h
index 1e418e62..1e418e62 100644
--- a/drivers/video/matrox/matroxfb_accel.h
+++ b/drivers/video/fbdev/matrox/matroxfb_accel.h
diff --git a/drivers/video/matrox/matroxfb_base.c b/drivers/video/fbdev/matrox/matroxfb_base.c
index 7116c53..7116c53 100644
--- a/drivers/video/matrox/matroxfb_base.c
+++ b/drivers/video/fbdev/matrox/matroxfb_base.c
diff --git a/drivers/video/matrox/matroxfb_base.h b/drivers/video/fbdev/matrox/matroxfb_base.h
index 556d96c..556d96c 100644
--- a/drivers/video/matrox/matroxfb_base.h
+++ b/drivers/video/fbdev/matrox/matroxfb_base.h
diff --git a/drivers/video/matrox/matroxfb_crtc2.c b/drivers/video/fbdev/matrox/matroxfb_crtc2.c
index 02796a4..02796a4 100644
--- a/drivers/video/matrox/matroxfb_crtc2.c
+++ b/drivers/video/fbdev/matrox/matroxfb_crtc2.c
diff --git a/drivers/video/matrox/matroxfb_crtc2.h b/drivers/video/fbdev/matrox/matroxfb_crtc2.h
index 1005582..1005582 100644
--- a/drivers/video/matrox/matroxfb_crtc2.h
+++ b/drivers/video/fbdev/matrox/matroxfb_crtc2.h
diff --git a/drivers/video/matrox/matroxfb_g450.c b/drivers/video/fbdev/matrox/matroxfb_g450.c
index cff0546..cff0546 100644
--- a/drivers/video/matrox/matroxfb_g450.c
+++ b/drivers/video/fbdev/matrox/matroxfb_g450.c
diff --git a/drivers/video/matrox/matroxfb_g450.h b/drivers/video/fbdev/matrox/matroxfb_g450.h
index 3a3e654..3a3e654 100644
--- a/drivers/video/matrox/matroxfb_g450.h
+++ b/drivers/video/fbdev/matrox/matroxfb_g450.h
diff --git a/drivers/video/matrox/matroxfb_maven.c b/drivers/video/fbdev/matrox/matroxfb_maven.c
index ee41a0f..ee41a0f 100644
--- a/drivers/video/matrox/matroxfb_maven.c
+++ b/drivers/video/fbdev/matrox/matroxfb_maven.c
diff --git a/drivers/video/matrox/matroxfb_maven.h b/drivers/video/fbdev/matrox/matroxfb_maven.h
index 99eddec..99eddec 100644
--- a/drivers/video/matrox/matroxfb_maven.h
+++ b/drivers/video/fbdev/matrox/matroxfb_maven.h
diff --git a/drivers/video/matrox/matroxfb_misc.c b/drivers/video/fbdev/matrox/matroxfb_misc.c
index 9948ca2..9948ca2 100644
--- a/drivers/video/matrox/matroxfb_misc.c
+++ b/drivers/video/fbdev/matrox/matroxfb_misc.c
diff --git a/drivers/video/matrox/matroxfb_misc.h b/drivers/video/fbdev/matrox/matroxfb_misc.h
index 351c823..351c823 100644
--- a/drivers/video/matrox/matroxfb_misc.h
+++ b/drivers/video/fbdev/matrox/matroxfb_misc.h
diff --git a/drivers/video/maxinefb.c b/drivers/video/fbdev/maxinefb.c
index 5cf52d3..5cf52d3 100644
--- a/drivers/video/maxinefb.c
+++ b/drivers/video/fbdev/maxinefb.c
diff --git a/drivers/video/mb862xx/Makefile b/drivers/video/fbdev/mb862xx/Makefile
index 5707ed0..5707ed0 100644
--- a/drivers/video/mb862xx/Makefile
+++ b/drivers/video/fbdev/mb862xx/Makefile
diff --git a/drivers/video/mb862xx/mb862xx-i2c.c b/drivers/video/fbdev/mb862xx/mb862xx-i2c.c
index c87e17a..c87e17a 100644
--- a/drivers/video/mb862xx/mb862xx-i2c.c
+++ b/drivers/video/fbdev/mb862xx/mb862xx-i2c.c
diff --git a/drivers/video/mb862xx/mb862xx_reg.h b/drivers/video/fbdev/mb862xx/mb862xx_reg.h
index 9df48b8..9df48b8 100644
--- a/drivers/video/mb862xx/mb862xx_reg.h
+++ b/drivers/video/fbdev/mb862xx/mb862xx_reg.h
diff --git a/drivers/video/mb862xx/mb862xxfb.h b/drivers/video/fbdev/mb862xx/mb862xxfb.h
index 8550630..8550630 100644
--- a/drivers/video/mb862xx/mb862xxfb.h
+++ b/drivers/video/fbdev/mb862xx/mb862xxfb.h
diff --git a/drivers/video/mb862xx/mb862xxfb_accel.c b/drivers/video/fbdev/mb862xx/mb862xxfb_accel.c
index fe92eed..fe92eed 100644
--- a/drivers/video/mb862xx/mb862xxfb_accel.c
+++ b/drivers/video/fbdev/mb862xx/mb862xxfb_accel.c
diff --git a/drivers/video/mb862xx/mb862xxfb_accel.h b/drivers/video/fbdev/mb862xx/mb862xxfb_accel.h
index 96a2dfe..96a2dfe 100644
--- a/drivers/video/mb862xx/mb862xxfb_accel.h
+++ b/drivers/video/fbdev/mb862xx/mb862xxfb_accel.h
diff --git a/drivers/video/mb862xx/mb862xxfbdrv.c b/drivers/video/fbdev/mb862xx/mb862xxfbdrv.c
index 0cd4c33..0cd4c33 100644
--- a/drivers/video/mb862xx/mb862xxfbdrv.c
+++ b/drivers/video/fbdev/mb862xx/mb862xxfbdrv.c
diff --git a/drivers/video/mbx/Makefile b/drivers/video/fbdev/mbx/Makefile
index 16c1165..16c1165 100644
--- a/drivers/video/mbx/Makefile
+++ b/drivers/video/fbdev/mbx/Makefile
diff --git a/drivers/video/mbx/mbxdebugfs.c b/drivers/video/fbdev/mbx/mbxdebugfs.c
index 4449f24..4449f24 100644
--- a/drivers/video/mbx/mbxdebugfs.c
+++ b/drivers/video/fbdev/mbx/mbxdebugfs.c
diff --git a/drivers/video/mbx/mbxfb.c b/drivers/video/fbdev/mbx/mbxfb.c
index f0a5392..f0a5392 100644
--- a/drivers/video/mbx/mbxfb.c
+++ b/drivers/video/fbdev/mbx/mbxfb.c
diff --git a/drivers/video/mbx/reg_bits.h b/drivers/video/fbdev/mbx/reg_bits.h
index 5f14b4b..5f14b4b 100644
--- a/drivers/video/mbx/reg_bits.h
+++ b/drivers/video/fbdev/mbx/reg_bits.h
diff --git a/drivers/video/mbx/regs.h b/drivers/video/fbdev/mbx/regs.h
index 063099d..063099d 100644
--- a/drivers/video/mbx/regs.h
+++ b/drivers/video/fbdev/mbx/regs.h
diff --git a/drivers/video/metronomefb.c b/drivers/video/fbdev/metronomefb.c
index 195cc2d..195cc2d 100644
--- a/drivers/video/metronomefb.c
+++ b/drivers/video/fbdev/metronomefb.c
diff --git a/drivers/video/mmp/Kconfig b/drivers/video/fbdev/mmp/Kconfig
index e9ea39e..d4a4ffc 100644
--- a/drivers/video/mmp/Kconfig
+++ b/drivers/video/fbdev/mmp/Kconfig
@@ -5,7 +5,7 @@ menuconfig MMP_DISP
Marvell Display Subsystem support.
if MMP_DISP
-source "drivers/video/mmp/hw/Kconfig"
-source "drivers/video/mmp/panel/Kconfig"
-source "drivers/video/mmp/fb/Kconfig"
+source "drivers/video/fbdev/mmp/hw/Kconfig"
+source "drivers/video/fbdev/mmp/panel/Kconfig"
+source "drivers/video/fbdev/mmp/fb/Kconfig"
endif
diff --git a/drivers/video/mmp/Makefile b/drivers/video/fbdev/mmp/Makefile
index a014cb3..a014cb3 100644
--- a/drivers/video/mmp/Makefile
+++ b/drivers/video/fbdev/mmp/Makefile
diff --git a/drivers/video/mmp/core.c b/drivers/video/fbdev/mmp/core.c
index b563b92..b563b92 100644
--- a/drivers/video/mmp/core.c
+++ b/drivers/video/fbdev/mmp/core.c
diff --git a/drivers/video/mmp/fb/Kconfig b/drivers/video/fbdev/mmp/fb/Kconfig
index 9b0141f..9b0141f 100644
--- a/drivers/video/mmp/fb/Kconfig
+++ b/drivers/video/fbdev/mmp/fb/Kconfig
diff --git a/drivers/video/mmp/fb/Makefile b/drivers/video/fbdev/mmp/fb/Makefile
index 709fd1f..709fd1f 100644
--- a/drivers/video/mmp/fb/Makefile
+++ b/drivers/video/fbdev/mmp/fb/Makefile
diff --git a/drivers/video/mmp/fb/mmpfb.c b/drivers/video/fbdev/mmp/fb/mmpfb.c
index 7ab31eb..7ab31eb 100644
--- a/drivers/video/mmp/fb/mmpfb.c
+++ b/drivers/video/fbdev/mmp/fb/mmpfb.c
diff --git a/drivers/video/mmp/fb/mmpfb.h b/drivers/video/fbdev/mmp/fb/mmpfb.h
index 88c23c1..88c23c1 100644
--- a/drivers/video/mmp/fb/mmpfb.h
+++ b/drivers/video/fbdev/mmp/fb/mmpfb.h
diff --git a/drivers/video/mmp/hw/Kconfig b/drivers/video/fbdev/mmp/hw/Kconfig
index 02f109a..02f109a 100644
--- a/drivers/video/mmp/hw/Kconfig
+++ b/drivers/video/fbdev/mmp/hw/Kconfig
diff --git a/drivers/video/mmp/hw/Makefile b/drivers/video/fbdev/mmp/hw/Makefile
index 0000a71..0000a71 100644
--- a/drivers/video/mmp/hw/Makefile
+++ b/drivers/video/fbdev/mmp/hw/Makefile
diff --git a/drivers/video/mmp/hw/mmp_ctrl.c b/drivers/video/fbdev/mmp/hw/mmp_ctrl.c
index 8621a9f..8621a9f 100644
--- a/drivers/video/mmp/hw/mmp_ctrl.c
+++ b/drivers/video/fbdev/mmp/hw/mmp_ctrl.c
diff --git a/drivers/video/mmp/hw/mmp_ctrl.h b/drivers/video/fbdev/mmp/hw/mmp_ctrl.h
index 53301cf..53301cf 100644
--- a/drivers/video/mmp/hw/mmp_ctrl.h
+++ b/drivers/video/fbdev/mmp/hw/mmp_ctrl.h
diff --git a/drivers/video/mmp/hw/mmp_spi.c b/drivers/video/fbdev/mmp/hw/mmp_spi.c
index e62ca7b..e62ca7b 100644
--- a/drivers/video/mmp/hw/mmp_spi.c
+++ b/drivers/video/fbdev/mmp/hw/mmp_spi.c
diff --git a/drivers/video/mmp/panel/Kconfig b/drivers/video/fbdev/mmp/panel/Kconfig
index 4b2c4f4..4b2c4f4 100644
--- a/drivers/video/mmp/panel/Kconfig
+++ b/drivers/video/fbdev/mmp/panel/Kconfig
diff --git a/drivers/video/mmp/panel/Makefile b/drivers/video/fbdev/mmp/panel/Makefile
index 2f91611..2f91611 100644
--- a/drivers/video/mmp/panel/Makefile
+++ b/drivers/video/fbdev/mmp/panel/Makefile
diff --git a/drivers/video/mmp/panel/tpo_tj032md01bw.c b/drivers/video/fbdev/mmp/panel/tpo_tj032md01bw.c
index 998978b..998978b 100644
--- a/drivers/video/mmp/panel/tpo_tj032md01bw.c
+++ b/drivers/video/fbdev/mmp/panel/tpo_tj032md01bw.c
diff --git a/drivers/video/msm/Makefile b/drivers/video/fbdev/msm/Makefile
index 802d6ae..802d6ae 100644
--- a/drivers/video/msm/Makefile
+++ b/drivers/video/fbdev/msm/Makefile
diff --git a/drivers/video/msm/mddi.c b/drivers/video/fbdev/msm/mddi.c
index e0f8011..e0f8011 100644
--- a/drivers/video/msm/mddi.c
+++ b/drivers/video/fbdev/msm/mddi.c
diff --git a/drivers/video/msm/mddi_client_dummy.c b/drivers/video/fbdev/msm/mddi_client_dummy.c
index f1b0dfc..f1b0dfc 100644
--- a/drivers/video/msm/mddi_client_dummy.c
+++ b/drivers/video/fbdev/msm/mddi_client_dummy.c
diff --git a/drivers/video/msm/mddi_client_nt35399.c b/drivers/video/fbdev/msm/mddi_client_nt35399.c
index f96df32e..f96df32e 100644
--- a/drivers/video/msm/mddi_client_nt35399.c
+++ b/drivers/video/fbdev/msm/mddi_client_nt35399.c
diff --git a/drivers/video/msm/mddi_client_toshiba.c b/drivers/video/fbdev/msm/mddi_client_toshiba.c
index 061d7df..061d7df 100644
--- a/drivers/video/msm/mddi_client_toshiba.c
+++ b/drivers/video/fbdev/msm/mddi_client_toshiba.c
diff --git a/drivers/video/msm/mddi_hw.h b/drivers/video/fbdev/msm/mddi_hw.h
index 45cc01f..45cc01f 100644
--- a/drivers/video/msm/mddi_hw.h
+++ b/drivers/video/fbdev/msm/mddi_hw.h
diff --git a/drivers/video/msm/mdp.c b/drivers/video/fbdev/msm/mdp.c
index 113c787..113c787 100644
--- a/drivers/video/msm/mdp.c
+++ b/drivers/video/fbdev/msm/mdp.c
diff --git a/drivers/video/msm/mdp_csc_table.h b/drivers/video/fbdev/msm/mdp_csc_table.h
index d1cde30..d1cde30 100644
--- a/drivers/video/msm/mdp_csc_table.h
+++ b/drivers/video/fbdev/msm/mdp_csc_table.h
diff --git a/drivers/video/msm/mdp_hw.h b/drivers/video/fbdev/msm/mdp_hw.h
index 35848d7..35848d7 100644
--- a/drivers/video/msm/mdp_hw.h
+++ b/drivers/video/fbdev/msm/mdp_hw.h
diff --git a/drivers/video/msm/mdp_ppp.c b/drivers/video/fbdev/msm/mdp_ppp.c
index be6079c..be6079c 100644
--- a/drivers/video/msm/mdp_ppp.c
+++ b/drivers/video/fbdev/msm/mdp_ppp.c
diff --git a/drivers/video/msm/mdp_scale_tables.c b/drivers/video/fbdev/msm/mdp_scale_tables.c
index 604783b..604783b 100644
--- a/drivers/video/msm/mdp_scale_tables.c
+++ b/drivers/video/fbdev/msm/mdp_scale_tables.c
diff --git a/drivers/video/msm/mdp_scale_tables.h b/drivers/video/fbdev/msm/mdp_scale_tables.h
index 34077b1..34077b1 100644
--- a/drivers/video/msm/mdp_scale_tables.h
+++ b/drivers/video/fbdev/msm/mdp_scale_tables.h
diff --git a/drivers/video/msm/msm_fb.c b/drivers/video/fbdev/msm/msm_fb.c
index 1374803..1374803 100644
--- a/drivers/video/msm/msm_fb.c
+++ b/drivers/video/fbdev/msm/msm_fb.c
diff --git a/drivers/video/mx3fb.c b/drivers/video/fbdev/mx3fb.c
index 142e860..142e860 100644
--- a/drivers/video/mx3fb.c
+++ b/drivers/video/fbdev/mx3fb.c
diff --git a/drivers/video/mxsfb.c b/drivers/video/fbdev/mxsfb.c
index accf48a2..accf48a2 100644
--- a/drivers/video/mxsfb.c
+++ b/drivers/video/fbdev/mxsfb.c
diff --git a/drivers/video/n411.c b/drivers/video/fbdev/n411.c
index 935830f..935830f 100644
--- a/drivers/video/n411.c
+++ b/drivers/video/fbdev/n411.c
diff --git a/drivers/video/neofb.c b/drivers/video/fbdev/neofb.c
index 44f99a6..44f99a6 100644
--- a/drivers/video/neofb.c
+++ b/drivers/video/fbdev/neofb.c
diff --git a/drivers/video/nuc900fb.c b/drivers/video/fbdev/nuc900fb.c
index 478f980..478f980 100644
--- a/drivers/video/nuc900fb.c
+++ b/drivers/video/fbdev/nuc900fb.c
diff --git a/drivers/video/nuc900fb.h b/drivers/video/fbdev/nuc900fb.h
index 9a1ca6d..9a1ca6d 100644
--- a/drivers/video/nuc900fb.h
+++ b/drivers/video/fbdev/nuc900fb.h
diff --git a/drivers/video/nvidia/Makefile b/drivers/video/fbdev/nvidia/Makefile
index ca47432..ca47432 100644
--- a/drivers/video/nvidia/Makefile
+++ b/drivers/video/fbdev/nvidia/Makefile
diff --git a/drivers/video/nvidia/nv_accel.c b/drivers/video/fbdev/nvidia/nv_accel.c
index ad6472a..ad6472a 100644
--- a/drivers/video/nvidia/nv_accel.c
+++ b/drivers/video/fbdev/nvidia/nv_accel.c
diff --git a/drivers/video/nvidia/nv_backlight.c b/drivers/video/fbdev/nvidia/nv_backlight.c
index 8471008..8471008 100644
--- a/drivers/video/nvidia/nv_backlight.c
+++ b/drivers/video/fbdev/nvidia/nv_backlight.c
diff --git a/drivers/video/nvidia/nv_dma.h b/drivers/video/fbdev/nvidia/nv_dma.h
index a7ed1c0..a7ed1c0 100644
--- a/drivers/video/nvidia/nv_dma.h
+++ b/drivers/video/fbdev/nvidia/nv_dma.h
diff --git a/drivers/video/nvidia/nv_hw.c b/drivers/video/fbdev/nvidia/nv_hw.c
index 81c80ac..81c80ac 100644
--- a/drivers/video/nvidia/nv_hw.c
+++ b/drivers/video/fbdev/nvidia/nv_hw.c
diff --git a/drivers/video/nvidia/nv_i2c.c b/drivers/video/fbdev/nvidia/nv_i2c.c
index d7994a1..d7994a1 100644
--- a/drivers/video/nvidia/nv_i2c.c
+++ b/drivers/video/fbdev/nvidia/nv_i2c.c
diff --git a/drivers/video/nvidia/nv_local.h b/drivers/video/fbdev/nvidia/nv_local.h
index 68e508d..68e508d 100644
--- a/drivers/video/nvidia/nv_local.h
+++ b/drivers/video/fbdev/nvidia/nv_local.h
diff --git a/drivers/video/nvidia/nv_of.c b/drivers/video/fbdev/nvidia/nv_of.c
index 3bc13df..3bc13df 100644
--- a/drivers/video/nvidia/nv_of.c
+++ b/drivers/video/fbdev/nvidia/nv_of.c
diff --git a/drivers/video/nvidia/nv_proto.h b/drivers/video/fbdev/nvidia/nv_proto.h
index ff5c410..ff5c410 100644
--- a/drivers/video/nvidia/nv_proto.h
+++ b/drivers/video/fbdev/nvidia/nv_proto.h
diff --git a/drivers/video/nvidia/nv_setup.c b/drivers/video/fbdev/nvidia/nv_setup.c
index 2f2e162..2f2e162 100644
--- a/drivers/video/nvidia/nv_setup.c
+++ b/drivers/video/fbdev/nvidia/nv_setup.c
diff --git a/drivers/video/nvidia/nv_type.h b/drivers/video/fbdev/nvidia/nv_type.h
index c03f7f5..c03f7f5 100644
--- a/drivers/video/nvidia/nv_type.h
+++ b/drivers/video/fbdev/nvidia/nv_type.h
diff --git a/drivers/video/nvidia/nvidia.c b/drivers/video/fbdev/nvidia/nvidia.c
index def0412..def0412 100644
--- a/drivers/video/nvidia/nvidia.c
+++ b/drivers/video/fbdev/nvidia/nvidia.c
diff --git a/drivers/video/ocfb.c b/drivers/video/fbdev/ocfb.c
index 7f9dc9b..7f9dc9b 100644
--- a/drivers/video/ocfb.c
+++ b/drivers/video/fbdev/ocfb.c
diff --git a/drivers/video/offb.c b/drivers/video/fbdev/offb.c
index 7d44d66..7d44d66 100644
--- a/drivers/video/offb.c
+++ b/drivers/video/fbdev/offb.c
diff --git a/drivers/video/omap/Kconfig b/drivers/video/fbdev/omap/Kconfig
index 0bc3a93..0bc3a93 100644
--- a/drivers/video/omap/Kconfig
+++ b/drivers/video/fbdev/omap/Kconfig
diff --git a/drivers/video/omap/Makefile b/drivers/video/fbdev/omap/Makefile
index 1927faf..1927faf 100644
--- a/drivers/video/omap/Makefile
+++ b/drivers/video/fbdev/omap/Makefile
diff --git a/drivers/video/omap/hwa742.c b/drivers/video/fbdev/omap/hwa742.c
index a4ee65b..a4ee65b 100644
--- a/drivers/video/omap/hwa742.c
+++ b/drivers/video/fbdev/omap/hwa742.c
diff --git a/drivers/video/omap/lcd_ams_delta.c b/drivers/video/fbdev/omap/lcd_ams_delta.c
index 4a5f2cd..4a5f2cd 100644
--- a/drivers/video/omap/lcd_ams_delta.c
+++ b/drivers/video/fbdev/omap/lcd_ams_delta.c
diff --git a/drivers/video/omap/lcd_h3.c b/drivers/video/fbdev/omap/lcd_h3.c
index 49bdeca..49bdeca 100644
--- a/drivers/video/omap/lcd_h3.c
+++ b/drivers/video/fbdev/omap/lcd_h3.c
diff --git a/drivers/video/omap/lcd_htcherald.c b/drivers/video/fbdev/omap/lcd_htcherald.c
index 20f4778..20f4778 100644
--- a/drivers/video/omap/lcd_htcherald.c
+++ b/drivers/video/fbdev/omap/lcd_htcherald.c
diff --git a/drivers/video/omap/lcd_inn1510.c b/drivers/video/fbdev/omap/lcd_inn1510.c
index 2ee4232..2ee4232 100644
--- a/drivers/video/omap/lcd_inn1510.c
+++ b/drivers/video/fbdev/omap/lcd_inn1510.c
diff --git a/drivers/video/omap/lcd_inn1610.c b/drivers/video/fbdev/omap/lcd_inn1610.c
index e3d3d13..e3d3d13 100644
--- a/drivers/video/omap/lcd_inn1610.c
+++ b/drivers/video/fbdev/omap/lcd_inn1610.c
diff --git a/drivers/video/omap/lcd_mipid.c b/drivers/video/fbdev/omap/lcd_mipid.c
index 803fee6..803fee6 100644
--- a/drivers/video/omap/lcd_mipid.c
+++ b/drivers/video/fbdev/omap/lcd_mipid.c
diff --git a/drivers/video/omap/lcd_osk.c b/drivers/video/fbdev/omap/lcd_osk.c
index 7fbe04b..7fbe04b 100644
--- a/drivers/video/omap/lcd_osk.c
+++ b/drivers/video/fbdev/omap/lcd_osk.c
diff --git a/drivers/video/omap/lcd_palmte.c b/drivers/video/fbdev/omap/lcd_palmte.c
index ff4fb62..ff4fb62 100644
--- a/drivers/video/omap/lcd_palmte.c
+++ b/drivers/video/fbdev/omap/lcd_palmte.c
diff --git a/drivers/video/omap/lcd_palmtt.c b/drivers/video/fbdev/omap/lcd_palmtt.c
index aaf3c8b..aaf3c8b 100644
--- a/drivers/video/omap/lcd_palmtt.c
+++ b/drivers/video/fbdev/omap/lcd_palmtt.c
diff --git a/drivers/video/omap/lcd_palmz71.c b/drivers/video/fbdev/omap/lcd_palmz71.c
index 3b7d8aa..3b7d8aa 100644
--- a/drivers/video/omap/lcd_palmz71.c
+++ b/drivers/video/fbdev/omap/lcd_palmz71.c
diff --git a/drivers/video/omap/lcdc.c b/drivers/video/fbdev/omap/lcdc.c
index b52f625..b52f625 100644
--- a/drivers/video/omap/lcdc.c
+++ b/drivers/video/fbdev/omap/lcdc.c
diff --git a/drivers/video/omap/lcdc.h b/drivers/video/fbdev/omap/lcdc.h
index 8452222..8452222 100644
--- a/drivers/video/omap/lcdc.h
+++ b/drivers/video/fbdev/omap/lcdc.h
diff --git a/drivers/video/omap/omapfb.h b/drivers/video/fbdev/omap/omapfb.h
index 2921d20..2921d20 100644
--- a/drivers/video/omap/omapfb.h
+++ b/drivers/video/fbdev/omap/omapfb.h
diff --git a/drivers/video/omap/omapfb_main.c b/drivers/video/fbdev/omap/omapfb_main.c
index e4fc6d9b..e4fc6d9b 100644
--- a/drivers/video/omap/omapfb_main.c
+++ b/drivers/video/fbdev/omap/omapfb_main.c
diff --git a/drivers/video/omap/sossi.c b/drivers/video/fbdev/omap/sossi.c
index d4e7684..d4e7684 100644
--- a/drivers/video/omap/sossi.c
+++ b/drivers/video/fbdev/omap/sossi.c
diff --git a/drivers/video/fbdev/omap2/Kconfig b/drivers/video/fbdev/omap2/Kconfig
new file mode 100644
index 0000000..c22955d
--- /dev/null
+++ b/drivers/video/fbdev/omap2/Kconfig
@@ -0,0 +1,10 @@
+config OMAP2_VRFB
+ bool
+
+if ARCH_OMAP2PLUS
+
+source "drivers/video/fbdev/omap2/dss/Kconfig"
+source "drivers/video/fbdev/omap2/omapfb/Kconfig"
+source "drivers/video/fbdev/omap2/displays-new/Kconfig"
+
+endif
diff --git a/drivers/video/omap2/Makefile b/drivers/video/fbdev/omap2/Makefile
index bf8127d..bf8127d 100644
--- a/drivers/video/omap2/Makefile
+++ b/drivers/video/fbdev/omap2/Makefile
diff --git a/drivers/video/omap2/displays-new/Kconfig b/drivers/video/fbdev/omap2/displays-new/Kconfig
index e6cfc38..e6cfc38 100644
--- a/drivers/video/omap2/displays-new/Kconfig
+++ b/drivers/video/fbdev/omap2/displays-new/Kconfig
diff --git a/drivers/video/omap2/displays-new/Makefile b/drivers/video/fbdev/omap2/displays-new/Makefile
index 0323a8a..0323a8a 100644
--- a/drivers/video/omap2/displays-new/Makefile
+++ b/drivers/video/fbdev/omap2/displays-new/Makefile
diff --git a/drivers/video/omap2/displays-new/connector-analog-tv.c b/drivers/video/fbdev/omap2/displays-new/connector-analog-tv.c
index 5ee3b55..5ee3b55 100644
--- a/drivers/video/omap2/displays-new/connector-analog-tv.c
+++ b/drivers/video/fbdev/omap2/displays-new/connector-analog-tv.c
diff --git a/drivers/video/omap2/displays-new/connector-dvi.c b/drivers/video/fbdev/omap2/displays-new/connector-dvi.c
index 74de2bc..74de2bc 100644
--- a/drivers/video/omap2/displays-new/connector-dvi.c
+++ b/drivers/video/fbdev/omap2/displays-new/connector-dvi.c
diff --git a/drivers/video/omap2/displays-new/connector-hdmi.c b/drivers/video/fbdev/omap2/displays-new/connector-hdmi.c
index 29ed21b..29ed21b 100644
--- a/drivers/video/omap2/displays-new/connector-hdmi.c
+++ b/drivers/video/fbdev/omap2/displays-new/connector-hdmi.c
diff --git a/drivers/video/omap2/displays-new/encoder-tfp410.c b/drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c
index b4e9a42..b4e9a42 100644
--- a/drivers/video/omap2/displays-new/encoder-tfp410.c
+++ b/drivers/video/fbdev/omap2/displays-new/encoder-tfp410.c
diff --git a/drivers/video/omap2/displays-new/encoder-tpd12s015.c b/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c
index 7e33686..7e33686 100644
--- a/drivers/video/omap2/displays-new/encoder-tpd12s015.c
+++ b/drivers/video/fbdev/omap2/displays-new/encoder-tpd12s015.c
diff --git a/drivers/video/omap2/displays-new/panel-dpi.c b/drivers/video/fbdev/omap2/displays-new/panel-dpi.c
index 5f8f7e7..5f8f7e7 100644
--- a/drivers/video/omap2/displays-new/panel-dpi.c
+++ b/drivers/video/fbdev/omap2/displays-new/panel-dpi.c
diff --git a/drivers/video/omap2/displays-new/panel-dsi-cm.c b/drivers/video/fbdev/omap2/displays-new/panel-dsi-cm.c
index d6f14e8..d6f14e8 100644
--- a/drivers/video/omap2/displays-new/panel-dsi-cm.c
+++ b/drivers/video/fbdev/omap2/displays-new/panel-dsi-cm.c
diff --git a/drivers/video/omap2/displays-new/panel-lgphilips-lb035q02.c b/drivers/video/fbdev/omap2/displays-new/panel-lgphilips-lb035q02.c
index 2e6b513..2e6b513 100644
--- a/drivers/video/omap2/displays-new/panel-lgphilips-lb035q02.c
+++ b/drivers/video/fbdev/omap2/displays-new/panel-lgphilips-lb035q02.c
diff --git a/drivers/video/omap2/displays-new/panel-nec-nl8048hl11.c b/drivers/video/fbdev/omap2/displays-new/panel-nec-nl8048hl11.c
index 996fa00..996fa00 100644
--- a/drivers/video/omap2/displays-new/panel-nec-nl8048hl11.c
+++ b/drivers/video/fbdev/omap2/displays-new/panel-nec-nl8048hl11.c
diff --git a/drivers/video/omap2/displays-new/panel-sharp-ls037v7dw01.c b/drivers/video/fbdev/omap2/displays-new/panel-sharp-ls037v7dw01.c
index b2f710b..b2f710b 100644
--- a/drivers/video/omap2/displays-new/panel-sharp-ls037v7dw01.c
+++ b/drivers/video/fbdev/omap2/displays-new/panel-sharp-ls037v7dw01.c
diff --git a/drivers/video/omap2/displays-new/panel-sony-acx565akm.c b/drivers/video/fbdev/omap2/displays-new/panel-sony-acx565akm.c
index c7ba4d8..c7ba4d8 100644
--- a/drivers/video/omap2/displays-new/panel-sony-acx565akm.c
+++ b/drivers/video/fbdev/omap2/displays-new/panel-sony-acx565akm.c
diff --git a/drivers/video/omap2/displays-new/panel-tpo-td028ttec1.c b/drivers/video/fbdev/omap2/displays-new/panel-tpo-td028ttec1.c
index fae6adc..fae6adc 100644
--- a/drivers/video/omap2/displays-new/panel-tpo-td028ttec1.c
+++ b/drivers/video/fbdev/omap2/displays-new/panel-tpo-td028ttec1.c
diff --git a/drivers/video/omap2/displays-new/panel-tpo-td043mtea1.c b/drivers/video/fbdev/omap2/displays-new/panel-tpo-td043mtea1.c
index 875b402..875b402 100644
--- a/drivers/video/omap2/displays-new/panel-tpo-td043mtea1.c
+++ b/drivers/video/fbdev/omap2/displays-new/panel-tpo-td043mtea1.c
diff --git a/drivers/video/omap2/dss/Kconfig b/drivers/video/fbdev/omap2/dss/Kconfig
index dde4281..dde4281 100644
--- a/drivers/video/omap2/dss/Kconfig
+++ b/drivers/video/fbdev/omap2/dss/Kconfig
diff --git a/drivers/video/omap2/dss/Makefile b/drivers/video/fbdev/omap2/dss/Makefile
index 8aec8bd..8aec8bd 100644
--- a/drivers/video/omap2/dss/Makefile
+++ b/drivers/video/fbdev/omap2/dss/Makefile
diff --git a/drivers/video/omap2/dss/apply.c b/drivers/video/fbdev/omap2/dss/apply.c
index 0a0b084..0a0b084 100644
--- a/drivers/video/omap2/dss/apply.c
+++ b/drivers/video/fbdev/omap2/dss/apply.c
diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/fbdev/omap2/dss/core.c
index ffa45c8..ffa45c8 100644
--- a/drivers/video/omap2/dss/core.c
+++ b/drivers/video/fbdev/omap2/dss/core.c
diff --git a/drivers/video/omap2/dss/dispc-compat.c b/drivers/video/fbdev/omap2/dss/dispc-compat.c
index 83779c2..83779c2 100644
--- a/drivers/video/omap2/dss/dispc-compat.c
+++ b/drivers/video/fbdev/omap2/dss/dispc-compat.c
diff --git a/drivers/video/omap2/dss/dispc-compat.h b/drivers/video/fbdev/omap2/dss/dispc-compat.h
index 14a69b3..14a69b3 100644
--- a/drivers/video/omap2/dss/dispc-compat.h
+++ b/drivers/video/fbdev/omap2/dss/dispc-compat.h
diff --git a/drivers/video/omap2/dss/dispc.c b/drivers/video/fbdev/omap2/dss/dispc.c
index 2bbdb7f..f18397c 100644
--- a/drivers/video/omap2/dss/dispc.c
+++ b/drivers/video/fbdev/omap2/dss/dispc.c
@@ -101,6 +101,8 @@ static struct {
void __iomem *base;
int irq;
+ irq_handler_t user_handler;
+ void *user_data;
unsigned long core_clk_rate;
unsigned long tv_pclk_rate;
@@ -113,6 +115,8 @@ static struct {
u32 ctx[DISPC_SZ_REGS / sizeof(u32)];
const struct dispc_features *feat;
+
+ bool is_enabled;
} dispc;
enum omap_color_component {
@@ -141,12 +145,18 @@ enum mgr_reg_fields {
DISPC_MGR_FLD_NUM,
};
+struct dispc_reg_field {
+ u16 reg;
+ u8 high;
+ u8 low;
+};
+
static const struct {
const char *name;
u32 vsync_irq;
u32 framedone_irq;
u32 sync_lost_irq;
- struct reg_field reg_desc[DISPC_MGR_FLD_NUM];
+ struct dispc_reg_field reg_desc[DISPC_MGR_FLD_NUM];
} mgr_desc[] = {
[OMAP_DSS_CHANNEL_LCD] = {
.name = "LCD",
@@ -238,13 +248,13 @@ static inline u32 dispc_read_reg(const u16 idx)
static u32 mgr_fld_read(enum omap_channel channel, enum mgr_reg_fields regfld)
{
- const struct reg_field rfld = mgr_desc[channel].reg_desc[regfld];
+ const struct dispc_reg_field rfld = mgr_desc[channel].reg_desc[regfld];
return REG_GET(rfld.reg, rfld.high, rfld.low);
}
static void mgr_fld_write(enum omap_channel channel,
enum mgr_reg_fields regfld, int val) {
- const struct reg_field rfld = mgr_desc[channel].reg_desc[regfld];
+ const struct dispc_reg_field rfld = mgr_desc[channel].reg_desc[regfld];
REG_FLD_MOD(rfld.reg, val, rfld.high, rfld.low);
}
@@ -3669,16 +3679,44 @@ static int __init dispc_init_features(struct platform_device *pdev)
return 0;
}
+static irqreturn_t dispc_irq_handler(int irq, void *arg)
+{
+ if (!dispc.is_enabled)
+ return IRQ_NONE;
+
+ return dispc.user_handler(irq, dispc.user_data);
+}
+
int dispc_request_irq(irq_handler_t handler, void *dev_id)
{
- return devm_request_irq(&dispc.pdev->dev, dispc.irq, handler,
- IRQF_SHARED, "OMAP DISPC", dev_id);
+ int r;
+
+ if (dispc.user_handler != NULL)
+ return -EBUSY;
+
+ dispc.user_handler = handler;
+ dispc.user_data = dev_id;
+
+ /* ensure the dispc_irq_handler sees the values above */
+ smp_wmb();
+
+ r = devm_request_irq(&dispc.pdev->dev, dispc.irq, dispc_irq_handler,
+ IRQF_SHARED, "OMAP DISPC", &dispc);
+ if (r) {
+ dispc.user_handler = NULL;
+ dispc.user_data = NULL;
+ }
+
+ return r;
}
EXPORT_SYMBOL(dispc_request_irq);
void dispc_free_irq(void *dev_id)
{
- devm_free_irq(&dispc.pdev->dev, dispc.irq, dev_id);
+ devm_free_irq(&dispc.pdev->dev, dispc.irq, &dispc);
+
+ dispc.user_handler = NULL;
+ dispc.user_data = NULL;
}
EXPORT_SYMBOL(dispc_free_irq);
@@ -3750,6 +3788,12 @@ static int __exit omap_dispchw_remove(struct platform_device *pdev)
static int dispc_runtime_suspend(struct device *dev)
{
+ dispc.is_enabled = false;
+ /* ensure the dispc_irq_handler sees the is_enabled value */
+ smp_wmb();
+ /* wait for current handler to finish before turning the DISPC off */
+ synchronize_irq(dispc.irq);
+
dispc_save_context();
return 0;
@@ -3763,12 +3807,15 @@ static int dispc_runtime_resume(struct device *dev)
* _omap_dispc_initial_config(). We can thus use it to detect if
* we have lost register context.
*/
- if (REG_GET(DISPC_CONFIG, 2, 1) == OMAP_DSS_LOAD_FRAME_ONLY)
- return 0;
+ if (REG_GET(DISPC_CONFIG, 2, 1) != OMAP_DSS_LOAD_FRAME_ONLY) {
+ _omap_dispc_initial_config();
- _omap_dispc_initial_config();
+ dispc_restore_context();
+ }
- dispc_restore_context();
+ dispc.is_enabled = true;
+ /* ensure the dispc_irq_handler sees the is_enabled value */
+ smp_wmb();
return 0;
}
diff --git a/drivers/video/omap2/dss/dispc.h b/drivers/video/fbdev/omap2/dss/dispc.h
index 78edb44..78edb44 100644
--- a/drivers/video/omap2/dss/dispc.h
+++ b/drivers/video/fbdev/omap2/dss/dispc.h
diff --git a/drivers/video/omap2/dss/dispc_coefs.c b/drivers/video/fbdev/omap2/dss/dispc_coefs.c
index 038c15b..038c15b 100644
--- a/drivers/video/omap2/dss/dispc_coefs.c
+++ b/drivers/video/fbdev/omap2/dss/dispc_coefs.c
diff --git a/drivers/video/omap2/dss/display-sysfs.c b/drivers/video/fbdev/omap2/dss/display-sysfs.c
index 5a2095a..5a2095a 100644
--- a/drivers/video/omap2/dss/display-sysfs.c
+++ b/drivers/video/fbdev/omap2/dss/display-sysfs.c
diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/fbdev/omap2/dss/display.c
index 2412a0d..2412a0d 100644
--- a/drivers/video/omap2/dss/display.c
+++ b/drivers/video/fbdev/omap2/dss/display.c
diff --git a/drivers/video/omap2/dss/dpi.c b/drivers/video/fbdev/omap2/dss/dpi.c
index 157921d..157921d 100644
--- a/drivers/video/omap2/dss/dpi.c
+++ b/drivers/video/fbdev/omap2/dss/dpi.c
diff --git a/drivers/video/omap2/dss/dsi.c b/drivers/video/fbdev/omap2/dss/dsi.c
index 121d104..8be9b04 100644
--- a/drivers/video/omap2/dss/dsi.c
+++ b/drivers/video/fbdev/omap2/dss/dsi.c
@@ -297,6 +297,8 @@ struct dsi_data {
int irq;
+ bool is_enabled;
+
struct clk *dss_clk;
struct clk *sys_clk;
@@ -795,6 +797,9 @@ static irqreturn_t omap_dsi_irq_handler(int irq, void *arg)
dsidev = (struct platform_device *) arg;
dsi = dsi_get_dsidrv_data(dsidev);
+ if (!dsi->is_enabled)
+ return IRQ_NONE;
+
spin_lock(&dsi->irq_lock);
irqstatus = dsi_read_reg(dsidev, DSI_IRQSTATUS);
@@ -5671,6 +5676,15 @@ static int __exit omap_dsihw_remove(struct platform_device *dsidev)
static int dsi_runtime_suspend(struct device *dev)
{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct dsi_data *dsi = dsi_get_dsidrv_data(pdev);
+
+ dsi->is_enabled = false;
+ /* ensure the irq handler sees the is_enabled value */
+ smp_wmb();
+ /* wait for current handler to finish before turning the DSI off */
+ synchronize_irq(dsi->irq);
+
dispc_runtime_put();
return 0;
@@ -5678,12 +5692,18 @@ static int dsi_runtime_suspend(struct device *dev)
static int dsi_runtime_resume(struct device *dev)
{
+ struct platform_device *pdev = to_platform_device(dev);
+ struct dsi_data *dsi = dsi_get_dsidrv_data(pdev);
int r;
r = dispc_runtime_get();
if (r)
return r;
+ dsi->is_enabled = true;
+ /* ensure the irq handler sees the is_enabled value */
+ smp_wmb();
+
return 0;
}
diff --git a/drivers/video/omap2/dss/dss-of.c b/drivers/video/fbdev/omap2/dss/dss-of.c
index a4b20aa..a4b20aa 100644
--- a/drivers/video/omap2/dss/dss-of.c
+++ b/drivers/video/fbdev/omap2/dss/dss-of.c
diff --git a/drivers/video/omap2/dss/dss.c b/drivers/video/fbdev/omap2/dss/dss.c
index 825c019..d55266c 100644
--- a/drivers/video/omap2/dss/dss.c
+++ b/drivers/video/fbdev/omap2/dss/dss.c
@@ -457,7 +457,7 @@ bool dss_div_calc(unsigned long pck, unsigned long fck_min,
fckd_stop = max(DIV_ROUND_UP(prate * m, fck_hw_max), 1ul);
for (fckd = fckd_start; fckd >= fckd_stop; --fckd) {
- fck = prate / fckd * m;
+ fck = DIV_ROUND_UP(prate, fckd) * m;
if (func(fck, data))
return true;
@@ -506,7 +506,7 @@ static int dss_setup_default_clock(void)
fck_div = DIV_ROUND_UP(prate * dss.feat->dss_fck_multiplier,
max_dss_fck);
- fck = prate / fck_div * dss.feat->dss_fck_multiplier;
+ fck = DIV_ROUND_UP(prate, fck_div) * dss.feat->dss_fck_multiplier;
}
r = dss_set_fck_rate(fck);
diff --git a/drivers/video/omap2/dss/dss.h b/drivers/video/fbdev/omap2/dss/dss.h
index 918fec1..560078f 100644
--- a/drivers/video/omap2/dss/dss.h
+++ b/drivers/video/fbdev/omap2/dss/dss.h
@@ -131,12 +131,6 @@ struct dsi_clock_info {
u16 lp_clk_div;
};
-struct reg_field {
- u16 reg;
- u8 high;
- u8 low;
-};
-
struct dss_lcd_mgr_config {
enum dss_io_pad_mode io_pad_mode;
diff --git a/drivers/video/omap2/dss/dss_features.c b/drivers/video/fbdev/omap2/dss/dss_features.c
index 7f89691..7f89691 100644
--- a/drivers/video/omap2/dss/dss_features.c
+++ b/drivers/video/fbdev/omap2/dss/dss_features.c
diff --git a/drivers/video/omap2/dss/dss_features.h b/drivers/video/fbdev/omap2/dss/dss_features.h
index e3ef3b7..e3ef3b7 100644
--- a/drivers/video/omap2/dss/dss_features.h
+++ b/drivers/video/fbdev/omap2/dss/dss_features.h
diff --git a/drivers/video/omap2/dss/hdmi.h b/drivers/video/fbdev/omap2/dss/hdmi.h
index e25681f..e25681f 100644
--- a/drivers/video/omap2/dss/hdmi.h
+++ b/drivers/video/fbdev/omap2/dss/hdmi.h
diff --git a/drivers/video/omap2/dss/hdmi4.c b/drivers/video/fbdev/omap2/dss/hdmi4.c
index f5f7944..f5f7944 100644
--- a/drivers/video/omap2/dss/hdmi4.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi4.c
diff --git a/drivers/video/omap2/dss/hdmi4_core.c b/drivers/video/fbdev/omap2/dss/hdmi4_core.c
index 2eb04dc..2eb04dc 100644
--- a/drivers/video/omap2/dss/hdmi4_core.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi4_core.c
diff --git a/drivers/video/omap2/dss/hdmi4_core.h b/drivers/video/fbdev/omap2/dss/hdmi4_core.h
index bb64689..bb64689 100644
--- a/drivers/video/omap2/dss/hdmi4_core.h
+++ b/drivers/video/fbdev/omap2/dss/hdmi4_core.h
diff --git a/drivers/video/omap2/dss/hdmi_common.c b/drivers/video/fbdev/omap2/dss/hdmi_common.c
index b11afac..0b12a3f 100644
--- a/drivers/video/omap2/dss/hdmi_common.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi_common.c
@@ -347,17 +347,17 @@ int hdmi_compute_acr(u32 pclk, u32 sample_freq, u32 *n, u32 *cts)
case 96000:
case 192000:
if (deep_color == 125)
- if (pclk == 27027 || pclk == 74250)
+ if (pclk == 27027000 || pclk == 74250000)
deep_color_correct = true;
if (deep_color == 150)
- if (pclk == 27027)
+ if (pclk == 27027000)
deep_color_correct = true;
break;
case 44100:
case 88200:
case 176400:
if (deep_color == 125)
- if (pclk == 27027)
+ if (pclk == 27027000)
deep_color_correct = true;
break;
default:
@@ -418,7 +418,7 @@ int hdmi_compute_acr(u32 pclk, u32 sample_freq, u32 *n, u32 *cts)
}
}
/* Calculate CTS. See HDMI 1.3a or 1.4a specifications */
- *cts = pclk * (*n / 128) * deep_color / (sample_freq / 10);
+ *cts = (pclk/1000) * (*n / 128) * deep_color / (sample_freq / 10);
return 0;
}
diff --git a/drivers/video/omap2/dss/hdmi_phy.c b/drivers/video/fbdev/omap2/dss/hdmi_phy.c
index dd376ce..dd376ce 100644
--- a/drivers/video/omap2/dss/hdmi_phy.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi_phy.c
diff --git a/drivers/video/omap2/dss/hdmi_pll.c b/drivers/video/fbdev/omap2/dss/hdmi_pll.c
index 5fc7121..5fc7121 100644
--- a/drivers/video/omap2/dss/hdmi_pll.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi_pll.c
diff --git a/drivers/video/omap2/dss/hdmi_wp.c b/drivers/video/fbdev/omap2/dss/hdmi_wp.c
index f5f4ccf..f5f4ccf 100644
--- a/drivers/video/omap2/dss/hdmi_wp.c
+++ b/drivers/video/fbdev/omap2/dss/hdmi_wp.c
diff --git a/drivers/video/omap2/dss/manager-sysfs.c b/drivers/video/fbdev/omap2/dss/manager-sysfs.c
index 37b59fe..37b59fe 100644
--- a/drivers/video/omap2/dss/manager-sysfs.c
+++ b/drivers/video/fbdev/omap2/dss/manager-sysfs.c
diff --git a/drivers/video/omap2/dss/manager.c b/drivers/video/fbdev/omap2/dss/manager.c
index 1aac9b4..1aac9b4 100644
--- a/drivers/video/omap2/dss/manager.c
+++ b/drivers/video/fbdev/omap2/dss/manager.c
diff --git a/drivers/video/omap2/dss/output.c b/drivers/video/fbdev/omap2/dss/output.c
index 2ab3afa..2ab3afa 100644
--- a/drivers/video/omap2/dss/output.c
+++ b/drivers/video/fbdev/omap2/dss/output.c
diff --git a/drivers/video/omap2/dss/overlay-sysfs.c b/drivers/video/fbdev/omap2/dss/overlay-sysfs.c
index 4cc5ddebf..4cc5ddebf 100644
--- a/drivers/video/omap2/dss/overlay-sysfs.c
+++ b/drivers/video/fbdev/omap2/dss/overlay-sysfs.c
diff --git a/drivers/video/omap2/dss/overlay.c b/drivers/video/fbdev/omap2/dss/overlay.c
index 2f7cee9..2f7cee9 100644
--- a/drivers/video/omap2/dss/overlay.c
+++ b/drivers/video/fbdev/omap2/dss/overlay.c
diff --git a/drivers/video/omap2/dss/rfbi.c b/drivers/video/fbdev/omap2/dss/rfbi.c
index c8a81a2..c8a81a2 100644
--- a/drivers/video/omap2/dss/rfbi.c
+++ b/drivers/video/fbdev/omap2/dss/rfbi.c
diff --git a/drivers/video/omap2/dss/sdi.c b/drivers/video/fbdev/omap2/dss/sdi.c
index 911dcc9..911dcc9 100644
--- a/drivers/video/omap2/dss/sdi.c
+++ b/drivers/video/fbdev/omap2/dss/sdi.c
diff --git a/drivers/video/omap2/dss/venc.c b/drivers/video/fbdev/omap2/dss/venc.c
index 21d8111..21d8111 100644
--- a/drivers/video/omap2/dss/venc.c
+++ b/drivers/video/fbdev/omap2/dss/venc.c
diff --git a/drivers/video/omap2/dss/venc_panel.c b/drivers/video/fbdev/omap2/dss/venc_panel.c
index af68cd4..af68cd4 100644
--- a/drivers/video/omap2/dss/venc_panel.c
+++ b/drivers/video/fbdev/omap2/dss/venc_panel.c
diff --git a/drivers/video/omap2/omapfb/Kconfig b/drivers/video/fbdev/omap2/omapfb/Kconfig
index 4cb12ce..4cb12ce 100644
--- a/drivers/video/omap2/omapfb/Kconfig
+++ b/drivers/video/fbdev/omap2/omapfb/Kconfig
diff --git a/drivers/video/omap2/omapfb/Makefile b/drivers/video/fbdev/omap2/omapfb/Makefile
index 51c2e00..51c2e00 100644
--- a/drivers/video/omap2/omapfb/Makefile
+++ b/drivers/video/fbdev/omap2/omapfb/Makefile
diff --git a/drivers/video/omap2/omapfb/omapfb-ioctl.c b/drivers/video/fbdev/omap2/omapfb/omapfb-ioctl.c
index 146b6f5..146b6f5 100644
--- a/drivers/video/omap2/omapfb/omapfb-ioctl.c
+++ b/drivers/video/fbdev/omap2/omapfb/omapfb-ioctl.c
diff --git a/drivers/video/omap2/omapfb/omapfb-main.c b/drivers/video/fbdev/omap2/omapfb/omapfb-main.c
index ec2d132..ec2d132 100644
--- a/drivers/video/omap2/omapfb/omapfb-main.c
+++ b/drivers/video/fbdev/omap2/omapfb/omapfb-main.c
diff --git a/drivers/video/omap2/omapfb/omapfb-sysfs.c b/drivers/video/fbdev/omap2/omapfb/omapfb-sysfs.c
index 18fa9e1..18fa9e1 100644
--- a/drivers/video/omap2/omapfb/omapfb-sysfs.c
+++ b/drivers/video/fbdev/omap2/omapfb/omapfb-sysfs.c
diff --git a/drivers/video/omap2/omapfb/omapfb.h b/drivers/video/fbdev/omap2/omapfb/omapfb.h
index 623cd87..623cd87 100644
--- a/drivers/video/omap2/omapfb/omapfb.h
+++ b/drivers/video/fbdev/omap2/omapfb/omapfb.h
diff --git a/drivers/video/omap2/vrfb.c b/drivers/video/fbdev/omap2/vrfb.c
index f346b02..f346b02 100644
--- a/drivers/video/omap2/vrfb.c
+++ b/drivers/video/fbdev/omap2/vrfb.c
diff --git a/drivers/video/p9100.c b/drivers/video/fbdev/p9100.c
index 367cea8..367cea8 100644
--- a/drivers/video/p9100.c
+++ b/drivers/video/fbdev/p9100.c
diff --git a/drivers/video/platinumfb.c b/drivers/video/fbdev/platinumfb.c
index 4c92995..4c92995 100644
--- a/drivers/video/platinumfb.c
+++ b/drivers/video/fbdev/platinumfb.c
diff --git a/drivers/video/platinumfb.h b/drivers/video/fbdev/platinumfb.h
index f6bd77c..f6bd77c 100644
--- a/drivers/video/platinumfb.h
+++ b/drivers/video/fbdev/platinumfb.h
diff --git a/drivers/video/pm2fb.c b/drivers/video/fbdev/pm2fb.c
index 3b85b64..3b85b64 100644
--- a/drivers/video/pm2fb.c
+++ b/drivers/video/fbdev/pm2fb.c
diff --git a/drivers/video/pm3fb.c b/drivers/video/fbdev/pm3fb.c
index 4bf3273..4bf3273 100644
--- a/drivers/video/pm3fb.c
+++ b/drivers/video/fbdev/pm3fb.c
diff --git a/drivers/video/pmag-aa-fb.c b/drivers/video/fbdev/pmag-aa-fb.c
index 8384248..8384248 100644
--- a/drivers/video/pmag-aa-fb.c
+++ b/drivers/video/fbdev/pmag-aa-fb.c
diff --git a/drivers/video/pmag-ba-fb.c b/drivers/video/fbdev/pmag-ba-fb.c
index 914a52b..914a52b 100644
--- a/drivers/video/pmag-ba-fb.c
+++ b/drivers/video/fbdev/pmag-ba-fb.c
diff --git a/drivers/video/pmagb-b-fb.c b/drivers/video/fbdev/pmagb-b-fb.c
index 0822b6f..0822b6f 100644
--- a/drivers/video/pmagb-b-fb.c
+++ b/drivers/video/fbdev/pmagb-b-fb.c
diff --git a/drivers/video/ps3fb.c b/drivers/video/fbdev/ps3fb.c
index b269abd..b269abd 100644
--- a/drivers/video/ps3fb.c
+++ b/drivers/video/fbdev/ps3fb.c
diff --git a/drivers/video/pvr2fb.c b/drivers/video/fbdev/pvr2fb.c
index 167cfff..167cfff 100644
--- a/drivers/video/pvr2fb.c
+++ b/drivers/video/fbdev/pvr2fb.c
diff --git a/drivers/video/pxa168fb.c b/drivers/video/fbdev/pxa168fb.c
index c95b9e4..c95b9e4 100644
--- a/drivers/video/pxa168fb.c
+++ b/drivers/video/fbdev/pxa168fb.c
diff --git a/drivers/video/pxa168fb.h b/drivers/video/fbdev/pxa168fb.h
index eee0927..eee0927 100644
--- a/drivers/video/pxa168fb.h
+++ b/drivers/video/fbdev/pxa168fb.h
diff --git a/drivers/video/pxa3xx-gcu.c b/drivers/video/fbdev/pxa3xx-gcu.c
index 417f9a2..417f9a2 100644
--- a/drivers/video/pxa3xx-gcu.c
+++ b/drivers/video/fbdev/pxa3xx-gcu.c
diff --git a/drivers/video/pxa3xx-gcu.h b/drivers/video/fbdev/pxa3xx-gcu.h
index 0428ed0..0428ed0 100644
--- a/drivers/video/pxa3xx-gcu.h
+++ b/drivers/video/fbdev/pxa3xx-gcu.h
diff --git a/drivers/video/pxafb.c b/drivers/video/fbdev/pxafb.c
index 1ecd9ce..1ecd9ce 100644
--- a/drivers/video/pxafb.c
+++ b/drivers/video/fbdev/pxafb.c
diff --git a/drivers/video/pxafb.h b/drivers/video/fbdev/pxafb.h
index 26ba9fa..26ba9fa 100644
--- a/drivers/video/pxafb.h
+++ b/drivers/video/fbdev/pxafb.h
diff --git a/drivers/video/q40fb.c b/drivers/video/fbdev/q40fb.c
index 7487f76..7487f76 100644
--- a/drivers/video/q40fb.c
+++ b/drivers/video/fbdev/q40fb.c
diff --git a/drivers/video/riva/Makefile b/drivers/video/fbdev/riva/Makefile
index 8898c99..8898c99 100644
--- a/drivers/video/riva/Makefile
+++ b/drivers/video/fbdev/riva/Makefile
diff --git a/drivers/video/riva/fbdev.c b/drivers/video/fbdev/riva/fbdev.c
index 8a8d7f0..8a8d7f0 100644
--- a/drivers/video/riva/fbdev.c
+++ b/drivers/video/fbdev/riva/fbdev.c
diff --git a/drivers/video/riva/nv_driver.c b/drivers/video/fbdev/riva/nv_driver.c
index f3694cf..f3694cf 100644
--- a/drivers/video/riva/nv_driver.c
+++ b/drivers/video/fbdev/riva/nv_driver.c
diff --git a/drivers/video/riva/nv_type.h b/drivers/video/fbdev/riva/nv_type.h
index a69480c..a69480c 100644
--- a/drivers/video/riva/nv_type.h
+++ b/drivers/video/fbdev/riva/nv_type.h
diff --git a/drivers/video/riva/nvreg.h b/drivers/video/fbdev/riva/nvreg.h
index abfc167..abfc167 100644
--- a/drivers/video/riva/nvreg.h
+++ b/drivers/video/fbdev/riva/nvreg.h
diff --git a/drivers/video/riva/riva_hw.c b/drivers/video/fbdev/riva/riva_hw.c
index 78fdbf5..78fdbf5 100644
--- a/drivers/video/riva/riva_hw.c
+++ b/drivers/video/fbdev/riva/riva_hw.c
diff --git a/drivers/video/riva/riva_hw.h b/drivers/video/fbdev/riva/riva_hw.h
index c2769f7..c2769f7 100644
--- a/drivers/video/riva/riva_hw.h
+++ b/drivers/video/fbdev/riva/riva_hw.h
diff --git a/drivers/video/riva/riva_tbl.h b/drivers/video/fbdev/riva/riva_tbl.h
index 7ee7d72..7ee7d72 100644
--- a/drivers/video/riva/riva_tbl.h
+++ b/drivers/video/fbdev/riva/riva_tbl.h
diff --git a/drivers/video/riva/rivafb-i2c.c b/drivers/video/fbdev/riva/rivafb-i2c.c
index 6a18337..6a18337 100644
--- a/drivers/video/riva/rivafb-i2c.c
+++ b/drivers/video/fbdev/riva/rivafb-i2c.c
diff --git a/drivers/video/riva/rivafb.h b/drivers/video/fbdev/riva/rivafb.h
index d9f107b..d9f107b 100644
--- a/drivers/video/riva/rivafb.h
+++ b/drivers/video/fbdev/riva/rivafb.h
diff --git a/drivers/video/s1d13xxxfb.c b/drivers/video/fbdev/s1d13xxxfb.c
index 83433cb..83433cb 100644
--- a/drivers/video/s1d13xxxfb.c
+++ b/drivers/video/fbdev/s1d13xxxfb.c
diff --git a/drivers/video/s3c-fb.c b/drivers/video/fbdev/s3c-fb.c
index 62acae2..62acae2 100644
--- a/drivers/video/s3c-fb.c
+++ b/drivers/video/fbdev/s3c-fb.c
diff --git a/drivers/video/s3c2410fb.c b/drivers/video/fbdev/s3c2410fb.c
index 81af5a6..81af5a6 100644
--- a/drivers/video/s3c2410fb.c
+++ b/drivers/video/fbdev/s3c2410fb.c
diff --git a/drivers/video/s3c2410fb.h b/drivers/video/fbdev/s3c2410fb.h
index 47a17bd..47a17bd 100644
--- a/drivers/video/s3c2410fb.h
+++ b/drivers/video/fbdev/s3c2410fb.h
diff --git a/drivers/video/s3fb.c b/drivers/video/fbdev/s3fb.c
index 9a3f8f1..9a3f8f1 100644
--- a/drivers/video/s3fb.c
+++ b/drivers/video/fbdev/s3fb.c
diff --git a/drivers/video/sa1100fb.c b/drivers/video/fbdev/sa1100fb.c
index 580c444e..580c444e 100644
--- a/drivers/video/sa1100fb.c
+++ b/drivers/video/fbdev/sa1100fb.c
diff --git a/drivers/video/sa1100fb.h b/drivers/video/fbdev/sa1100fb.h
index fc5d429..fc5d429 100644
--- a/drivers/video/sa1100fb.h
+++ b/drivers/video/fbdev/sa1100fb.h
diff --git a/drivers/video/savage/Makefile b/drivers/video/fbdev/savage/Makefile
index e09770f..e09770f 100644
--- a/drivers/video/savage/Makefile
+++ b/drivers/video/fbdev/savage/Makefile
diff --git a/drivers/video/savage/savagefb-i2c.c b/drivers/video/fbdev/savage/savagefb-i2c.c
index 80fa87e..80fa87e 100644
--- a/drivers/video/savage/savagefb-i2c.c
+++ b/drivers/video/fbdev/savage/savagefb-i2c.c
diff --git a/drivers/video/savage/savagefb.h b/drivers/video/fbdev/savage/savagefb.h
index dcaab90..dcaab90 100644
--- a/drivers/video/savage/savagefb.h
+++ b/drivers/video/fbdev/savage/savagefb.h
diff --git a/drivers/video/savage/savagefb_accel.c b/drivers/video/fbdev/savage/savagefb_accel.c
index bfefa62..bfefa62 100644
--- a/drivers/video/savage/savagefb_accel.c
+++ b/drivers/video/fbdev/savage/savagefb_accel.c
diff --git a/drivers/video/savage/savagefb_driver.c b/drivers/video/fbdev/savage/savagefb_driver.c
index 4dbf45f..4dbf45f 100644
--- a/drivers/video/savage/savagefb_driver.c
+++ b/drivers/video/fbdev/savage/savagefb_driver.c
diff --git a/drivers/video/sbuslib.c b/drivers/video/fbdev/sbuslib.c
index a350209..a350209 100644
--- a/drivers/video/sbuslib.c
+++ b/drivers/video/fbdev/sbuslib.c
diff --git a/drivers/video/sbuslib.h b/drivers/video/fbdev/sbuslib.h
index 7ba3250..7ba3250 100644
--- a/drivers/video/sbuslib.h
+++ b/drivers/video/fbdev/sbuslib.h
diff --git a/drivers/video/sh7760fb.c b/drivers/video/fbdev/sh7760fb.c
index 1265b25..1265b25 100644
--- a/drivers/video/sh7760fb.c
+++ b/drivers/video/fbdev/sh7760fb.c
diff --git a/drivers/video/sh_mipi_dsi.c b/drivers/video/fbdev/sh_mipi_dsi.c
index 8f6e8ff..8f6e8ff 100644
--- a/drivers/video/sh_mipi_dsi.c
+++ b/drivers/video/fbdev/sh_mipi_dsi.c
diff --git a/drivers/video/sh_mobile_hdmi.c b/drivers/video/fbdev/sh_mobile_hdmi.c
index 9a33ee0..9a33ee0 100644
--- a/drivers/video/sh_mobile_hdmi.c
+++ b/drivers/video/fbdev/sh_mobile_hdmi.c
diff --git a/drivers/video/sh_mobile_lcdcfb.c b/drivers/video/fbdev/sh_mobile_lcdcfb.c
index 2bcc84a..2bcc84a 100644
--- a/drivers/video/sh_mobile_lcdcfb.c
+++ b/drivers/video/fbdev/sh_mobile_lcdcfb.c
diff --git a/drivers/video/sh_mobile_lcdcfb.h b/drivers/video/fbdev/sh_mobile_lcdcfb.h
index f839ade..f839ade 100644
--- a/drivers/video/sh_mobile_lcdcfb.h
+++ b/drivers/video/fbdev/sh_mobile_lcdcfb.h
diff --git a/drivers/video/sh_mobile_meram.c b/drivers/video/fbdev/sh_mobile_meram.c
index a297de5..a297de5 100644
--- a/drivers/video/sh_mobile_meram.c
+++ b/drivers/video/fbdev/sh_mobile_meram.c
diff --git a/drivers/video/simplefb.c b/drivers/video/fbdev/simplefb.c
index 210f3a0..210f3a0 100644
--- a/drivers/video/simplefb.c
+++ b/drivers/video/fbdev/simplefb.c
diff --git a/drivers/video/sis/300vtbl.h b/drivers/video/fbdev/sis/300vtbl.h
index e4b4a26..e4b4a26 100644
--- a/drivers/video/sis/300vtbl.h
+++ b/drivers/video/fbdev/sis/300vtbl.h
diff --git a/drivers/video/sis/310vtbl.h b/drivers/video/fbdev/sis/310vtbl.h
index 54fcbbf..54fcbbf 100644
--- a/drivers/video/sis/310vtbl.h
+++ b/drivers/video/fbdev/sis/310vtbl.h
diff --git a/drivers/video/sis/Makefile b/drivers/video/fbdev/sis/Makefile
index f7c0046..f7c0046 100644
--- a/drivers/video/sis/Makefile
+++ b/drivers/video/fbdev/sis/Makefile
diff --git a/drivers/video/sis/init.c b/drivers/video/fbdev/sis/init.c
index bd40f5e..bd40f5e 100644
--- a/drivers/video/sis/init.c
+++ b/drivers/video/fbdev/sis/init.c
diff --git a/drivers/video/sis/init.h b/drivers/video/fbdev/sis/init.h
index 85d6738..85d6738 100644
--- a/drivers/video/sis/init.h
+++ b/drivers/video/fbdev/sis/init.h
diff --git a/drivers/video/sis/init301.c b/drivers/video/fbdev/sis/init301.c
index a89e3ca..a89e3ca 100644
--- a/drivers/video/sis/init301.c
+++ b/drivers/video/fbdev/sis/init301.c
diff --git a/drivers/video/sis/init301.h b/drivers/video/fbdev/sis/init301.h
index 2112d6d..2112d6d 100644
--- a/drivers/video/sis/init301.h
+++ b/drivers/video/fbdev/sis/init301.h
diff --git a/drivers/video/sis/initdef.h b/drivers/video/fbdev/sis/initdef.h
index 264b55a..264b55a 100644
--- a/drivers/video/sis/initdef.h
+++ b/drivers/video/fbdev/sis/initdef.h
diff --git a/drivers/video/sis/initextlfb.c b/drivers/video/fbdev/sis/initextlfb.c
index 3ab18f5..3ab18f5 100644
--- a/drivers/video/sis/initextlfb.c
+++ b/drivers/video/fbdev/sis/initextlfb.c
diff --git a/drivers/video/sis/oem300.h b/drivers/video/fbdev/sis/oem300.h
index b73f268..b73f268 100644
--- a/drivers/video/sis/oem300.h
+++ b/drivers/video/fbdev/sis/oem300.h
diff --git a/drivers/video/sis/oem310.h b/drivers/video/fbdev/sis/oem310.h
index 8fce56e..8fce56e 100644
--- a/drivers/video/sis/oem310.h
+++ b/drivers/video/fbdev/sis/oem310.h
diff --git a/drivers/video/sis/sis.h b/drivers/video/fbdev/sis/sis.h
index 1987f1b7..1987f1b7 100644
--- a/drivers/video/sis/sis.h
+++ b/drivers/video/fbdev/sis/sis.h
diff --git a/drivers/video/sis/sis_accel.c b/drivers/video/fbdev/sis/sis_accel.c
index ceb434c..ceb434c 100644
--- a/drivers/video/sis/sis_accel.c
+++ b/drivers/video/fbdev/sis/sis_accel.c
diff --git a/drivers/video/sis/sis_accel.h b/drivers/video/fbdev/sis/sis_accel.h
index 30e03cd..30e03cd 100644
--- a/drivers/video/sis/sis_accel.h
+++ b/drivers/video/fbdev/sis/sis_accel.h
diff --git a/drivers/video/sis/sis_main.c b/drivers/video/fbdev/sis/sis_main.c
index 22ad028..22ad028 100644
--- a/drivers/video/sis/sis_main.c
+++ b/drivers/video/fbdev/sis/sis_main.c
diff --git a/drivers/video/sis/sis_main.h b/drivers/video/fbdev/sis/sis_main.h
index 32e23c2..32e23c2 100644
--- a/drivers/video/sis/sis_main.h
+++ b/drivers/video/fbdev/sis/sis_main.h
diff --git a/drivers/video/sis/vgatypes.h b/drivers/video/fbdev/sis/vgatypes.h
index e3f9976..e3f9976 100644
--- a/drivers/video/sis/vgatypes.h
+++ b/drivers/video/fbdev/sis/vgatypes.h
diff --git a/drivers/video/sis/vstruct.h b/drivers/video/fbdev/sis/vstruct.h
index ea94d21..ea94d21 100644
--- a/drivers/video/sis/vstruct.h
+++ b/drivers/video/fbdev/sis/vstruct.h
diff --git a/drivers/video/skeletonfb.c b/drivers/video/fbdev/skeletonfb.c
index fefde7c..fefde7c 100644
--- a/drivers/video/skeletonfb.c
+++ b/drivers/video/fbdev/skeletonfb.c
diff --git a/drivers/video/sm501fb.c b/drivers/video/fbdev/sm501fb.c
index 1501979..1501979 100644
--- a/drivers/video/sm501fb.c
+++ b/drivers/video/fbdev/sm501fb.c
diff --git a/drivers/video/smscufx.c b/drivers/video/fbdev/smscufx.c
index d513ed6..d513ed6 100644
--- a/drivers/video/smscufx.c
+++ b/drivers/video/fbdev/smscufx.c
diff --git a/drivers/video/ssd1307fb.c b/drivers/video/fbdev/ssd1307fb.c
index f4daa59..f4daa59 100644
--- a/drivers/video/ssd1307fb.c
+++ b/drivers/video/fbdev/ssd1307fb.c
diff --git a/drivers/video/sstfb.c b/drivers/video/fbdev/sstfb.c
index f0cb279..f0cb279 100644
--- a/drivers/video/sstfb.c
+++ b/drivers/video/fbdev/sstfb.c
diff --git a/drivers/video/sticore.h b/drivers/video/fbdev/sticore.h
index af16195..af16195 100644
--- a/drivers/video/sticore.h
+++ b/drivers/video/fbdev/sticore.h
diff --git a/drivers/video/stifb.c b/drivers/video/fbdev/stifb.c
index cfe8a2f..cfe8a2f 100644
--- a/drivers/video/stifb.c
+++ b/drivers/video/fbdev/stifb.c
diff --git a/drivers/video/sunxvr1000.c b/drivers/video/fbdev/sunxvr1000.c
index 58241b4..58241b4 100644
--- a/drivers/video/sunxvr1000.c
+++ b/drivers/video/fbdev/sunxvr1000.c
diff --git a/drivers/video/sunxvr2500.c b/drivers/video/fbdev/sunxvr2500.c
index 843b6ba..843b6ba 100644
--- a/drivers/video/sunxvr2500.c
+++ b/drivers/video/fbdev/sunxvr2500.c
diff --git a/drivers/video/sunxvr500.c b/drivers/video/fbdev/sunxvr500.c
index 387350d..387350d 100644
--- a/drivers/video/sunxvr500.c
+++ b/drivers/video/fbdev/sunxvr500.c
diff --git a/drivers/video/tcx.c b/drivers/video/fbdev/tcx.c
index 7fb2d69..7fb2d69 100644
--- a/drivers/video/tcx.c
+++ b/drivers/video/fbdev/tcx.c
diff --git a/drivers/video/tdfxfb.c b/drivers/video/fbdev/tdfxfb.c
index f761fe3..f761fe3 100644
--- a/drivers/video/tdfxfb.c
+++ b/drivers/video/fbdev/tdfxfb.c
diff --git a/drivers/video/tgafb.c b/drivers/video/fbdev/tgafb.c
index 65ba992..65ba992 100644
--- a/drivers/video/tgafb.c
+++ b/drivers/video/fbdev/tgafb.c
diff --git a/drivers/video/tmiofb.c b/drivers/video/fbdev/tmiofb.c
index 7fb4e32..7fb4e32 100644
--- a/drivers/video/tmiofb.c
+++ b/drivers/video/fbdev/tmiofb.c
diff --git a/drivers/video/tridentfb.c b/drivers/video/fbdev/tridentfb.c
index 7ed9a22..7ed9a22 100644
--- a/drivers/video/tridentfb.c
+++ b/drivers/video/fbdev/tridentfb.c
diff --git a/drivers/video/udlfb.c b/drivers/video/fbdev/udlfb.c
index 77b890e..77b890e 100644
--- a/drivers/video/udlfb.c
+++ b/drivers/video/fbdev/udlfb.c
diff --git a/drivers/video/uvesafb.c b/drivers/video/fbdev/uvesafb.c
index 509d452..509d452 100644
--- a/drivers/video/uvesafb.c
+++ b/drivers/video/fbdev/uvesafb.c
diff --git a/drivers/video/valkyriefb.c b/drivers/video/fbdev/valkyriefb.c
index 97cb9bd..97cb9bd 100644
--- a/drivers/video/valkyriefb.c
+++ b/drivers/video/fbdev/valkyriefb.c
diff --git a/drivers/video/valkyriefb.h b/drivers/video/fbdev/valkyriefb.h
index d787441..d787441 100644
--- a/drivers/video/valkyriefb.h
+++ b/drivers/video/fbdev/valkyriefb.h
diff --git a/drivers/video/vermilion/Makefile b/drivers/video/fbdev/vermilion/Makefile
index cc21a65..cc21a65 100644
--- a/drivers/video/vermilion/Makefile
+++ b/drivers/video/fbdev/vermilion/Makefile
diff --git a/drivers/video/vermilion/cr_pll.c b/drivers/video/fbdev/vermilion/cr_pll.c
index ebc6e6e..ebc6e6e 100644
--- a/drivers/video/vermilion/cr_pll.c
+++ b/drivers/video/fbdev/vermilion/cr_pll.c
diff --git a/drivers/video/vermilion/vermilion.c b/drivers/video/fbdev/vermilion/vermilion.c
index 048a666..048a666 100644
--- a/drivers/video/vermilion/vermilion.c
+++ b/drivers/video/fbdev/vermilion/vermilion.c
diff --git a/drivers/video/vermilion/vermilion.h b/drivers/video/fbdev/vermilion/vermilion.h
index 43d11ec..43d11ec 100644
--- a/drivers/video/vermilion/vermilion.h
+++ b/drivers/video/fbdev/vermilion/vermilion.h
diff --git a/drivers/video/vesafb.c b/drivers/video/fbdev/vesafb.c
index 6170e7f..6170e7f 100644
--- a/drivers/video/vesafb.c
+++ b/drivers/video/fbdev/vesafb.c
diff --git a/drivers/video/vfb.c b/drivers/video/fbdev/vfb.c
index 70a897b..70a897b 100644
--- a/drivers/video/vfb.c
+++ b/drivers/video/fbdev/vfb.c
diff --git a/drivers/video/vga16fb.c b/drivers/video/fbdev/vga16fb.c
index 283d335..283d335 100644
--- a/drivers/video/vga16fb.c
+++ b/drivers/video/fbdev/vga16fb.c
diff --git a/drivers/video/via/Makefile b/drivers/video/fbdev/via/Makefile
index 159f26e..159f26e 100644
--- a/drivers/video/via/Makefile
+++ b/drivers/video/fbdev/via/Makefile
diff --git a/drivers/video/via/accel.c b/drivers/video/fbdev/via/accel.c
index 4b67b8e..4b67b8e 100644
--- a/drivers/video/via/accel.c
+++ b/drivers/video/fbdev/via/accel.c
diff --git a/drivers/video/via/accel.h b/drivers/video/fbdev/via/accel.h
index 79d5e10..79d5e10 100644
--- a/drivers/video/via/accel.h
+++ b/drivers/video/fbdev/via/accel.h
diff --git a/drivers/video/via/chip.h b/drivers/video/fbdev/via/chip.h
index d32a507..d32a507 100644
--- a/drivers/video/via/chip.h
+++ b/drivers/video/fbdev/via/chip.h
diff --git a/drivers/video/via/debug.h b/drivers/video/fbdev/via/debug.h
index 86eacc2..86eacc2 100644
--- a/drivers/video/via/debug.h
+++ b/drivers/video/fbdev/via/debug.h
diff --git a/drivers/video/via/dvi.c b/drivers/video/fbdev/via/dvi.c
index 7789553..7789553 100644
--- a/drivers/video/via/dvi.c
+++ b/drivers/video/fbdev/via/dvi.c
diff --git a/drivers/video/via/dvi.h b/drivers/video/fbdev/via/dvi.h
index 4c6bfba..4c6bfba 100644
--- a/drivers/video/via/dvi.h
+++ b/drivers/video/fbdev/via/dvi.h
diff --git a/drivers/video/via/global.c b/drivers/video/fbdev/via/global.c
index 3102171..3102171 100644
--- a/drivers/video/via/global.c
+++ b/drivers/video/fbdev/via/global.c
diff --git a/drivers/video/via/global.h b/drivers/video/fbdev/via/global.h
index 275dbbb..275dbbb 100644
--- a/drivers/video/via/global.h
+++ b/drivers/video/fbdev/via/global.h
diff --git a/drivers/video/via/hw.c b/drivers/video/fbdev/via/hw.c
index 22450908..22450908 100644
--- a/drivers/video/via/hw.c
+++ b/drivers/video/fbdev/via/hw.c
diff --git a/drivers/video/via/hw.h b/drivers/video/fbdev/via/hw.h
index 3be073c..3be073c 100644
--- a/drivers/video/via/hw.h
+++ b/drivers/video/fbdev/via/hw.h
diff --git a/drivers/video/via/ioctl.c b/drivers/video/fbdev/via/ioctl.c
index ea1c514..ea1c514 100644
--- a/drivers/video/via/ioctl.c
+++ b/drivers/video/fbdev/via/ioctl.c
diff --git a/drivers/video/via/ioctl.h b/drivers/video/fbdev/via/ioctl.h
index 6010d10..6010d10 100644
--- a/drivers/video/via/ioctl.h
+++ b/drivers/video/fbdev/via/ioctl.h
diff --git a/drivers/video/via/lcd.c b/drivers/video/fbdev/via/lcd.c
index 5d21ff4..5d21ff4 100644
--- a/drivers/video/via/lcd.c
+++ b/drivers/video/fbdev/via/lcd.c
diff --git a/drivers/video/via/lcd.h b/drivers/video/fbdev/via/lcd.h
index 5c988a0..5c988a0 100644
--- a/drivers/video/via/lcd.h
+++ b/drivers/video/fbdev/via/lcd.h
diff --git a/drivers/video/via/share.h b/drivers/video/fbdev/via/share.h
index 65c65c6..65c65c6 100644
--- a/drivers/video/via/share.h
+++ b/drivers/video/fbdev/via/share.h
diff --git a/drivers/video/via/tblDPASetting.c b/drivers/video/fbdev/via/tblDPASetting.c
index 73bb554..73bb554 100644
--- a/drivers/video/via/tblDPASetting.c
+++ b/drivers/video/fbdev/via/tblDPASetting.c
diff --git a/drivers/video/via/tblDPASetting.h b/drivers/video/fbdev/via/tblDPASetting.h
index 6db6151..6db6151 100644
--- a/drivers/video/via/tblDPASetting.h
+++ b/drivers/video/fbdev/via/tblDPASetting.h
diff --git a/drivers/video/via/via-core.c b/drivers/video/fbdev/via/via-core.c
index 6e27482..6e27482 100644
--- a/drivers/video/via/via-core.c
+++ b/drivers/video/fbdev/via/via-core.c
diff --git a/drivers/video/via/via-gpio.c b/drivers/video/fbdev/via/via-gpio.c
index e408679..e408679 100644
--- a/drivers/video/via/via-gpio.c
+++ b/drivers/video/fbdev/via/via-gpio.c
diff --git a/drivers/video/via/via_aux.c b/drivers/video/fbdev/via/via_aux.c
index 4a0a55c..4a0a55c 100644
--- a/drivers/video/via/via_aux.c
+++ b/drivers/video/fbdev/via/via_aux.c
diff --git a/drivers/video/via/via_aux.h b/drivers/video/fbdev/via/via_aux.h
index a8de3f0..a8de3f0 100644
--- a/drivers/video/via/via_aux.h
+++ b/drivers/video/fbdev/via/via_aux.h
diff --git a/drivers/video/via/via_aux_ch7301.c b/drivers/video/fbdev/via/via_aux_ch7301.c
index 1cbe503..1cbe503 100644
--- a/drivers/video/via/via_aux_ch7301.c
+++ b/drivers/video/fbdev/via/via_aux_ch7301.c
diff --git a/drivers/video/via/via_aux_edid.c b/drivers/video/fbdev/via/via_aux_edid.c
index 754d450..754d450 100644
--- a/drivers/video/via/via_aux_edid.c
+++ b/drivers/video/fbdev/via/via_aux_edid.c
diff --git a/drivers/video/via/via_aux_sii164.c b/drivers/video/fbdev/via/via_aux_sii164.c
index ca1b35f..ca1b35f 100644
--- a/drivers/video/via/via_aux_sii164.c
+++ b/drivers/video/fbdev/via/via_aux_sii164.c
diff --git a/drivers/video/via/via_aux_vt1621.c b/drivers/video/fbdev/via/via_aux_vt1621.c
index 38eca84..38eca84 100644
--- a/drivers/video/via/via_aux_vt1621.c
+++ b/drivers/video/fbdev/via/via_aux_vt1621.c
diff --git a/drivers/video/via/via_aux_vt1622.c b/drivers/video/fbdev/via/via_aux_vt1622.c
index 8c79c68..8c79c68 100644
--- a/drivers/video/via/via_aux_vt1622.c
+++ b/drivers/video/fbdev/via/via_aux_vt1622.c
diff --git a/drivers/video/via/via_aux_vt1625.c b/drivers/video/fbdev/via/via_aux_vt1625.c
index 03eb301..03eb301 100644
--- a/drivers/video/via/via_aux_vt1625.c
+++ b/drivers/video/fbdev/via/via_aux_vt1625.c
diff --git a/drivers/video/via/via_aux_vt1631.c b/drivers/video/fbdev/via/via_aux_vt1631.c
index 06e742f..06e742f 100644
--- a/drivers/video/via/via_aux_vt1631.c
+++ b/drivers/video/fbdev/via/via_aux_vt1631.c
diff --git a/drivers/video/via/via_aux_vt1632.c b/drivers/video/fbdev/via/via_aux_vt1632.c
index d24f4cd..d24f4cd 100644
--- a/drivers/video/via/via_aux_vt1632.c
+++ b/drivers/video/fbdev/via/via_aux_vt1632.c
diff --git a/drivers/video/via/via_aux_vt1636.c b/drivers/video/fbdev/via/via_aux_vt1636.c
index 9e015c1..9e015c1 100644
--- a/drivers/video/via/via_aux_vt1636.c
+++ b/drivers/video/fbdev/via/via_aux_vt1636.c
diff --git a/drivers/video/via/via_clock.c b/drivers/video/fbdev/via/via_clock.c
index db1e392..db1e392 100644
--- a/drivers/video/via/via_clock.c
+++ b/drivers/video/fbdev/via/via_clock.c
diff --git a/drivers/video/via/via_clock.h b/drivers/video/fbdev/via/via_clock.h
index 88714ae..88714ae 100644
--- a/drivers/video/via/via_clock.h
+++ b/drivers/video/fbdev/via/via_clock.h
diff --git a/drivers/video/via/via_i2c.c b/drivers/video/fbdev/via/via_i2c.c
index dd53058..dd53058 100644
--- a/drivers/video/via/via_i2c.c
+++ b/drivers/video/fbdev/via/via_i2c.c
diff --git a/drivers/video/via/via_modesetting.c b/drivers/video/fbdev/via/via_modesetting.c
index 0b414b0..0b414b0 100644
--- a/drivers/video/via/via_modesetting.c
+++ b/drivers/video/fbdev/via/via_modesetting.c
diff --git a/drivers/video/via/via_modesetting.h b/drivers/video/fbdev/via/via_modesetting.h
index f6a6503..f6a6503 100644
--- a/drivers/video/via/via_modesetting.h
+++ b/drivers/video/fbdev/via/via_modesetting.h
diff --git a/drivers/video/via/via_utility.c b/drivers/video/fbdev/via/via_utility.c
index 35458a5..35458a5 100644
--- a/drivers/video/via/via_utility.c
+++ b/drivers/video/fbdev/via/via_utility.c
diff --git a/drivers/video/via/via_utility.h b/drivers/video/fbdev/via/via_utility.h
index f23be17..f23be17 100644
--- a/drivers/video/via/via_utility.h
+++ b/drivers/video/fbdev/via/via_utility.h
diff --git a/drivers/video/via/viafbdev.c b/drivers/video/fbdev/via/viafbdev.c
index 325c43c..325c43c 100644
--- a/drivers/video/via/viafbdev.c
+++ b/drivers/video/fbdev/via/viafbdev.c
diff --git a/drivers/video/via/viafbdev.h b/drivers/video/fbdev/via/viafbdev.h
index f6b2ddf..f6b2ddf 100644
--- a/drivers/video/via/viafbdev.h
+++ b/drivers/video/fbdev/via/viafbdev.h
diff --git a/drivers/video/via/viamode.c b/drivers/video/fbdev/via/viamode.c
index 0666ab0..0666ab0 100644
--- a/drivers/video/via/viamode.c
+++ b/drivers/video/fbdev/via/viamode.c
diff --git a/drivers/video/via/viamode.h b/drivers/video/fbdev/via/viamode.h
index dd19106..dd19106 100644
--- a/drivers/video/via/viamode.h
+++ b/drivers/video/fbdev/via/viamode.h
diff --git a/drivers/video/via/vt1636.c b/drivers/video/fbdev/via/vt1636.c
index ee2903b..ee2903b 100644
--- a/drivers/video/via/vt1636.c
+++ b/drivers/video/fbdev/via/vt1636.c
diff --git a/drivers/video/via/vt1636.h b/drivers/video/fbdev/via/vt1636.h
index 4c1314e..4c1314e 100644
--- a/drivers/video/via/vt1636.h
+++ b/drivers/video/fbdev/via/vt1636.h
diff --git a/drivers/video/vt8500lcdfb.c b/drivers/video/fbdev/vt8500lcdfb.c
index a8f2b28..a8f2b28 100644
--- a/drivers/video/vt8500lcdfb.c
+++ b/drivers/video/fbdev/vt8500lcdfb.c
diff --git a/drivers/video/vt8500lcdfb.h b/drivers/video/fbdev/vt8500lcdfb.h
index 36ca3ca..36ca3ca 100644
--- a/drivers/video/vt8500lcdfb.h
+++ b/drivers/video/fbdev/vt8500lcdfb.h
diff --git a/drivers/video/vt8623fb.c b/drivers/video/fbdev/vt8623fb.c
index 5c7cbc6..5c7cbc6 100644
--- a/drivers/video/vt8623fb.c
+++ b/drivers/video/fbdev/vt8623fb.c
diff --git a/drivers/video/w100fb.c b/drivers/video/fbdev/w100fb.c
index 10951c8..10951c8 100644
--- a/drivers/video/w100fb.c
+++ b/drivers/video/fbdev/w100fb.c
diff --git a/drivers/video/w100fb.h b/drivers/video/fbdev/w100fb.h
index fffae7b..fffae7b 100644
--- a/drivers/video/w100fb.h
+++ b/drivers/video/fbdev/w100fb.h
diff --git a/drivers/video/wm8505fb.c b/drivers/video/fbdev/wm8505fb.c
index 537d199..537d199 100644
--- a/drivers/video/wm8505fb.c
+++ b/drivers/video/fbdev/wm8505fb.c
diff --git a/drivers/video/wm8505fb_regs.h b/drivers/video/fbdev/wm8505fb_regs.h
index 4dd4166..4dd4166 100644
--- a/drivers/video/wm8505fb_regs.h
+++ b/drivers/video/fbdev/wm8505fb_regs.h
diff --git a/drivers/video/wmt_ge_rops.c b/drivers/video/fbdev/wmt_ge_rops.c
index b0a9f34..9df6fe7 100644
--- a/drivers/video/wmt_ge_rops.c
+++ b/drivers/video/fbdev/wmt_ge_rops.c
@@ -18,7 +18,7 @@
#include <linux/module.h>
#include <linux/fb.h>
#include <linux/platform_device.h>
-#include "fb_draw.h"
+#include "core/fb_draw.h"
#define GE_COMMAND_OFF 0x00
#define GE_DEPTH_OFF 0x04
diff --git a/drivers/video/wmt_ge_rops.h b/drivers/video/fbdev/wmt_ge_rops.h
index f73ec63..f73ec63 100644
--- a/drivers/video/wmt_ge_rops.h
+++ b/drivers/video/fbdev/wmt_ge_rops.h
diff --git a/drivers/video/xen-fbfront.c b/drivers/video/fbdev/xen-fbfront.c
index 901014b..901014b 100644
--- a/drivers/video/xen-fbfront.c
+++ b/drivers/video/fbdev/xen-fbfront.c
diff --git a/drivers/video/xilinxfb.c b/drivers/video/fbdev/xilinxfb.c
index 553cff2f..553cff2f 100644
--- a/drivers/video/xilinxfb.c
+++ b/drivers/video/fbdev/xilinxfb.c
diff --git a/drivers/video/omap2/Kconfig b/drivers/video/omap2/Kconfig
deleted file mode 100644
index 63b23f8..0000000
--- a/drivers/video/omap2/Kconfig
+++ /dev/null
@@ -1,10 +0,0 @@
-config OMAP2_VRFB
- bool
-
-if ARCH_OMAP2PLUS
-
-source "drivers/video/omap2/dss/Kconfig"
-source "drivers/video/omap2/omapfb/Kconfig"
-source "drivers/video/omap2/displays-new/Kconfig"
-
-endif
diff --git a/drivers/vme/bridges/vme_tsi148.c b/drivers/vme/bridges/vme_tsi148.c
index 06990c6..61e706c0 100644
--- a/drivers/vme/bridges/vme_tsi148.c
+++ b/drivers/vme/bridges/vme_tsi148.c
@@ -320,7 +320,7 @@ static int tsi148_irq_init(struct vme_bridge *tsi148_bridge)
struct pci_dev *pdev;
struct tsi148_driver *bridge;
- pdev = container_of(tsi148_bridge->parent, struct pci_dev, dev);
+ pdev = to_pci_dev(tsi148_bridge->parent);
bridge = tsi148_bridge->driver_priv;
@@ -433,9 +433,7 @@ static void tsi148_irq_set(struct vme_bridge *tsi148_bridge, int level,
iowrite32be(tmp, bridge->base + TSI148_LCSR_INTEO);
if (sync != 0) {
- pdev = container_of(tsi148_bridge->parent,
- struct pci_dev, dev);
-
+ pdev = to_pci_dev(tsi148_bridge->parent);
synchronize_irq(pdev->irq);
}
} else {
@@ -741,7 +739,7 @@ static int tsi148_slave_get(struct vme_slave_resource *image, int *enabled,
reg_join(vme_bound_high, vme_bound_low, &vme_bound);
reg_join(pci_offset_high, pci_offset_low, &pci_offset);
- *pci_base = (dma_addr_t)vme_base + pci_offset;
+ *pci_base = (dma_addr_t)(*vme_base + pci_offset);
*enabled = 0;
*aspace = 0;
@@ -814,7 +812,7 @@ static int tsi148_alloc_resource(struct vme_master_resource *image,
tsi148_bridge = image->parent;
- pdev = container_of(tsi148_bridge->parent, struct pci_dev, dev);
+ pdev = to_pci_dev(tsi148_bridge->parent);
existing_size = (unsigned long long)(image->bus_resource.end -
image->bus_resource.start);
@@ -910,11 +908,15 @@ static int tsi148_master_set(struct vme_master_resource *image, int enabled,
unsigned long long pci_bound, vme_offset, pci_base;
struct vme_bridge *tsi148_bridge;
struct tsi148_driver *bridge;
+ struct pci_bus_region region;
+ struct pci_dev *pdev;
tsi148_bridge = image->parent;
bridge = tsi148_bridge->driver_priv;
+ pdev = to_pci_dev(tsi148_bridge->parent);
+
/* Verify input data */
if (vme_base & 0xFFFF) {
dev_err(tsi148_bridge->parent, "Invalid VME Window "
@@ -949,7 +951,9 @@ static int tsi148_master_set(struct vme_master_resource *image, int enabled,
pci_bound = 0;
vme_offset = 0;
} else {
- pci_base = (unsigned long long)image->bus_resource.start;
+ pcibios_resource_to_bus(pdev->bus, &region,
+ &image->bus_resource);
+ pci_base = region.start;
/*
* Bound address is a valid address for the window, adjust
@@ -2232,7 +2236,7 @@ static void *tsi148_alloc_consistent(struct device *parent, size_t size,
struct pci_dev *pdev;
/* Find pci_dev container of dev */
- pdev = container_of(parent, struct pci_dev, dev);
+ pdev = to_pci_dev(parent);
return pci_alloc_consistent(pdev, size, dma);
}
@@ -2243,7 +2247,7 @@ static void tsi148_free_consistent(struct device *parent, size_t size,
struct pci_dev *pdev;
/* Find pci_dev container of dev */
- pdev = container_of(parent, struct pci_dev, dev);
+ pdev = to_pci_dev(parent);
pci_free_consistent(pdev, size, vaddr, dma);
}
diff --git a/drivers/w1/w1.c b/drivers/w1/w1.c
index b96f61b..ff52618 100644
--- a/drivers/w1/w1.c
+++ b/drivers/w1/w1.c
@@ -614,27 +614,11 @@ end:
return err;
}
-/*
- * Handle sysfs file creation and removal here, before userspace is told that
- * the device is added / removed from the system
- */
-static int w1_bus_notify(struct notifier_block *nb, unsigned long action,
- void *data)
+static int w1_family_notify(unsigned long action, struct w1_slave *sl)
{
- struct device *dev = data;
- struct w1_slave *sl;
struct w1_family_ops *fops;
int err;
- /*
- * Only care about slave devices at the moment. Yes, we should use a
- * separate "type" for this, but for now, look at the release function
- * to know which type it is...
- */
- if (dev->release != w1_slave_release)
- return 0;
-
- sl = dev_to_w1_slave(dev);
fops = sl->family->fops;
if (!fops)
@@ -673,10 +657,6 @@ static int w1_bus_notify(struct notifier_block *nb, unsigned long action,
return 0;
}
-static struct notifier_block w1_bus_nb = {
- .notifier_call = w1_bus_notify,
-};
-
static int __w1_attach_slave_device(struct w1_slave *sl)
{
int err;
@@ -698,6 +678,9 @@ static int __w1_attach_slave_device(struct w1_slave *sl)
dev_dbg(&sl->dev, "%s: registering %s as %p.\n", __func__,
dev_name(&sl->dev), sl);
+ /* suppress for w1_family_notify before sending KOBJ_ADD */
+ dev_set_uevent_suppress(&sl->dev, true);
+
err = device_register(&sl->dev);
if (err < 0) {
dev_err(&sl->dev,
@@ -705,7 +688,7 @@ static int __w1_attach_slave_device(struct w1_slave *sl)
dev_name(&sl->dev), err);
return err;
}
-
+ w1_family_notify(BUS_NOTIFY_ADD_DEVICE, sl);
dev_set_uevent_suppress(&sl->dev, false);
kobject_uevent(&sl->dev.kobj, KOBJ_ADD);
@@ -799,6 +782,7 @@ int w1_unref_slave(struct w1_slave *sl)
msg.type = W1_SLAVE_REMOVE;
w1_netlink_send(sl->master, &msg);
+ w1_family_notify(BUS_NOTIFY_DEL_DEVICE, sl);
device_unregister(&sl->dev);
#ifdef DEBUG
memset(sl, 0, sizeof(*sl));
@@ -1186,10 +1170,6 @@ static int __init w1_init(void)
goto err_out_exit_init;
}
- retval = bus_register_notifier(&w1_bus_type, &w1_bus_nb);
- if (retval)
- goto err_out_bus_unregister;
-
retval = driver_register(&w1_master_driver);
if (retval) {
printk(KERN_ERR
diff --git a/drivers/w1/w1_netlink.c b/drivers/w1/w1_netlink.c
index 5234964..a02704a 100644
--- a/drivers/w1/w1_netlink.c
+++ b/drivers/w1/w1_netlink.c
@@ -300,12 +300,6 @@ static int w1_process_command_root(struct cn_msg *msg,
struct w1_netlink_msg *w;
u32 *id;
- if (mcmd->type != W1_LIST_MASTERS) {
- printk(KERN_NOTICE "%s: msg: %x.%x, wrong type: %u, len: %u.\n",
- __func__, msg->id.idx, msg->id.val, mcmd->type, mcmd->len);
- return -EPROTO;
- }
-
cn = kmalloc(PAGE_SIZE, GFP_KERNEL);
if (!cn)
return -ENOMEM;
@@ -441,6 +435,9 @@ static void w1_process_cb(struct w1_master *dev, struct w1_async_cmd *async_cmd)
w1_netlink_send_error(&node->block->msg, node->m, cmd,
node->block->portid, err);
+ /* ref taken in w1_search_slave or w1_search_master_id when building
+ * the block
+ */
if (sl)
w1_unref_slave(sl);
else
@@ -503,30 +500,42 @@ static void w1_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
msg_len = msg->len;
while (msg_len && !err) {
- struct w1_reg_num id;
- u16 mlen = m->len;
dev = NULL;
sl = NULL;
- memcpy(&id, m->id.id, sizeof(id));
-#if 0
- printk("%s: %02x.%012llx.%02x: type=%02x, len=%u.\n",
- __func__, id.family, (unsigned long long)id.id, id.crc, m->type, m->len);
-#endif
if (m->len + sizeof(struct w1_netlink_msg) > msg_len) {
err = -E2BIG;
break;
}
+ /* execute on this thread, no need to process later */
+ if (m->type == W1_LIST_MASTERS) {
+ err = w1_process_command_root(msg, m, nsp->portid);
+ goto out_cont;
+ }
+
+ /* All following message types require additional data,
+ * check here before references are taken.
+ */
+ if (!m->len) {
+ err = -EPROTO;
+ goto out_cont;
+ }
+
+ /* both search calls take reference counts */
if (m->type == W1_MASTER_CMD) {
dev = w1_search_master_id(m->id.mst.id);
} else if (m->type == W1_SLAVE_CMD) {
- sl = w1_search_slave(&id);
+ sl = w1_search_slave((struct w1_reg_num *)m->id.id);
if (sl)
dev = sl->master;
} else {
- err = w1_process_command_root(msg, m, nsp->portid);
+ printk(KERN_NOTICE
+ "%s: msg: %x.%x, wrong type: %u, len: %u.\n",
+ __func__, msg->id.idx, msg->id.val,
+ m->type, m->len);
+ err = -EPROTO;
goto out_cont;
}
@@ -536,8 +545,6 @@ static void w1_cn_callback(struct cn_msg *msg, struct netlink_skb_parms *nsp)
}
err = 0;
- if (!mlen)
- goto out_cont;
atomic_inc(&block->refcnt);
node->async.cb = w1_process_cb;
@@ -557,7 +564,8 @@ out_cont:
if (err)
w1_netlink_send_error(msg, m, NULL, nsp->portid, err);
msg_len -= sizeof(struct w1_netlink_msg) + m->len;
- m = (struct w1_netlink_msg *)(((u8 *)m) + sizeof(struct w1_netlink_msg) + m->len);
+ m = (struct w1_netlink_msg *)(((u8 *)m) +
+ sizeof(struct w1_netlink_msg) + m->len);
/*
* Let's allow requests for nonexisting devices.
diff --git a/drivers/xen/manage.c b/drivers/xen/manage.c
index fc6c94c..32f9236 100644
--- a/drivers/xen/manage.c
+++ b/drivers/xen/manage.c
@@ -198,10 +198,32 @@ struct shutdown_handler {
void (*cb)(void);
};
+static int poweroff_nb(struct notifier_block *cb, unsigned long code, void *unused)
+{
+ switch (code) {
+ case SYS_DOWN:
+ case SYS_HALT:
+ case SYS_POWER_OFF:
+ shutting_down = SHUTDOWN_POWEROFF;
+ default:
+ break;
+ }
+ return NOTIFY_DONE;
+}
static void do_poweroff(void)
{
- shutting_down = SHUTDOWN_POWEROFF;
- orderly_poweroff(false);
+ switch (system_state) {
+ case SYSTEM_BOOTING:
+ orderly_poweroff(true);
+ break;
+ case SYSTEM_RUNNING:
+ orderly_poweroff(false);
+ break;
+ default:
+ /* Don't do it when we are halting/rebooting. */
+ pr_info("Ignoring Xen toolstack shutdown.\n");
+ break;
+ }
}
static void do_reboot(void)
@@ -307,6 +329,10 @@ static struct xenbus_watch shutdown_watch = {
.callback = shutdown_handler
};
+static struct notifier_block xen_reboot_nb = {
+ .notifier_call = poweroff_nb,
+};
+
static int setup_shutdown_watcher(void)
{
int err;
@@ -317,6 +343,7 @@ static int setup_shutdown_watcher(void)
return err;
}
+
#ifdef CONFIG_MAGIC_SYSRQ
err = register_xenbus_watch(&sysrq_watch);
if (err) {
@@ -345,6 +372,7 @@ int xen_setup_shutdown_event(void)
if (!xen_domain())
return -ENODEV;
register_xenstore_notifier(&xenstore_notifier);
+ register_reboot_notifier(&xen_reboot_nb);
return 0;
}
diff --git a/drivers/xen/xen-pciback/pciback_ops.c b/drivers/xen/xen-pciback/pciback_ops.c
index 929dd46..607e414 100644
--- a/drivers/xen/xen-pciback/pciback_ops.c
+++ b/drivers/xen/xen-pciback/pciback_ops.c
@@ -217,7 +217,7 @@ int xen_pcibk_enable_msix(struct xen_pcibk_device *pdev,
if (result == 0) {
for (i = 0; i < op->value; i++) {
op->msix_entries[i].entry = entries[i].entry;
- if (entries[i].vector)
+ if (entries[i].vector) {
op->msix_entries[i].vector =
xen_pirq_from_irq(entries[i].vector);
if (unlikely(verbose_request))
@@ -225,6 +225,7 @@ int xen_pcibk_enable_msix(struct xen_pcibk_device *pdev,
"MSI-X[%d]: %d\n",
pci_name(dev), i,
op->msix_entries[i].vector);
+ }
}
} else
pr_warn_ratelimited("%s: error enabling MSI-X for guest %u: err %d!\n",
diff --git a/drivers/xen/xen-pciback/vpci.c b/drivers/xen/xen-pciback/vpci.c
index 3165ce3..51afff9 100644
--- a/drivers/xen/xen-pciback/vpci.c
+++ b/drivers/xen/xen-pciback/vpci.c
@@ -137,6 +137,8 @@ unlock:
/* Publish this device. */
if (!err)
err = publish_cb(pdev, 0, 0, PCI_DEVFN(slot, func), devid);
+ else
+ kfree(dev_entry);
out:
return err;
diff --git a/drivers/xen/xenbus/xenbus_xs.c b/drivers/xen/xenbus/xenbus_xs.c
index b6d5fff..ba804f3 100644
--- a/drivers/xen/xenbus/xenbus_xs.c
+++ b/drivers/xen/xenbus/xenbus_xs.c
@@ -50,6 +50,7 @@
#include <xen/xenbus.h>
#include <xen/xen.h>
#include "xenbus_comms.h"
+#include "xenbus_probe.h"
struct xs_stored_msg {
struct list_head list;
@@ -139,6 +140,29 @@ static int get_error(const char *errorstring)
return xsd_errors[i].errnum;
}
+static bool xenbus_ok(void)
+{
+ switch (xen_store_domain_type) {
+ case XS_LOCAL:
+ switch (system_state) {
+ case SYSTEM_POWER_OFF:
+ case SYSTEM_RESTART:
+ case SYSTEM_HALT:
+ return false;
+ default:
+ break;
+ }
+ return true;
+ case XS_PV:
+ case XS_HVM:
+ /* FIXME: Could check that the remote domain is alive,
+ * but it is normally initial domain. */
+ return true;
+ default:
+ break;
+ }
+ return false;
+}
static void *read_reply(enum xsd_sockmsg_type *type, unsigned int *len)
{
struct xs_stored_msg *msg;
@@ -148,9 +172,20 @@ static void *read_reply(enum xsd_sockmsg_type *type, unsigned int *len)
while (list_empty(&xs_state.reply_list)) {
spin_unlock(&xs_state.reply_lock);
- /* XXX FIXME: Avoid synchronous wait for response here. */
- wait_event(xs_state.reply_waitq,
- !list_empty(&xs_state.reply_list));
+ if (xenbus_ok())
+ /* XXX FIXME: Avoid synchronous wait for response here. */
+ wait_event_timeout(xs_state.reply_waitq,
+ !list_empty(&xs_state.reply_list),
+ msecs_to_jiffies(500));
+ else {
+ /*
+ * If we are in the process of being shut-down there is
+ * no point of trying to contact XenBus - it is either
+ * killed (xenstored application) or the other domain
+ * has been killed or is unreachable.
+ */
+ return ERR_PTR(-EIO);
+ }
spin_lock(&xs_state.reply_lock);
}
@@ -215,6 +250,9 @@ void *xenbus_dev_request_and_reply(struct xsd_sockmsg *msg)
mutex_unlock(&xs_state.request_mutex);
+ if (IS_ERR(ret))
+ return ret;
+
if ((msg->type == XS_TRANSACTION_END) ||
((req_msg.type == XS_TRANSACTION_START) &&
(msg->type == XS_ERROR)))
diff --git a/firmware/WHENCE b/firmware/WHENCE
index 8388f02..0c4d96d 100644
--- a/firmware/WHENCE
+++ b/firmware/WHENCE
@@ -273,16 +273,6 @@ Converted from Intel HEX files, used in our binary representation of ihex.
--------------------------------------------------------------------------
-Driver: ip2 -- Computone IntelliPort Plus serial device
-
-File: intelliport2.bin
-
-Licence: Unknown
-
-Found in hex form in kernel source.
-
---------------------------------------------------------------------------
-
Driver: CPiA2 -- cameras based on Vision's CPiA2
File: cpia2/stv0672_vp4.bin
diff --git a/fs/cifs/cifsfs.c b/fs/cifs/cifsfs.c
index df9c9141..5be1f99 100644
--- a/fs/cifs/cifsfs.c
+++ b/fs/cifs/cifsfs.c
@@ -253,6 +253,11 @@ cifs_alloc_inode(struct super_block *sb)
cifs_set_oplock_level(cifs_inode, 0);
cifs_inode->delete_pending = false;
cifs_inode->invalid_mapping = false;
+ clear_bit(CIFS_INODE_PENDING_OPLOCK_BREAK, &cifs_inode->flags);
+ clear_bit(CIFS_INODE_PENDING_WRITERS, &cifs_inode->flags);
+ clear_bit(CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2, &cifs_inode->flags);
+ spin_lock_init(&cifs_inode->writers_lock);
+ cifs_inode->writers = 0;
cifs_inode->vfs_inode.i_blkbits = 14; /* 2**14 = CIFS_MAX_MSGSIZE */
cifs_inode->server_eof = 0;
cifs_inode->uniqueid = 0;
@@ -732,19 +737,26 @@ static ssize_t cifs_file_aio_write(struct kiocb *iocb, const struct iovec *iov,
unsigned long nr_segs, loff_t pos)
{
struct inode *inode = file_inode(iocb->ki_filp);
+ struct cifsInodeInfo *cinode = CIFS_I(inode);
ssize_t written;
int rc;
+ written = cifs_get_writer(cinode);
+ if (written)
+ return written;
+
written = generic_file_aio_write(iocb, iov, nr_segs, pos);
if (CIFS_CACHE_WRITE(CIFS_I(inode)))
- return written;
+ goto out;
rc = filemap_fdatawrite(inode->i_mapping);
if (rc)
cifs_dbg(FYI, "cifs_file_aio_write: %d rc on %p inode\n",
rc, inode);
+out:
+ cifs_put_writer(cinode);
return written;
}
diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h
index c0f3718..30f6e92 100644
--- a/fs/cifs/cifsglob.h
+++ b/fs/cifs/cifsglob.h
@@ -228,6 +228,8 @@ struct smb_version_operations {
/* verify the message */
int (*check_message)(char *, unsigned int);
bool (*is_oplock_break)(char *, struct TCP_Server_Info *);
+ void (*downgrade_oplock)(struct TCP_Server_Info *,
+ struct cifsInodeInfo *, bool);
/* process transaction2 response */
bool (*check_trans2)(struct mid_q_entry *, struct TCP_Server_Info *,
char *, int);
@@ -1113,6 +1115,12 @@ struct cifsInodeInfo {
unsigned int epoch; /* used to track lease state changes */
bool delete_pending; /* DELETE_ON_CLOSE is set */
bool invalid_mapping; /* pagecache is invalid */
+ unsigned long flags;
+#define CIFS_INODE_PENDING_OPLOCK_BREAK (0) /* oplock break in progress */
+#define CIFS_INODE_PENDING_WRITERS (1) /* Writes in progress */
+#define CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2 (2) /* Downgrade oplock to L2 */
+ spinlock_t writers_lock;
+ unsigned int writers; /* Number of writers on this inode */
unsigned long time; /* jiffies of last update of inode */
u64 server_eof; /* current file size on server -- protected by i_lock */
u64 uniqueid; /* server inode number */
diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h
index acc4ee8..ca7980a 100644
--- a/fs/cifs/cifsproto.h
+++ b/fs/cifs/cifsproto.h
@@ -127,6 +127,9 @@ extern u64 cifs_UnixTimeToNT(struct timespec);
extern struct timespec cnvrtDosUnixTm(__le16 le_date, __le16 le_time,
int offset);
extern void cifs_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock);
+extern int cifs_get_writer(struct cifsInodeInfo *cinode);
+extern void cifs_put_writer(struct cifsInodeInfo *cinode);
+extern void cifs_done_oplock_break(struct cifsInodeInfo *cinode);
extern int cifs_unlock_range(struct cifsFileInfo *cfile,
struct file_lock *flock, const unsigned int xid);
extern int cifs_push_mandatory_locks(struct cifsFileInfo *cfile);
diff --git a/fs/cifs/cifssmb.c b/fs/cifs/cifssmb.c
index f3264bd..6ce4e09 100644
--- a/fs/cifs/cifssmb.c
+++ b/fs/cifs/cifssmb.c
@@ -6197,6 +6197,9 @@ QAllEAsRetry:
cifs_dbg(FYI, "ea length %d\n", list_len);
if (list_len <= 8) {
cifs_dbg(FYI, "empty EA list returned from server\n");
+ /* didn't find the named attribute */
+ if (ea_name)
+ rc = -ENODATA;
goto QAllEAsOut;
}
diff --git a/fs/cifs/file.c b/fs/cifs/file.c
index 8add255..5ed03e0 100644
--- a/fs/cifs/file.c
+++ b/fs/cifs/file.c
@@ -2599,7 +2599,7 @@ cifs_writev(struct kiocb *iocb, const struct iovec *iov,
ssize_t err;
err = generic_write_sync(file, iocb->ki_pos - rc, rc);
- if (rc < 0)
+ if (err < 0)
rc = err;
}
} else {
@@ -2621,12 +2621,20 @@ cifs_strict_writev(struct kiocb *iocb, const struct iovec *iov,
struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
ssize_t written;
+ written = cifs_get_writer(cinode);
+ if (written)
+ return written;
+
if (CIFS_CACHE_WRITE(cinode)) {
if (cap_unix(tcon->ses) &&
(CIFS_UNIX_FCNTL_CAP & le64_to_cpu(tcon->fsUnixInfo.Capability))
- && ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0))
- return generic_file_aio_write(iocb, iov, nr_segs, pos);
- return cifs_writev(iocb, iov, nr_segs, pos);
+ && ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_NOPOSIXBRL) == 0)) {
+ written = generic_file_aio_write(
+ iocb, iov, nr_segs, pos);
+ goto out;
+ }
+ written = cifs_writev(iocb, iov, nr_segs, pos);
+ goto out;
}
/*
* For non-oplocked files in strict cache mode we need to write the data
@@ -2646,6 +2654,8 @@ cifs_strict_writev(struct kiocb *iocb, const struct iovec *iov,
inode);
cinode->oplock = 0;
}
+out:
+ cifs_put_writer(cinode);
return written;
}
@@ -2872,7 +2882,7 @@ ssize_t cifs_user_readv(struct kiocb *iocb, const struct iovec *iov,
cifs_uncached_readv_complete);
if (!rdata) {
rc = -ENOMEM;
- goto error;
+ break;
}
rc = cifs_read_allocate_pages(rdata, npages);
@@ -3621,6 +3631,13 @@ static int cifs_launder_page(struct page *page)
return rc;
}
+static int
+cifs_pending_writers_wait(void *unused)
+{
+ schedule();
+ return 0;
+}
+
void cifs_oplock_break(struct work_struct *work)
{
struct cifsFileInfo *cfile = container_of(work, struct cifsFileInfo,
@@ -3628,8 +3645,15 @@ void cifs_oplock_break(struct work_struct *work)
struct inode *inode = cfile->dentry->d_inode;
struct cifsInodeInfo *cinode = CIFS_I(inode);
struct cifs_tcon *tcon = tlink_tcon(cfile->tlink);
+ struct TCP_Server_Info *server = tcon->ses->server;
int rc = 0;
+ wait_on_bit(&cinode->flags, CIFS_INODE_PENDING_WRITERS,
+ cifs_pending_writers_wait, TASK_UNINTERRUPTIBLE);
+
+ server->ops->downgrade_oplock(server, cinode,
+ test_bit(CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2, &cinode->flags));
+
if (!CIFS_CACHE_WRITE(cinode) && CIFS_CACHE_READ(cinode) &&
cifs_has_mand_locks(cinode)) {
cifs_dbg(FYI, "Reset oplock to None for inode=%p due to mand locks\n",
@@ -3666,6 +3690,7 @@ void cifs_oplock_break(struct work_struct *work)
cinode);
cifs_dbg(FYI, "Oplock release rc = %d\n", rc);
}
+ cifs_done_oplock_break(cinode);
}
/*
diff --git a/fs/cifs/misc.c b/fs/cifs/misc.c
index 2f9f379..3b0c62e 100644
--- a/fs/cifs/misc.c
+++ b/fs/cifs/misc.c
@@ -466,8 +466,22 @@ is_valid_oplock_break(char *buffer, struct TCP_Server_Info *srv)
cifs_dbg(FYI, "file id match, oplock break\n");
pCifsInode = CIFS_I(netfile->dentry->d_inode);
- cifs_set_oplock_level(pCifsInode,
- pSMB->OplockLevel ? OPLOCK_READ : 0);
+ set_bit(CIFS_INODE_PENDING_OPLOCK_BREAK,
+ &pCifsInode->flags);
+
+ /*
+ * Set flag if the server downgrades the oplock
+ * to L2 else clear.
+ */
+ if (pSMB->OplockLevel)
+ set_bit(
+ CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2,
+ &pCifsInode->flags);
+ else
+ clear_bit(
+ CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2,
+ &pCifsInode->flags);
+
queue_work(cifsiod_wq,
&netfile->oplock_break);
netfile->oplock_break_cancelled = false;
@@ -551,6 +565,62 @@ void cifs_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock)
cinode->oplock = 0;
}
+static int
+cifs_oplock_break_wait(void *unused)
+{
+ schedule();
+ return signal_pending(current) ? -ERESTARTSYS : 0;
+}
+
+/*
+ * We wait for oplock breaks to be processed before we attempt to perform
+ * writes.
+ */
+int cifs_get_writer(struct cifsInodeInfo *cinode)
+{
+ int rc;
+
+start:
+ rc = wait_on_bit(&cinode->flags, CIFS_INODE_PENDING_OPLOCK_BREAK,
+ cifs_oplock_break_wait, TASK_KILLABLE);
+ if (rc)
+ return rc;
+
+ spin_lock(&cinode->writers_lock);
+ if (!cinode->writers)
+ set_bit(CIFS_INODE_PENDING_WRITERS, &cinode->flags);
+ cinode->writers++;
+ /* Check to see if we have started servicing an oplock break */
+ if (test_bit(CIFS_INODE_PENDING_OPLOCK_BREAK, &cinode->flags)) {
+ cinode->writers--;
+ if (cinode->writers == 0) {
+ clear_bit(CIFS_INODE_PENDING_WRITERS, &cinode->flags);
+ wake_up_bit(&cinode->flags, CIFS_INODE_PENDING_WRITERS);
+ }
+ spin_unlock(&cinode->writers_lock);
+ goto start;
+ }
+ spin_unlock(&cinode->writers_lock);
+ return 0;
+}
+
+void cifs_put_writer(struct cifsInodeInfo *cinode)
+{
+ spin_lock(&cinode->writers_lock);
+ cinode->writers--;
+ if (cinode->writers == 0) {
+ clear_bit(CIFS_INODE_PENDING_WRITERS, &cinode->flags);
+ wake_up_bit(&cinode->flags, CIFS_INODE_PENDING_WRITERS);
+ }
+ spin_unlock(&cinode->writers_lock);
+}
+
+void cifs_done_oplock_break(struct cifsInodeInfo *cinode)
+{
+ clear_bit(CIFS_INODE_PENDING_OPLOCK_BREAK, &cinode->flags);
+ wake_up_bit(&cinode->flags, CIFS_INODE_PENDING_OPLOCK_BREAK);
+}
+
bool
backup_cred(struct cifs_sb_info *cifs_sb)
{
diff --git a/fs/cifs/smb1ops.c b/fs/cifs/smb1ops.c
index 526fb89..d1fdfa8 100644
--- a/fs/cifs/smb1ops.c
+++ b/fs/cifs/smb1ops.c
@@ -372,6 +372,16 @@ coalesce_t2(char *second_buf, struct smb_hdr *target_hdr)
return 0;
}
+static void
+cifs_downgrade_oplock(struct TCP_Server_Info *server,
+ struct cifsInodeInfo *cinode, bool set_level2)
+{
+ if (set_level2)
+ cifs_set_oplock_level(cinode, OPLOCK_READ);
+ else
+ cifs_set_oplock_level(cinode, 0);
+}
+
static bool
cifs_check_trans2(struct mid_q_entry *mid, struct TCP_Server_Info *server,
char *buf, int malformed)
@@ -1019,6 +1029,7 @@ struct smb_version_operations smb1_operations = {
.clear_stats = cifs_clear_stats,
.print_stats = cifs_print_stats,
.is_oplock_break = is_valid_oplock_break,
+ .downgrade_oplock = cifs_downgrade_oplock,
.check_trans2 = cifs_check_trans2,
.need_neg = cifs_need_neg,
.negotiate = cifs_negotiate,
diff --git a/fs/cifs/smb2misc.c b/fs/cifs/smb2misc.c
index fb39662..b8021fd 100644
--- a/fs/cifs/smb2misc.c
+++ b/fs/cifs/smb2misc.c
@@ -575,9 +575,21 @@ smb2_is_valid_oplock_break(char *buffer, struct TCP_Server_Info *server)
else
cfile->oplock_break_cancelled = false;
- server->ops->set_oplock_level(cinode,
- rsp->OplockLevel ? SMB2_OPLOCK_LEVEL_II : 0,
- 0, NULL);
+ set_bit(CIFS_INODE_PENDING_OPLOCK_BREAK,
+ &cinode->flags);
+
+ /*
+ * Set flag if the server downgrades the oplock
+ * to L2 else clear.
+ */
+ if (rsp->OplockLevel)
+ set_bit(
+ CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2,
+ &cinode->flags);
+ else
+ clear_bit(
+ CIFS_INODE_DOWNGRADE_OPLOCK_TO_L2,
+ &cinode->flags);
queue_work(cifsiod_wq, &cfile->oplock_break);
diff --git a/fs/cifs/smb2ops.c b/fs/cifs/smb2ops.c
index 192f51a..35ddc3e 100644
--- a/fs/cifs/smb2ops.c
+++ b/fs/cifs/smb2ops.c
@@ -905,6 +905,17 @@ smb2_query_symlink(const unsigned int xid, struct cifs_tcon *tcon,
}
static void
+smb2_downgrade_oplock(struct TCP_Server_Info *server,
+ struct cifsInodeInfo *cinode, bool set_level2)
+{
+ if (set_level2)
+ server->ops->set_oplock_level(cinode, SMB2_OPLOCK_LEVEL_II,
+ 0, NULL);
+ else
+ server->ops->set_oplock_level(cinode, 0, 0, NULL);
+}
+
+static void
smb2_set_oplock_level(struct cifsInodeInfo *cinode, __u32 oplock,
unsigned int epoch, bool *purge_cache)
{
@@ -1110,6 +1121,7 @@ struct smb_version_operations smb20_operations = {
.clear_stats = smb2_clear_stats,
.print_stats = smb2_print_stats,
.is_oplock_break = smb2_is_valid_oplock_break,
+ .downgrade_oplock = smb2_downgrade_oplock,
.need_neg = smb2_need_neg,
.negotiate = smb2_negotiate,
.negotiate_wsize = smb2_negotiate_wsize,
@@ -1184,6 +1196,7 @@ struct smb_version_operations smb21_operations = {
.clear_stats = smb2_clear_stats,
.print_stats = smb2_print_stats,
.is_oplock_break = smb2_is_valid_oplock_break,
+ .downgrade_oplock = smb2_downgrade_oplock,
.need_neg = smb2_need_neg,
.negotiate = smb2_negotiate,
.negotiate_wsize = smb2_negotiate_wsize,
@@ -1259,6 +1272,7 @@ struct smb_version_operations smb30_operations = {
.print_stats = smb2_print_stats,
.dump_share_caps = smb2_dump_share_caps,
.is_oplock_break = smb2_is_valid_oplock_break,
+ .downgrade_oplock = smb2_downgrade_oplock,
.need_neg = smb2_need_neg,
.negotiate = smb2_negotiate,
.negotiate_wsize = smb2_negotiate_wsize,
diff --git a/fs/cifs/smb2pdu.c b/fs/cifs/smb2pdu.c
index 8603447..3802f8c 100644
--- a/fs/cifs/smb2pdu.c
+++ b/fs/cifs/smb2pdu.c
@@ -1352,7 +1352,6 @@ SMB2_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
u64 persistent_fid, u64 volatile_fid)
{
int rc;
- char *res_key = NULL;
struct compress_ioctl fsctl_input;
char *ret_data = NULL;
@@ -1365,7 +1364,6 @@ SMB2_set_compression(const unsigned int xid, struct cifs_tcon *tcon,
2 /* in data len */, &ret_data /* out data */, NULL);
cifs_dbg(FYI, "set compression rc %d\n", rc);
- kfree(res_key);
return rc;
}
diff --git a/fs/kernfs/inode.c b/fs/kernfs/inode.c
index abb0f1f..9852176 100644
--- a/fs/kernfs/inode.c
+++ b/fs/kernfs/inode.c
@@ -48,14 +48,18 @@ void __init kernfs_inode_init(void)
static struct kernfs_iattrs *kernfs_iattrs(struct kernfs_node *kn)
{
+ static DEFINE_MUTEX(iattr_mutex);
+ struct kernfs_iattrs *ret;
struct iattr *iattrs;
+ mutex_lock(&iattr_mutex);
+
if (kn->iattr)
- return kn->iattr;
+ goto out_unlock;
kn->iattr = kzalloc(sizeof(struct kernfs_iattrs), GFP_KERNEL);
if (!kn->iattr)
- return NULL;
+ goto out_unlock;
iattrs = &kn->iattr->ia_iattr;
/* assign default attributes */
@@ -65,8 +69,10 @@ static struct kernfs_iattrs *kernfs_iattrs(struct kernfs_node *kn)
iattrs->ia_atime = iattrs->ia_mtime = iattrs->ia_ctime = CURRENT_TIME;
simple_xattrs_init(&kn->iattr->xattrs);
-
- return kn->iattr;
+out_unlock:
+ ret = kn->iattr;
+ mutex_unlock(&iattr_mutex);
+ return ret;
}
static int __kernfs_setattr(struct kernfs_node *kn, const struct iattr *iattr)
diff --git a/fs/super.c b/fs/super.c
index e9dc3c3..48377f7 100644
--- a/fs/super.c
+++ b/fs/super.c
@@ -800,7 +800,10 @@ void emergency_remount(void)
static DEFINE_IDA(unnamed_dev_ida);
static DEFINE_SPINLOCK(unnamed_dev_lock);/* protects the above */
-static int unnamed_dev_start = 0; /* don't bother trying below it */
+/* Many userspace utilities consider an FSID of 0 invalid.
+ * Always return at least 1 from get_anon_bdev.
+ */
+static int unnamed_dev_start = 1;
int get_anon_bdev(dev_t *p)
{
diff --git a/fs/sysfs/file.c b/fs/sysfs/file.c
index 1b8b91b..28cc1acd 100644
--- a/fs/sysfs/file.c
+++ b/fs/sysfs/file.c
@@ -453,95 +453,3 @@ void sysfs_remove_bin_file(struct kobject *kobj,
kernfs_remove_by_name(kobj->sd, attr->attr.name);
}
EXPORT_SYMBOL_GPL(sysfs_remove_bin_file);
-
-struct sysfs_schedule_callback_struct {
- struct list_head workq_list;
- struct kobject *kobj;
- void (*func)(void *);
- void *data;
- struct module *owner;
- struct work_struct work;
-};
-
-static struct workqueue_struct *sysfs_workqueue;
-static DEFINE_MUTEX(sysfs_workq_mutex);
-static LIST_HEAD(sysfs_workq);
-static void sysfs_schedule_callback_work(struct work_struct *work)
-{
- struct sysfs_schedule_callback_struct *ss = container_of(work,
- struct sysfs_schedule_callback_struct, work);
-
- (ss->func)(ss->data);
- kobject_put(ss->kobj);
- module_put(ss->owner);
- mutex_lock(&sysfs_workq_mutex);
- list_del(&ss->workq_list);
- mutex_unlock(&sysfs_workq_mutex);
- kfree(ss);
-}
-
-/**
- * sysfs_schedule_callback - helper to schedule a callback for a kobject
- * @kobj: object we're acting for.
- * @func: callback function to invoke later.
- * @data: argument to pass to @func.
- * @owner: module owning the callback code
- *
- * sysfs attribute methods must not unregister themselves or their parent
- * kobject (which would amount to the same thing). Attempts to do so will
- * deadlock, since unregistration is mutually exclusive with driver
- * callbacks.
- *
- * Instead methods can call this routine, which will attempt to allocate
- * and schedule a workqueue request to call back @func with @data as its
- * argument in the workqueue's process context. @kobj will be pinned
- * until @func returns.
- *
- * Returns 0 if the request was submitted, -ENOMEM if storage could not
- * be allocated, -ENODEV if a reference to @owner isn't available,
- * -EAGAIN if a callback has already been scheduled for @kobj.
- */
-int sysfs_schedule_callback(struct kobject *kobj, void (*func)(void *),
- void *data, struct module *owner)
-{
- struct sysfs_schedule_callback_struct *ss, *tmp;
-
- if (!try_module_get(owner))
- return -ENODEV;
-
- mutex_lock(&sysfs_workq_mutex);
- list_for_each_entry_safe(ss, tmp, &sysfs_workq, workq_list)
- if (ss->kobj == kobj) {
- module_put(owner);
- mutex_unlock(&sysfs_workq_mutex);
- return -EAGAIN;
- }
- mutex_unlock(&sysfs_workq_mutex);
-
- if (sysfs_workqueue == NULL) {
- sysfs_workqueue = create_singlethread_workqueue("sysfsd");
- if (sysfs_workqueue == NULL) {
- module_put(owner);
- return -ENOMEM;
- }
- }
-
- ss = kmalloc(sizeof(*ss), GFP_KERNEL);
- if (!ss) {
- module_put(owner);
- return -ENOMEM;
- }
- kobject_get(kobj);
- ss->kobj = kobj;
- ss->func = func;
- ss->data = data;
- ss->owner = owner;
- INIT_WORK(&ss->work, sysfs_schedule_callback_work);
- INIT_LIST_HEAD(&ss->workq_list);
- mutex_lock(&sysfs_workq_mutex);
- list_add_tail(&ss->workq_list, &sysfs_workq);
- mutex_unlock(&sysfs_workq_mutex);
- queue_work(sysfs_workqueue, &ss->work);
- return 0;
-}
-EXPORT_SYMBOL_GPL(sysfs_schedule_callback);
diff --git a/fs/xfs/xfs_aops.c b/fs/xfs/xfs_aops.c
index 75df77d..0479c32 100644
--- a/fs/xfs/xfs_aops.c
+++ b/fs/xfs/xfs_aops.c
@@ -1344,6 +1344,14 @@ __xfs_get_blocks(
/*
* If this is O_DIRECT or the mpage code calling tell them how large
* the mapping is, so that we can avoid repeated get_blocks calls.
+ *
+ * If the mapping spans EOF, then we have to break the mapping up as the
+ * mapping for blocks beyond EOF must be marked new so that sub block
+ * regions can be correctly zeroed. We can't do this for mappings within
+ * EOF unless the mapping was just allocated or is unwritten, otherwise
+ * the callers would overwrite existing data with zeros. Hence we have
+ * to split the mapping into a range up to and including EOF, and a
+ * second mapping for beyond EOF.
*/
if (direct || size > (1 << inode->i_blkbits)) {
xfs_off_t mapping_size;
@@ -1354,6 +1362,12 @@ __xfs_get_blocks(
ASSERT(mapping_size > 0);
if (mapping_size > size)
mapping_size = size;
+ if (offset < i_size_read(inode) &&
+ offset + mapping_size >= i_size_read(inode)) {
+ /* limit mapping to block that spans EOF */
+ mapping_size = roundup_64(i_size_read(inode) - offset,
+ 1 << inode->i_blkbits);
+ }
if (mapping_size > LONG_MAX)
mapping_size = LONG_MAX;
@@ -1566,6 +1580,16 @@ xfs_vm_write_failed(
xfs_vm_kill_delalloc_range(inode, block_offset,
block_offset + bh->b_size);
+
+ /*
+ * This buffer does not contain data anymore. make sure anyone
+ * who finds it knows that for certain.
+ */
+ clear_buffer_delay(bh);
+ clear_buffer_uptodate(bh);
+ clear_buffer_mapped(bh);
+ clear_buffer_new(bh);
+ clear_buffer_dirty(bh);
}
}
@@ -1599,12 +1623,21 @@ xfs_vm_write_begin(
status = __block_write_begin(page, pos, len, xfs_get_blocks);
if (unlikely(status)) {
struct inode *inode = mapping->host;
+ size_t isize = i_size_read(inode);
xfs_vm_write_failed(inode, page, pos, len);
unlock_page(page);
- if (pos + len > i_size_read(inode))
- truncate_pagecache(inode, i_size_read(inode));
+ /*
+ * If the write is beyond EOF, we only want to kill blocks
+ * allocated in this write, not blocks that were previously
+ * written successfully.
+ */
+ if (pos + len > isize) {
+ ssize_t start = max_t(ssize_t, pos, isize);
+
+ truncate_pagecache_range(inode, start, pos + len);
+ }
page_cache_release(page);
page = NULL;
@@ -1615,9 +1648,12 @@ xfs_vm_write_begin(
}
/*
- * On failure, we only need to kill delalloc blocks beyond EOF because they
- * will never be written. For blocks within EOF, generic_write_end() zeros them
- * so they are safe to leave alone and be written with all the other valid data.
+ * On failure, we only need to kill delalloc blocks beyond EOF in the range of
+ * this specific write because they will never be written. Previous writes
+ * beyond EOF where block allocation succeeded do not need to be trashed, so
+ * only new blocks from this write should be trashed. For blocks within
+ * EOF, generic_write_end() zeros them so they are safe to leave alone and be
+ * written with all the other valid data.
*/
STATIC int
xfs_vm_write_end(
@@ -1640,8 +1676,11 @@ xfs_vm_write_end(
loff_t to = pos + len;
if (to > isize) {
- truncate_pagecache(inode, isize);
+ /* only kill blocks in this write beyond EOF */
+ if (pos > isize)
+ isize = pos;
xfs_vm_kill_delalloc_range(inode, isize, to);
+ truncate_pagecache_range(inode, isize, to);
}
}
return ret;
diff --git a/fs/xfs/xfs_bmap.c b/fs/xfs/xfs_bmap.c
index 5b6092e..f0efc7e 100644
--- a/fs/xfs/xfs_bmap.c
+++ b/fs/xfs/xfs_bmap.c
@@ -5413,6 +5413,7 @@ xfs_bmap_shift_extents(
int whichfork = XFS_DATA_FORK;
int logflags;
xfs_filblks_t blockcount = 0;
+ int total_extents;
if (unlikely(XFS_TEST_ERROR(
(XFS_IFORK_FORMAT(ip, whichfork) != XFS_DINODE_FMT_EXTENTS &&
@@ -5429,7 +5430,6 @@ xfs_bmap_shift_extents(
ASSERT(current_ext != NULL);
ifp = XFS_IFORK_PTR(ip, whichfork);
-
if (!(ifp->if_flags & XFS_IFEXTENTS)) {
/* Read in all the extents */
error = xfs_iread_extents(tp, ip, whichfork);
@@ -5456,7 +5456,6 @@ xfs_bmap_shift_extents(
/* We are going to change core inode */
logflags = XFS_ILOG_CORE;
-
if (ifp->if_flags & XFS_IFBROOT) {
cur = xfs_bmbt_init_cursor(mp, tp, ip, whichfork);
cur->bc_private.b.firstblock = *firstblock;
@@ -5467,8 +5466,14 @@ xfs_bmap_shift_extents(
logflags |= XFS_ILOG_DEXT;
}
- while (nexts++ < num_exts &&
- *current_ext < XFS_IFORK_NEXTENTS(ip, whichfork)) {
+ /*
+ * There may be delalloc extents in the data fork before the range we
+ * are collapsing out, so we cannot
+ * use the count of real extents here. Instead we have to calculate it
+ * from the incore fork.
+ */
+ total_extents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t);
+ while (nexts++ < num_exts && *current_ext < total_extents) {
gotp = xfs_iext_get_ext(ifp, *current_ext);
xfs_bmbt_get_all(gotp, &got);
@@ -5556,10 +5561,11 @@ xfs_bmap_shift_extents(
}
(*current_ext)++;
+ total_extents = ifp->if_bytes / sizeof(xfs_bmbt_rec_t);
}
/* Check if we are done */
- if (*current_ext == XFS_IFORK_NEXTENTS(ip, whichfork))
+ if (*current_ext == total_extents)
*done = 1;
del_cursor:
@@ -5568,6 +5574,5 @@ del_cursor:
error ? XFS_BTREE_ERROR : XFS_BTREE_NOERROR);
xfs_trans_log_inode(tp, ip, logflags);
-
return error;
}
diff --git a/fs/xfs/xfs_bmap_util.c b/fs/xfs/xfs_bmap_util.c
index 01f6a64..296160b 100644
--- a/fs/xfs/xfs_bmap_util.c
+++ b/fs/xfs/xfs_bmap_util.c
@@ -1418,6 +1418,8 @@ xfs_zero_file_space(
xfs_off_t end_boundary;
int error;
+ trace_xfs_zero_file_space(ip);
+
granularity = max_t(uint, 1 << mp->m_sb.sb_blocklog, PAGE_CACHE_SIZE);
/*
@@ -1432,9 +1434,18 @@ xfs_zero_file_space(
ASSERT(end_boundary <= offset + len);
if (start_boundary < end_boundary - 1) {
- /* punch out the page cache over the conversion range */
+ /*
+ * punch out delayed allocation blocks and the page cache over
+ * the conversion range
+ */
+ xfs_ilock(ip, XFS_ILOCK_EXCL);
+ error = xfs_bmap_punch_delalloc_range(ip,
+ XFS_B_TO_FSBT(mp, start_boundary),
+ XFS_B_TO_FSB(mp, end_boundary - start_boundary));
+ xfs_iunlock(ip, XFS_ILOCK_EXCL);
truncate_pagecache_range(VFS_I(ip), start_boundary,
end_boundary - 1);
+
/* convert the blocks */
error = xfs_alloc_file_space(ip, start_boundary,
end_boundary - start_boundary - 1,
diff --git a/fs/xfs/xfs_buf.c b/fs/xfs/xfs_buf.c
index 107f2fd..cb10a0a 100644
--- a/fs/xfs/xfs_buf.c
+++ b/fs/xfs/xfs_buf.c
@@ -1372,21 +1372,29 @@ xfs_buf_iorequest(
xfs_buf_wait_unpin(bp);
xfs_buf_hold(bp);
- /* Set the count to 1 initially, this will stop an I/O
+ /*
+ * Set the count to 1 initially, this will stop an I/O
* completion callout which happens before we have started
* all the I/O from calling xfs_buf_ioend too early.
*/
atomic_set(&bp->b_io_remaining, 1);
_xfs_buf_ioapply(bp);
- _xfs_buf_ioend(bp, 1);
+ /*
+ * If _xfs_buf_ioapply failed, we'll get back here with
+ * only the reference we took above. _xfs_buf_ioend will
+ * drop it to zero, so we'd better not queue it for later,
+ * or we'll free it before it's done.
+ */
+ _xfs_buf_ioend(bp, bp->b_error ? 0 : 1);
xfs_buf_rele(bp);
}
/*
* Waits for I/O to complete on the buffer supplied. It returns immediately if
- * no I/O is pending or there is already a pending error on the buffer. It
- * returns the I/O error code, if any, or 0 if there was no error.
+ * no I/O is pending or there is already a pending error on the buffer, in which
+ * case nothing will ever complete. It returns the I/O error code, if any, or
+ * 0 if there was no error.
*/
int
xfs_buf_iowait(
diff --git a/fs/xfs/xfs_file.c b/fs/xfs/xfs_file.c
index 79e96ce..82afdcb 100644
--- a/fs/xfs/xfs_file.c
+++ b/fs/xfs/xfs_file.c
@@ -679,7 +679,7 @@ xfs_file_dio_aio_write(
goto out;
if (mapping->nrpages) {
- ret = -filemap_write_and_wait_range(VFS_I(ip)->i_mapping,
+ ret = filemap_write_and_wait_range(VFS_I(ip)->i_mapping,
pos, -1);
if (ret)
goto out;
diff --git a/fs/xfs/xfs_inode.c b/fs/xfs/xfs_inode.c
index 5e7a38f..768087b 100644
--- a/fs/xfs/xfs_inode.c
+++ b/fs/xfs/xfs_inode.c
@@ -1334,7 +1334,8 @@ int
xfs_create_tmpfile(
struct xfs_inode *dp,
struct dentry *dentry,
- umode_t mode)
+ umode_t mode,
+ struct xfs_inode **ipp)
{
struct xfs_mount *mp = dp->i_mount;
struct xfs_inode *ip = NULL;
@@ -1402,7 +1403,6 @@ xfs_create_tmpfile(
xfs_qm_vop_create_dqattach(tp, ip, udqp, gdqp, pdqp);
ip->i_d.di_nlink--;
- d_tmpfile(dentry, VFS_I(ip));
error = xfs_iunlink(tp, ip);
if (error)
goto out_trans_abort;
@@ -1415,6 +1415,7 @@ xfs_create_tmpfile(
xfs_qm_dqrele(gdqp);
xfs_qm_dqrele(pdqp);
+ *ipp = ip;
return 0;
out_trans_abort:
diff --git a/fs/xfs/xfs_inode.h b/fs/xfs/xfs_inode.h
index 396cc1f..f2fcde5 100644
--- a/fs/xfs/xfs_inode.h
+++ b/fs/xfs/xfs_inode.h
@@ -334,7 +334,7 @@ int xfs_lookup(struct xfs_inode *dp, struct xfs_name *name,
int xfs_create(struct xfs_inode *dp, struct xfs_name *name,
umode_t mode, xfs_dev_t rdev, struct xfs_inode **ipp);
int xfs_create_tmpfile(struct xfs_inode *dp, struct dentry *dentry,
- umode_t mode);
+ umode_t mode, struct xfs_inode **ipp);
int xfs_remove(struct xfs_inode *dp, struct xfs_name *name,
struct xfs_inode *ip);
int xfs_link(struct xfs_inode *tdp, struct xfs_inode *sip,
diff --git a/fs/xfs/xfs_iops.c b/fs/xfs/xfs_iops.c
index 89b07e4..ef1ca01 100644
--- a/fs/xfs/xfs_iops.c
+++ b/fs/xfs/xfs_iops.c
@@ -1053,11 +1053,25 @@ xfs_vn_tmpfile(
struct dentry *dentry,
umode_t mode)
{
- int error;
+ int error;
+ struct xfs_inode *ip;
+ struct inode *inode;
- error = xfs_create_tmpfile(XFS_I(dir), dentry, mode);
+ error = xfs_create_tmpfile(XFS_I(dir), dentry, mode, &ip);
+ if (unlikely(error))
+ return -error;
- return -error;
+ inode = VFS_I(ip);
+
+ error = xfs_init_security(inode, dir, &dentry->d_name);
+ if (unlikely(error)) {
+ iput(inode);
+ return -error;
+ }
+
+ d_tmpfile(dentry, inode);
+
+ return 0;
}
static const struct inode_operations xfs_inode_operations = {
diff --git a/fs/xfs/xfs_log.c b/fs/xfs/xfs_log.c
index 8497a00..08624dc 100644
--- a/fs/xfs/xfs_log.c
+++ b/fs/xfs/xfs_log.c
@@ -1181,11 +1181,14 @@ xlog_iodone(xfs_buf_t *bp)
/* log I/O is always issued ASYNC */
ASSERT(XFS_BUF_ISASYNC(bp));
xlog_state_done_syncing(iclog, aborted);
+
/*
- * do not reference the buffer (bp) here as we could race
- * with it being freed after writing the unmount record to the
- * log.
+ * drop the buffer lock now that we are done. Nothing references
+ * the buffer after this, so an unmount waiting on this lock can now
+ * tear it down safely. As such, it is unsafe to reference the buffer
+ * (bp) after the unlock as we could race with it being freed.
*/
+ xfs_buf_unlock(bp);
}
/*
@@ -1368,8 +1371,16 @@ xlog_alloc_log(
bp = xfs_buf_alloc(mp->m_logdev_targp, 0, BTOBB(log->l_iclog_size), 0);
if (!bp)
goto out_free_log;
- bp->b_iodone = xlog_iodone;
+
+ /*
+ * The iclogbuf buffer locks are held over IO but we are not going to do
+ * IO yet. Hence unlock the buffer so that the log IO path can grab it
+ * when appropriately.
+ */
ASSERT(xfs_buf_islocked(bp));
+ xfs_buf_unlock(bp);
+
+ bp->b_iodone = xlog_iodone;
log->l_xbuf = bp;
spin_lock_init(&log->l_icloglock);
@@ -1398,6 +1409,9 @@ xlog_alloc_log(
if (!bp)
goto out_free_iclog;
+ ASSERT(xfs_buf_islocked(bp));
+ xfs_buf_unlock(bp);
+
bp->b_iodone = xlog_iodone;
iclog->ic_bp = bp;
iclog->ic_data = bp->b_addr;
@@ -1422,7 +1436,6 @@ xlog_alloc_log(
iclog->ic_callback_tail = &(iclog->ic_callback);
iclog->ic_datap = (char *)iclog->ic_data + log->l_iclog_hsize;
- ASSERT(xfs_buf_islocked(iclog->ic_bp));
init_waitqueue_head(&iclog->ic_force_wait);
init_waitqueue_head(&iclog->ic_write_wait);
@@ -1631,6 +1644,12 @@ xlog_cksum(
* we transition the iclogs to IOERROR state *after* flushing all existing
* iclogs to disk. This is because we don't want anymore new transactions to be
* started or completed afterwards.
+ *
+ * We lock the iclogbufs here so that we can serialise against IO completion
+ * during unmount. We might be processing a shutdown triggered during unmount,
+ * and that can occur asynchronously to the unmount thread, and hence we need to
+ * ensure that completes before tearing down the iclogbufs. Hence we need to
+ * hold the buffer lock across the log IO to acheive that.
*/
STATIC int
xlog_bdstrat(
@@ -1638,6 +1657,7 @@ xlog_bdstrat(
{
struct xlog_in_core *iclog = bp->b_fspriv;
+ xfs_buf_lock(bp);
if (iclog->ic_state & XLOG_STATE_IOERROR) {
xfs_buf_ioerror(bp, EIO);
xfs_buf_stale(bp);
@@ -1645,7 +1665,8 @@ xlog_bdstrat(
/*
* It would seem logical to return EIO here, but we rely on
* the log state machine to propagate I/O errors instead of
- * doing it here.
+ * doing it here. Similarly, IO completion will unlock the
+ * buffer, so we don't do it here.
*/
return 0;
}
@@ -1847,14 +1868,28 @@ xlog_dealloc_log(
xlog_cil_destroy(log);
/*
- * always need to ensure that the extra buffer does not point to memory
- * owned by another log buffer before we free it.
+ * Cycle all the iclogbuf locks to make sure all log IO completion
+ * is done before we tear down these buffers.
*/
+ iclog = log->l_iclog;
+ for (i = 0; i < log->l_iclog_bufs; i++) {
+ xfs_buf_lock(iclog->ic_bp);
+ xfs_buf_unlock(iclog->ic_bp);
+ iclog = iclog->ic_next;
+ }
+
+ /*
+ * Always need to ensure that the extra buffer does not point to memory
+ * owned by another log buffer before we free it. Also, cycle the lock
+ * first to ensure we've completed IO on it.
+ */
+ xfs_buf_lock(log->l_xbuf);
+ xfs_buf_unlock(log->l_xbuf);
xfs_buf_set_empty(log->l_xbuf, BTOBB(log->l_iclog_size));
xfs_buf_free(log->l_xbuf);
iclog = log->l_iclog;
- for (i=0; i<log->l_iclog_bufs; i++) {
+ for (i = 0; i < log->l_iclog_bufs; i++) {
xfs_buf_free(iclog->ic_bp);
next_iclog = iclog->ic_next;
kmem_free(iclog);
diff --git a/fs/xfs/xfs_trace.h b/fs/xfs/xfs_trace.h
index a4ae41c..65d8c79 100644
--- a/fs/xfs/xfs_trace.h
+++ b/fs/xfs/xfs_trace.h
@@ -603,6 +603,7 @@ DEFINE_INODE_EVENT(xfs_readlink);
DEFINE_INODE_EVENT(xfs_inactive_symlink);
DEFINE_INODE_EVENT(xfs_alloc_file_space);
DEFINE_INODE_EVENT(xfs_free_file_space);
+DEFINE_INODE_EVENT(xfs_zero_file_space);
DEFINE_INODE_EVENT(xfs_collapse_file_space);
DEFINE_INODE_EVENT(xfs_readdir);
#ifdef CONFIG_XFS_POSIX_ACL
diff --git a/include/asm-generic/pgtable.h b/include/asm-generic/pgtable.h
index 1ec08c1..a8015a7 100644
--- a/include/asm-generic/pgtable.h
+++ b/include/asm-generic/pgtable.h
@@ -693,24 +693,35 @@ static inline int pmd_numa(pmd_t pmd)
#ifndef pte_mknonnuma
static inline pte_t pte_mknonnuma(pte_t pte)
{
- pte = pte_clear_flags(pte, _PAGE_NUMA);
- return pte_set_flags(pte, _PAGE_PRESENT|_PAGE_ACCESSED);
+ pteval_t val = pte_val(pte);
+
+ val &= ~_PAGE_NUMA;
+ val |= (_PAGE_PRESENT|_PAGE_ACCESSED);
+ return __pte(val);
}
#endif
#ifndef pmd_mknonnuma
static inline pmd_t pmd_mknonnuma(pmd_t pmd)
{
- pmd = pmd_clear_flags(pmd, _PAGE_NUMA);
- return pmd_set_flags(pmd, _PAGE_PRESENT|_PAGE_ACCESSED);
+ pmdval_t val = pmd_val(pmd);
+
+ val &= ~_PAGE_NUMA;
+ val |= (_PAGE_PRESENT|_PAGE_ACCESSED);
+
+ return __pmd(val);
}
#endif
#ifndef pte_mknuma
static inline pte_t pte_mknuma(pte_t pte)
{
- pte = pte_set_flags(pte, _PAGE_NUMA);
- return pte_clear_flags(pte, _PAGE_PRESENT);
+ pteval_t val = pte_val(pte);
+
+ val &= ~_PAGE_PRESENT;
+ val |= _PAGE_NUMA;
+
+ return __pte(val);
}
#endif
@@ -729,8 +740,12 @@ static inline void ptep_set_numa(struct mm_struct *mm, unsigned long addr,
#ifndef pmd_mknuma
static inline pmd_t pmd_mknuma(pmd_t pmd)
{
- pmd = pmd_set_flags(pmd, _PAGE_NUMA);
- return pmd_clear_flags(pmd, _PAGE_PRESENT);
+ pmdval_t val = pmd_val(pmd);
+
+ val &= ~_PAGE_PRESENT;
+ val |= _PAGE_NUMA;
+
+ return __pmd(val);
}
#endif
diff --git a/include/drm/drm_crtc_helper.h b/include/drm/drm_crtc_helper.h
index 0bb34ca..36a5feb 100644
--- a/include/drm/drm_crtc_helper.h
+++ b/include/drm/drm_crtc_helper.h
@@ -125,7 +125,6 @@ struct drm_connector_helper_funcs {
struct drm_encoder *(*best_encoder)(struct drm_connector *connector);
};
-extern int drm_helper_probe_single_connector_modes(struct drm_connector *connector, uint32_t maxX, uint32_t maxY);
extern void drm_helper_disable_unused_functions(struct drm_device *dev);
extern int drm_crtc_helper_set_config(struct drm_mode_set *set);
extern bool drm_crtc_helper_set_mode(struct drm_crtc *crtc,
@@ -161,6 +160,11 @@ static inline void drm_connector_helper_add(struct drm_connector *connector,
}
extern void drm_helper_resume_force_mode(struct drm_device *dev);
+
+/* drm_probe_helper.c */
+extern int drm_helper_probe_single_connector_modes(struct drm_connector
+ *connector, uint32_t maxX,
+ uint32_t maxY);
extern void drm_kms_helper_poll_init(struct drm_device *dev);
extern void drm_kms_helper_poll_fini(struct drm_device *dev);
extern bool drm_helper_hpd_irq_event(struct drm_device *dev);
diff --git a/include/drm/drm_dp_helper.h b/include/drm/drm_dp_helper.h
index b4f5891..cfcacec 100644
--- a/include/drm/drm_dp_helper.h
+++ b/include/drm/drm_dp_helper.h
@@ -456,6 +456,10 @@ struct drm_dp_aux_msg {
* transactions. The drm_dp_aux_register_i2c_bus() function registers an
* I2C adapter that can be passed to drm_probe_ddc(). Upon removal, drivers
* should call drm_dp_aux_unregister_i2c_bus() to remove the I2C adapter.
+ *
+ * Note that the aux helper code assumes that the .transfer() function
+ * only modifies the reply field of the drm_dp_aux_msg structure. The
+ * retry logic and i2c helpers assume this is the case.
*/
struct drm_dp_aux {
const char *name;
diff --git a/include/linux/device.h b/include/linux/device.h
index 233bbbe..d1d1c05 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -566,12 +566,6 @@ extern int __must_check device_create_bin_file(struct device *dev,
const struct bin_attribute *attr);
extern void device_remove_bin_file(struct device *dev,
const struct bin_attribute *attr);
-extern int device_schedule_callback_owner(struct device *dev,
- void (*func)(struct device *dev), struct module *owner);
-
-/* This is a macro to avoid include problems with THIS_MODULE */
-#define device_schedule_callback(dev, func) \
- device_schedule_callback_owner(dev, func, THIS_MODULE)
/* device resource management */
typedef void (*dr_release_t)(struct device *dev, void *res);
@@ -932,10 +926,7 @@ extern int device_online(struct device *dev);
extern struct device *__root_device_register(const char *name,
struct module *owner);
-/*
- * This is a macro to avoid include problems with THIS_MODULE,
- * just as per what is done for device_schedule_callback() above.
- */
+/* This is a macro to avoid include problems with THIS_MODULE */
#define root_device_register(name) \
__root_device_register(name, THIS_MODULE)
diff --git a/include/linux/ethtool.h b/include/linux/ethtool.h
index 0a114d0..212f537 100644
--- a/include/linux/ethtool.h
+++ b/include/linux/ethtool.h
@@ -154,13 +154,23 @@ static inline u32 ethtool_rxfh_indir_default(u32 index, u32 n_rx_rings)
* @reset: Reset (part of) the device, as specified by a bitmask of
* flags from &enum ethtool_reset_flags. Returns a negative
* error code or zero.
+ * @get_rxfh_key_size: Get the size of the RX flow hash key.
+ * Returns zero if not supported for this specific device.
* @get_rxfh_indir_size: Get the size of the RX flow hash indirection table.
* Returns zero if not supported for this specific device.
* @get_rxfh_indir: Get the contents of the RX flow hash indirection table.
* Will not be called if @get_rxfh_indir_size returns zero.
+ * @get_rxfh: Get the contents of the RX flow hash indirection table and hash
+ * key.
+ * Will not be called if @get_rxfh_indir_size and @get_rxfh_key_size
+ * returns zero.
* Returns a negative error code or zero.
* @set_rxfh_indir: Set the contents of the RX flow hash indirection table.
* Will not be called if @get_rxfh_indir_size returns zero.
+ * @set_rxfh: Set the contents of the RX flow hash indirection table and
+ * hash key.
+ * Will not be called if @get_rxfh_indir_size and @get_rxfh_key_size
+ * returns zero.
* Returns a negative error code or zero.
* @get_channels: Get number of channels.
* @set_channels: Set number of channels. Returns a negative error code or
@@ -232,7 +242,10 @@ struct ethtool_ops {
int (*set_rxnfc)(struct net_device *, struct ethtool_rxnfc *);
int (*flash_device)(struct net_device *, struct ethtool_flash *);
int (*reset)(struct net_device *, u32 *);
+ u32 (*get_rxfh_key_size)(struct net_device *);
u32 (*get_rxfh_indir_size)(struct net_device *);
+ int (*get_rxfh)(struct net_device *, u32 *, u8 *);
+ int (*set_rxfh)(struct net_device *, u32 *, u8 *);
int (*get_rxfh_indir)(struct net_device *, u32 *);
int (*set_rxfh_indir)(struct net_device *, const u32 *);
void (*get_channels)(struct net_device *, struct ethtool_channels *);
diff --git a/include/linux/filter.h b/include/linux/filter.h
index 024fd03..759abf7 100644
--- a/include/linux/filter.h
+++ b/include/linux/filter.h
@@ -223,6 +223,7 @@ enum {
BPF_S_ANC_VLAN_TAG,
BPF_S_ANC_VLAN_TAG_PRESENT,
BPF_S_ANC_PAY_OFFSET,
+ BPF_S_ANC_RANDOM,
};
#endif /* __LINUX_FILTER_H__ */
diff --git a/include/linux/hyperv.h b/include/linux/hyperv.h
index ab7359f..2d7b4f1 100644
--- a/include/linux/hyperv.h
+++ b/include/linux/hyperv.h
@@ -147,15 +147,17 @@ hv_get_ringbuffer_availbytes(struct hv_ring_buffer_info *rbi,
* 0 . 13 (Windows Server 2008)
* 1 . 1 (Windows 7)
* 2 . 4 (Windows 8)
+ * 3 . 0 (Windows 8 R2)
*/
#define VERSION_WS2008 ((0 << 16) | (13))
#define VERSION_WIN7 ((1 << 16) | (1))
#define VERSION_WIN8 ((2 << 16) | (4))
+#define VERSION_WIN8_1 ((3 << 16) | (0))
#define VERSION_INVAL -1
-#define VERSION_CURRENT VERSION_WIN8
+#define VERSION_CURRENT VERSION_WIN8_1
/* Make maximum size of pipe payload of 16K */
#define MAX_PIPE_DATA_PAYLOAD (sizeof(u8) * 16384)
diff --git a/include/linux/ipmi.h b/include/linux/ipmi.h
index 1f9f56e..76d2acb 100644
--- a/include/linux/ipmi.h
+++ b/include/linux/ipmi.h
@@ -237,7 +237,7 @@ int ipmi_set_maintenance_mode(ipmi_user_t user, int mode);
* The first user that sets this to TRUE will receive all events that
* have been queued while no one was waiting for events.
*/
-int ipmi_set_gets_events(ipmi_user_t user, int val);
+int ipmi_set_gets_events(ipmi_user_t user, bool val);
/*
* Called when a new SMI is registered. This will also be called on
diff --git a/include/linux/ipmi_smi.h b/include/linux/ipmi_smi.h
index 8ea3fe0..bd34924 100644
--- a/include/linux/ipmi_smi.h
+++ b/include/linux/ipmi_smi.h
@@ -109,12 +109,19 @@ struct ipmi_smi_handlers {
events from the BMC we are attached to. */
void (*request_events)(void *send_info);
+ /* Called by the upper layer when some user requires that the
+ interface watch for events, received messages, watchdog
+ pretimeouts, or not. Used by the SMI to know if it should
+ watch for these. This may be NULL if the SMI does not
+ implement it. */
+ void (*set_need_watch)(void *send_info, bool enable);
+
/* Called when the interface should go into "run to
completion" mode. If this call sets the value to true, the
interface should make sure that all messages are flushed
out and that none are pending, and any new requests are run
to completion immediately. */
- void (*set_run_to_completion)(void *send_info, int run_to_completion);
+ void (*set_run_to_completion)(void *send_info, bool run_to_completion);
/* Called to poll for work to do. This is so upper layers can
poll for operations during things like crash dumps. */
@@ -125,7 +132,7 @@ struct ipmi_smi_handlers {
setting. The message handler does the mode handling. Note
that this is called from interrupt context, so it cannot
block. */
- void (*set_maintenance_mode)(void *send_info, int enable);
+ void (*set_maintenance_mode)(void *send_info, bool enable);
/* Tell the handler that we are using it/not using it. The
message handler get the modules that this handler belongs
diff --git a/include/linux/mlx5/device.h b/include/linux/mlx5/device.h
index 407bdb6..3406cfb 100644
--- a/include/linux/mlx5/device.h
+++ b/include/linux/mlx5/device.h
@@ -179,6 +179,7 @@ enum {
MLX5_DEV_CAP_FLAG_BAD_QKEY_CNTR = 1LL << 9,
MLX5_DEV_CAP_FLAG_APM = 1LL << 17,
MLX5_DEV_CAP_FLAG_ATOMIC = 1LL << 18,
+ MLX5_DEV_CAP_FLAG_BLOCK_MCAST = 1LL << 23,
MLX5_DEV_CAP_FLAG_ON_DMND_PG = 1LL << 24,
MLX5_DEV_CAP_FLAG_CQ_MODER = 1LL << 29,
MLX5_DEV_CAP_FLAG_RESIZE_CQ = 1LL << 30,
diff --git a/include/linux/mlx5/qp.h b/include/linux/mlx5/qp.h
index f829ad8..9709b30 100644
--- a/include/linux/mlx5/qp.h
+++ b/include/linux/mlx5/qp.h
@@ -146,6 +146,7 @@ enum {
enum {
MLX5_QP_LAT_SENSITIVE = 1 << 28,
+ MLX5_QP_BLOCK_MCAST = 1 << 30,
MLX5_QP_ENABLE_SIG = 1 << 31,
};
diff --git a/include/linux/mtd/spear_smi.h b/include/linux/mtd/spear_smi.h
index 8ae1726..581603a 100644
--- a/include/linux/mtd/spear_smi.h
+++ b/include/linux/mtd/spear_smi.h
@@ -1,6 +1,6 @@
/*
* Copyright © 2010 ST Microelectronics
- * Shiraz Hashim <shiraz.hashim@st.com>
+ * Shiraz Hashim <shiraz.linux.kernel@gmail.com>
*
* This file is licensed under the terms of the GNU General Public
* License version 2. This program is licensed "as is" without any
diff --git a/include/linux/netdevice.h b/include/linux/netdevice.h
index 7ed3a3a..a803d79 100644
--- a/include/linux/netdevice.h
+++ b/include/linux/netdevice.h
@@ -2633,6 +2633,7 @@ int dev_get_phys_port_id(struct net_device *dev,
struct netdev_phys_port_id *ppid);
int dev_hard_start_xmit(struct sk_buff *skb, struct net_device *dev,
struct netdev_queue *txq);
+int __dev_forward_skb(struct net_device *dev, struct sk_buff *skb);
int dev_forward_skb(struct net_device *dev, struct sk_buff *skb);
bool is_skb_forwardable(struct net_device *dev, struct sk_buff *skb);
diff --git a/include/linux/netlink.h b/include/linux/netlink.h
index aad8eea..5146ce0 100644
--- a/include/linux/netlink.h
+++ b/include/linux/netlink.h
@@ -45,7 +45,8 @@ struct netlink_kernel_cfg {
unsigned int flags;
void (*input)(struct sk_buff *skb);
struct mutex *cb_mutex;
- void (*bind)(int group);
+ int (*bind)(int group);
+ void (*unbind)(int group);
bool (*compare)(struct net *net, struct sock *sk);
};
diff --git a/include/linux/of.h b/include/linux/of.h
index 919bf21..3bad8d1 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -374,6 +374,11 @@ static inline struct device_node *of_find_matching_node_and_match(
return NULL;
}
+static inline struct device_node *of_find_node_by_path(const char *path)
+{
+ return NULL;
+}
+
static inline struct device_node *of_get_parent(const struct device_node *node)
{
return NULL;
diff --git a/include/linux/phy.h b/include/linux/phy.h
index 4d0221f..51d15f6 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -666,6 +666,7 @@ static inline int phy_read_status(struct phy_device *phydev)
return phydev->drv->read_status(phydev);
}
+int genphy_config_init(struct phy_device *phydev);
int genphy_setup_forced(struct phy_device *phydev);
int genphy_restart_aneg(struct phy_device *phydev);
int genphy_config_aneg(struct phy_device *phydev);
diff --git a/include/linux/reboot.h b/include/linux/reboot.h
index 9e7db9e..48bf152 100644
--- a/include/linux/reboot.h
+++ b/include/linux/reboot.h
@@ -20,13 +20,13 @@ enum reboot_mode {
extern enum reboot_mode reboot_mode;
enum reboot_type {
- BOOT_TRIPLE = 't',
- BOOT_KBD = 'k',
- BOOT_BIOS = 'b',
- BOOT_ACPI = 'a',
- BOOT_EFI = 'e',
- BOOT_CF9 = 'p',
- BOOT_CF9_COND = 'q',
+ BOOT_TRIPLE = 't',
+ BOOT_KBD = 'k',
+ BOOT_BIOS = 'b',
+ BOOT_ACPI = 'a',
+ BOOT_EFI = 'e',
+ BOOT_CF9_FORCE = 'p',
+ BOOT_CF9_SAFE = 'q',
};
extern enum reboot_type reboot_type;
diff --git a/include/linux/sock_diag.h b/include/linux/sock_diag.h
index 54f91d3..302ab80 100644
--- a/include/linux/sock_diag.h
+++ b/include/linux/sock_diag.h
@@ -23,7 +23,7 @@ int sock_diag_check_cookie(void *sk, __u32 *cookie);
void sock_diag_save_cookie(void *sk, __u32 *cookie);
int sock_diag_put_meminfo(struct sock *sk, struct sk_buff *skb, int attr);
-int sock_diag_put_filterinfo(struct user_namespace *user_ns, struct sock *sk,
+int sock_diag_put_filterinfo(struct sock *sk,
struct sk_buff *skb, int attrtype);
#endif
diff --git a/include/linux/spi/at86rf230.h b/include/linux/spi/at86rf230.h
index aa327a8..b2b1afb 100644
--- a/include/linux/spi/at86rf230.h
+++ b/include/linux/spi/at86rf230.h
@@ -26,20 +26,6 @@ struct at86rf230_platform_data {
int rstn;
int slp_tr;
int dig2;
-
- /* Setting the irq_type will configure the driver to request
- * the platform irq trigger type according to the given value
- * and configure the interrupt polarity of the device to the
- * corresponding polarity.
- *
- * Allowed values are: IRQF_TRIGGER_RISING, IRQF_TRIGGER_FALLING,
- * IRQF_TRIGGER_HIGH and IRQF_TRIGGER_LOW
- *
- * Setting it to 0, the driver does not touch the trigger type
- * configuration of the interrupt and sets the interrupt polarity
- * of the device to high active (the default value).
- */
- int irq_type;
};
#endif
diff --git a/include/linux/sysfs.h b/include/linux/sysfs.h
index 084354b..5ffaa34 100644
--- a/include/linux/sysfs.h
+++ b/include/linux/sysfs.h
@@ -179,9 +179,6 @@ struct sysfs_ops {
#ifdef CONFIG_SYSFS
-int sysfs_schedule_callback(struct kobject *kobj, void (*func)(void *),
- void *data, struct module *owner);
-
int __must_check sysfs_create_dir_ns(struct kobject *kobj, const void *ns);
void sysfs_remove_dir(struct kobject *kobj);
int __must_check sysfs_rename_dir_ns(struct kobject *kobj, const char *new_name,
@@ -255,12 +252,6 @@ static inline void sysfs_enable_ns(struct kernfs_node *kn)
#else /* CONFIG_SYSFS */
-static inline int sysfs_schedule_callback(struct kobject *kobj,
- void (*func)(void *), void *data, struct module *owner)
-{
- return -ENOSYS;
-}
-
static inline int sysfs_create_dir_ns(struct kobject *kobj, const void *ns)
{
return 0;
diff --git a/include/linux/wait.h b/include/linux/wait.h
index e7d9d9e..bd68819 100644
--- a/include/linux/wait.h
+++ b/include/linux/wait.h
@@ -191,11 +191,23 @@ wait_queue_head_t *bit_waitqueue(void *, int);
(!__builtin_constant_p(state) || \
state == TASK_INTERRUPTIBLE || state == TASK_KILLABLE) \
+/*
+ * The below macro ___wait_event() has an explicit shadow of the __ret
+ * variable when used from the wait_event_*() macros.
+ *
+ * This is so that both can use the ___wait_cond_timeout() construct
+ * to wrap the condition.
+ *
+ * The type inconsistency of the wait_event_*() __ret variable is also
+ * on purpose; we use long where we can return timeout values and int
+ * otherwise.
+ */
+
#define ___wait_event(wq, condition, state, exclusive, ret, cmd) \
({ \
__label__ __out; \
wait_queue_t __wait; \
- long __ret = ret; \
+ long __ret = ret; /* explicit shadow */ \
\
INIT_LIST_HEAD(&__wait.task_list); \
if (exclusive) \
diff --git a/include/net/6lowpan.h b/include/net/6lowpan.h
index f7d372b..79b530f 100644
--- a/include/net/6lowpan.h
+++ b/include/net/6lowpan.h
@@ -54,6 +54,7 @@
#define __6LOWPAN_H__
#include <net/ipv6.h>
+#include <net/net_namespace.h>
#define UIP_802154_SHORTADDR_LEN 2 /* compressed ipv6 address length */
#define UIP_IPH_LEN 40 /* ipv6 fixed header size */
diff --git a/include/net/addrconf.h b/include/net/addrconf.h
index 933a9f2..f679877 100644
--- a/include/net/addrconf.h
+++ b/include/net/addrconf.h
@@ -306,11 +306,6 @@ static inline void addrconf_addr_solict_mult(const struct in6_addr *addr,
htonl(0xFF000000) | addr->s6_addr32[3]);
}
-static inline bool ipv6_addr_is_multicast(const struct in6_addr *addr)
-{
- return (addr->s6_addr32[0] & htonl(0xFF000000)) == htonl(0xFF000000);
-}
-
static inline bool ipv6_addr_is_ll_all_nodes(const struct in6_addr *addr)
{
#if defined(CONFIG_HAVE_EFFICIENT_UNALIGNED_ACCESS) && BITS_PER_LONG == 64
diff --git a/include/net/dsa.h b/include/net/dsa.h
index 7828ebf..6efce38 100644
--- a/include/net/dsa.h
+++ b/include/net/dsa.h
@@ -181,6 +181,11 @@ struct dsa_switch_driver {
void register_switch_driver(struct dsa_switch_driver *type);
void unregister_switch_driver(struct dsa_switch_driver *type);
+static inline void *ds_to_priv(struct dsa_switch *ds)
+{
+ return (void *)(ds + 1);
+}
+
/*
* The original DSA tag format and some other tag formats have no
* ethertype, which means that we need to add a little hack to the
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index d640925..5b40ad2 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -583,6 +583,11 @@ static inline bool ipv6_addr_orchid(const struct in6_addr *a)
return (a->s6_addr32[0] & htonl(0xfffffff0)) == htonl(0x20010010);
}
+static inline bool ipv6_addr_is_multicast(const struct in6_addr *addr)
+{
+ return (addr->s6_addr32[0] & htonl(0xFF000000)) == htonl(0xFF000000);
+}
+
static inline void ipv6_addr_set_v4mapped(const __be32 addr,
struct in6_addr *v4mapped)
{
@@ -664,6 +669,20 @@ void ipv6_select_ident(struct frag_hdr *fhdr, struct rt6_info *rt);
int ip6_dst_hoplimit(struct dst_entry *dst);
+static inline int ip6_sk_dst_hoplimit(struct ipv6_pinfo *np, struct flowi6 *fl6,
+ struct dst_entry *dst)
+{
+ int hlimit;
+
+ if (ipv6_addr_is_multicast(&fl6->daddr))
+ hlimit = np->mcast_hops;
+ else
+ hlimit = np->hop_limit;
+ if (hlimit < 0)
+ hlimit = ip6_dst_hoplimit(dst);
+ return hlimit;
+}
+
/*
* Header manipulation
*/
diff --git a/include/net/net_namespace.h b/include/net/net_namespace.h
index 5f9eb26..361d260 100644
--- a/include/net/net_namespace.h
+++ b/include/net/net_namespace.h
@@ -373,6 +373,14 @@ static inline void rt_genid_bump_ipv6(struct net *net)
}
#endif
+#if IS_ENABLED(CONFIG_IEEE802154_6LOWPAN)
+static inline struct netns_ieee802154_lowpan *
+net_ieee802154_lowpan(struct net *net)
+{
+ return &net->ieee802154_lowpan;
+}
+#endif
+
/* For callers who don't really care about whether it's IPv4 or IPv6 */
static inline void rt_genid_bump_all(struct net *net)
{
diff --git a/include/net/pkt_cls.h b/include/net/pkt_cls.h
index a2441fb..6da46dc 100644
--- a/include/net/pkt_cls.h
+++ b/include/net/pkt_cls.h
@@ -136,7 +136,7 @@ tcf_exts_exec(struct sk_buff *skb, struct tcf_exts *exts,
int tcf_exts_validate(struct net *net, struct tcf_proto *tp,
struct nlattr **tb, struct nlattr *rate_tlv,
- struct tcf_exts *exts);
+ struct tcf_exts *exts, bool ovr);
void tcf_exts_destroy(struct tcf_proto *tp, struct tcf_exts *exts);
void tcf_exts_change(struct tcf_proto *tp, struct tcf_exts *dst,
struct tcf_exts *src);
diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index d062f81..624f985 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -199,7 +199,7 @@ struct tcf_proto_ops {
int (*change)(struct net *net, struct sk_buff *,
struct tcf_proto*, unsigned long,
u32 handle, struct nlattr **,
- unsigned long *);
+ unsigned long *, bool);
int (*delete)(struct tcf_proto*, unsigned long);
void (*walk)(struct tcf_proto*, struct tcf_walker *arg);
diff --git a/include/net/sctp/structs.h b/include/net/sctp/structs.h
index d992ca3..0dfcc92 100644
--- a/include/net/sctp/structs.h
+++ b/include/net/sctp/structs.h
@@ -1241,6 +1241,7 @@ struct sctp_endpoint {
/* SCTP-AUTH: endpoint shared keys */
struct list_head endpoint_shared_keys;
__u16 active_key_id;
+ __u8 auth_enable;
};
/* Recover the outter endpoint structure. */
@@ -1269,7 +1270,8 @@ struct sctp_endpoint *sctp_endpoint_is_match(struct sctp_endpoint *,
int sctp_has_association(struct net *net, const union sctp_addr *laddr,
const union sctp_addr *paddr);
-int sctp_verify_init(struct net *net, const struct sctp_association *asoc,
+int sctp_verify_init(struct net *net, const struct sctp_endpoint *ep,
+ const struct sctp_association *asoc,
sctp_cid_t, sctp_init_chunk_t *peer_init,
struct sctp_chunk *chunk, struct sctp_chunk **err_chunk);
int sctp_process_init(struct sctp_association *, struct sctp_chunk *chunk,
diff --git a/include/net/tcp.h b/include/net/tcp.h
index 87d8774..163d2b4 100644
--- a/include/net/tcp.h
+++ b/include/net/tcp.h
@@ -558,7 +558,6 @@ void tcp_send_loss_probe(struct sock *sk);
bool tcp_schedule_loss_probe(struct sock *sk);
/* tcp_input.c */
-void tcp_cwnd_application_limited(struct sock *sk);
void tcp_resume_early_retransmit(struct sock *sk);
void tcp_rearm_rto(struct sock *sk);
void tcp_reset(struct sock *sk);
diff --git a/include/net/vxlan.h b/include/net/vxlan.h
index 5deef1a..7bb4084 100644
--- a/include/net/vxlan.h
+++ b/include/net/vxlan.h
@@ -33,7 +33,7 @@ void vxlan_sock_release(struct vxlan_sock *vs);
int vxlan_xmit_skb(struct vxlan_sock *vs,
struct rtable *rt, struct sk_buff *skb,
__be32 src, __be32 dst, __u8 tos, __u8 ttl, __be16 df,
- __be16 src_port, __be16 dst_port, __be32 vni);
+ __be16 src_port, __be16 dst_port, __be32 vni, bool xnet);
__be16 vxlan_src_port(__u16 port_min, __u16 port_max, struct sk_buff *skb);
diff --git a/include/uapi/drm/tegra_drm.h b/include/uapi/drm/tegra_drm.h
index b042b48..b754821 100644
--- a/include/uapi/drm/tegra_drm.h
+++ b/include/uapi/drm/tegra_drm.h
@@ -120,7 +120,6 @@ struct drm_tegra_submit {
__u32 num_waitchks;
__u32 waitchk_mask;
__u32 timeout;
- __u32 pad;
__u64 syncpts;
__u64 cmdbufs;
__u64 relocs;
diff --git a/include/uapi/linux/audit.h b/include/uapi/linux/audit.h
index 11917f7..dfa4c86 100644
--- a/include/uapi/linux/audit.h
+++ b/include/uapi/linux/audit.h
@@ -373,6 +373,14 @@ enum {
*/
#define AUDIT_MESSAGE_TEXT_MAX 8560
+/* Multicast Netlink socket groups (default up to 32) */
+enum audit_nlgrps {
+ AUDIT_NLGRP_NONE, /* Group 0 not used */
+ AUDIT_NLGRP_READLOG, /* "best effort" read only socket */
+ __AUDIT_NLGRP_MAX
+};
+#define AUDIT_NLGRP_MAX (__AUDIT_NLGRP_MAX - 1)
+
struct audit_status {
__u32 mask; /* Bit mask for valid entries */
__u32 enabled; /* 1 = enabled, 0 = disabled */
diff --git a/include/uapi/linux/capability.h b/include/uapi/linux/capability.h
index 154dd6d..12c37a1 100644
--- a/include/uapi/linux/capability.h
+++ b/include/uapi/linux/capability.h
@@ -347,7 +347,12 @@ struct vfs_cap_data {
#define CAP_BLOCK_SUSPEND 36
-#define CAP_LAST_CAP CAP_BLOCK_SUSPEND
+/* Allow reading the audit log via multicast netlink socket */
+
+#define CAP_AUDIT_READ 37
+
+
+#define CAP_LAST_CAP CAP_AUDIT_READ
#define cap_valid(x) ((x) >= 0 && (x) <= CAP_LAST_CAP)
diff --git a/include/uapi/linux/ethtool.h b/include/uapi/linux/ethtool.h
index fd161e9..d47d31d 100644
--- a/include/uapi/linux/ethtool.h
+++ b/include/uapi/linux/ethtool.h
@@ -847,6 +847,35 @@ struct ethtool_rxfh_indir {
};
/**
+ * struct ethtool_rxfh - command to get/set RX flow hash indir or/and hash key.
+ * @cmd: Specific command number - %ETHTOOL_GRSSH or %ETHTOOL_SRSSH
+ * @rss_context: RSS context identifier.
+ * @indir_size: On entry, the array size of the user buffer, which may be zero.
+ * On return from %ETHTOOL_GRSSH, the array size of the hardware
+ * indirection table.
+ * @key_size: On entry, the array size of the user buffer in bytes,
+ * which may be zero.
+ * On return from %ETHTOOL_GRSSH, the size of the RSS hash key.
+ * @rsvd: Reserved for future extensions.
+ * @rss_config: RX ring/queue index for each hash value i.e., indirection table
+ * of size @indir_size followed by hash key of size @key_size.
+ *
+ * For %ETHTOOL_GRSSH, a @indir_size and key_size of zero means that only the
+ * size should be returned. For %ETHTOOL_SRSSH, a @indir_size of 0xDEADBEEF
+ * means that indir table setting is not requested and a @indir_size of zero
+ * means the indir table should be reset to default values. This last feature
+ * is not supported by the original implementations.
+ */
+struct ethtool_rxfh {
+ __u32 cmd;
+ __u32 rss_context;
+ __u32 indir_size;
+ __u32 key_size;
+ __u32 rsvd[2];
+ __u32 rss_config[0];
+};
+
+/**
* struct ethtool_rx_ntuple_flow_spec - specification for RX flow filter
* @flow_type: Type of match to perform, e.g. %TCP_V4_FLOW
* @h_u: Flow field values to match (dependent on @flow_type)
@@ -1118,6 +1147,9 @@ enum ethtool_sfeatures_retval_bits {
#define ETHTOOL_GEEE 0x00000044 /* Get EEE settings */
#define ETHTOOL_SEEE 0x00000045 /* Set EEE settings */
+#define ETHTOOL_GRSSH 0x00000046 /* Get RX flow hash configuration */
+#define ETHTOOL_SRSSH 0x00000047 /* Set RX flow hash configuration */
+
/* compatibility with older code */
#define SPARC_ETH_GSET ETHTOOL_GSET
#define SPARC_ETH_SSET ETHTOOL_SSET
diff --git a/include/uapi/linux/filter.h b/include/uapi/linux/filter.h
index 8eb9cca..253b4d4 100644
--- a/include/uapi/linux/filter.h
+++ b/include/uapi/linux/filter.h
@@ -130,7 +130,8 @@ struct sock_fprog { /* Required for SO_ATTACH_FILTER. */
#define SKF_AD_VLAN_TAG 44
#define SKF_AD_VLAN_TAG_PRESENT 48
#define SKF_AD_PAY_OFFSET 52
-#define SKF_AD_MAX 56
+#define SKF_AD_RANDOM 56
+#define SKF_AD_MAX 60
#define SKF_NET_OFF (-0x100000)
#define SKF_LL_OFF (-0x200000)
diff --git a/include/uapi/linux/hyperv.h b/include/uapi/linux/hyperv.h
index 9beb7c9..78e4a86 100644
--- a/include/uapi/linux/hyperv.h
+++ b/include/uapi/linux/hyperv.h
@@ -305,6 +305,7 @@ enum hv_kvp_exchg_pool {
#define HV_ERROR_DEVICE_NOT_CONNECTED 0x8007048F
#define HV_INVALIDARG 0x80070057
#define HV_GUID_NOTFOUND 0x80041002
+#define HV_ERROR_ALREADY_EXISTS 0x80070050
#define ADDR_FAMILY_NONE 0x00
#define ADDR_FAMILY_IPV4 0x01
diff --git a/include/uapi/linux/if_fddi.h b/include/uapi/linux/if_fddi.h
index 0d36909..1086cd9 100644
--- a/include/uapi/linux/if_fddi.h
+++ b/include/uapi/linux/if_fddi.h
@@ -30,74 +30,76 @@
* Define max and min legal sizes. The frame sizes do not include
* 4 byte FCS/CRC (frame check sequence).
*/
-#define FDDI_K_ALEN 6 /* Octets in one FDDI address */
-#define FDDI_K_8022_HLEN 16 /* Total octets in 802.2 header */
-#define FDDI_K_SNAP_HLEN 21 /* Total octets in 802.2 SNAP header */
-#define FDDI_K_8022_ZLEN 16 /* Min octets in 802.2 frame sans FCS */
-#define FDDI_K_SNAP_ZLEN 21 /* Min octets in 802.2 SNAP frame sans FCS */
+#define FDDI_K_ALEN 6 /* Octets in one FDDI address */
+#define FDDI_K_8022_HLEN 16 /* Total octets in 802.2 header */
+#define FDDI_K_SNAP_HLEN 21 /* Total octets in 802.2 SNAP header */
+#define FDDI_K_8022_ZLEN 16 /* Min octets in 802.2 frame sans
+ FCS */
+#define FDDI_K_SNAP_ZLEN 21 /* Min octets in 802.2 SNAP frame sans
+ FCS */
#define FDDI_K_8022_DLEN 4475 /* Max octets in 802.2 payload */
#define FDDI_K_SNAP_DLEN 4470 /* Max octets in 802.2 SNAP payload */
-#define FDDI_K_LLC_ZLEN 13 /* Min octets in LLC frame sans FCS */
+#define FDDI_K_LLC_ZLEN 13 /* Min octets in LLC frame sans FCS */
#define FDDI_K_LLC_LEN 4491 /* Max octets in LLC frame sans FCS */
+#define FDDI_K_OUI_LEN 3 /* Octets in OUI in 802.2 SNAP
+ header */
/* Define FDDI Frame Control (FC) Byte values */
-#define FDDI_FC_K_VOID 0x00
-#define FDDI_FC_K_NON_RESTRICTED_TOKEN 0x80
-#define FDDI_FC_K_RESTRICTED_TOKEN 0xC0
-#define FDDI_FC_K_SMT_MIN 0x41
-#define FDDI_FC_K_SMT_MAX 0x4F
-#define FDDI_FC_K_MAC_MIN 0xC1
-#define FDDI_FC_K_MAC_MAX 0xCF
-#define FDDI_FC_K_ASYNC_LLC_MIN 0x50
-#define FDDI_FC_K_ASYNC_LLC_DEF 0x54
-#define FDDI_FC_K_ASYNC_LLC_MAX 0x5F
-#define FDDI_FC_K_SYNC_LLC_MIN 0xD0
-#define FDDI_FC_K_SYNC_LLC_MAX 0xD7
-#define FDDI_FC_K_IMPLEMENTOR_MIN 0x60
-#define FDDI_FC_K_IMPLEMENTOR_MAX 0x6F
-#define FDDI_FC_K_RESERVED_MIN 0x70
-#define FDDI_FC_K_RESERVED_MAX 0x7F
+#define FDDI_FC_K_VOID 0x00
+#define FDDI_FC_K_NON_RESTRICTED_TOKEN 0x80
+#define FDDI_FC_K_RESTRICTED_TOKEN 0xC0
+#define FDDI_FC_K_SMT_MIN 0x41
+#define FDDI_FC_K_SMT_MAX 0x4F
+#define FDDI_FC_K_MAC_MIN 0xC1
+#define FDDI_FC_K_MAC_MAX 0xCF
+#define FDDI_FC_K_ASYNC_LLC_MIN 0x50
+#define FDDI_FC_K_ASYNC_LLC_DEF 0x54
+#define FDDI_FC_K_ASYNC_LLC_MAX 0x5F
+#define FDDI_FC_K_SYNC_LLC_MIN 0xD0
+#define FDDI_FC_K_SYNC_LLC_MAX 0xD7
+#define FDDI_FC_K_IMPLEMENTOR_MIN 0x60
+#define FDDI_FC_K_IMPLEMENTOR_MAX 0x6F
+#define FDDI_FC_K_RESERVED_MIN 0x70
+#define FDDI_FC_K_RESERVED_MAX 0x7F
/* Define LLC and SNAP constants */
-#define FDDI_EXTENDED_SAP 0xAA
+#define FDDI_EXTENDED_SAP 0xAA
#define FDDI_UI_CMD 0x03
/* Define 802.2 Type 1 header */
struct fddi_8022_1_hdr {
- __u8 dsap; /* destination service access point */
- __u8 ssap; /* source service access point */
- __u8 ctrl; /* control byte #1 */
+ __u8 dsap; /* destination service access point */
+ __u8 ssap; /* source service access point */
+ __u8 ctrl; /* control byte #1 */
} __attribute__((packed));
/* Define 802.2 Type 2 header */
struct fddi_8022_2_hdr {
- __u8 dsap; /* destination service access point */
- __u8 ssap; /* source service access point */
- __u8 ctrl_1; /* control byte #1 */
- __u8 ctrl_2; /* control byte #2 */
+ __u8 dsap; /* destination service access point */
+ __u8 ssap; /* source service access point */
+ __u8 ctrl_1; /* control byte #1 */
+ __u8 ctrl_2; /* control byte #2 */
} __attribute__((packed));
/* Define 802.2 SNAP header */
-#define FDDI_K_OUI_LEN 3
struct fddi_snap_hdr {
- __u8 dsap; /* always 0xAA */
- __u8 ssap; /* always 0xAA */
- __u8 ctrl; /* always 0x03 */
+ __u8 dsap; /* always 0xAA */
+ __u8 ssap; /* always 0xAA */
+ __u8 ctrl; /* always 0x03 */
__u8 oui[FDDI_K_OUI_LEN]; /* organizational universal id */
- __be16 ethertype; /* packet type ID field */
+ __be16 ethertype; /* packet type ID field */
} __attribute__((packed));
/* Define FDDI LLC frame header */
struct fddihdr {
- __u8 fc; /* frame control */
- __u8 daddr[FDDI_K_ALEN]; /* destination address */
- __u8 saddr[FDDI_K_ALEN]; /* source address */
- union
- {
- struct fddi_8022_1_hdr llc_8022_1;
- struct fddi_8022_2_hdr llc_8022_2;
- struct fddi_snap_hdr llc_snap;
- } hdr;
+ __u8 fc; /* frame control */
+ __u8 daddr[FDDI_K_ALEN]; /* destination address */
+ __u8 saddr[FDDI_K_ALEN]; /* source address */
+ union {
+ struct fddi_8022_1_hdr llc_8022_1;
+ struct fddi_8022_2_hdr llc_8022_2;
+ struct fddi_snap_hdr llc_snap;
+ } hdr;
} __attribute__((packed));
diff --git a/include/uapi/linux/tipc.h b/include/uapi/linux/tipc.h
index 852373d..6f71b9b 100644
--- a/include/uapi/linux/tipc.h
+++ b/include/uapi/linux/tipc.h
@@ -38,6 +38,7 @@
#define _LINUX_TIPC_H_
#include <linux/types.h>
+#include <linux/sockios.h>
/*
* TIPC addressing primitives
@@ -87,6 +88,7 @@ static inline unsigned int tipc_node(__u32 addr)
#define TIPC_CFG_SRV 0 /* configuration service name type */
#define TIPC_TOP_SRV 1 /* topology service name type */
+#define TIPC_LINK_STATE 2 /* link state name type */
#define TIPC_RESERVED_TYPES 64 /* lowest user-publishable name type */
/*
@@ -206,4 +208,25 @@ struct sockaddr_tipc {
#define TIPC_NODE_RECVQ_DEPTH 131 /* Default: none (read only) */
#define TIPC_SOCK_RECVQ_DEPTH 132 /* Default: none (read only) */
+/*
+ * Maximum sizes of TIPC bearer-related names (including terminating NULL)
+ * The string formatting for each name element is:
+ * media: media
+ * interface: media:interface name
+ * link: Z.C.N:interface-Z.C.N:interface
+ *
+ */
+
+#define TIPC_MAX_MEDIA_NAME 16
+#define TIPC_MAX_IF_NAME 16
+#define TIPC_MAX_BEARER_NAME 32
+#define TIPC_MAX_LINK_NAME 60
+
+#define SIOCGETLINKNAME SIOCPROTOPRIVATE
+
+struct tipc_sioc_ln_req {
+ __u32 peer;
+ __u32 bearer_id;
+ char linkname[TIPC_MAX_LINK_NAME];
+};
#endif
diff --git a/include/uapi/linux/tipc_config.h b/include/uapi/linux/tipc_config.h
index 6b0bff0..41a76ac 100644
--- a/include/uapi/linux/tipc_config.h
+++ b/include/uapi/linux/tipc_config.h
@@ -39,6 +39,7 @@
#include <linux/types.h>
#include <linux/string.h>
+#include <linux/tipc.h>
#include <asm/byteorder.h>
#ifndef __KERNEL__
@@ -155,15 +156,6 @@
#define TIPC_TLV_PORT_REF 26 /* 32-bit port reference */
/*
- * Maximum sizes of TIPC bearer-related names (including terminating NUL)
- */
-
-#define TIPC_MAX_MEDIA_NAME 16 /* format = media */
-#define TIPC_MAX_IF_NAME 16 /* format = interface */
-#define TIPC_MAX_BEARER_NAME 32 /* format = media:interface */
-#define TIPC_MAX_LINK_NAME 60 /* format = Z.C.N:interface-Z.C.N:interface */
-
-/*
* Link priority limits (min, default, max, media default)
*/
diff --git a/init/Kconfig b/init/Kconfig
index 765018c..9d3585b 100644
--- a/init/Kconfig
+++ b/init/Kconfig
@@ -1646,6 +1646,18 @@ config MMAP_ALLOW_UNINITIALIZED
See Documentation/nommu-mmap.txt for more information.
+config SYSTEM_TRUSTED_KEYRING
+ bool "Provide system-wide ring of trusted keys"
+ depends on KEYS
+ help
+ Provide a system keyring to which trusted keys can be added. Keys in
+ the keyring are considered to be trusted. Keys may be added at will
+ by the kernel from compiled-in data and from hardware key stores, but
+ userspace may only add extra keys if those keys can be verified by
+ keys already in the keyring.
+
+ Keys in this keyring are used by module signature checking.
+
config PROFILING
bool "Profiling support"
help
@@ -1681,18 +1693,6 @@ config BASE_SMALL
default 0 if BASE_FULL
default 1 if !BASE_FULL
-config SYSTEM_TRUSTED_KEYRING
- bool "Provide system-wide ring of trusted keys"
- depends on KEYS
- help
- Provide a system keyring to which trusted keys can be added. Keys in
- the keyring are considered to be trusted. Keys may be added at will
- by the kernel from compiled-in data and from hardware key stores, but
- userspace may only add extra keys if those keys can be verified by
- keys already in the keyring.
-
- Keys in this keyring are used by module signature checking.
-
menuconfig MODULES
bool "Enable loadable module support"
option modules
diff --git a/kernel/audit.c b/kernel/audit.c
index 7c28936..33531d7 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -424,6 +424,38 @@ static void kauditd_send_skb(struct sk_buff *skb)
}
/*
+ * kauditd_send_multicast_skb - send the skb to multicast userspace listeners
+ *
+ * This function doesn't consume an skb as might be expected since it has to
+ * copy it anyways.
+ */
+static void kauditd_send_multicast_skb(struct sk_buff *skb)
+{
+ struct sk_buff *copy;
+ struct audit_net *aunet = net_generic(&init_net, audit_net_id);
+ struct sock *sock = aunet->nlsk;
+
+ if (!netlink_has_listeners(sock, AUDIT_NLGRP_READLOG))
+ return;
+
+ /*
+ * The seemingly wasteful skb_copy() rather than bumping the refcount
+ * using skb_get() is necessary because non-standard mods are made to
+ * the skb by the original kaudit unicast socket send routine. The
+ * existing auditd daemon assumes this breakage. Fixing this would
+ * require co-ordinating a change in the established protocol between
+ * the kaudit kernel subsystem and the auditd userspace code. There is
+ * no reason for new multicast clients to continue with this
+ * non-compliance.
+ */
+ copy = skb_copy(skb, GFP_KERNEL);
+ if (!copy)
+ return;
+
+ nlmsg_multicast(sock, copy, 0, AUDIT_NLGRP_READLOG, GFP_KERNEL);
+}
+
+/*
* flush_hold_queue - empty the hold queue if auditd appears
*
* If auditd just started, drain the queue of messages already
@@ -1076,10 +1108,22 @@ static void audit_receive(struct sk_buff *skb)
mutex_unlock(&audit_cmd_mutex);
}
+/* Run custom bind function on netlink socket group connect or bind requests. */
+static int audit_bind(int group)
+{
+ if (!capable(CAP_AUDIT_READ))
+ return -EPERM;
+
+ return 0;
+}
+
static int __net_init audit_net_init(struct net *net)
{
struct netlink_kernel_cfg cfg = {
.input = audit_receive,
+ .bind = audit_bind,
+ .flags = NL_CFG_F_NONROOT_RECV,
+ .groups = AUDIT_NLGRP_MAX,
};
struct audit_net *aunet = net_generic(net, audit_net_id);
@@ -1901,10 +1945,10 @@ out:
* audit_log_end - end one audit record
* @ab: the audit_buffer
*
- * The netlink_* functions cannot be called inside an irq context, so
- * the audit buffer is placed on a queue and a tasklet is scheduled to
- * remove them from the queue outside the irq context. May be called in
- * any context.
+ * netlink_unicast() cannot be called inside an irq context because it blocks
+ * (last arg, flags, is not set to MSG_DONTWAIT), so the audit buffer is placed
+ * on a queue and a tasklet is scheduled to remove them from the queue outside
+ * the irq context. May be called in any context.
*/
void audit_log_end(struct audit_buffer *ab)
{
@@ -1914,6 +1958,18 @@ void audit_log_end(struct audit_buffer *ab)
audit_log_lost("rate limit exceeded");
} else {
struct nlmsghdr *nlh = nlmsg_hdr(ab->skb);
+
+ kauditd_send_multicast_skb(ab->skb);
+
+ /*
+ * The original kaudit unicast socket sends up messages with
+ * nlmsg_len set to the payload length rather than the entire
+ * message length. This breaks the standard set by netlink.
+ * The existing auditd daemon assumes this breakage. Fixing
+ * this would require co-ordinating a change in the established
+ * protocol between the kaudit kernel subsystem and the auditd
+ * userspace code.
+ */
nlh->nlmsg_len = ab->skb->len - NLMSG_HDRLEN;
if (audit_pid) {
diff --git a/kernel/locking/mutex-debug.c b/kernel/locking/mutex-debug.c
index e1191c9..5cf6731 100644
--- a/kernel/locking/mutex-debug.c
+++ b/kernel/locking/mutex-debug.c
@@ -71,18 +71,17 @@ void mutex_remove_waiter(struct mutex *lock, struct mutex_waiter *waiter,
void debug_mutex_unlock(struct mutex *lock)
{
- if (unlikely(!debug_locks))
- return;
+ if (likely(debug_locks)) {
+ DEBUG_LOCKS_WARN_ON(lock->magic != lock);
- DEBUG_LOCKS_WARN_ON(lock->magic != lock);
+ if (!lock->owner)
+ DEBUG_LOCKS_WARN_ON(!lock->owner);
+ else
+ DEBUG_LOCKS_WARN_ON(lock->owner != current);
- if (!lock->owner)
- DEBUG_LOCKS_WARN_ON(!lock->owner);
- else
- DEBUG_LOCKS_WARN_ON(lock->owner != current);
-
- DEBUG_LOCKS_WARN_ON(!lock->wait_list.prev && !lock->wait_list.next);
- mutex_clear_owner(lock);
+ DEBUG_LOCKS_WARN_ON(!lock->wait_list.prev && !lock->wait_list.next);
+ mutex_clear_owner(lock);
+ }
/*
* __mutex_slowpath_needs_to_unlock() is explicitly 0 for debug
diff --git a/kernel/sched/deadline.c b/kernel/sched/deadline.c
index 27ef409..b080957 100644
--- a/kernel/sched/deadline.c
+++ b/kernel/sched/deadline.c
@@ -1021,8 +1021,17 @@ struct task_struct *pick_next_task_dl(struct rq *rq, struct task_struct *prev)
dl_rq = &rq->dl;
- if (need_pull_dl_task(rq, prev))
+ if (need_pull_dl_task(rq, prev)) {
pull_dl_task(rq);
+ /*
+ * pull_rt_task() can drop (and re-acquire) rq->lock; this
+ * means a stop task can slip in, in which case we need to
+ * re-start task selection.
+ */
+ if (rq->stop && rq->stop->on_rq)
+ return RETRY_TASK;
+ }
+
/*
* When prev is DL, we may throttle it in put_prev_task().
* So, we update time before we check for dl_nr_running.
diff --git a/kernel/sched/fair.c b/kernel/sched/fair.c
index 7e9bd0b..7570dd9 100644
--- a/kernel/sched/fair.c
+++ b/kernel/sched/fair.c
@@ -1497,7 +1497,7 @@ static void task_numa_placement(struct task_struct *p)
/* If the task is part of a group prevent parallel updates to group stats */
if (p->numa_group) {
group_lock = &p->numa_group->lock;
- spin_lock(group_lock);
+ spin_lock_irq(group_lock);
}
/* Find the node with the highest number of faults */
@@ -1572,7 +1572,7 @@ static void task_numa_placement(struct task_struct *p)
}
}
- spin_unlock(group_lock);
+ spin_unlock_irq(group_lock);
}
/* Preferred node as the node with the most faults */
@@ -1677,7 +1677,8 @@ static void task_numa_group(struct task_struct *p, int cpupid, int flags,
if (!join)
return;
- double_lock(&my_grp->lock, &grp->lock);
+ BUG_ON(irqs_disabled());
+ double_lock_irq(&my_grp->lock, &grp->lock);
for (i = 0; i < NR_NUMA_HINT_FAULT_STATS * nr_node_ids; i++) {
my_grp->faults[i] -= p->numa_faults_memory[i];
@@ -1691,7 +1692,7 @@ static void task_numa_group(struct task_struct *p, int cpupid, int flags,
grp->nr_tasks++;
spin_unlock(&my_grp->lock);
- spin_unlock(&grp->lock);
+ spin_unlock_irq(&grp->lock);
rcu_assign_pointer(p->numa_group, grp);
@@ -1710,14 +1711,14 @@ void task_numa_free(struct task_struct *p)
void *numa_faults = p->numa_faults_memory;
if (grp) {
- spin_lock(&grp->lock);
+ spin_lock_irq(&grp->lock);
for (i = 0; i < NR_NUMA_HINT_FAULT_STATS * nr_node_ids; i++)
grp->faults[i] -= p->numa_faults_memory[i];
grp->total_faults -= p->total_numa_faults;
list_del(&p->numa_entry);
grp->nr_tasks--;
- spin_unlock(&grp->lock);
+ spin_unlock_irq(&grp->lock);
rcu_assign_pointer(p->numa_group, NULL);
put_numa_group(grp);
}
@@ -6727,7 +6728,8 @@ static int idle_balance(struct rq *this_rq)
out:
/* Is there a task of a high priority class? */
if (this_rq->nr_running != this_rq->cfs.h_nr_running &&
- (this_rq->dl.dl_nr_running ||
+ ((this_rq->stop && this_rq->stop->on_rq) ||
+ this_rq->dl.dl_nr_running ||
(this_rq->rt.rt_nr_running && !rt_rq_throttled(&this_rq->rt))))
pulled_task = -1;
diff --git a/kernel/sched/rt.c b/kernel/sched/rt.c
index d8cdf16..bd2267a 100644
--- a/kernel/sched/rt.c
+++ b/kernel/sched/rt.c
@@ -1362,10 +1362,11 @@ pick_next_task_rt(struct rq *rq, struct task_struct *prev)
pull_rt_task(rq);
/*
* pull_rt_task() can drop (and re-acquire) rq->lock; this
- * means a dl task can slip in, in which case we need to
- * re-start task selection.
+ * means a dl or stop task can slip in, in which case we need
+ * to re-start task selection.
*/
- if (unlikely(rq->dl.dl_nr_running))
+ if (unlikely((rq->stop && rq->stop->on_rq) ||
+ rq->dl.dl_nr_running))
return RETRY_TASK;
}
diff --git a/kernel/sched/sched.h b/kernel/sched/sched.h
index c9007f2..456e492 100644
--- a/kernel/sched/sched.h
+++ b/kernel/sched/sched.h
@@ -1385,6 +1385,15 @@ static inline void double_lock(spinlock_t *l1, spinlock_t *l2)
spin_lock_nested(l2, SINGLE_DEPTH_NESTING);
}
+static inline void double_lock_irq(spinlock_t *l1, spinlock_t *l2)
+{
+ if (l1 > l2)
+ swap(l1, l2);
+
+ spin_lock_irq(l1);
+ spin_lock_nested(l2, SINGLE_DEPTH_NESTING);
+}
+
static inline void double_raw_lock(raw_spinlock_t *l1, raw_spinlock_t *l2)
{
if (l1 > l2)
diff --git a/kernel/time/tick-common.c b/kernel/time/tick-common.c
index 0156612..0a0608e 100644
--- a/kernel/time/tick-common.c
+++ b/kernel/time/tick-common.c
@@ -276,7 +276,7 @@ static bool tick_check_preferred(struct clock_event_device *curdev,
bool tick_check_replacement(struct clock_event_device *curdev,
struct clock_event_device *newdev)
{
- if (tick_check_percpu(curdev, newdev, smp_processor_id()))
+ if (!tick_check_percpu(curdev, newdev, smp_processor_id()))
return false;
return tick_check_preferred(curdev, newdev);
diff --git a/kernel/time/tick-sched.c b/kernel/time/tick-sched.c
index 9f8af69..6558b7a 100644
--- a/kernel/time/tick-sched.c
+++ b/kernel/time/tick-sched.c
@@ -84,6 +84,9 @@ static void tick_do_update_jiffies64(ktime_t now)
/* Keep the tick_next_period variable up to date */
tick_next_period = ktime_add(last_jiffies_update, tick_period);
+ } else {
+ write_sequnlock(&jiffies_lock);
+ return;
}
write_sequnlock(&jiffies_lock);
update_wall_time();
@@ -967,7 +970,7 @@ static void tick_nohz_switch_to_nohz(void)
struct tick_sched *ts = &__get_cpu_var(tick_cpu_sched);
ktime_t next;
- if (!tick_nohz_active)
+ if (!tick_nohz_enabled)
return;
local_irq_disable();
diff --git a/kernel/trace/trace_functions.c b/kernel/trace/trace_functions.c
index 5b781d2..ffd5635 100644
--- a/kernel/trace/trace_functions.c
+++ b/kernel/trace/trace_functions.c
@@ -58,12 +58,16 @@ int ftrace_create_function_files(struct trace_array *tr,
{
int ret;
- /* The top level array uses the "global_ops". */
- if (!(tr->flags & TRACE_ARRAY_FL_GLOBAL)) {
- ret = allocate_ftrace_ops(tr);
- if (ret)
- return ret;
- }
+ /*
+ * The top level array uses the "global_ops", and the files are
+ * created on boot up.
+ */
+ if (tr->flags & TRACE_ARRAY_FL_GLOBAL)
+ return 0;
+
+ ret = allocate_ftrace_ops(tr);
+ if (ret)
+ return ret;
ftrace_create_filter_files(tr->ops, parent);
diff --git a/kernel/trace/trace_uprobe.c b/kernel/trace/trace_uprobe.c
index 930e514..c082a74 100644
--- a/kernel/trace/trace_uprobe.c
+++ b/kernel/trace/trace_uprobe.c
@@ -732,9 +732,15 @@ static int uprobe_buffer_enable(void)
static void uprobe_buffer_disable(void)
{
+ int cpu;
+
BUG_ON(!mutex_is_locked(&event_mutex));
if (--uprobe_buffer_refcnt == 0) {
+ for_each_possible_cpu(cpu)
+ free_page((unsigned long)per_cpu_ptr(uprobe_cpu_buffer,
+ cpu)->buf);
+
free_percpu(uprobe_cpu_buffer);
uprobe_cpu_buffer = NULL;
}
diff --git a/kernel/watchdog.c b/kernel/watchdog.c
index e90089f..516203e 100644
--- a/kernel/watchdog.c
+++ b/kernel/watchdog.c
@@ -138,7 +138,11 @@ static void __touch_watchdog(void)
void touch_softlockup_watchdog(void)
{
- __this_cpu_write(watchdog_touch_ts, 0);
+ /*
+ * Preemption can be enabled. It doesn't matter which CPU's timestamp
+ * gets zeroed here, so use the raw_ operation.
+ */
+ raw_cpu_write(watchdog_touch_ts, 0);
}
EXPORT_SYMBOL(touch_softlockup_watchdog);
diff --git a/lib/Kconfig.debug b/lib/Kconfig.debug
index 140b66a..819ac51 100644
--- a/lib/Kconfig.debug
+++ b/lib/Kconfig.debug
@@ -505,8 +505,7 @@ config DEBUG_VM_RB
bool "Debug VM red-black trees"
depends on DEBUG_VM
help
- Enable this to turn on more extended checks in the virtual-memory
- system that may impact performance.
+ Enable VM red-black tree debugging information and extra validations.
If unsure, say N.
diff --git a/mm/filemap.c b/mm/filemap.c
index a82fbe4..5020b28 100644
--- a/mm/filemap.c
+++ b/mm/filemap.c
@@ -2581,7 +2581,6 @@ EXPORT_SYMBOL(generic_perform_write);
* @iocb: IO state structure (file, offset, etc.)
* @iov: vector with data to write
* @nr_segs: number of segments in the vector
- * @ppos: position where to write
*
* This function does all the work needed for actually writing data to a
* file. It does all basic checks, removes SUID from the file, updates
diff --git a/mm/huge_memory.c b/mm/huge_memory.c
index 64635f5..b4b1feb 100644
--- a/mm/huge_memory.c
+++ b/mm/huge_memory.c
@@ -1536,16 +1536,23 @@ pmd_t *page_check_address_pmd(struct page *page,
enum page_check_address_pmd_flag flag,
spinlock_t **ptl)
{
+ pgd_t *pgd;
+ pud_t *pud;
pmd_t *pmd;
if (address & ~HPAGE_PMD_MASK)
return NULL;
- pmd = mm_find_pmd(mm, address);
- if (!pmd)
+ pgd = pgd_offset(mm, address);
+ if (!pgd_present(*pgd))
return NULL;
+ pud = pud_offset(pgd, address);
+ if (!pud_present(*pud))
+ return NULL;
+ pmd = pmd_offset(pud, address);
+
*ptl = pmd_lock(mm, pmd);
- if (pmd_none(*pmd))
+ if (!pmd_present(*pmd))
goto unlock;
if (pmd_page(*pmd) != page)
goto unlock;
diff --git a/mm/hugetlb.c b/mm/hugetlb.c
index dd30f22..2461929 100644
--- a/mm/hugetlb.c
+++ b/mm/hugetlb.c
@@ -1172,6 +1172,7 @@ static void return_unused_surplus_pages(struct hstate *h,
while (nr_pages--) {
if (!free_pool_huge_page(h, &node_states[N_MEMORY], 1))
break;
+ cond_resched_lock(&hugetlb_lock);
}
}
diff --git a/mm/vmscan.c b/mm/vmscan.c
index 9b6497e..3f56c8d 100644
--- a/mm/vmscan.c
+++ b/mm/vmscan.c
@@ -1158,7 +1158,7 @@ unsigned long reclaim_clean_pages_from_list(struct zone *zone,
TTU_UNMAP|TTU_IGNORE_ACCESS,
&dummy1, &dummy2, &dummy3, &dummy4, &dummy5, true);
list_splice(&clean_pages, page_list);
- __mod_zone_page_state(zone, NR_ISOLATED_FILE, -ret);
+ mod_zone_page_state(zone, NR_ISOLATED_FILE, -ret);
return ret;
}
diff --git a/net/8021q/vlan_dev.c b/net/8021q/vlan_dev.c
index 6f142f0..8f025af 100644
--- a/net/8021q/vlan_dev.c
+++ b/net/8021q/vlan_dev.c
@@ -493,10 +493,48 @@ static void vlan_dev_change_rx_flags(struct net_device *dev, int change)
}
}
+static int vlan_calculate_locking_subclass(struct net_device *real_dev)
+{
+ int subclass = 0;
+
+ while (is_vlan_dev(real_dev)) {
+ subclass++;
+ real_dev = vlan_dev_priv(real_dev)->real_dev;
+ }
+
+ return subclass;
+}
+
+static void vlan_dev_mc_sync(struct net_device *to, struct net_device *from)
+{
+ int err = 0, subclass;
+
+ subclass = vlan_calculate_locking_subclass(to);
+
+ spin_lock_nested(&to->addr_list_lock, subclass);
+ err = __hw_addr_sync(&to->mc, &from->mc, to->addr_len);
+ if (!err)
+ __dev_set_rx_mode(to);
+ spin_unlock(&to->addr_list_lock);
+}
+
+static void vlan_dev_uc_sync(struct net_device *to, struct net_device *from)
+{
+ int err = 0, subclass;
+
+ subclass = vlan_calculate_locking_subclass(to);
+
+ spin_lock_nested(&to->addr_list_lock, subclass);
+ err = __hw_addr_sync(&to->uc, &from->uc, to->addr_len);
+ if (!err)
+ __dev_set_rx_mode(to);
+ spin_unlock(&to->addr_list_lock);
+}
+
static void vlan_dev_set_rx_mode(struct net_device *vlan_dev)
{
- dev_mc_sync(vlan_dev_priv(vlan_dev)->real_dev, vlan_dev);
- dev_uc_sync(vlan_dev_priv(vlan_dev)->real_dev, vlan_dev);
+ vlan_dev_mc_sync(vlan_dev_priv(vlan_dev)->real_dev, vlan_dev);
+ vlan_dev_uc_sync(vlan_dev_priv(vlan_dev)->real_dev, vlan_dev);
}
/*
@@ -608,9 +646,7 @@ static int vlan_dev_init(struct net_device *dev)
SET_NETDEV_DEVTYPE(dev, &vlan_type);
- if (is_vlan_dev(real_dev))
- subclass = 1;
-
+ subclass = vlan_calculate_locking_subclass(dev);
vlan_dev_set_lockdep_class(dev, subclass);
vlan_dev_priv(dev)->vlan_pcpu_stats = netdev_alloc_pcpu_stats(struct vlan_pcpu_stats);
@@ -670,38 +706,36 @@ static void vlan_ethtool_get_drvinfo(struct net_device *dev,
static struct rtnl_link_stats64 *vlan_dev_get_stats64(struct net_device *dev, struct rtnl_link_stats64 *stats)
{
+ struct vlan_pcpu_stats *p;
+ u32 rx_errors = 0, tx_dropped = 0;
+ int i;
- if (vlan_dev_priv(dev)->vlan_pcpu_stats) {
- struct vlan_pcpu_stats *p;
- u32 rx_errors = 0, tx_dropped = 0;
- int i;
-
- for_each_possible_cpu(i) {
- u64 rxpackets, rxbytes, rxmulticast, txpackets, txbytes;
- unsigned int start;
-
- p = per_cpu_ptr(vlan_dev_priv(dev)->vlan_pcpu_stats, i);
- do {
- start = u64_stats_fetch_begin_irq(&p->syncp);
- rxpackets = p->rx_packets;
- rxbytes = p->rx_bytes;
- rxmulticast = p->rx_multicast;
- txpackets = p->tx_packets;
- txbytes = p->tx_bytes;
- } while (u64_stats_fetch_retry_irq(&p->syncp, start));
-
- stats->rx_packets += rxpackets;
- stats->rx_bytes += rxbytes;
- stats->multicast += rxmulticast;
- stats->tx_packets += txpackets;
- stats->tx_bytes += txbytes;
- /* rx_errors & tx_dropped are u32 */
- rx_errors += p->rx_errors;
- tx_dropped += p->tx_dropped;
- }
- stats->rx_errors = rx_errors;
- stats->tx_dropped = tx_dropped;
+ for_each_possible_cpu(i) {
+ u64 rxpackets, rxbytes, rxmulticast, txpackets, txbytes;
+ unsigned int start;
+
+ p = per_cpu_ptr(vlan_dev_priv(dev)->vlan_pcpu_stats, i);
+ do {
+ start = u64_stats_fetch_begin_irq(&p->syncp);
+ rxpackets = p->rx_packets;
+ rxbytes = p->rx_bytes;
+ rxmulticast = p->rx_multicast;
+ txpackets = p->tx_packets;
+ txbytes = p->tx_bytes;
+ } while (u64_stats_fetch_retry_irq(&p->syncp, start));
+
+ stats->rx_packets += rxpackets;
+ stats->rx_bytes += rxbytes;
+ stats->multicast += rxmulticast;
+ stats->tx_packets += txpackets;
+ stats->tx_bytes += txbytes;
+ /* rx_errors & tx_dropped are u32 */
+ rx_errors += p->rx_errors;
+ tx_dropped += p->tx_dropped;
}
+ stats->rx_errors = rx_errors;
+ stats->tx_dropped = tx_dropped;
+
return stats;
}
diff --git a/net/core/dev.c b/net/core/dev.c
index 5b3042e..11d70e3 100644
--- a/net/core/dev.c
+++ b/net/core/dev.c
@@ -1661,6 +1661,29 @@ bool is_skb_forwardable(struct net_device *dev, struct sk_buff *skb)
}
EXPORT_SYMBOL_GPL(is_skb_forwardable);
+int __dev_forward_skb(struct net_device *dev, struct sk_buff *skb)
+{
+ if (skb_shinfo(skb)->tx_flags & SKBTX_DEV_ZEROCOPY) {
+ if (skb_copy_ubufs(skb, GFP_ATOMIC)) {
+ atomic_long_inc(&dev->rx_dropped);
+ kfree_skb(skb);
+ return NET_RX_DROP;
+ }
+ }
+
+ if (unlikely(!is_skb_forwardable(dev, skb))) {
+ atomic_long_inc(&dev->rx_dropped);
+ kfree_skb(skb);
+ return NET_RX_DROP;
+ }
+
+ skb_scrub_packet(skb, true);
+ skb->protocol = eth_type_trans(skb, dev);
+
+ return 0;
+}
+EXPORT_SYMBOL_GPL(__dev_forward_skb);
+
/**
* dev_forward_skb - loopback an skb to another netif
*
@@ -1681,24 +1704,7 @@ EXPORT_SYMBOL_GPL(is_skb_forwardable);
*/
int dev_forward_skb(struct net_device *dev, struct sk_buff *skb)
{
- if (skb_shinfo(skb)->tx_flags & SKBTX_DEV_ZEROCOPY) {
- if (skb_copy_ubufs(skb, GFP_ATOMIC)) {
- atomic_long_inc(&dev->rx_dropped);
- kfree_skb(skb);
- return NET_RX_DROP;
- }
- }
-
- if (unlikely(!is_skb_forwardable(dev, skb))) {
- atomic_long_inc(&dev->rx_dropped);
- kfree_skb(skb);
- return NET_RX_DROP;
- }
-
- skb_scrub_packet(skb, true);
- skb->protocol = eth_type_trans(skb, dev);
-
- return netif_rx_internal(skb);
+ return __dev_forward_skb(dev, skb) ?: netif_rx_internal(skb);
}
EXPORT_SYMBOL_GPL(dev_forward_skb);
@@ -5238,6 +5244,7 @@ void __dev_set_rx_mode(struct net_device *dev)
if (ops->ndo_set_rx_mode)
ops->ndo_set_rx_mode(dev);
}
+EXPORT_SYMBOL(__dev_set_rx_mode);
void dev_set_rx_mode(struct net_device *dev)
{
diff --git a/net/core/ethtool.c b/net/core/ethtool.c
index 640ba0e..aa8978ac 100644
--- a/net/core/ethtool.c
+++ b/net/core/ethtool.c
@@ -557,6 +557,25 @@ err_out:
return ret;
}
+static int ethtool_copy_validate_indir(u32 *indir, void __user *useraddr,
+ struct ethtool_rxnfc *rx_rings,
+ u32 size)
+{
+ int ret = 0, i;
+
+ if (copy_from_user(indir, useraddr, size * sizeof(indir[0])))
+ ret = -EFAULT;
+
+ /* Validate ring indices */
+ for (i = 0; i < size; i++) {
+ if (indir[i] >= rx_rings->data) {
+ ret = -EINVAL;
+ break;
+ }
+ }
+ return ret;
+}
+
static noinline_for_stack int ethtool_get_rxfh_indir(struct net_device *dev,
void __user *useraddr)
{
@@ -613,6 +632,7 @@ static noinline_for_stack int ethtool_set_rxfh_indir(struct net_device *dev,
u32 *indir;
const struct ethtool_ops *ops = dev->ethtool_ops;
int ret;
+ u32 ringidx_offset = offsetof(struct ethtool_rxfh_indir, ring_index[0]);
if (!ops->get_rxfh_indir_size || !ops->set_rxfh_indir ||
!ops->get_rxnfc)
@@ -643,28 +663,196 @@ static noinline_for_stack int ethtool_set_rxfh_indir(struct net_device *dev,
for (i = 0; i < dev_size; i++)
indir[i] = ethtool_rxfh_indir_default(i, rx_rings.data);
} else {
- if (copy_from_user(indir,
- useraddr +
- offsetof(struct ethtool_rxfh_indir,
- ring_index[0]),
- dev_size * sizeof(indir[0]))) {
+ ret = ethtool_copy_validate_indir(indir,
+ useraddr + ringidx_offset,
+ &rx_rings,
+ dev_size);
+ if (ret)
+ goto out;
+ }
+
+ ret = ops->set_rxfh_indir(dev, indir);
+
+out:
+ kfree(indir);
+ return ret;
+}
+
+static noinline_for_stack int ethtool_get_rxfh(struct net_device *dev,
+ void __user *useraddr)
+{
+ int ret;
+ const struct ethtool_ops *ops = dev->ethtool_ops;
+ u32 user_indir_size = 0, user_key_size = 0;
+ u32 dev_indir_size = 0, dev_key_size = 0;
+ u32 total_size;
+ u32 indir_offset, indir_bytes;
+ u32 key_offset;
+ u32 *indir = NULL;
+ u8 *hkey = NULL;
+ u8 *rss_config;
+
+ if (!(dev->ethtool_ops->get_rxfh_indir_size ||
+ dev->ethtool_ops->get_rxfh_key_size) ||
+ !dev->ethtool_ops->get_rxfh)
+ return -EOPNOTSUPP;
+
+ if (ops->get_rxfh_indir_size)
+ dev_indir_size = ops->get_rxfh_indir_size(dev);
+
+ indir_offset = offsetof(struct ethtool_rxfh, indir_size);
+
+ if (copy_from_user(&user_indir_size,
+ useraddr + indir_offset,
+ sizeof(user_indir_size)))
+ return -EFAULT;
+
+ if (copy_to_user(useraddr + indir_offset,
+ &dev_indir_size, sizeof(dev_indir_size)))
+ return -EFAULT;
+
+ if (ops->get_rxfh_key_size)
+ dev_key_size = ops->get_rxfh_key_size(dev);
+
+ if ((dev_key_size + dev_indir_size) == 0)
+ return -EOPNOTSUPP;
+
+ key_offset = offsetof(struct ethtool_rxfh, key_size);
+
+ if (copy_from_user(&user_key_size,
+ useraddr + key_offset,
+ sizeof(user_key_size)))
+ return -EFAULT;
+
+ if (copy_to_user(useraddr + key_offset,
+ &dev_key_size, sizeof(dev_key_size)))
+ return -EFAULT;
+
+ /* If the user buffer size is 0, this is just a query for the
+ * device table size and key size. Otherwise, if the User size is
+ * not equal to device table size or key size it's an error.
+ */
+ if (!user_indir_size && !user_key_size)
+ return 0;
+
+ if ((user_indir_size && (user_indir_size != dev_indir_size)) ||
+ (user_key_size && (user_key_size != dev_key_size)))
+ return -EINVAL;
+
+ indir_bytes = user_indir_size * sizeof(indir[0]);
+ total_size = indir_bytes + user_key_size;
+ rss_config = kzalloc(total_size, GFP_USER);
+ if (!rss_config)
+ return -ENOMEM;
+
+ if (user_indir_size)
+ indir = (u32 *)rss_config;
+
+ if (user_key_size)
+ hkey = rss_config + indir_bytes;
+
+ ret = dev->ethtool_ops->get_rxfh(dev, indir, hkey);
+ if (!ret) {
+ if (copy_to_user(useraddr +
+ offsetof(struct ethtool_rxfh, rss_config[0]),
+ rss_config, total_size))
ret = -EFAULT;
+ }
+
+ kfree(rss_config);
+
+ return ret;
+}
+
+static noinline_for_stack int ethtool_set_rxfh(struct net_device *dev,
+ void __user *useraddr)
+{
+ int ret;
+ const struct ethtool_ops *ops = dev->ethtool_ops;
+ struct ethtool_rxnfc rx_rings;
+ u32 user_indir_size = 0, dev_indir_size = 0, i;
+ u32 user_key_size = 0, dev_key_size = 0;
+ u32 *indir = NULL, indir_bytes = 0;
+ u8 *hkey = NULL;
+ u8 *rss_config;
+ u32 indir_offset, key_offset;
+ u32 rss_cfg_offset = offsetof(struct ethtool_rxfh, rss_config[0]);
+
+ if (!(ops->get_rxfh_indir_size || ops->get_rxfh_key_size) ||
+ !ops->get_rxnfc || !ops->set_rxfh)
+ return -EOPNOTSUPP;
+
+ if (ops->get_rxfh_indir_size)
+ dev_indir_size = ops->get_rxfh_indir_size(dev);
+
+ indir_offset = offsetof(struct ethtool_rxfh, indir_size);
+ if (copy_from_user(&user_indir_size,
+ useraddr + indir_offset,
+ sizeof(user_indir_size)))
+ return -EFAULT;
+
+ if (ops->get_rxfh_key_size)
+ dev_key_size = dev->ethtool_ops->get_rxfh_key_size(dev);
+
+ if ((dev_key_size + dev_indir_size) == 0)
+ return -EOPNOTSUPP;
+
+ key_offset = offsetof(struct ethtool_rxfh, key_size);
+ if (copy_from_user(&user_key_size,
+ useraddr + key_offset,
+ sizeof(user_key_size)))
+ return -EFAULT;
+
+ /* If either indir or hash key is valid, proceed further.
+ */
+ if ((user_indir_size && ((user_indir_size != 0xDEADBEEF) &&
+ user_indir_size != dev_indir_size)) ||
+ (user_key_size && (user_key_size != dev_key_size)))
+ return -EINVAL;
+
+ if (user_indir_size != 0xDEADBEEF)
+ indir_bytes = dev_indir_size * sizeof(indir[0]);
+
+ rss_config = kzalloc(indir_bytes + user_key_size, GFP_USER);
+ if (!rss_config)
+ return -ENOMEM;
+
+ rx_rings.cmd = ETHTOOL_GRXRINGS;
+ ret = ops->get_rxnfc(dev, &rx_rings, NULL);
+ if (ret)
+ goto out;
+
+ /* user_indir_size == 0 means reset the indir table to default.
+ * user_indir_size == 0xDEADBEEF means indir setting is not requested.
+ */
+ if (user_indir_size && user_indir_size != 0xDEADBEEF) {
+ indir = (u32 *)rss_config;
+ ret = ethtool_copy_validate_indir(indir,
+ useraddr + rss_cfg_offset,
+ &rx_rings,
+ user_indir_size);
+ if (ret)
goto out;
- }
+ } else if (user_indir_size == 0) {
+ indir = (u32 *)rss_config;
+ for (i = 0; i < dev_indir_size; i++)
+ indir[i] = ethtool_rxfh_indir_default(i, rx_rings.data);
+ }
- /* Validate ring indices */
- for (i = 0; i < dev_size; i++) {
- if (indir[i] >= rx_rings.data) {
- ret = -EINVAL;
- goto out;
- }
+ if (user_key_size) {
+ hkey = rss_config + indir_bytes;
+ if (copy_from_user(hkey,
+ useraddr + rss_cfg_offset + indir_bytes,
+ user_key_size)) {
+ ret = -EFAULT;
+ goto out;
}
}
- ret = ops->set_rxfh_indir(dev, indir);
+ ret = ops->set_rxfh(dev, indir, hkey);
out:
- kfree(indir);
+ kfree(rss_config);
return ret;
}
@@ -1491,6 +1679,7 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
case ETHTOOL_GRXCLSRULE:
case ETHTOOL_GRXCLSRLALL:
case ETHTOOL_GRXFHINDIR:
+ case ETHTOOL_GRSSH:
case ETHTOOL_GFEATURES:
case ETHTOOL_GCHANNELS:
case ETHTOOL_GET_TS_INFO:
@@ -1628,6 +1817,12 @@ int dev_ethtool(struct net *net, struct ifreq *ifr)
case ETHTOOL_SRXFHINDIR:
rc = ethtool_set_rxfh_indir(dev, useraddr);
break;
+ case ETHTOOL_GRSSH:
+ rc = ethtool_get_rxfh(dev, useraddr);
+ break;
+ case ETHTOOL_SRSSH:
+ rc = ethtool_set_rxfh(dev, useraddr);
+ break;
case ETHTOOL_GFEATURES:
rc = ethtool_get_features(dev, useraddr);
break;
diff --git a/net/core/filter.c b/net/core/filter.c
index cd58614..7c4db3d 100644
--- a/net/core/filter.c
+++ b/net/core/filter.c
@@ -122,6 +122,13 @@ noinline u64 __bpf_call_base(u64 r1, u64 r2, u64 r3, u64 r4, u64 r5)
return 0;
}
+/* Register mappings for user programs. */
+#define A_REG 0
+#define X_REG 7
+#define TMP_REG 8
+#define ARG2_REG 2
+#define ARG3_REG 3
+
/**
* __sk_run_filter - run a filter on a given context
* @ctx: buffer to run the filter on
@@ -242,6 +249,8 @@ unsigned int __sk_run_filter(void *ctx, const struct sock_filter_int *insn)
regs[FP_REG] = (u64) (unsigned long) &stack[ARRAY_SIZE(stack)];
regs[ARG1_REG] = (u64) (unsigned long) ctx;
+ regs[A_REG] = 0;
+ regs[X_REG] = 0;
select_insn:
goto *jumptable[insn->code];
@@ -643,12 +652,11 @@ static u64 __get_raw_cpu_id(u64 ctx, u64 A, u64 X, u64 r4, u64 r5)
return raw_smp_processor_id();
}
-/* Register mappings for user programs. */
-#define A_REG 0
-#define X_REG 7
-#define TMP_REG 8
-#define ARG2_REG 2
-#define ARG3_REG 3
+/* note that this only generates 32-bit random numbers */
+static u64 __get_random_u32(u64 ctx, u64 A, u64 X, u64 r4, u64 r5)
+{
+ return (u64)prandom_u32();
+}
static bool convert_bpf_extensions(struct sock_filter *fp,
struct sock_filter_int **insnp)
@@ -779,6 +787,7 @@ static bool convert_bpf_extensions(struct sock_filter *fp,
case SKF_AD_OFF + SKF_AD_NLATTR:
case SKF_AD_OFF + SKF_AD_NLATTR_NEST:
case SKF_AD_OFF + SKF_AD_CPU:
+ case SKF_AD_OFF + SKF_AD_RANDOM:
/* arg1 = ctx */
insn->code = BPF_ALU64 | BPF_MOV | BPF_X;
insn->a_reg = ARG1_REG;
@@ -812,6 +821,9 @@ static bool convert_bpf_extensions(struct sock_filter *fp,
case SKF_AD_OFF + SKF_AD_CPU:
insn->imm = __get_raw_cpu_id - __bpf_call_base;
break;
+ case SKF_AD_OFF + SKF_AD_RANDOM:
+ insn->imm = __get_random_u32 - __bpf_call_base;
+ break;
}
break;
@@ -1362,6 +1374,7 @@ int sk_chk_filter(struct sock_filter *filter, unsigned int flen)
ANCILLARY(VLAN_TAG);
ANCILLARY(VLAN_TAG_PRESENT);
ANCILLARY(PAY_OFFSET);
+ ANCILLARY(RANDOM);
}
/* ancillary operation unknown or unsupported */
@@ -1746,6 +1759,7 @@ void sk_decode_filter(struct sock_filter *filt, struct sock_filter *to)
[BPF_S_ANC_VLAN_TAG] = BPF_LD|BPF_B|BPF_ABS,
[BPF_S_ANC_VLAN_TAG_PRESENT] = BPF_LD|BPF_B|BPF_ABS,
[BPF_S_ANC_PAY_OFFSET] = BPF_LD|BPF_B|BPF_ABS,
+ [BPF_S_ANC_RANDOM] = BPF_LD|BPF_B|BPF_ABS,
[BPF_S_LD_W_LEN] = BPF_LD|BPF_W|BPF_LEN,
[BPF_S_LD_W_IND] = BPF_LD|BPF_W|BPF_IND,
[BPF_S_LD_H_IND] = BPF_LD|BPF_H|BPF_IND,
diff --git a/net/core/net_namespace.c b/net/core/net_namespace.c
index 81d3a9a..05e949d 100644
--- a/net/core/net_namespace.c
+++ b/net/core/net_namespace.c
@@ -273,7 +273,7 @@ static void cleanup_net(struct work_struct *work)
{
const struct pernet_operations *ops;
struct net *net, *tmp;
- LIST_HEAD(net_kill_list);
+ struct list_head net_kill_list;
LIST_HEAD(net_exit_list);
/* Atomically snapshot the list of namespaces to cleanup */
diff --git a/net/core/sock_diag.c b/net/core/sock_diag.c
index d7af188..9deb6ab 100644
--- a/net/core/sock_diag.c
+++ b/net/core/sock_diag.c
@@ -49,7 +49,7 @@ int sock_diag_put_meminfo(struct sock *sk, struct sk_buff *skb, int attrtype)
}
EXPORT_SYMBOL_GPL(sock_diag_put_meminfo);
-int sock_diag_put_filterinfo(struct user_namespace *user_ns, struct sock *sk,
+int sock_diag_put_filterinfo(struct sock *sk,
struct sk_buff *skb, int attrtype)
{
struct sock_fprog_kern *fprog;
@@ -58,7 +58,7 @@ int sock_diag_put_filterinfo(struct user_namespace *user_ns, struct sock *sk,
unsigned int flen;
int err = 0;
- if (!ns_capable(user_ns, CAP_NET_ADMIN)) {
+ if (!ns_capable(sock_net(sk)->user_ns, CAP_NET_ADMIN)) {
nla_reserve(skb, attrtype, 0);
return 0;
}
diff --git a/net/ieee802154/reassembly.c b/net/ieee802154/reassembly.c
index ef2d543..6f1428c 100644
--- a/net/ieee802154/reassembly.c
+++ b/net/ieee802154/reassembly.c
@@ -36,7 +36,7 @@ struct lowpan_frag_info {
u8 d_offset;
};
-struct lowpan_frag_info *lowpan_cb(struct sk_buff *skb)
+static struct lowpan_frag_info *lowpan_cb(struct sk_buff *skb)
{
return (struct lowpan_frag_info *)skb->cb;
}
@@ -120,6 +120,8 @@ fq_find(struct net *net, const struct lowpan_frag_info *frag_info,
struct inet_frag_queue *q;
struct lowpan_create_arg arg;
unsigned int hash;
+ struct netns_ieee802154_lowpan *ieee802154_lowpan =
+ net_ieee802154_lowpan(net);
arg.tag = frag_info->d_tag;
arg.d_size = frag_info->d_size;
@@ -129,7 +131,7 @@ fq_find(struct net *net, const struct lowpan_frag_info *frag_info,
read_lock(&lowpan_frags.lock);
hash = lowpan_hash_frag(frag_info->d_tag, frag_info->d_size, src, dst);
- q = inet_frag_find(&net->ieee802154_lowpan.frags,
+ q = inet_frag_find(&ieee802154_lowpan->frags,
&lowpan_frags, &arg, hash);
if (IS_ERR_OR_NULL(q)) {
inet_frag_maybe_warn_overflow(q, pr_fmt());
@@ -357,6 +359,8 @@ int lowpan_frag_rcv(struct sk_buff *skb, const u8 frag_type)
struct net *net = dev_net(skb->dev);
struct lowpan_frag_info *frag_info = lowpan_cb(skb);
struct ieee802154_addr source, dest;
+ struct netns_ieee802154_lowpan *ieee802154_lowpan =
+ net_ieee802154_lowpan(net);
int err;
source = mac_cb(skb)->source;
@@ -366,10 +370,10 @@ int lowpan_frag_rcv(struct sk_buff *skb, const u8 frag_type)
if (err < 0)
goto err;
- if (frag_info->d_size > net->ieee802154_lowpan.max_dsize)
+ if (frag_info->d_size > ieee802154_lowpan->max_dsize)
goto err;
- inet_frag_evictor(&net->ieee802154_lowpan.frags, &lowpan_frags, false);
+ inet_frag_evictor(&ieee802154_lowpan->frags, &lowpan_frags, false);
fq = fq_find(net, frag_info, &source, &dest);
if (fq != NULL) {
@@ -436,6 +440,8 @@ static int __net_init lowpan_frags_ns_sysctl_register(struct net *net)
{
struct ctl_table *table;
struct ctl_table_header *hdr;
+ struct netns_ieee802154_lowpan *ieee802154_lowpan =
+ net_ieee802154_lowpan(net);
table = lowpan_frags_ns_ctl_table;
if (!net_eq(net, &init_net)) {
@@ -444,10 +450,10 @@ static int __net_init lowpan_frags_ns_sysctl_register(struct net *net)
if (table == NULL)
goto err_alloc;
- table[0].data = &net->ieee802154_lowpan.frags.high_thresh;
- table[1].data = &net->ieee802154_lowpan.frags.low_thresh;
- table[2].data = &net->ieee802154_lowpan.frags.timeout;
- table[3].data = &net->ieee802154_lowpan.max_dsize;
+ table[0].data = &ieee802154_lowpan->frags.high_thresh;
+ table[1].data = &ieee802154_lowpan->frags.low_thresh;
+ table[2].data = &ieee802154_lowpan->frags.timeout;
+ table[3].data = &ieee802154_lowpan->max_dsize;
/* Don't export sysctls to unprivileged users */
if (net->user_ns != &init_user_ns)
@@ -458,7 +464,7 @@ static int __net_init lowpan_frags_ns_sysctl_register(struct net *net)
if (hdr == NULL)
goto err_reg;
- net->ieee802154_lowpan.sysctl.frags_hdr = hdr;
+ ieee802154_lowpan->sysctl.frags_hdr = hdr;
return 0;
err_reg:
@@ -471,9 +477,11 @@ err_alloc:
static void __net_exit lowpan_frags_ns_sysctl_unregister(struct net *net)
{
struct ctl_table *table;
+ struct netns_ieee802154_lowpan *ieee802154_lowpan =
+ net_ieee802154_lowpan(net);
- table = net->ieee802154_lowpan.sysctl.frags_hdr->ctl_table_arg;
- unregister_net_sysctl_table(net->ieee802154_lowpan.sysctl.frags_hdr);
+ table = ieee802154_lowpan->sysctl.frags_hdr->ctl_table_arg;
+ unregister_net_sysctl_table(ieee802154_lowpan->sysctl.frags_hdr);
if (!net_eq(net, &init_net))
kfree(table);
}
@@ -514,20 +522,26 @@ static inline void lowpan_frags_sysctl_unregister(void)
static int __net_init lowpan_frags_init_net(struct net *net)
{
- net->ieee802154_lowpan.frags.high_thresh = IPV6_FRAG_HIGH_THRESH;
- net->ieee802154_lowpan.frags.low_thresh = IPV6_FRAG_LOW_THRESH;
- net->ieee802154_lowpan.frags.timeout = IPV6_FRAG_TIMEOUT;
- net->ieee802154_lowpan.max_dsize = 0xFFFF;
+ struct netns_ieee802154_lowpan *ieee802154_lowpan =
+ net_ieee802154_lowpan(net);
- inet_frags_init_net(&net->ieee802154_lowpan.frags);
+ ieee802154_lowpan->frags.high_thresh = IPV6_FRAG_HIGH_THRESH;
+ ieee802154_lowpan->frags.low_thresh = IPV6_FRAG_LOW_THRESH;
+ ieee802154_lowpan->frags.timeout = IPV6_FRAG_TIMEOUT;
+ ieee802154_lowpan->max_dsize = 0xFFFF;
+
+ inet_frags_init_net(&ieee802154_lowpan->frags);
return lowpan_frags_ns_sysctl_register(net);
}
static void __net_exit lowpan_frags_exit_net(struct net *net)
{
+ struct netns_ieee802154_lowpan *ieee802154_lowpan =
+ net_ieee802154_lowpan(net);
+
lowpan_frags_ns_sysctl_unregister(net);
- inet_frags_exit_net(&net->ieee802154_lowpan.frags, &lowpan_frags);
+ inet_frags_exit_net(&ieee802154_lowpan->frags, &lowpan_frags);
}
static struct pernet_operations lowpan_frags_ops = {
diff --git a/net/ipv4/inetpeer.c b/net/ipv4/inetpeer.c
index 48f4244..c98cf14 100644
--- a/net/ipv4/inetpeer.c
+++ b/net/ipv4/inetpeer.c
@@ -120,7 +120,7 @@ int inet_peer_maxttl __read_mostly = 10 * 60 * HZ; /* usual time to live: 10 min
static void inetpeer_gc_worker(struct work_struct *work)
{
struct inet_peer *p, *n, *c;
- LIST_HEAD(list);
+ struct list_head list;
spin_lock_bh(&gc_lock);
list_replace_init(&gc_list, &list);
diff --git a/net/ipv4/ip_gre.c b/net/ipv4/ip_gre.c
index 94213c8..c5a557a 100644
--- a/net/ipv4/ip_gre.c
+++ b/net/ipv4/ip_gre.c
@@ -410,7 +410,7 @@ static int ipgre_open(struct net_device *dev)
struct flowi4 fl4;
struct rtable *rt;
- rt = ip_route_output_gre(dev_net(dev), &fl4,
+ rt = ip_route_output_gre(t->net, &fl4,
t->parms.iph.daddr,
t->parms.iph.saddr,
t->parms.o_key,
@@ -434,7 +434,7 @@ static int ipgre_close(struct net_device *dev)
if (ipv4_is_multicast(t->parms.iph.daddr) && t->mlink) {
struct in_device *in_dev;
- in_dev = inetdev_by_index(dev_net(dev), t->mlink);
+ in_dev = inetdev_by_index(t->net, t->mlink);
if (in_dev)
ip_mc_dec_group(in_dev, t->parms.iph.daddr);
}
@@ -478,7 +478,7 @@ static void __gre_tunnel_init(struct net_device *dev)
dev->needed_headroom = LL_MAX_HEADER + sizeof(struct iphdr) + 4;
dev->mtu = ETH_DATA_LEN - sizeof(struct iphdr) - 4;
- dev->features |= NETIF_F_NETNS_LOCAL | GRE_FEATURES;
+ dev->features |= GRE_FEATURES;
dev->hw_features |= GRE_FEATURES;
if (!(tunnel->parms.o_flags & TUNNEL_SEQ)) {
diff --git a/net/ipv4/ip_options.c b/net/ipv4/ip_options.c
index f4ab72e..5e7aece 100644
--- a/net/ipv4/ip_options.c
+++ b/net/ipv4/ip_options.c
@@ -364,7 +364,7 @@ int ip_options_compile(struct net *net,
}
if (optptr[2] <= optlen) {
unsigned char *timeptr = NULL;
- if (optptr[2]+3 > optptr[1]) {
+ if (optptr[2]+3 > optlen) {
pp_ptr = optptr + 2;
goto error;
}
@@ -376,7 +376,7 @@ int ip_options_compile(struct net *net,
optptr[2] += 4;
break;
case IPOPT_TS_TSANDADDR:
- if (optptr[2]+7 > optptr[1]) {
+ if (optptr[2]+7 > optlen) {
pp_ptr = optptr + 2;
goto error;
}
@@ -390,7 +390,7 @@ int ip_options_compile(struct net *net,
optptr[2] += 8;
break;
case IPOPT_TS_PRESPEC:
- if (optptr[2]+7 > optptr[1]) {
+ if (optptr[2]+7 > optlen) {
pp_ptr = optptr + 2;
goto error;
}
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 4bd6d52..eb1dde3 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -2916,6 +2916,14 @@ static int do_tcp_getsockopt(struct sock *sk, int level,
case TCP_USER_TIMEOUT:
val = jiffies_to_msecs(icsk->icsk_user_timeout);
break;
+
+ case TCP_FASTOPEN:
+ if (icsk->icsk_accept_queue.fastopenq != NULL)
+ val = icsk->icsk_accept_queue.fastopenq->max_qlen;
+ else
+ val = 0;
+ break;
+
case TCP_TIMESTAMP:
val = tcp_time_stamp + tp->tsoffset;
break;
diff --git a/net/ipv4/tcp_input.c b/net/ipv4/tcp_input.c
index d6b46eb..6efed13 100644
--- a/net/ipv4/tcp_input.c
+++ b/net/ipv4/tcp_input.c
@@ -4703,28 +4703,6 @@ static int tcp_prune_queue(struct sock *sk)
return -1;
}
-/* RFC2861, slow part. Adjust cwnd, after it was not full during one rto.
- * As additional protections, we do not touch cwnd in retransmission phases,
- * and if application hit its sndbuf limit recently.
- */
-void tcp_cwnd_application_limited(struct sock *sk)
-{
- struct tcp_sock *tp = tcp_sk(sk);
-
- if (inet_csk(sk)->icsk_ca_state == TCP_CA_Open &&
- sk->sk_socket && !test_bit(SOCK_NOSPACE, &sk->sk_socket->flags)) {
- /* Limited by application or receiver window. */
- u32 init_win = tcp_init_cwnd(tp, __sk_dst_get(sk));
- u32 win_used = max(tp->snd_cwnd_used, init_win);
- if (win_used < tp->snd_cwnd) {
- tp->snd_ssthresh = tcp_current_ssthresh(sk);
- tp->snd_cwnd = (tp->snd_cwnd + win_used) >> 1;
- }
- tp->snd_cwnd_used = 0;
- }
- tp->snd_cwnd_stamp = tcp_time_stamp;
-}
-
static bool tcp_should_expand_sndbuf(const struct sock *sk)
{
const struct tcp_sock *tp = tcp_sk(sk);
diff --git a/net/ipv4/tcp_output.c b/net/ipv4/tcp_output.c
index 025e250..20847de 100644
--- a/net/ipv4/tcp_output.c
+++ b/net/ipv4/tcp_output.c
@@ -878,15 +878,8 @@ static int tcp_transmit_skb(struct sock *sk, struct sk_buff *skb, int clone_it,
BUG_ON(!skb || !tcp_skb_pcount(skb));
if (clone_it) {
- const struct sk_buff *fclone = skb + 1;
-
skb_mstamp_get(&skb->skb_mstamp);
- if (unlikely(skb->fclone == SKB_FCLONE_ORIG &&
- fclone->fclone == SKB_FCLONE_CLONE))
- NET_INC_STATS(sock_net(sk),
- LINUX_MIB_TCPSPURIOUS_RTX_HOSTQUEUES);
-
if (unlikely(skb_cloned(skb)))
skb = pskb_copy(skb, gfp_mask);
else
@@ -1387,6 +1380,28 @@ unsigned int tcp_current_mss(struct sock *sk)
return mss_now;
}
+/* RFC2861, slow part. Adjust cwnd, after it was not full during one rto.
+ * As additional protections, we do not touch cwnd in retransmission phases,
+ * and if application hit its sndbuf limit recently.
+ */
+static void tcp_cwnd_application_limited(struct sock *sk)
+{
+ struct tcp_sock *tp = tcp_sk(sk);
+
+ if (inet_csk(sk)->icsk_ca_state == TCP_CA_Open &&
+ sk->sk_socket && !test_bit(SOCK_NOSPACE, &sk->sk_socket->flags)) {
+ /* Limited by application or receiver window. */
+ u32 init_win = tcp_init_cwnd(tp, __sk_dst_get(sk));
+ u32 win_used = max(tp->snd_cwnd_used, init_win);
+ if (win_used < tp->snd_cwnd) {
+ tp->snd_ssthresh = tcp_current_ssthresh(sk);
+ tp->snd_cwnd = (tp->snd_cwnd + win_used) >> 1;
+ }
+ tp->snd_cwnd_used = 0;
+ }
+ tp->snd_cwnd_stamp = tcp_time_stamp;
+}
+
/* Congestion window validation. (RFC2861) */
static void tcp_cwnd_validate(struct sock *sk)
{
@@ -2039,6 +2054,25 @@ bool tcp_schedule_loss_probe(struct sock *sk)
return true;
}
+/* Thanks to skb fast clones, we can detect if a prior transmit of
+ * a packet is still in a qdisc or driver queue.
+ * In this case, there is very little point doing a retransmit !
+ * Note: This is called from BH context only.
+ */
+static bool skb_still_in_host_queue(const struct sock *sk,
+ const struct sk_buff *skb)
+{
+ const struct sk_buff *fclone = skb + 1;
+
+ if (unlikely(skb->fclone == SKB_FCLONE_ORIG &&
+ fclone->fclone == SKB_FCLONE_CLONE)) {
+ NET_INC_STATS_BH(sock_net(sk),
+ LINUX_MIB_TCPSPURIOUS_RTX_HOSTQUEUES);
+ return true;
+ }
+ return false;
+}
+
/* When probe timeout (PTO) fires, send a new segment if one exists, else
* retransmit the last segment.
*/
@@ -2064,6 +2098,9 @@ void tcp_send_loss_probe(struct sock *sk)
if (WARN_ON(!skb))
goto rearm_timer;
+ if (skb_still_in_host_queue(sk, skb))
+ goto rearm_timer;
+
pcount = tcp_skb_pcount(skb);
if (WARN_ON(!pcount))
goto rearm_timer;
@@ -2385,6 +2422,9 @@ int __tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
min(sk->sk_wmem_queued + (sk->sk_wmem_queued >> 2), sk->sk_sndbuf))
return -EAGAIN;
+ if (skb_still_in_host_queue(sk, skb))
+ return -EBUSY;
+
if (before(TCP_SKB_CB(skb)->seq, tp->snd_una)) {
if (before(TCP_SKB_CB(skb)->end_seq, tp->snd_una))
BUG();
@@ -2478,7 +2518,7 @@ int tcp_retransmit_skb(struct sock *sk, struct sk_buff *skb)
* see tcp_input.c tcp_sacktag_write_queue().
*/
TCP_SKB_CB(skb)->ack_seq = tp->snd_nxt;
- } else {
+ } else if (err != -EBUSY) {
NET_INC_STATS_BH(sock_net(sk), LINUX_MIB_TCPRETRANSFAIL);
}
return err;
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index 6c7fa08..fc203db 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -2504,8 +2504,8 @@ static int inet6_addr_add(struct net *net, int ifindex,
return PTR_ERR(ifp);
}
-static int inet6_addr_del(struct net *net, int ifindex, const struct in6_addr *pfx,
- unsigned int plen)
+static int inet6_addr_del(struct net *net, int ifindex, u32 ifa_flags,
+ const struct in6_addr *pfx, unsigned int plen)
{
struct inet6_ifaddr *ifp;
struct inet6_dev *idev;
@@ -2528,7 +2528,12 @@ static int inet6_addr_del(struct net *net, int ifindex, const struct in6_addr *p
in6_ifa_hold(ifp);
read_unlock_bh(&idev->lock);
+ if (!(ifp->flags & IFA_F_TEMPORARY) &&
+ (ifa_flags & IFA_F_MANAGETEMPADDR))
+ manage_tempaddrs(idev, ifp, 0, 0, false,
+ jiffies);
ipv6_del_addr(ifp);
+ addrconf_verify_rtnl();
return 0;
}
}
@@ -2568,7 +2573,7 @@ int addrconf_del_ifaddr(struct net *net, void __user *arg)
return -EFAULT;
rtnl_lock();
- err = inet6_addr_del(net, ireq.ifr6_ifindex, &ireq.ifr6_addr,
+ err = inet6_addr_del(net, ireq.ifr6_ifindex, 0, &ireq.ifr6_addr,
ireq.ifr6_prefixlen);
rtnl_unlock();
return err;
@@ -3743,6 +3748,7 @@ inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh)
struct ifaddrmsg *ifm;
struct nlattr *tb[IFA_MAX+1];
struct in6_addr *pfx, *peer_pfx;
+ u32 ifa_flags;
int err;
err = nlmsg_parse(nlh, sizeof(*ifm), tb, IFA_MAX, ifa_ipv6_policy);
@@ -3754,7 +3760,13 @@ inet6_rtm_deladdr(struct sk_buff *skb, struct nlmsghdr *nlh)
if (pfx == NULL)
return -EINVAL;
- return inet6_addr_del(net, ifm->ifa_index, pfx, ifm->ifa_prefixlen);
+ ifa_flags = tb[IFA_FLAGS] ? nla_get_u32(tb[IFA_FLAGS]) : ifm->ifa_flags;
+
+ /* We ignore other flags so far. */
+ ifa_flags &= IFA_F_MANAGETEMPADDR;
+
+ return inet6_addr_del(net, ifm->ifa_index, ifa_flags, pfx,
+ ifm->ifa_prefixlen);
}
static int inet6_addr_modify(struct inet6_ifaddr *ifp, u32 ifa_flags,
diff --git a/net/ipv6/icmp.c b/net/ipv6/icmp.c
index 7b32652..3b0905b 100644
--- a/net/ipv6/icmp.c
+++ b/net/ipv6/icmp.c
@@ -493,12 +493,7 @@ static void icmp6_send(struct sk_buff *skb, u8 type, u8 code, __u32 info)
if (IS_ERR(dst))
goto out;
- if (ipv6_addr_is_multicast(&fl6.daddr))
- hlimit = np->mcast_hops;
- else
- hlimit = np->hop_limit;
- if (hlimit < 0)
- hlimit = ip6_dst_hoplimit(dst);
+ hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst);
msg.skb = skb;
msg.offset = skb_network_offset(skb);
@@ -593,12 +588,7 @@ static void icmpv6_echo_reply(struct sk_buff *skb)
if (IS_ERR(dst))
goto out;
- if (ipv6_addr_is_multicast(&fl6.daddr))
- hlimit = np->mcast_hops;
- else
- hlimit = np->hop_limit;
- if (hlimit < 0)
- hlimit = ip6_dst_hoplimit(dst);
+ hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst);
idev = __in6_dev_get(skb->dev);
diff --git a/net/ipv6/ip6_flowlabel.c b/net/ipv6/ip6_flowlabel.c
index 0961b5e..4052694 100644
--- a/net/ipv6/ip6_flowlabel.c
+++ b/net/ipv6/ip6_flowlabel.c
@@ -26,7 +26,6 @@
#include <net/sock.h>
#include <net/ipv6.h>
-#include <net/addrconf.h>
#include <net/rawv6.h>
#include <net/transp_v6.h>
diff --git a/net/ipv6/ip6_gre.c b/net/ipv6/ip6_gre.c
index 9d92146..75277b7 100644
--- a/net/ipv6/ip6_gre.c
+++ b/net/ipv6/ip6_gre.c
@@ -72,6 +72,7 @@ struct ip6gre_net {
};
static struct rtnl_link_ops ip6gre_link_ops __read_mostly;
+static struct rtnl_link_ops ip6gre_tap_ops __read_mostly;
static int ip6gre_tunnel_init(struct net_device *dev);
static void ip6gre_tunnel_setup(struct net_device *dev);
static void ip6gre_tunnel_link(struct ip6gre_net *ign, struct ip6_tnl *t);
@@ -353,10 +354,10 @@ failed_free:
static void ip6gre_tunnel_uninit(struct net_device *dev)
{
- struct net *net = dev_net(dev);
- struct ip6gre_net *ign = net_generic(net, ip6gre_net_id);
+ struct ip6_tnl *t = netdev_priv(dev);
+ struct ip6gre_net *ign = net_generic(t->net, ip6gre_net_id);
- ip6gre_tunnel_unlink(ign, netdev_priv(dev));
+ ip6gre_tunnel_unlink(ign, t);
dev_put(dev);
}
@@ -611,8 +612,8 @@ static netdev_tx_t ip6gre_xmit2(struct sk_buff *skb,
int encap_limit,
__u32 *pmtu)
{
- struct net *net = dev_net(dev);
struct ip6_tnl *tunnel = netdev_priv(dev);
+ struct net *net = tunnel->net;
struct net_device *tdev; /* Device to other host */
struct ipv6hdr *ipv6h; /* Our new IP header */
unsigned int max_headroom = 0; /* The extra header space needed */
@@ -979,7 +980,7 @@ static void ip6gre_tnl_link_config(struct ip6_tnl *t, int set_mtu)
int strict = (ipv6_addr_type(&p->raddr) &
(IPV6_ADDR_MULTICAST|IPV6_ADDR_LINKLOCAL));
- struct rt6_info *rt = rt6_lookup(dev_net(dev),
+ struct rt6_info *rt = rt6_lookup(t->net,
&p->raddr, &p->laddr,
p->link, strict);
@@ -1063,13 +1064,12 @@ static int ip6gre_tunnel_ioctl(struct net_device *dev,
int err = 0;
struct ip6_tnl_parm2 p;
struct __ip6_tnl_parm p1;
- struct ip6_tnl *t;
- struct net *net = dev_net(dev);
+ struct ip6_tnl *t = netdev_priv(dev);
+ struct net *net = t->net;
struct ip6gre_net *ign = net_generic(net, ip6gre_net_id);
switch (cmd) {
case SIOCGETTUNNEL:
- t = NULL;
if (dev == ign->fb_tunnel_dev) {
if (copy_from_user(&p, ifr->ifr_ifru.ifru_data, sizeof(p))) {
err = -EFAULT;
@@ -1077,9 +1077,9 @@ static int ip6gre_tunnel_ioctl(struct net_device *dev,
}
ip6gre_tnl_parm_from_user(&p1, &p);
t = ip6gre_tunnel_locate(net, &p1, 0);
+ if (t == NULL)
+ t = netdev_priv(dev);
}
- if (t == NULL)
- t = netdev_priv(dev);
memset(&p, 0, sizeof(p));
ip6gre_tnl_parm_to_user(&p, &t->parms);
if (copy_to_user(ifr->ifr_ifru.ifru_data, &p, sizeof(p)))
@@ -1242,7 +1242,6 @@ static void ip6gre_tunnel_setup(struct net_device *dev)
dev->flags |= IFF_NOARP;
dev->iflink = 0;
dev->addr_len = sizeof(struct in6_addr);
- dev->features |= NETIF_F_NETNS_LOCAL;
dev->priv_flags &= ~IFF_XMIT_DST_RELEASE;
}
@@ -1297,11 +1296,17 @@ static struct inet6_protocol ip6gre_protocol __read_mostly = {
.flags = INET6_PROTO_NOPOLICY|INET6_PROTO_FINAL,
};
-static void ip6gre_destroy_tunnels(struct ip6gre_net *ign,
- struct list_head *head)
+static void ip6gre_destroy_tunnels(struct net *net, struct list_head *head)
{
+ struct ip6gre_net *ign = net_generic(net, ip6gre_net_id);
+ struct net_device *dev, *aux;
int prio;
+ for_each_netdev_safe(net, dev, aux)
+ if (dev->rtnl_link_ops == &ip6gre_link_ops ||
+ dev->rtnl_link_ops == &ip6gre_tap_ops)
+ unregister_netdevice_queue(dev, head);
+
for (prio = 0; prio < 4; prio++) {
int h;
for (h = 0; h < HASH_SIZE; h++) {
@@ -1310,7 +1315,12 @@ static void ip6gre_destroy_tunnels(struct ip6gre_net *ign,
t = rtnl_dereference(ign->tunnels[prio][h]);
while (t != NULL) {
- unregister_netdevice_queue(t->dev, head);
+ /* If dev is in the same netns, it has already
+ * been added to the list by the previous loop.
+ */
+ if (!net_eq(dev_net(t->dev), net))
+ unregister_netdevice_queue(t->dev,
+ head);
t = rtnl_dereference(t->next);
}
}
@@ -1329,6 +1339,11 @@ static int __net_init ip6gre_init_net(struct net *net)
goto err_alloc_dev;
}
dev_net_set(ign->fb_tunnel_dev, net);
+ /* FB netdevice is special: we have one, and only one per netns.
+ * Allowing to move it to another netns is clearly unsafe.
+ */
+ ign->fb_tunnel_dev->features |= NETIF_F_NETNS_LOCAL;
+
ip6gre_fb_tunnel_init(ign->fb_tunnel_dev);
ign->fb_tunnel_dev->rtnl_link_ops = &ip6gre_link_ops;
@@ -1349,12 +1364,10 @@ err_alloc_dev:
static void __net_exit ip6gre_exit_net(struct net *net)
{
- struct ip6gre_net *ign;
LIST_HEAD(list);
- ign = net_generic(net, ip6gre_net_id);
rtnl_lock();
- ip6gre_destroy_tunnels(ign, &list);
+ ip6gre_destroy_tunnels(net, &list);
unregister_netdevice_many(&list);
rtnl_unlock();
}
@@ -1531,15 +1544,14 @@ out:
static int ip6gre_changelink(struct net_device *dev, struct nlattr *tb[],
struct nlattr *data[])
{
- struct ip6_tnl *t, *nt;
- struct net *net = dev_net(dev);
+ struct ip6_tnl *t, *nt = netdev_priv(dev);
+ struct net *net = nt->net;
struct ip6gre_net *ign = net_generic(net, ip6gre_net_id);
struct __ip6_tnl_parm p;
if (dev == ign->fb_tunnel_dev)
return -EINVAL;
- nt = netdev_priv(dev);
ip6gre_netlink_parms(data, &p);
t = ip6gre_tunnel_locate(net, &p, 0);
diff --git a/net/ipv6/ping.c b/net/ipv6/ping.c
index bda7429..a2a1d80 100644
--- a/net/ipv6/ping.c
+++ b/net/ipv6/ping.c
@@ -168,12 +168,7 @@ int ping_v6_sendmsg(struct kiocb *iocb, struct sock *sk, struct msghdr *msg,
pfh.wcheck = 0;
pfh.family = AF_INET6;
- if (ipv6_addr_is_multicast(&fl6.daddr))
- hlimit = np->mcast_hops;
- else
- hlimit = np->hop_limit;
- if (hlimit < 0)
- hlimit = ip6_dst_hoplimit(dst);
+ hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst);
lock_sock(sk);
err = ip6_append_data(sk, ping_getfrag, &pfh, len,
diff --git a/net/ipv6/raw.c b/net/ipv6/raw.c
index 1f29996..dddfb5f 100644
--- a/net/ipv6/raw.c
+++ b/net/ipv6/raw.c
@@ -873,14 +873,8 @@ static int rawv6_sendmsg(struct kiocb *iocb, struct sock *sk,
err = PTR_ERR(dst);
goto out;
}
- if (hlimit < 0) {
- if (ipv6_addr_is_multicast(&fl6.daddr))
- hlimit = np->mcast_hops;
- else
- hlimit = np->hop_limit;
- if (hlimit < 0)
- hlimit = ip6_dst_hoplimit(dst);
- }
+ if (hlimit < 0)
+ hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst);
if (tclass < 0)
tclass = np->tclass;
diff --git a/net/ipv6/udp.c b/net/ipv6/udp.c
index 1e586d9..d8d6ca0 100644
--- a/net/ipv6/udp.c
+++ b/net/ipv6/udp.c
@@ -1232,14 +1232,8 @@ do_udp_sendmsg:
goto out;
}
- if (hlimit < 0) {
- if (ipv6_addr_is_multicast(&fl6.daddr))
- hlimit = np->mcast_hops;
- else
- hlimit = np->hop_limit;
- if (hlimit < 0)
- hlimit = ip6_dst_hoplimit(dst);
- }
+ if (hlimit < 0)
+ hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst);
if (tclass < 0)
tclass = np->tclass;
diff --git a/net/l2tp/l2tp_ip6.c b/net/l2tp/l2tp_ip6.c
index 7704ea9..e472d44 100644
--- a/net/l2tp/l2tp_ip6.c
+++ b/net/l2tp/l2tp_ip6.c
@@ -605,14 +605,8 @@ static int l2tp_ip6_sendmsg(struct kiocb *iocb, struct sock *sk,
goto out;
}
- if (hlimit < 0) {
- if (ipv6_addr_is_multicast(&fl6.daddr))
- hlimit = np->mcast_hops;
- else
- hlimit = np->hop_limit;
- if (hlimit < 0)
- hlimit = ip6_dst_hoplimit(dst);
- }
+ if (hlimit < 0)
+ hlimit = ip6_sk_dst_hoplimit(np, &fl6, dst);
if (tclass < 0)
tclass = np->tclass;
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c
index e8138da..6e42dcf 100644
--- a/net/netfilter/nfnetlink.c
+++ b/net/netfilter/nfnetlink.c
@@ -400,19 +400,17 @@ static void nfnetlink_rcv(struct sk_buff *skb)
}
#ifdef CONFIG_MODULES
-static void nfnetlink_bind(int group)
+static int nfnetlink_bind(int group)
{
const struct nfnetlink_subsystem *ss;
int type = nfnl_group2type[group];
rcu_read_lock();
ss = nfnetlink_get_subsys(type);
- if (!ss) {
- rcu_read_unlock();
- request_module("nfnetlink-subsys-%d", type);
- return;
- }
rcu_read_unlock();
+ if (!ss)
+ request_module("nfnetlink-subsys-%d", type);
+ return 0;
}
#endif
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 894cda0..92f4b69 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -1206,7 +1206,8 @@ static int netlink_create(struct net *net, struct socket *sock, int protocol,
struct module *module = NULL;
struct mutex *cb_mutex;
struct netlink_sock *nlk;
- void (*bind)(int group);
+ int (*bind)(int group);
+ void (*unbind)(int group);
int err = 0;
sock->state = SS_UNCONNECTED;
@@ -1232,6 +1233,7 @@ static int netlink_create(struct net *net, struct socket *sock, int protocol,
err = -EPROTONOSUPPORT;
cb_mutex = nl_table[protocol].cb_mutex;
bind = nl_table[protocol].bind;
+ unbind = nl_table[protocol].unbind;
netlink_unlock_table();
if (err < 0)
@@ -1248,6 +1250,7 @@ static int netlink_create(struct net *net, struct socket *sock, int protocol,
nlk = nlk_sk(sock->sk);
nlk->module = module;
nlk->netlink_bind = bind;
+ nlk->netlink_unbind = unbind;
out:
return err;
@@ -1301,6 +1304,7 @@ static int netlink_release(struct socket *sock)
kfree_rcu(old, rcu);
nl_table[sk->sk_protocol].module = NULL;
nl_table[sk->sk_protocol].bind = NULL;
+ nl_table[sk->sk_protocol].unbind = NULL;
nl_table[sk->sk_protocol].flags = 0;
nl_table[sk->sk_protocol].registered = 0;
}
@@ -1411,6 +1415,19 @@ static int netlink_realloc_groups(struct sock *sk)
return err;
}
+static void netlink_unbind(int group, long unsigned int groups,
+ struct netlink_sock *nlk)
+{
+ int undo;
+
+ if (!nlk->netlink_unbind)
+ return;
+
+ for (undo = 0; undo < group; undo++)
+ if (test_bit(group, &groups))
+ nlk->netlink_unbind(undo);
+}
+
static int netlink_bind(struct socket *sock, struct sockaddr *addr,
int addr_len)
{
@@ -1419,6 +1436,7 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr,
struct netlink_sock *nlk = nlk_sk(sk);
struct sockaddr_nl *nladdr = (struct sockaddr_nl *)addr;
int err;
+ long unsigned int groups = nladdr->nl_groups;
if (addr_len < sizeof(struct sockaddr_nl))
return -EINVAL;
@@ -1427,7 +1445,7 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr,
return -EINVAL;
/* Only superuser is allowed to listen multicasts */
- if (nladdr->nl_groups) {
+ if (groups) {
if (!netlink_capable(sock, NL_CFG_F_NONROOT_RECV))
return -EPERM;
err = netlink_realloc_groups(sk);
@@ -1435,37 +1453,45 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr,
return err;
}
- if (nlk->portid) {
+ if (nlk->portid)
if (nladdr->nl_pid != nlk->portid)
return -EINVAL;
- } else {
+
+ if (nlk->netlink_bind && groups) {
+ int group;
+
+ for (group = 0; group < nlk->ngroups; group++) {
+ if (!test_bit(group, &groups))
+ continue;
+ err = nlk->netlink_bind(group);
+ if (!err)
+ continue;
+ netlink_unbind(group, groups, nlk);
+ return err;
+ }
+ }
+
+ if (!nlk->portid) {
err = nladdr->nl_pid ?
netlink_insert(sk, net, nladdr->nl_pid) :
netlink_autobind(sock);
- if (err)
+ if (err) {
+ netlink_unbind(nlk->ngroups - 1, groups, nlk);
return err;
+ }
}
- if (!nladdr->nl_groups && (nlk->groups == NULL || !(u32)nlk->groups[0]))
+ if (!groups && (nlk->groups == NULL || !(u32)nlk->groups[0]))
return 0;
netlink_table_grab();
netlink_update_subscriptions(sk, nlk->subscriptions +
- hweight32(nladdr->nl_groups) -
+ hweight32(groups) -
hweight32(nlk->groups[0]));
- nlk->groups[0] = (nlk->groups[0] & ~0xffffffffUL) | nladdr->nl_groups;
+ nlk->groups[0] = (nlk->groups[0] & ~0xffffffffUL) | groups;
netlink_update_listeners(sk);
netlink_table_ungrab();
- if (nlk->netlink_bind && nlk->groups[0]) {
- int i;
-
- for (i = 0; i < nlk->ngroups; i++) {
- if (test_bit(i, nlk->groups))
- nlk->netlink_bind(i);
- }
- }
-
return 0;
}
@@ -2103,13 +2129,17 @@ static int netlink_setsockopt(struct socket *sock, int level, int optname,
return err;
if (!val || val - 1 >= nlk->ngroups)
return -EINVAL;
+ if (optname == NETLINK_ADD_MEMBERSHIP && nlk->netlink_bind) {
+ err = nlk->netlink_bind(val);
+ if (err)
+ return err;
+ }
netlink_table_grab();
netlink_update_socket_mc(nlk, val,
optname == NETLINK_ADD_MEMBERSHIP);
netlink_table_ungrab();
-
- if (nlk->netlink_bind)
- nlk->netlink_bind(val);
+ if (optname == NETLINK_DROP_MEMBERSHIP && nlk->netlink_unbind)
+ nlk->netlink_unbind(val);
err = 0;
break;
diff --git a/net/netlink/af_netlink.h b/net/netlink/af_netlink.h
index ed13a79..0b59d44 100644
--- a/net/netlink/af_netlink.h
+++ b/net/netlink/af_netlink.h
@@ -38,7 +38,8 @@ struct netlink_sock {
struct mutex *cb_mutex;
struct mutex cb_def_mutex;
void (*netlink_rcv)(struct sk_buff *skb);
- void (*netlink_bind)(int group);
+ int (*netlink_bind)(int group);
+ void (*netlink_unbind)(int group);
struct module *module;
#ifdef CONFIG_NETLINK_MMAP
struct mutex pg_vec_lock;
@@ -74,7 +75,8 @@ struct netlink_table {
unsigned int groups;
struct mutex *cb_mutex;
struct module *module;
- void (*bind)(int group);
+ int (*bind)(int group);
+ void (*unbind)(int group);
bool (*compare)(struct net *net, struct sock *sock);
int registered;
};
diff --git a/net/openvswitch/vport-vxlan.c b/net/openvswitch/vport-vxlan.c
index e797a50..21cceb3 100644
--- a/net/openvswitch/vport-vxlan.c
+++ b/net/openvswitch/vport-vxlan.c
@@ -180,7 +180,8 @@ static int vxlan_tnl_send(struct vport *vport, struct sk_buff *skb)
OVS_CB(skb)->tun_key->ipv4_tos,
OVS_CB(skb)->tun_key->ipv4_ttl, df,
src_port, dst_port,
- htonl(be64_to_cpu(OVS_CB(skb)->tun_key->tun_id) << 8));
+ htonl(be64_to_cpu(OVS_CB(skb)->tun_key->tun_id) << 8),
+ false);
if (err < 0)
ip_rt_put(rt);
error:
diff --git a/net/packet/diag.c b/net/packet/diag.c
index 533ce4f..435ff99 100644
--- a/net/packet/diag.c
+++ b/net/packet/diag.c
@@ -172,7 +172,7 @@ static int sk_diag_fill(struct sock *sk, struct sk_buff *skb,
goto out_nlmsg_trim;
if ((req->pdiag_show & PACKET_SHOW_FILTER) &&
- sock_diag_put_filterinfo(user_ns, sk, skb, PACKET_DIAG_FILTER))
+ sock_diag_put_filterinfo(sk, skb, PACKET_DIAG_FILTER))
goto out_nlmsg_trim;
return nlmsg_end(skb, nlh);
diff --git a/net/sched/cls_api.c b/net/sched/cls_api.c
index 29a30a1..a481bbe 100644
--- a/net/sched/cls_api.c
+++ b/net/sched/cls_api.c
@@ -317,7 +317,8 @@ replay:
}
}
- err = tp->ops->change(net, skb, tp, cl, t->tcm_handle, tca, &fh);
+ err = tp->ops->change(net, skb, tp, cl, t->tcm_handle, tca, &fh,
+ n->nlmsg_flags & NLM_F_CREATE ? TCA_ACT_NOREPLACE : TCA_ACT_REPLACE);
if (err == 0) {
if (tp_created) {
spin_lock_bh(root_lock);
@@ -504,7 +505,7 @@ void tcf_exts_destroy(struct tcf_proto *tp, struct tcf_exts *exts)
EXPORT_SYMBOL(tcf_exts_destroy);
int tcf_exts_validate(struct net *net, struct tcf_proto *tp, struct nlattr **tb,
- struct nlattr *rate_tlv, struct tcf_exts *exts)
+ struct nlattr *rate_tlv, struct tcf_exts *exts, bool ovr)
{
#ifdef CONFIG_NET_CLS_ACT
{
@@ -513,7 +514,7 @@ int tcf_exts_validate(struct net *net, struct tcf_proto *tp, struct nlattr **tb,
INIT_LIST_HEAD(&exts->actions);
if (exts->police && tb[exts->police]) {
act = tcf_action_init_1(net, tb[exts->police], rate_tlv,
- "police", TCA_ACT_NOREPLACE,
+ "police", ovr,
TCA_ACT_BIND);
if (IS_ERR(act))
return PTR_ERR(act);
@@ -523,7 +524,7 @@ int tcf_exts_validate(struct net *net, struct tcf_proto *tp, struct nlattr **tb,
} else if (exts->action && tb[exts->action]) {
int err;
err = tcf_action_init(net, tb[exts->action], rate_tlv,
- NULL, TCA_ACT_NOREPLACE,
+ NULL, ovr,
TCA_ACT_BIND, &exts->actions);
if (err)
return err;
@@ -543,14 +544,12 @@ void tcf_exts_change(struct tcf_proto *tp, struct tcf_exts *dst,
struct tcf_exts *src)
{
#ifdef CONFIG_NET_CLS_ACT
- if (!list_empty(&src->actions)) {
- LIST_HEAD(tmp);
- tcf_tree_lock(tp);
- list_splice_init(&dst->actions, &tmp);
- list_splice(&src->actions, &dst->actions);
- tcf_tree_unlock(tp);
- tcf_action_destroy(&tmp, TCA_ACT_UNBIND);
- }
+ LIST_HEAD(tmp);
+ tcf_tree_lock(tp);
+ list_splice_init(&dst->actions, &tmp);
+ list_splice(&src->actions, &dst->actions);
+ tcf_tree_unlock(tp);
+ tcf_action_destroy(&tmp, TCA_ACT_UNBIND);
#endif
}
EXPORT_SYMBOL(tcf_exts_change);
diff --git a/net/sched/cls_basic.c b/net/sched/cls_basic.c
index e98ca99..0ae1813 100644
--- a/net/sched/cls_basic.c
+++ b/net/sched/cls_basic.c
@@ -130,14 +130,14 @@ static const struct nla_policy basic_policy[TCA_BASIC_MAX + 1] = {
static int basic_set_parms(struct net *net, struct tcf_proto *tp,
struct basic_filter *f, unsigned long base,
struct nlattr **tb,
- struct nlattr *est)
+ struct nlattr *est, bool ovr)
{
int err;
struct tcf_exts e;
struct tcf_ematch_tree t;
tcf_exts_init(&e, TCA_BASIC_ACT, TCA_BASIC_POLICE);
- err = tcf_exts_validate(net, tp, tb, est, &e);
+ err = tcf_exts_validate(net, tp, tb, est, &e, ovr);
if (err < 0)
return err;
@@ -161,7 +161,7 @@ errout:
static int basic_change(struct net *net, struct sk_buff *in_skb,
struct tcf_proto *tp, unsigned long base, u32 handle,
- struct nlattr **tca, unsigned long *arg)
+ struct nlattr **tca, unsigned long *arg, bool ovr)
{
int err;
struct basic_head *head = tp->root;
@@ -179,7 +179,7 @@ static int basic_change(struct net *net, struct sk_buff *in_skb,
if (f != NULL) {
if (handle && f->handle != handle)
return -EINVAL;
- return basic_set_parms(net, tp, f, base, tb, tca[TCA_RATE]);
+ return basic_set_parms(net, tp, f, base, tb, tca[TCA_RATE], ovr);
}
err = -ENOBUFS;
@@ -206,7 +206,7 @@ static int basic_change(struct net *net, struct sk_buff *in_skb,
f->handle = head->hgenerator;
}
- err = basic_set_parms(net, tp, f, base, tb, tca[TCA_RATE]);
+ err = basic_set_parms(net, tp, f, base, tb, tca[TCA_RATE], ovr);
if (err < 0)
goto errout;
diff --git a/net/sched/cls_bpf.c b/net/sched/cls_bpf.c
index 8e3cf49..1618696 100644
--- a/net/sched/cls_bpf.c
+++ b/net/sched/cls_bpf.c
@@ -156,7 +156,7 @@ static void cls_bpf_put(struct tcf_proto *tp, unsigned long f)
static int cls_bpf_modify_existing(struct net *net, struct tcf_proto *tp,
struct cls_bpf_prog *prog,
unsigned long base, struct nlattr **tb,
- struct nlattr *est)
+ struct nlattr *est, bool ovr)
{
struct sock_filter *bpf_ops, *bpf_old;
struct tcf_exts exts;
@@ -170,7 +170,7 @@ static int cls_bpf_modify_existing(struct net *net, struct tcf_proto *tp,
return -EINVAL;
tcf_exts_init(&exts, TCA_BPF_ACT, TCA_BPF_POLICE);
- ret = tcf_exts_validate(net, tp, tb, est, &exts);
+ ret = tcf_exts_validate(net, tp, tb, est, &exts, ovr);
if (ret < 0)
return ret;
@@ -242,7 +242,7 @@ static u32 cls_bpf_grab_new_handle(struct tcf_proto *tp,
static int cls_bpf_change(struct net *net, struct sk_buff *in_skb,
struct tcf_proto *tp, unsigned long base,
u32 handle, struct nlattr **tca,
- unsigned long *arg)
+ unsigned long *arg, bool ovr)
{
struct cls_bpf_head *head = tp->root;
struct cls_bpf_prog *prog = (struct cls_bpf_prog *) *arg;
@@ -260,7 +260,7 @@ static int cls_bpf_change(struct net *net, struct sk_buff *in_skb,
if (handle && prog->handle != handle)
return -EINVAL;
return cls_bpf_modify_existing(net, tp, prog, base, tb,
- tca[TCA_RATE]);
+ tca[TCA_RATE], ovr);
}
prog = kzalloc(sizeof(*prog), GFP_KERNEL);
@@ -277,7 +277,7 @@ static int cls_bpf_change(struct net *net, struct sk_buff *in_skb,
goto errout;
}
- ret = cls_bpf_modify_existing(net, tp, prog, base, tb, tca[TCA_RATE]);
+ ret = cls_bpf_modify_existing(net, tp, prog, base, tb, tca[TCA_RATE], ovr);
if (ret < 0)
goto errout;
diff --git a/net/sched/cls_cgroup.c b/net/sched/cls_cgroup.c
index 8e2158a..cacf01b 100644
--- a/net/sched/cls_cgroup.c
+++ b/net/sched/cls_cgroup.c
@@ -83,7 +83,7 @@ static const struct nla_policy cgroup_policy[TCA_CGROUP_MAX + 1] = {
static int cls_cgroup_change(struct net *net, struct sk_buff *in_skb,
struct tcf_proto *tp, unsigned long base,
u32 handle, struct nlattr **tca,
- unsigned long *arg)
+ unsigned long *arg, bool ovr)
{
struct nlattr *tb[TCA_CGROUP_MAX + 1];
struct cls_cgroup_head *head = tp->root;
@@ -119,7 +119,7 @@ static int cls_cgroup_change(struct net *net, struct sk_buff *in_skb,
return err;
tcf_exts_init(&e, TCA_CGROUP_ACT, TCA_CGROUP_POLICE);
- err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &e);
+ err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &e, ovr);
if (err < 0)
return err;
diff --git a/net/sched/cls_flow.c b/net/sched/cls_flow.c
index 257029c..35be16f 100644
--- a/net/sched/cls_flow.c
+++ b/net/sched/cls_flow.c
@@ -349,7 +349,7 @@ static const struct nla_policy flow_policy[TCA_FLOW_MAX + 1] = {
static int flow_change(struct net *net, struct sk_buff *in_skb,
struct tcf_proto *tp, unsigned long base,
u32 handle, struct nlattr **tca,
- unsigned long *arg)
+ unsigned long *arg, bool ovr)
{
struct flow_head *head = tp->root;
struct flow_filter *f;
@@ -393,7 +393,7 @@ static int flow_change(struct net *net, struct sk_buff *in_skb,
}
tcf_exts_init(&e, TCA_FLOW_ACT, TCA_FLOW_POLICE);
- err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &e);
+ err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &e, ovr);
if (err < 0)
return err;
diff --git a/net/sched/cls_fw.c b/net/sched/cls_fw.c
index 63a3ce7..861b03c 100644
--- a/net/sched/cls_fw.c
+++ b/net/sched/cls_fw.c
@@ -169,7 +169,7 @@ static const struct nla_policy fw_policy[TCA_FW_MAX + 1] = {
static int
fw_change_attrs(struct net *net, struct tcf_proto *tp, struct fw_filter *f,
- struct nlattr **tb, struct nlattr **tca, unsigned long base)
+ struct nlattr **tb, struct nlattr **tca, unsigned long base, bool ovr)
{
struct fw_head *head = tp->root;
struct tcf_exts e;
@@ -177,7 +177,7 @@ fw_change_attrs(struct net *net, struct tcf_proto *tp, struct fw_filter *f,
int err;
tcf_exts_init(&e, TCA_FW_ACT, TCA_FW_POLICE);
- err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &e);
+ err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &e, ovr);
if (err < 0)
return err;
@@ -218,7 +218,7 @@ static int fw_change(struct net *net, struct sk_buff *in_skb,
struct tcf_proto *tp, unsigned long base,
u32 handle,
struct nlattr **tca,
- unsigned long *arg)
+ unsigned long *arg, bool ovr)
{
struct fw_head *head = tp->root;
struct fw_filter *f = (struct fw_filter *) *arg;
@@ -236,7 +236,7 @@ static int fw_change(struct net *net, struct sk_buff *in_skb,
if (f != NULL) {
if (f->id != handle && handle)
return -EINVAL;
- return fw_change_attrs(net, tp, f, tb, tca, base);
+ return fw_change_attrs(net, tp, f, tb, tca, base, ovr);
}
if (!handle)
@@ -264,7 +264,7 @@ static int fw_change(struct net *net, struct sk_buff *in_skb,
tcf_exts_init(&f->exts, TCA_FW_ACT, TCA_FW_POLICE);
f->id = handle;
- err = fw_change_attrs(net, tp, f, tb, tca, base);
+ err = fw_change_attrs(net, tp, f, tb, tca, base, ovr);
if (err < 0)
goto errout;
diff --git a/net/sched/cls_route.c b/net/sched/cls_route.c
index 1ad3068..dd9fc25 100644
--- a/net/sched/cls_route.c
+++ b/net/sched/cls_route.c
@@ -333,7 +333,8 @@ static const struct nla_policy route4_policy[TCA_ROUTE4_MAX + 1] = {
static int route4_set_parms(struct net *net, struct tcf_proto *tp,
unsigned long base, struct route4_filter *f,
u32 handle, struct route4_head *head,
- struct nlattr **tb, struct nlattr *est, int new)
+ struct nlattr **tb, struct nlattr *est, int new,
+ bool ovr)
{
int err;
u32 id = 0, to = 0, nhandle = 0x8000;
@@ -343,7 +344,7 @@ static int route4_set_parms(struct net *net, struct tcf_proto *tp,
struct tcf_exts e;
tcf_exts_init(&e, TCA_ROUTE4_ACT, TCA_ROUTE4_POLICE);
- err = tcf_exts_validate(net, tp, tb, est, &e);
+ err = tcf_exts_validate(net, tp, tb, est, &e, ovr);
if (err < 0)
return err;
@@ -428,7 +429,7 @@ static int route4_change(struct net *net, struct sk_buff *in_skb,
struct tcf_proto *tp, unsigned long base,
u32 handle,
struct nlattr **tca,
- unsigned long *arg)
+ unsigned long *arg, bool ovr)
{
struct route4_head *head = tp->root;
struct route4_filter *f, *f1, **fp;
@@ -455,7 +456,7 @@ static int route4_change(struct net *net, struct sk_buff *in_skb,
old_handle = f->handle;
err = route4_set_parms(net, tp, base, f, handle, head, tb,
- tca[TCA_RATE], 0);
+ tca[TCA_RATE], 0, ovr);
if (err < 0)
return err;
@@ -479,7 +480,7 @@ static int route4_change(struct net *net, struct sk_buff *in_skb,
tcf_exts_init(&f->exts, TCA_ROUTE4_ACT, TCA_ROUTE4_POLICE);
err = route4_set_parms(net, tp, base, f, handle, head, tb,
- tca[TCA_RATE], 1);
+ tca[TCA_RATE], 1, ovr);
if (err < 0)
goto errout;
diff --git a/net/sched/cls_rsvp.h b/net/sched/cls_rsvp.h
index 19f8e5d..1020e23 100644
--- a/net/sched/cls_rsvp.h
+++ b/net/sched/cls_rsvp.h
@@ -415,7 +415,7 @@ static int rsvp_change(struct net *net, struct sk_buff *in_skb,
struct tcf_proto *tp, unsigned long base,
u32 handle,
struct nlattr **tca,
- unsigned long *arg)
+ unsigned long *arg, bool ovr)
{
struct rsvp_head *data = tp->root;
struct rsvp_filter *f, **fp;
@@ -436,7 +436,7 @@ static int rsvp_change(struct net *net, struct sk_buff *in_skb,
return err;
tcf_exts_init(&e, TCA_RSVP_ACT, TCA_RSVP_POLICE);
- err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &e);
+ err = tcf_exts_validate(net, tp, tb, tca[TCA_RATE], &e, ovr);
if (err < 0)
return err;
diff --git a/net/sched/cls_tcindex.c b/net/sched/cls_tcindex.c
index eed8404..d11d0a4 100644
--- a/net/sched/cls_tcindex.c
+++ b/net/sched/cls_tcindex.c
@@ -192,7 +192,7 @@ static int
tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base,
u32 handle, struct tcindex_data *p,
struct tcindex_filter_result *r, struct nlattr **tb,
- struct nlattr *est)
+ struct nlattr *est, bool ovr)
{
int err, balloc = 0;
struct tcindex_filter_result new_filter_result, *old_r = r;
@@ -202,7 +202,7 @@ tcindex_set_parms(struct net *net, struct tcf_proto *tp, unsigned long base,
struct tcf_exts e;
tcf_exts_init(&e, TCA_TCINDEX_ACT, TCA_TCINDEX_POLICE);
- err = tcf_exts_validate(net, tp, tb, est, &e);
+ err = tcf_exts_validate(net, tp, tb, est, &e, ovr);
if (err < 0)
return err;
@@ -331,7 +331,7 @@ errout:
static int
tcindex_change(struct net *net, struct sk_buff *in_skb,
struct tcf_proto *tp, unsigned long base, u32 handle,
- struct nlattr **tca, unsigned long *arg)
+ struct nlattr **tca, unsigned long *arg, bool ovr)
{
struct nlattr *opt = tca[TCA_OPTIONS];
struct nlattr *tb[TCA_TCINDEX_MAX + 1];
@@ -351,7 +351,7 @@ tcindex_change(struct net *net, struct sk_buff *in_skb,
return err;
return tcindex_set_parms(net, tp, base, handle, p, r, tb,
- tca[TCA_RATE]);
+ tca[TCA_RATE], ovr);
}
diff --git a/net/sched/cls_u32.c b/net/sched/cls_u32.c
index 84c28da..c39b583 100644
--- a/net/sched/cls_u32.c
+++ b/net/sched/cls_u32.c
@@ -486,13 +486,13 @@ static const struct nla_policy u32_policy[TCA_U32_MAX + 1] = {
static int u32_set_parms(struct net *net, struct tcf_proto *tp,
unsigned long base, struct tc_u_hnode *ht,
struct tc_u_knode *n, struct nlattr **tb,
- struct nlattr *est)
+ struct nlattr *est, bool ovr)
{
int err;
struct tcf_exts e;
tcf_exts_init(&e, TCA_U32_ACT, TCA_U32_POLICE);
- err = tcf_exts_validate(net, tp, tb, est, &e);
+ err = tcf_exts_validate(net, tp, tb, est, &e, ovr);
if (err < 0)
return err;
@@ -545,7 +545,7 @@ errout:
static int u32_change(struct net *net, struct sk_buff *in_skb,
struct tcf_proto *tp, unsigned long base, u32 handle,
struct nlattr **tca,
- unsigned long *arg)
+ unsigned long *arg, bool ovr)
{
struct tc_u_common *tp_c = tp->data;
struct tc_u_hnode *ht;
@@ -569,7 +569,7 @@ static int u32_change(struct net *net, struct sk_buff *in_skb,
return -EINVAL;
return u32_set_parms(net, tp, base, n->ht_up, n, tb,
- tca[TCA_RATE]);
+ tca[TCA_RATE], ovr);
}
if (tb[TCA_U32_DIVISOR]) {
@@ -656,7 +656,7 @@ static int u32_change(struct net *net, struct sk_buff *in_skb,
}
#endif
- err = u32_set_parms(net, tp, base, ht, n, tb, tca[TCA_RATE]);
+ err = u32_set_parms(net, tp, base, ht, n, tb, tca[TCA_RATE], ovr);
if (err == 0) {
struct tc_u_knode **ins;
for (ins = &ht->ht[TC_U32_HASH(handle)]; *ins; ins = &(*ins)->next)
diff --git a/net/sctp/auth.c b/net/sctp/auth.c
index 683c7d1..0e85291 100644
--- a/net/sctp/auth.c
+++ b/net/sctp/auth.c
@@ -386,14 +386,13 @@ nomem:
*/
int sctp_auth_asoc_init_active_key(struct sctp_association *asoc, gfp_t gfp)
{
- struct net *net = sock_net(asoc->base.sk);
struct sctp_auth_bytes *secret;
struct sctp_shared_key *ep_key;
/* If we don't support AUTH, or peer is not capable
* we don't need to do anything.
*/
- if (!net->sctp.auth_enable || !asoc->peer.auth_capable)
+ if (!asoc->ep->auth_enable || !asoc->peer.auth_capable)
return 0;
/* If the key_id is non-zero and we couldn't find an
@@ -440,16 +439,16 @@ struct sctp_shared_key *sctp_auth_get_shkey(
*/
int sctp_auth_init_hmacs(struct sctp_endpoint *ep, gfp_t gfp)
{
- struct net *net = sock_net(ep->base.sk);
struct crypto_hash *tfm = NULL;
__u16 id;
- /* if the transforms are already allocted, we are done */
- if (!net->sctp.auth_enable) {
+ /* If AUTH extension is disabled, we are done */
+ if (!ep->auth_enable) {
ep->auth_hmacs = NULL;
return 0;
}
+ /* If the transforms are already allocated, we are done */
if (ep->auth_hmacs)
return 0;
@@ -665,12 +664,10 @@ static int __sctp_auth_cid(sctp_cid_t chunk, struct sctp_chunks_param *param)
/* Check if peer requested that this chunk is authenticated */
int sctp_auth_send_cid(sctp_cid_t chunk, const struct sctp_association *asoc)
{
- struct net *net;
if (!asoc)
return 0;
- net = sock_net(asoc->base.sk);
- if (!net->sctp.auth_enable || !asoc->peer.auth_capable)
+ if (!asoc->ep->auth_enable || !asoc->peer.auth_capable)
return 0;
return __sctp_auth_cid(chunk, asoc->peer.peer_chunks);
@@ -679,12 +676,10 @@ int sctp_auth_send_cid(sctp_cid_t chunk, const struct sctp_association *asoc)
/* Check if we requested that peer authenticate this chunk. */
int sctp_auth_recv_cid(sctp_cid_t chunk, const struct sctp_association *asoc)
{
- struct net *net;
if (!asoc)
return 0;
- net = sock_net(asoc->base.sk);
- if (!net->sctp.auth_enable)
+ if (!asoc->ep->auth_enable)
return 0;
return __sctp_auth_cid(chunk,
diff --git a/net/sctp/endpointola.c b/net/sctp/endpointola.c
index 8e5fdea..3d9f429 100644
--- a/net/sctp/endpointola.c
+++ b/net/sctp/endpointola.c
@@ -68,7 +68,8 @@ static struct sctp_endpoint *sctp_endpoint_init(struct sctp_endpoint *ep,
if (!ep->digest)
return NULL;
- if (net->sctp.auth_enable) {
+ ep->auth_enable = net->sctp.auth_enable;
+ if (ep->auth_enable) {
/* Allocate space for HMACS and CHUNKS authentication
* variables. There are arrays that we encode directly
* into parameters to make the rest of the operations easier.
diff --git a/net/sctp/sm_make_chunk.c b/net/sctp/sm_make_chunk.c
index 3a1767e..fee5552 100644
--- a/net/sctp/sm_make_chunk.c
+++ b/net/sctp/sm_make_chunk.c
@@ -219,6 +219,7 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
gfp_t gfp, int vparam_len)
{
struct net *net = sock_net(asoc->base.sk);
+ struct sctp_endpoint *ep = asoc->ep;
sctp_inithdr_t init;
union sctp_params addrs;
size_t chunksize;
@@ -278,7 +279,7 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
chunksize += vparam_len;
/* Account for AUTH related parameters */
- if (net->sctp.auth_enable) {
+ if (ep->auth_enable) {
/* Add random parameter length*/
chunksize += sizeof(asoc->c.auth_random);
@@ -363,7 +364,7 @@ struct sctp_chunk *sctp_make_init(const struct sctp_association *asoc,
}
/* Add SCTP-AUTH chunks to the parameter list */
- if (net->sctp.auth_enable) {
+ if (ep->auth_enable) {
sctp_addto_chunk(retval, sizeof(asoc->c.auth_random),
asoc->c.auth_random);
if (auth_hmacs)
@@ -2010,7 +2011,7 @@ static void sctp_process_ext_param(struct sctp_association *asoc,
/* if the peer reports AUTH, assume that he
* supports AUTH.
*/
- if (net->sctp.auth_enable)
+ if (asoc->ep->auth_enable)
asoc->peer.auth_capable = 1;
break;
case SCTP_CID_ASCONF:
@@ -2102,6 +2103,7 @@ static sctp_ierror_t sctp_process_unk_param(const struct sctp_association *asoc,
* SCTP_IERROR_NO_ERROR - continue with the chunk
*/
static sctp_ierror_t sctp_verify_param(struct net *net,
+ const struct sctp_endpoint *ep,
const struct sctp_association *asoc,
union sctp_params param,
sctp_cid_t cid,
@@ -2152,7 +2154,7 @@ static sctp_ierror_t sctp_verify_param(struct net *net,
goto fallthrough;
case SCTP_PARAM_RANDOM:
- if (!net->sctp.auth_enable)
+ if (!ep->auth_enable)
goto fallthrough;
/* SCTP-AUTH: Secion 6.1
@@ -2169,7 +2171,7 @@ static sctp_ierror_t sctp_verify_param(struct net *net,
break;
case SCTP_PARAM_CHUNKS:
- if (!net->sctp.auth_enable)
+ if (!ep->auth_enable)
goto fallthrough;
/* SCTP-AUTH: Section 3.2
@@ -2185,7 +2187,7 @@ static sctp_ierror_t sctp_verify_param(struct net *net,
break;
case SCTP_PARAM_HMAC_ALGO:
- if (!net->sctp.auth_enable)
+ if (!ep->auth_enable)
goto fallthrough;
hmacs = (struct sctp_hmac_algo_param *)param.p;
@@ -2220,10 +2222,9 @@ fallthrough:
}
/* Verify the INIT packet before we process it. */
-int sctp_verify_init(struct net *net, const struct sctp_association *asoc,
- sctp_cid_t cid,
- sctp_init_chunk_t *peer_init,
- struct sctp_chunk *chunk,
+int sctp_verify_init(struct net *net, const struct sctp_endpoint *ep,
+ const struct sctp_association *asoc, sctp_cid_t cid,
+ sctp_init_chunk_t *peer_init, struct sctp_chunk *chunk,
struct sctp_chunk **errp)
{
union sctp_params param;
@@ -2264,8 +2265,8 @@ int sctp_verify_init(struct net *net, const struct sctp_association *asoc,
/* Verify all the variable length parameters */
sctp_walk_params(param, peer_init, init_hdr.params) {
-
- result = sctp_verify_param(net, asoc, param, cid, chunk, errp);
+ result = sctp_verify_param(net, ep, asoc, param, cid,
+ chunk, errp);
switch (result) {
case SCTP_IERROR_ABORT:
case SCTP_IERROR_NOMEM:
@@ -2497,6 +2498,7 @@ static int sctp_process_param(struct sctp_association *asoc,
struct sctp_af *af;
union sctp_addr_param *addr_param;
struct sctp_transport *t;
+ struct sctp_endpoint *ep = asoc->ep;
/* We maintain all INIT parameters in network byte order all the
* time. This allows us to not worry about whether the parameters
@@ -2636,7 +2638,7 @@ do_addr_param:
goto fall_through;
case SCTP_PARAM_RANDOM:
- if (!net->sctp.auth_enable)
+ if (!ep->auth_enable)
goto fall_through;
/* Save peer's random parameter */
@@ -2649,7 +2651,7 @@ do_addr_param:
break;
case SCTP_PARAM_HMAC_ALGO:
- if (!net->sctp.auth_enable)
+ if (!ep->auth_enable)
goto fall_through;
/* Save peer's HMAC list */
@@ -2665,7 +2667,7 @@ do_addr_param:
break;
case SCTP_PARAM_CHUNKS:
- if (!net->sctp.auth_enable)
+ if (!ep->auth_enable)
goto fall_through;
asoc->peer.peer_chunks = kmemdup(param.p,
diff --git a/net/sctp/sm_statefuns.c b/net/sctp/sm_statefuns.c
index ae9fbeb..5170a1f 100644
--- a/net/sctp/sm_statefuns.c
+++ b/net/sctp/sm_statefuns.c
@@ -357,7 +357,7 @@ sctp_disposition_t sctp_sf_do_5_1B_init(struct net *net,
/* Verify the INIT chunk before processing it. */
err_chunk = NULL;
- if (!sctp_verify_init(net, asoc, chunk->chunk_hdr->type,
+ if (!sctp_verify_init(net, ep, asoc, chunk->chunk_hdr->type,
(sctp_init_chunk_t *)chunk->chunk_hdr, chunk,
&err_chunk)) {
/* This chunk contains fatal error. It is to be discarded.
@@ -524,7 +524,7 @@ sctp_disposition_t sctp_sf_do_5_1C_ack(struct net *net,
/* Verify the INIT chunk before processing it. */
err_chunk = NULL;
- if (!sctp_verify_init(net, asoc, chunk->chunk_hdr->type,
+ if (!sctp_verify_init(net, ep, asoc, chunk->chunk_hdr->type,
(sctp_init_chunk_t *)chunk->chunk_hdr, chunk,
&err_chunk)) {
@@ -1430,7 +1430,7 @@ static sctp_disposition_t sctp_sf_do_unexpected_init(
/* Verify the INIT chunk before processing it. */
err_chunk = NULL;
- if (!sctp_verify_init(net, asoc, chunk->chunk_hdr->type,
+ if (!sctp_verify_init(net, ep, asoc, chunk->chunk_hdr->type,
(sctp_init_chunk_t *)chunk->chunk_hdr, chunk,
&err_chunk)) {
/* This chunk contains fatal error. It is to be discarded.
diff --git a/net/sctp/socket.c b/net/sctp/socket.c
index ff20e2d..e37b2cb 100644
--- a/net/sctp/socket.c
+++ b/net/sctp/socket.c
@@ -71,6 +71,7 @@
#include <net/route.h>
#include <net/ipv6.h>
#include <net/inet_common.h>
+#include <net/busy_poll.h>
#include <linux/socket.h> /* for sa_family_t */
#include <linux/export.h>
@@ -3321,10 +3322,10 @@ static int sctp_setsockopt_auth_chunk(struct sock *sk,
char __user *optval,
unsigned int optlen)
{
- struct net *net = sock_net(sk);
+ struct sctp_endpoint *ep = sctp_sk(sk)->ep;
struct sctp_authchunk val;
- if (!net->sctp.auth_enable)
+ if (!ep->auth_enable)
return -EACCES;
if (optlen != sizeof(struct sctp_authchunk))
@@ -3341,7 +3342,7 @@ static int sctp_setsockopt_auth_chunk(struct sock *sk,
}
/* add this chunk id to the endpoint */
- return sctp_auth_ep_add_chunkid(sctp_sk(sk)->ep, val.sauth_chunk);
+ return sctp_auth_ep_add_chunkid(ep, val.sauth_chunk);
}
/*
@@ -3354,12 +3355,12 @@ static int sctp_setsockopt_hmac_ident(struct sock *sk,
char __user *optval,
unsigned int optlen)
{
- struct net *net = sock_net(sk);
+ struct sctp_endpoint *ep = sctp_sk(sk)->ep;
struct sctp_hmacalgo *hmacs;
u32 idents;
int err;
- if (!net->sctp.auth_enable)
+ if (!ep->auth_enable)
return -EACCES;
if (optlen < sizeof(struct sctp_hmacalgo))
@@ -3376,7 +3377,7 @@ static int sctp_setsockopt_hmac_ident(struct sock *sk,
goto out;
}
- err = sctp_auth_ep_set_hmacs(sctp_sk(sk)->ep, hmacs);
+ err = sctp_auth_ep_set_hmacs(ep, hmacs);
out:
kfree(hmacs);
return err;
@@ -3392,12 +3393,12 @@ static int sctp_setsockopt_auth_key(struct sock *sk,
char __user *optval,
unsigned int optlen)
{
- struct net *net = sock_net(sk);
+ struct sctp_endpoint *ep = sctp_sk(sk)->ep;
struct sctp_authkey *authkey;
struct sctp_association *asoc;
int ret;
- if (!net->sctp.auth_enable)
+ if (!ep->auth_enable)
return -EACCES;
if (optlen <= sizeof(struct sctp_authkey))
@@ -3418,7 +3419,7 @@ static int sctp_setsockopt_auth_key(struct sock *sk,
goto out;
}
- ret = sctp_auth_set_key(sctp_sk(sk)->ep, asoc, authkey);
+ ret = sctp_auth_set_key(ep, asoc, authkey);
out:
kzfree(authkey);
return ret;
@@ -3434,11 +3435,11 @@ static int sctp_setsockopt_active_key(struct sock *sk,
char __user *optval,
unsigned int optlen)
{
- struct net *net = sock_net(sk);
+ struct sctp_endpoint *ep = sctp_sk(sk)->ep;
struct sctp_authkeyid val;
struct sctp_association *asoc;
- if (!net->sctp.auth_enable)
+ if (!ep->auth_enable)
return -EACCES;
if (optlen != sizeof(struct sctp_authkeyid))
@@ -3450,8 +3451,7 @@ static int sctp_setsockopt_active_key(struct sock *sk,
if (!asoc && val.scact_assoc_id && sctp_style(sk, UDP))
return -EINVAL;
- return sctp_auth_set_active_key(sctp_sk(sk)->ep, asoc,
- val.scact_keynumber);
+ return sctp_auth_set_active_key(ep, asoc, val.scact_keynumber);
}
/*
@@ -3463,11 +3463,11 @@ static int sctp_setsockopt_del_key(struct sock *sk,
char __user *optval,
unsigned int optlen)
{
- struct net *net = sock_net(sk);
+ struct sctp_endpoint *ep = sctp_sk(sk)->ep;
struct sctp_authkeyid val;
struct sctp_association *asoc;
- if (!net->sctp.auth_enable)
+ if (!ep->auth_enable)
return -EACCES;
if (optlen != sizeof(struct sctp_authkeyid))
@@ -3479,8 +3479,7 @@ static int sctp_setsockopt_del_key(struct sock *sk,
if (!asoc && val.scact_assoc_id && sctp_style(sk, UDP))
return -EINVAL;
- return sctp_auth_del_key_id(sctp_sk(sk)->ep, asoc,
- val.scact_keynumber);
+ return sctp_auth_del_key_id(ep, asoc, val.scact_keynumber);
}
@@ -5387,16 +5386,16 @@ static int sctp_getsockopt_maxburst(struct sock *sk, int len,
static int sctp_getsockopt_hmac_ident(struct sock *sk, int len,
char __user *optval, int __user *optlen)
{
- struct net *net = sock_net(sk);
+ struct sctp_endpoint *ep = sctp_sk(sk)->ep;
struct sctp_hmacalgo __user *p = (void __user *)optval;
struct sctp_hmac_algo_param *hmacs;
__u16 data_len = 0;
u32 num_idents;
- if (!net->sctp.auth_enable)
+ if (!ep->auth_enable)
return -EACCES;
- hmacs = sctp_sk(sk)->ep->auth_hmacs_list;
+ hmacs = ep->auth_hmacs_list;
data_len = ntohs(hmacs->param_hdr.length) - sizeof(sctp_paramhdr_t);
if (len < sizeof(struct sctp_hmacalgo) + data_len)
@@ -5417,11 +5416,11 @@ static int sctp_getsockopt_hmac_ident(struct sock *sk, int len,
static int sctp_getsockopt_active_key(struct sock *sk, int len,
char __user *optval, int __user *optlen)
{
- struct net *net = sock_net(sk);
+ struct sctp_endpoint *ep = sctp_sk(sk)->ep;
struct sctp_authkeyid val;
struct sctp_association *asoc;
- if (!net->sctp.auth_enable)
+ if (!ep->auth_enable)
return -EACCES;
if (len < sizeof(struct sctp_authkeyid))
@@ -5436,7 +5435,7 @@ static int sctp_getsockopt_active_key(struct sock *sk, int len,
if (asoc)
val.scact_keynumber = asoc->active_key_id;
else
- val.scact_keynumber = sctp_sk(sk)->ep->active_key_id;
+ val.scact_keynumber = ep->active_key_id;
len = sizeof(struct sctp_authkeyid);
if (put_user(len, optlen))
@@ -5450,7 +5449,7 @@ static int sctp_getsockopt_active_key(struct sock *sk, int len,
static int sctp_getsockopt_peer_auth_chunks(struct sock *sk, int len,
char __user *optval, int __user *optlen)
{
- struct net *net = sock_net(sk);
+ struct sctp_endpoint *ep = sctp_sk(sk)->ep;
struct sctp_authchunks __user *p = (void __user *)optval;
struct sctp_authchunks val;
struct sctp_association *asoc;
@@ -5458,7 +5457,7 @@ static int sctp_getsockopt_peer_auth_chunks(struct sock *sk, int len,
u32 num_chunks = 0;
char __user *to;
- if (!net->sctp.auth_enable)
+ if (!ep->auth_enable)
return -EACCES;
if (len < sizeof(struct sctp_authchunks))
@@ -5495,7 +5494,7 @@ num:
static int sctp_getsockopt_local_auth_chunks(struct sock *sk, int len,
char __user *optval, int __user *optlen)
{
- struct net *net = sock_net(sk);
+ struct sctp_endpoint *ep = sctp_sk(sk)->ep;
struct sctp_authchunks __user *p = (void __user *)optval;
struct sctp_authchunks val;
struct sctp_association *asoc;
@@ -5503,7 +5502,7 @@ static int sctp_getsockopt_local_auth_chunks(struct sock *sk, int len,
u32 num_chunks = 0;
char __user *to;
- if (!net->sctp.auth_enable)
+ if (!ep->auth_enable)
return -EACCES;
if (len < sizeof(struct sctp_authchunks))
@@ -5520,7 +5519,7 @@ static int sctp_getsockopt_local_auth_chunks(struct sock *sk, int len,
if (asoc)
ch = (struct sctp_chunks_param *)asoc->c.auth_chunks;
else
- ch = sctp_sk(sk)->ep->auth_chunk_list;
+ ch = ep->auth_chunk_list;
if (!ch)
goto num;
@@ -6559,6 +6558,10 @@ static struct sk_buff *sctp_skb_recv_datagram(struct sock *sk, int flags,
if (sk->sk_shutdown & RCV_SHUTDOWN)
break;
+ if (sk_can_busy_loop(sk) &&
+ sk_busy_loop(sk, noblock))
+ continue;
+
/* User doesn't want to wait. */
error = -EAGAIN;
if (!timeo)
diff --git a/net/sctp/sysctl.c b/net/sctp/sysctl.c
index 35c8923..c82fdc1 100644
--- a/net/sctp/sysctl.c
+++ b/net/sctp/sysctl.c
@@ -64,6 +64,9 @@ static int proc_sctp_do_rto_min(struct ctl_table *ctl, int write,
static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write,
void __user *buffer, size_t *lenp,
loff_t *ppos);
+static int proc_sctp_do_auth(struct ctl_table *ctl, int write,
+ void __user *buffer, size_t *lenp,
+ loff_t *ppos);
static struct ctl_table sctp_table[] = {
{
@@ -266,7 +269,7 @@ static struct ctl_table sctp_net_table[] = {
.data = &init_net.sctp.auth_enable,
.maxlen = sizeof(int),
.mode = 0644,
- .proc_handler = proc_dointvec,
+ .proc_handler = proc_sctp_do_auth,
},
{
.procname = "addr_scope_policy",
@@ -400,6 +403,37 @@ static int proc_sctp_do_rto_max(struct ctl_table *ctl, int write,
return ret;
}
+static int proc_sctp_do_auth(struct ctl_table *ctl, int write,
+ void __user *buffer, size_t *lenp,
+ loff_t *ppos)
+{
+ struct net *net = current->nsproxy->net_ns;
+ struct ctl_table tbl;
+ int new_value, ret;
+
+ memset(&tbl, 0, sizeof(struct ctl_table));
+ tbl.maxlen = sizeof(unsigned int);
+
+ if (write)
+ tbl.data = &new_value;
+ else
+ tbl.data = &net->sctp.auth_enable;
+
+ ret = proc_dointvec(&tbl, write, buffer, lenp, ppos);
+
+ if (write) {
+ struct sock *sk = net->sctp.ctl_sock;
+
+ net->sctp.auth_enable = new_value;
+ /* Update the value in the control socket */
+ lock_sock(sk);
+ sctp_sk(sk)->ep->auth_enable = new_value;
+ release_sock(sk);
+ }
+
+ return ret;
+}
+
int sctp_sysctl_net_register(struct net *net)
{
struct ctl_table *table = sctp_net_table;
diff --git a/net/sctp/ulpqueue.c b/net/sctp/ulpqueue.c
index 7144eb6..d49dc2ed 100644
--- a/net/sctp/ulpqueue.c
+++ b/net/sctp/ulpqueue.c
@@ -38,6 +38,7 @@
#include <linux/types.h>
#include <linux/skbuff.h>
#include <net/sock.h>
+#include <net/busy_poll.h>
#include <net/sctp/structs.h>
#include <net/sctp/sctp.h>
#include <net/sctp/sm.h>
@@ -204,6 +205,9 @@ int sctp_ulpq_tail_event(struct sctp_ulpq *ulpq, struct sctp_ulpevent *event)
if (sock_flag(sk, SOCK_DEAD) || (sk->sk_shutdown & RCV_SHUTDOWN))
goto out_free;
+ if (!sctp_ulpevent_is_notification(event))
+ sk_mark_napi_id(sk, skb);
+
/* Check if the user wishes to receive this event. */
if (!sctp_ulpevent_is_enabled(event, &sctp_sk(sk)->subscribe))
goto out_free;
diff --git a/net/tipc/bcast.c b/net/tipc/bcast.c
index 95ab5ef..119a59b 100644
--- a/net/tipc/bcast.c
+++ b/net/tipc/bcast.c
@@ -112,6 +112,8 @@ const char tipc_bclink_name[] = "broadcast-link";
static void tipc_nmap_diff(struct tipc_node_map *nm_a,
struct tipc_node_map *nm_b,
struct tipc_node_map *nm_diff);
+static void tipc_nmap_add(struct tipc_node_map *nm_ptr, u32 node);
+static void tipc_nmap_remove(struct tipc_node_map *nm_ptr, u32 node);
static u32 bcbuf_acks(struct sk_buff *buf)
{
@@ -273,7 +275,7 @@ exit:
/**
* tipc_bclink_update_link_state - update broadcast link state
*
- * tipc_net_lock and node lock set
+ * RCU and node lock set
*/
void tipc_bclink_update_link_state(struct tipc_node *n_ptr, u32 last_sent)
{
@@ -321,7 +323,7 @@ void tipc_bclink_update_link_state(struct tipc_node *n_ptr, u32 last_sent)
: n_ptr->bclink.last_sent);
spin_lock_bh(&bc_lock);
- tipc_bearer_send(&bcbearer->bearer, buf, NULL);
+ tipc_bearer_send(MAX_BEARERS, buf, NULL);
bcl->stats.sent_nacks++;
spin_unlock_bh(&bc_lock);
kfree_skb(buf);
@@ -335,8 +337,6 @@ void tipc_bclink_update_link_state(struct tipc_node *n_ptr, u32 last_sent)
*
* Delay any upcoming NACK by this node if another node has already
* requested the first message this node is going to ask for.
- *
- * Only tipc_net_lock set.
*/
static void bclink_peek_nack(struct tipc_msg *msg)
{
@@ -408,7 +408,7 @@ static void bclink_accept_pkt(struct tipc_node *node, u32 seqno)
/**
* tipc_bclink_rcv - receive a broadcast packet, and deliver upwards
*
- * tipc_net_lock is read_locked, no other locks set
+ * RCU is locked, no other locks set
*/
void tipc_bclink_rcv(struct sk_buff *buf)
{
@@ -627,13 +627,13 @@ static int tipc_bcbearer_send(struct sk_buff *buf, struct tipc_bearer *unused1,
if (bp_index == 0) {
/* Use original buffer for first bearer */
- tipc_bearer_send(b, buf, &b->bcast_addr);
+ tipc_bearer_send(b->identity, buf, &b->bcast_addr);
} else {
/* Avoid concurrent buffer access */
tbuf = pskb_copy(buf, GFP_ATOMIC);
if (!tbuf)
break;
- tipc_bearer_send(b, tbuf, &b->bcast_addr);
+ tipc_bearer_send(b->identity, tbuf, &b->bcast_addr);
kfree_skb(tbuf); /* Bearer keeps a clone */
}
@@ -655,20 +655,27 @@ static int tipc_bcbearer_send(struct sk_buff *buf, struct tipc_bearer *unused1,
/**
* tipc_bcbearer_sort - create sets of bearer pairs used by broadcast bearer
*/
-void tipc_bcbearer_sort(void)
+void tipc_bcbearer_sort(struct tipc_node_map *nm_ptr, u32 node, bool action)
{
struct tipc_bcbearer_pair *bp_temp = bcbearer->bpairs_temp;
struct tipc_bcbearer_pair *bp_curr;
+ struct tipc_bearer *b;
int b_index;
int pri;
spin_lock_bh(&bc_lock);
+ if (action)
+ tipc_nmap_add(nm_ptr, node);
+ else
+ tipc_nmap_remove(nm_ptr, node);
+
/* Group bearers by priority (can assume max of two per priority) */
memset(bp_temp, 0, sizeof(bcbearer->bpairs_temp));
+ rcu_read_lock();
for (b_index = 0; b_index < MAX_BEARERS; b_index++) {
- struct tipc_bearer *b = bearer_list[b_index];
+ b = rcu_dereference_rtnl(bearer_list[b_index]);
if (!b || !b->nodes.count)
continue;
@@ -677,6 +684,7 @@ void tipc_bcbearer_sort(void)
else
bp_temp[b->priority].secondary = b;
}
+ rcu_read_unlock();
/* Create array of bearer pairs for broadcasting */
bp_curr = bcbearer->bpairs;
@@ -783,8 +791,8 @@ void tipc_bclink_init(void)
bcl->owner = &bclink->node;
bcl->max_pkt = MAX_PKT_DEFAULT_MCAST;
tipc_link_set_queue_limits(bcl, BCLINK_WIN_DEFAULT);
- bcl->b_ptr = &bcbearer->bearer;
- bearer_list[BCBEARER] = &bcbearer->bearer;
+ bcl->bearer_id = MAX_BEARERS;
+ rcu_assign_pointer(bearer_list[MAX_BEARERS], &bcbearer->bearer);
bcl->state = WORKING_WORKING;
strlcpy(bcl->name, tipc_bclink_name, TIPC_MAX_LINK_NAME);
}
@@ -795,16 +803,15 @@ void tipc_bclink_stop(void)
tipc_link_purge_queues(bcl);
spin_unlock_bh(&bc_lock);
- bearer_list[BCBEARER] = NULL;
+ RCU_INIT_POINTER(bearer_list[BCBEARER], NULL);
memset(bclink, 0, sizeof(*bclink));
memset(bcbearer, 0, sizeof(*bcbearer));
}
-
/**
* tipc_nmap_add - add a node to a node map
*/
-void tipc_nmap_add(struct tipc_node_map *nm_ptr, u32 node)
+static void tipc_nmap_add(struct tipc_node_map *nm_ptr, u32 node)
{
int n = tipc_node(node);
int w = n / WSIZE;
@@ -819,7 +826,7 @@ void tipc_nmap_add(struct tipc_node_map *nm_ptr, u32 node)
/**
* tipc_nmap_remove - remove a node from a node map
*/
-void tipc_nmap_remove(struct tipc_node_map *nm_ptr, u32 node)
+static void tipc_nmap_remove(struct tipc_node_map *nm_ptr, u32 node)
{
int n = tipc_node(node);
int w = n / WSIZE;
diff --git a/net/tipc/bcast.h b/net/tipc/bcast.h
index a80ef54..7c1ef1b 100644
--- a/net/tipc/bcast.h
+++ b/net/tipc/bcast.h
@@ -69,9 +69,6 @@ struct tipc_node;
extern const char tipc_bclink_name[];
-void tipc_nmap_add(struct tipc_node_map *nm_ptr, u32 node);
-void tipc_nmap_remove(struct tipc_node_map *nm_ptr, u32 node);
-
/**
* tipc_nmap_equal - test for equality of node maps
*/
@@ -98,6 +95,6 @@ void tipc_bclink_update_link_state(struct tipc_node *n_ptr, u32 last_sent);
int tipc_bclink_stats(char *stats_buf, const u32 buf_size);
int tipc_bclink_reset_stats(void);
int tipc_bclink_set_queue_limits(u32 limit);
-void tipc_bcbearer_sort(void);
+void tipc_bcbearer_sort(struct tipc_node_map *nm_ptr, u32 node, bool action);
#endif
diff --git a/net/tipc/bearer.c b/net/tipc/bearer.c
index 3fef7eb..f3259d4 100644
--- a/net/tipc/bearer.c
+++ b/net/tipc/bearer.c
@@ -49,7 +49,7 @@ static struct tipc_media * const media_info_array[] = {
NULL
};
-struct tipc_bearer *bearer_list[MAX_BEARERS + 1];
+struct tipc_bearer __rcu *bearer_list[MAX_BEARERS + 1];
static void bearer_disable(struct tipc_bearer *b_ptr, bool shutting_down);
@@ -178,7 +178,7 @@ struct tipc_bearer *tipc_bearer_find(const char *name)
u32 i;
for (i = 0; i < MAX_BEARERS; i++) {
- b_ptr = bearer_list[i];
+ b_ptr = rtnl_dereference(bearer_list[i]);
if (b_ptr && (!strcmp(b_ptr->name, name)))
return b_ptr;
}
@@ -198,10 +198,9 @@ struct sk_buff *tipc_bearer_get_names(void)
if (!buf)
return NULL;
- read_lock_bh(&tipc_net_lock);
for (i = 0; media_info_array[i] != NULL; i++) {
for (j = 0; j < MAX_BEARERS; j++) {
- b = bearer_list[j];
+ b = rtnl_dereference(bearer_list[j]);
if (!b)
continue;
if (b->media == media_info_array[i]) {
@@ -211,22 +210,33 @@ struct sk_buff *tipc_bearer_get_names(void)
}
}
}
- read_unlock_bh(&tipc_net_lock);
return buf;
}
-void tipc_bearer_add_dest(struct tipc_bearer *b_ptr, u32 dest)
+void tipc_bearer_add_dest(u32 bearer_id, u32 dest)
{
- tipc_nmap_add(&b_ptr->nodes, dest);
- tipc_bcbearer_sort();
- tipc_disc_add_dest(b_ptr->link_req);
+ struct tipc_bearer *b_ptr;
+
+ rcu_read_lock();
+ b_ptr = rcu_dereference_rtnl(bearer_list[bearer_id]);
+ if (b_ptr) {
+ tipc_bcbearer_sort(&b_ptr->nodes, dest, true);
+ tipc_disc_add_dest(b_ptr->link_req);
+ }
+ rcu_read_unlock();
}
-void tipc_bearer_remove_dest(struct tipc_bearer *b_ptr, u32 dest)
+void tipc_bearer_remove_dest(u32 bearer_id, u32 dest)
{
- tipc_nmap_remove(&b_ptr->nodes, dest);
- tipc_bcbearer_sort();
- tipc_disc_remove_dest(b_ptr->link_req);
+ struct tipc_bearer *b_ptr;
+
+ rcu_read_lock();
+ b_ptr = rcu_dereference_rtnl(bearer_list[bearer_id]);
+ if (b_ptr) {
+ tipc_bcbearer_sort(&b_ptr->nodes, dest, false);
+ tipc_disc_remove_dest(b_ptr->link_req);
+ }
+ rcu_read_unlock();
}
/**
@@ -271,13 +281,11 @@ int tipc_enable_bearer(const char *name, u32 disc_domain, u32 priority)
return -EINVAL;
}
- write_lock_bh(&tipc_net_lock);
-
m_ptr = tipc_media_find(b_names.media_name);
if (!m_ptr) {
pr_warn("Bearer <%s> rejected, media <%s> not registered\n",
name, b_names.media_name);
- goto exit;
+ return -EINVAL;
}
if (priority == TIPC_MEDIA_LINK_PRI)
@@ -287,7 +295,7 @@ restart:
bearer_id = MAX_BEARERS;
with_this_prio = 1;
for (i = MAX_BEARERS; i-- != 0; ) {
- b_ptr = bearer_list[i];
+ b_ptr = rtnl_dereference(bearer_list[i]);
if (!b_ptr) {
bearer_id = i;
continue;
@@ -295,14 +303,14 @@ restart:
if (!strcmp(name, b_ptr->name)) {
pr_warn("Bearer <%s> rejected, already enabled\n",
name);
- goto exit;
+ return -EINVAL;
}
if ((b_ptr->priority == priority) &&
(++with_this_prio > 2)) {
if (priority-- == 0) {
pr_warn("Bearer <%s> rejected, duplicate priority\n",
name);
- goto exit;
+ return -EINVAL;
}
pr_warn("Bearer <%s> priority adjustment required %u->%u\n",
name, priority + 1, priority);
@@ -312,21 +320,20 @@ restart:
if (bearer_id >= MAX_BEARERS) {
pr_warn("Bearer <%s> rejected, bearer limit reached (%u)\n",
name, MAX_BEARERS);
- goto exit;
+ return -EINVAL;
}
b_ptr = kzalloc(sizeof(*b_ptr), GFP_ATOMIC);
- if (!b_ptr) {
- res = -ENOMEM;
- goto exit;
- }
+ if (!b_ptr)
+ return -ENOMEM;
+
strcpy(b_ptr->name, name);
b_ptr->media = m_ptr;
res = m_ptr->enable_media(b_ptr);
if (res) {
pr_warn("Bearer <%s> rejected, enable failure (%d)\n",
name, -res);
- goto exit;
+ return -EINVAL;
}
b_ptr->identity = bearer_id;
@@ -341,16 +348,14 @@ restart:
bearer_disable(b_ptr, false);
pr_warn("Bearer <%s> rejected, discovery object creation failed\n",
name);
- goto exit;
+ return -EINVAL;
}
- bearer_list[bearer_id] = b_ptr;
+ rcu_assign_pointer(bearer_list[bearer_id], b_ptr);
pr_info("Enabled bearer <%s>, discovery domain %s, priority %u\n",
name,
tipc_addr_string_fill(addr_string, disc_domain), priority);
-exit:
- write_unlock_bh(&tipc_net_lock);
return res;
}
@@ -359,19 +364,16 @@ exit:
*/
static int tipc_reset_bearer(struct tipc_bearer *b_ptr)
{
- read_lock_bh(&tipc_net_lock);
pr_info("Resetting bearer <%s>\n", b_ptr->name);
- tipc_disc_delete(b_ptr->link_req);
tipc_link_reset_list(b_ptr->identity);
- tipc_disc_create(b_ptr, &b_ptr->bcast_addr);
- read_unlock_bh(&tipc_net_lock);
+ tipc_disc_reset(b_ptr);
return 0;
}
/**
* bearer_disable
*
- * Note: This routine assumes caller holds tipc_net_lock.
+ * Note: This routine assumes caller holds RTNL lock.
*/
static void bearer_disable(struct tipc_bearer *b_ptr, bool shutting_down)
{
@@ -385,12 +387,12 @@ static void bearer_disable(struct tipc_bearer *b_ptr, bool shutting_down)
tipc_disc_delete(b_ptr->link_req);
for (i = 0; i < MAX_BEARERS; i++) {
- if (b_ptr == bearer_list[i]) {
- bearer_list[i] = NULL;
+ if (b_ptr == rtnl_dereference(bearer_list[i])) {
+ RCU_INIT_POINTER(bearer_list[i], NULL);
break;
}
}
- kfree(b_ptr);
+ kfree_rcu(b_ptr, rcu);
}
int tipc_disable_bearer(const char *name)
@@ -398,7 +400,6 @@ int tipc_disable_bearer(const char *name)
struct tipc_bearer *b_ptr;
int res;
- write_lock_bh(&tipc_net_lock);
b_ptr = tipc_bearer_find(name);
if (b_ptr == NULL) {
pr_warn("Attempt to disable unknown bearer <%s>\n", name);
@@ -407,7 +408,6 @@ int tipc_disable_bearer(const char *name)
bearer_disable(b_ptr, false);
res = 0;
}
- write_unlock_bh(&tipc_net_lock);
return res;
}
@@ -444,7 +444,7 @@ int tipc_enable_l2_media(struct tipc_bearer *b)
return -ENODEV;
/* Associate TIPC bearer with Ethernet bearer */
- b->media_ptr = dev;
+ rcu_assign_pointer(b->media_ptr, dev);
memset(b->bcast_addr.value, 0, sizeof(b->bcast_addr.value));
memcpy(b->bcast_addr.value, dev->broadcast, b->media->hwaddr_len);
b->bcast_addr.media_id = b->media->type_id;
@@ -463,8 +463,12 @@ int tipc_enable_l2_media(struct tipc_bearer *b)
*/
void tipc_disable_l2_media(struct tipc_bearer *b)
{
- struct net_device *dev = (struct net_device *)b->media_ptr;
+ struct net_device *dev;
+
+ dev = (struct net_device *)rtnl_dereference(b->media_ptr);
+ RCU_INIT_POINTER(b->media_ptr, NULL);
RCU_INIT_POINTER(dev->tipc_ptr, NULL);
+ synchronize_net();
dev_put(dev);
}
@@ -478,8 +482,12 @@ int tipc_l2_send_msg(struct sk_buff *buf, struct tipc_bearer *b,
struct tipc_media_addr *dest)
{
struct sk_buff *clone;
+ struct net_device *dev;
int delta;
- struct net_device *dev = (struct net_device *)b->media_ptr;
+
+ dev = (struct net_device *)rcu_dereference_rtnl(b->media_ptr);
+ if (!dev)
+ return 0;
clone = skb_clone(buf, GFP_ATOMIC);
if (!clone)
@@ -507,10 +515,16 @@ int tipc_l2_send_msg(struct sk_buff *buf, struct tipc_bearer *b,
* The media send routine must not alter the buffer being passed in
* as it may be needed for later retransmission!
*/
-void tipc_bearer_send(struct tipc_bearer *b, struct sk_buff *buf,
+void tipc_bearer_send(u32 bearer_id, struct sk_buff *buf,
struct tipc_media_addr *dest)
{
- b->media->send_msg(buf, b, dest);
+ struct tipc_bearer *b_ptr;
+
+ rcu_read_lock();
+ b_ptr = rcu_dereference_rtnl(bearer_list[bearer_id]);
+ if (likely(b_ptr))
+ b_ptr->media->send_msg(buf, b_ptr, dest);
+ rcu_read_unlock();
}
/**
@@ -535,7 +549,7 @@ static int tipc_l2_rcv_msg(struct sk_buff *buf, struct net_device *dev,
}
rcu_read_lock();
- b_ptr = rcu_dereference(dev->tipc_ptr);
+ b_ptr = rcu_dereference_rtnl(dev->tipc_ptr);
if (likely(b_ptr)) {
if (likely(buf->pkt_type <= PACKET_BROADCAST)) {
buf->next = NULL;
@@ -568,12 +582,9 @@ static int tipc_l2_device_event(struct notifier_block *nb, unsigned long evt,
if (!net_eq(dev_net(dev), &init_net))
return NOTIFY_DONE;
- rcu_read_lock();
- b_ptr = rcu_dereference(dev->tipc_ptr);
- if (!b_ptr) {
- rcu_read_unlock();
+ b_ptr = rtnl_dereference(dev->tipc_ptr);
+ if (!b_ptr)
return NOTIFY_DONE;
- }
b_ptr->mtu = dev->mtu;
@@ -592,11 +603,9 @@ static int tipc_l2_device_event(struct notifier_block *nb, unsigned long evt,
break;
case NETDEV_UNREGISTER:
case NETDEV_CHANGENAME:
- tipc_disable_bearer(b_ptr->name);
+ bearer_disable(b_ptr, false);
break;
}
- rcu_read_unlock();
-
return NOTIFY_OK;
}
@@ -633,7 +642,7 @@ void tipc_bearer_stop(void)
u32 i;
for (i = 0; i < MAX_BEARERS; i++) {
- b_ptr = bearer_list[i];
+ b_ptr = rtnl_dereference(bearer_list[i]);
if (b_ptr) {
bearer_disable(b_ptr, true);
bearer_list[i] = NULL;
diff --git a/net/tipc/bearer.h b/net/tipc/bearer.h
index ba48145..a983b30 100644
--- a/net/tipc/bearer.h
+++ b/net/tipc/bearer.h
@@ -113,6 +113,7 @@ struct tipc_media {
* @name: bearer name (format = media:interface)
* @media: ptr to media structure associated with bearer
* @bcast_addr: media address used in broadcasting
+ * @rcu: rcu struct for tipc_bearer
* @priority: default link priority for bearer
* @window: default window size for bearer
* @tolerance: default link tolerance for bearer
@@ -127,12 +128,13 @@ struct tipc_media {
* care of initializing all other fields.
*/
struct tipc_bearer {
- void *media_ptr; /* initalized by media */
+ void __rcu *media_ptr; /* initalized by media */
u32 mtu; /* initalized by media */
struct tipc_media_addr addr; /* initalized by media */
char name[TIPC_MAX_BEARER_NAME];
struct tipc_media *media;
struct tipc_media_addr bcast_addr;
+ struct rcu_head rcu;
u32 priority;
u32 window;
u32 tolerance;
@@ -150,7 +152,7 @@ struct tipc_bearer_names {
struct tipc_link;
-extern struct tipc_bearer *bearer_list[];
+extern struct tipc_bearer __rcu *bearer_list[];
/*
* TIPC routines available to supported media types
@@ -181,14 +183,14 @@ int tipc_l2_send_msg(struct sk_buff *buf, struct tipc_bearer *b,
struct tipc_media_addr *dest);
struct sk_buff *tipc_bearer_get_names(void);
-void tipc_bearer_add_dest(struct tipc_bearer *b_ptr, u32 dest);
-void tipc_bearer_remove_dest(struct tipc_bearer *b_ptr, u32 dest);
+void tipc_bearer_add_dest(u32 bearer_id, u32 dest);
+void tipc_bearer_remove_dest(u32 bearer_id, u32 dest);
struct tipc_bearer *tipc_bearer_find(const char *name);
struct tipc_media *tipc_media_find(const char *name);
int tipc_bearer_setup(void);
void tipc_bearer_cleanup(void);
void tipc_bearer_stop(void);
-void tipc_bearer_send(struct tipc_bearer *b, struct sk_buff *buf,
+void tipc_bearer_send(u32 bearer_id, struct sk_buff *buf,
struct tipc_media_addr *dest);
#endif /* _TIPC_BEARER_H */
diff --git a/net/tipc/config.c b/net/tipc/config.c
index 4b981c0..251f5a2 100644
--- a/net/tipc/config.c
+++ b/net/tipc/config.c
@@ -42,8 +42,6 @@
#define REPLY_TRUNCATED "<truncated>\n"
-static DEFINE_MUTEX(config_mutex);
-
static const void *req_tlv_area; /* request message TLV area */
static int req_tlv_space; /* request message TLV area size */
static int rep_headroom; /* reply message headroom to use */
@@ -223,7 +221,7 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area
{
struct sk_buff *rep_tlv_buf;
- mutex_lock(&config_mutex);
+ rtnl_lock();
/* Save request and reply details in a well-known location */
req_tlv_area = request_area;
@@ -337,6 +335,6 @@ struct sk_buff *tipc_cfg_do_cmd(u32 orig_node, u16 cmd, const void *request_area
/* Return reply buffer */
exit:
- mutex_unlock(&config_mutex);
+ rtnl_unlock();
return rep_tlv_buf;
}
diff --git a/net/tipc/core.h b/net/tipc/core.h
index 8985bbc..36cbf15 100644
--- a/net/tipc/core.h
+++ b/net/tipc/core.h
@@ -56,7 +56,7 @@
#include <linux/list.h>
#include <linux/slab.h>
#include <linux/vmalloc.h>
-
+#include <linux/rtnetlink.h>
#define TIPC_MOD_VER "2.0.0"
diff --git a/net/tipc/discover.c b/net/tipc/discover.c
index 542fe34..bd35c4a 100644
--- a/net/tipc/discover.c
+++ b/net/tipc/discover.c
@@ -46,8 +46,9 @@
/**
* struct tipc_link_req - information about an ongoing link setup request
- * @bearer: bearer issuing requests
+ * @bearer_id: identity of bearer issuing requests
* @dest: destination address for request messages
+ * @domain: network domain to which links can be established
* @num_nodes: number of nodes currently discovered (i.e. with an active link)
* @lock: spinlock for controlling access to requests
* @buf: request message to be (repeatedly) sent
@@ -55,8 +56,9 @@
* @timer_intv: current interval between requests (in ms)
*/
struct tipc_link_req {
- struct tipc_bearer *bearer;
+ u32 bearer_id;
struct tipc_media_addr dest;
+ u32 domain;
int num_nodes;
spinlock_t lock;
struct sk_buff *buf;
@@ -69,22 +71,19 @@ struct tipc_link_req {
* @type: message type (request or response)
* @b_ptr: ptr to bearer issuing message
*/
-static struct sk_buff *tipc_disc_init_msg(u32 type, struct tipc_bearer *b_ptr)
+static void tipc_disc_init_msg(struct sk_buff *buf, u32 type,
+ struct tipc_bearer *b_ptr)
{
- struct sk_buff *buf = tipc_buf_acquire(INT_H_SIZE);
struct tipc_msg *msg;
u32 dest_domain = b_ptr->domain;
- if (buf) {
- msg = buf_msg(buf);
- tipc_msg_init(msg, LINK_CONFIG, type, INT_H_SIZE, dest_domain);
- msg_set_non_seq(msg, 1);
- msg_set_node_sig(msg, tipc_random);
- msg_set_dest_domain(msg, dest_domain);
- msg_set_bc_netid(msg, tipc_net_id);
- b_ptr->media->addr2msg(&b_ptr->addr, msg_media_addr(msg));
- }
- return buf;
+ msg = buf_msg(buf);
+ tipc_msg_init(msg, LINK_CONFIG, type, INT_H_SIZE, dest_domain);
+ msg_set_non_seq(msg, 1);
+ msg_set_node_sig(msg, tipc_random);
+ msg_set_dest_domain(msg, dest_domain);
+ msg_set_bc_netid(msg, tipc_net_id);
+ b_ptr->media->addr2msg(&b_ptr->addr, msg_media_addr(msg));
}
/**
@@ -239,9 +238,10 @@ void tipc_disc_rcv(struct sk_buff *buf, struct tipc_bearer *b_ptr)
link_fully_up = link_working_working(link);
if ((type == DSC_REQ_MSG) && !link_fully_up) {
- rbuf = tipc_disc_init_msg(DSC_RESP_MSG, b_ptr);
+ rbuf = tipc_buf_acquire(INT_H_SIZE);
if (rbuf) {
- tipc_bearer_send(b_ptr, rbuf, &media_addr);
+ tipc_disc_init_msg(rbuf, DSC_RESP_MSG, b_ptr);
+ tipc_bearer_send(b_ptr->identity, rbuf, &media_addr);
kfree_skb(rbuf);
}
}
@@ -303,7 +303,7 @@ static void disc_timeout(struct tipc_link_req *req)
spin_lock_bh(&req->lock);
/* Stop searching if only desired node has been found */
- if (tipc_node(req->bearer->domain) && req->num_nodes) {
+ if (tipc_node(req->domain) && req->num_nodes) {
req->timer_intv = TIPC_LINK_REQ_INACTIVE;
goto exit;
}
@@ -315,7 +315,7 @@ static void disc_timeout(struct tipc_link_req *req)
* hold at fast polling rate if don't have any associated nodes,
* otherwise hold at slow polling rate
*/
- tipc_bearer_send(req->bearer, req->buf, &req->dest);
+ tipc_bearer_send(req->bearer_id, req->buf, &req->dest);
req->timer_intv *= 2;
@@ -347,21 +347,23 @@ int tipc_disc_create(struct tipc_bearer *b_ptr, struct tipc_media_addr *dest)
if (!req)
return -ENOMEM;
- req->buf = tipc_disc_init_msg(DSC_REQ_MSG, b_ptr);
+ req->buf = tipc_buf_acquire(INT_H_SIZE);
if (!req->buf) {
kfree(req);
- return -ENOMSG;
+ return -ENOMEM;
}
+ tipc_disc_init_msg(req->buf, DSC_REQ_MSG, b_ptr);
memcpy(&req->dest, dest, sizeof(*dest));
- req->bearer = b_ptr;
+ req->bearer_id = b_ptr->identity;
+ req->domain = b_ptr->domain;
req->num_nodes = 0;
req->timer_intv = TIPC_LINK_REQ_INIT;
spin_lock_init(&req->lock);
k_init_timer(&req->timer, (Handler)disc_timeout, (unsigned long)req);
k_start_timer(&req->timer, req->timer_intv);
b_ptr->link_req = req;
- tipc_bearer_send(req->bearer, req->buf, &req->dest);
+ tipc_bearer_send(req->bearer_id, req->buf, &req->dest);
return 0;
}
@@ -376,3 +378,23 @@ void tipc_disc_delete(struct tipc_link_req *req)
kfree_skb(req->buf);
kfree(req);
}
+
+/**
+ * tipc_disc_reset - reset object to send periodic link setup requests
+ * @b_ptr: ptr to bearer issuing requests
+ * @dest_domain: network domain to which links can be established
+ */
+void tipc_disc_reset(struct tipc_bearer *b_ptr)
+{
+ struct tipc_link_req *req = b_ptr->link_req;
+
+ spin_lock_bh(&req->lock);
+ tipc_disc_init_msg(req->buf, DSC_REQ_MSG, b_ptr);
+ req->bearer_id = b_ptr->identity;
+ req->domain = b_ptr->domain;
+ req->num_nodes = 0;
+ req->timer_intv = TIPC_LINK_REQ_INIT;
+ k_start_timer(&req->timer, req->timer_intv);
+ tipc_bearer_send(req->bearer_id, req->buf, &req->dest);
+ spin_unlock_bh(&req->lock);
+}
diff --git a/net/tipc/discover.h b/net/tipc/discover.h
index 07f3472..515b573 100644
--- a/net/tipc/discover.h
+++ b/net/tipc/discover.h
@@ -41,6 +41,7 @@ struct tipc_link_req;
int tipc_disc_create(struct tipc_bearer *b_ptr, struct tipc_media_addr *dest);
void tipc_disc_delete(struct tipc_link_req *req);
+void tipc_disc_reset(struct tipc_bearer *b_ptr);
void tipc_disc_add_dest(struct tipc_link_req *req);
void tipc_disc_remove_dest(struct tipc_link_req *req);
void tipc_disc_rcv(struct sk_buff *buf, struct tipc_bearer *b_ptr);
diff --git a/net/tipc/link.c b/net/tipc/link.c
index c5190ab..c723ee9 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -101,9 +101,18 @@ static unsigned int align(unsigned int i)
static void link_init_max_pkt(struct tipc_link *l_ptr)
{
+ struct tipc_bearer *b_ptr;
u32 max_pkt;
- max_pkt = (l_ptr->b_ptr->mtu & ~3);
+ rcu_read_lock();
+ b_ptr = rcu_dereference_rtnl(bearer_list[l_ptr->bearer_id]);
+ if (!b_ptr) {
+ rcu_read_unlock();
+ return;
+ }
+ max_pkt = (b_ptr->mtu & ~3);
+ rcu_read_unlock();
+
if (max_pkt > MAX_MSG_SIZE)
max_pkt = MAX_MSG_SIZE;
@@ -248,7 +257,7 @@ struct tipc_link *tipc_link_create(struct tipc_node *n_ptr,
l_ptr->owner = n_ptr;
l_ptr->checkpoint = 1;
l_ptr->peer_session = INVALID_SESSION;
- l_ptr->b_ptr = b_ptr;
+ l_ptr->bearer_id = b_ptr->identity;
link_set_supervision_props(l_ptr, b_ptr->tolerance);
l_ptr->state = RESET_UNKNOWN;
@@ -263,6 +272,7 @@ struct tipc_link *tipc_link_create(struct tipc_node *n_ptr,
l_ptr->priority = b_ptr->priority;
tipc_link_set_queue_limits(l_ptr, b_ptr->window);
+ l_ptr->net_plane = b_ptr->net_plane;
link_init_max_pkt(l_ptr);
l_ptr->next_out_no = 1;
@@ -426,7 +436,7 @@ void tipc_link_reset(struct tipc_link *l_ptr)
return;
tipc_node_link_down(l_ptr->owner, l_ptr);
- tipc_bearer_remove_dest(l_ptr->b_ptr, l_ptr->addr);
+ tipc_bearer_remove_dest(l_ptr->bearer_id, l_ptr->addr);
if (was_active_link && tipc_node_active_links(l_ptr->owner)) {
l_ptr->reset_checkpoint = checkpoint;
@@ -477,7 +487,7 @@ static void link_activate(struct tipc_link *l_ptr)
{
l_ptr->next_in_no = l_ptr->stats.recv_info = 1;
tipc_node_link_up(l_ptr->owner, l_ptr);
- tipc_bearer_add_dest(l_ptr->b_ptr, l_ptr->addr);
+ tipc_bearer_add_dest(l_ptr->bearer_id, l_ptr->addr);
}
/**
@@ -777,7 +787,7 @@ int __tipc_link_xmit(struct tipc_link *l_ptr, struct sk_buff *buf)
if (likely(!link_congested(l_ptr))) {
link_add_to_outqueue(l_ptr, buf, msg);
- tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr);
+ tipc_bearer_send(l_ptr->bearer_id, buf, &l_ptr->media_addr);
l_ptr->unacked_window = 0;
return dsz;
}
@@ -825,7 +835,6 @@ int tipc_link_xmit(struct sk_buff *buf, u32 dest, u32 selector)
struct tipc_node *n_ptr;
int res = -ELINKCONG;
- read_lock_bh(&tipc_net_lock);
n_ptr = tipc_node_find(dest);
if (n_ptr) {
tipc_node_lock(n_ptr);
@@ -838,7 +847,6 @@ int tipc_link_xmit(struct sk_buff *buf, u32 dest, u32 selector)
} else {
kfree_skb(buf);
}
- read_unlock_bh(&tipc_net_lock);
return res;
}
@@ -902,7 +910,6 @@ void tipc_link_names_xmit(struct list_head *message_list, u32 dest)
if (list_empty(message_list))
return;
- read_lock_bh(&tipc_net_lock);
n_ptr = tipc_node_find(dest);
if (n_ptr) {
tipc_node_lock(n_ptr);
@@ -917,7 +924,6 @@ void tipc_link_names_xmit(struct list_head *message_list, u32 dest)
}
tipc_node_unlock(n_ptr);
}
- read_unlock_bh(&tipc_net_lock);
/* discard the messages if they couldn't be sent */
list_for_each_safe(buf, temp_buf, ((struct sk_buff *)message_list)) {
@@ -941,7 +947,7 @@ static int tipc_link_xmit_fast(struct tipc_link *l_ptr, struct sk_buff *buf,
if (likely(!link_congested(l_ptr))) {
if (likely(msg_size(msg) <= l_ptr->max_pkt)) {
link_add_to_outqueue(l_ptr, buf, msg);
- tipc_bearer_send(l_ptr->b_ptr, buf,
+ tipc_bearer_send(l_ptr->bearer_id, buf,
&l_ptr->media_addr);
l_ptr->unacked_window = 0;
return res;
@@ -979,7 +985,6 @@ again:
if (unlikely(res < 0))
return res;
- read_lock_bh(&tipc_net_lock);
node = tipc_node_find(destaddr);
if (likely(node)) {
tipc_node_lock(node);
@@ -990,7 +995,6 @@ again:
&sender->max_pkt);
exit:
tipc_node_unlock(node);
- read_unlock_bh(&tipc_net_lock);
return res;
}
@@ -1007,7 +1011,6 @@ exit:
*/
sender->max_pkt = l_ptr->max_pkt;
tipc_node_unlock(node);
- read_unlock_bh(&tipc_net_lock);
if ((msg_hdr_sz(hdr) + res) <= sender->max_pkt)
@@ -1018,7 +1021,6 @@ exit:
}
tipc_node_unlock(node);
}
- read_unlock_bh(&tipc_net_lock);
/* Couldn't find a link to the destination node */
kfree_skb(buf);
@@ -1204,7 +1206,7 @@ static u32 tipc_link_push_packet(struct tipc_link *l_ptr)
if (r_q_size && buf) {
msg_set_ack(buf_msg(buf), mod(l_ptr->next_in_no - 1));
msg_set_bcast_ack(buf_msg(buf), l_ptr->owner->bclink.last_in);
- tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr);
+ tipc_bearer_send(l_ptr->bearer_id, buf, &l_ptr->media_addr);
l_ptr->retransm_queue_head = mod(++r_q_head);
l_ptr->retransm_queue_size = --r_q_size;
l_ptr->stats.retransmitted++;
@@ -1216,7 +1218,7 @@ static u32 tipc_link_push_packet(struct tipc_link *l_ptr)
if (buf) {
msg_set_ack(buf_msg(buf), mod(l_ptr->next_in_no - 1));
msg_set_bcast_ack(buf_msg(buf), l_ptr->owner->bclink.last_in);
- tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr);
+ tipc_bearer_send(l_ptr->bearer_id, buf, &l_ptr->media_addr);
l_ptr->unacked_window = 0;
kfree_skb(buf);
l_ptr->proto_msg_queue = NULL;
@@ -1233,7 +1235,8 @@ static u32 tipc_link_push_packet(struct tipc_link *l_ptr)
if (mod(next - first) < l_ptr->queue_limit[0]) {
msg_set_ack(msg, mod(l_ptr->next_in_no - 1));
msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in);
- tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr);
+ tipc_bearer_send(l_ptr->bearer_id, buf,
+ &l_ptr->media_addr);
if (msg_user(msg) == MSG_BUNDLER)
msg_set_type(msg, CLOSED_MSG);
l_ptr->next_out = buf->next;
@@ -1262,12 +1265,9 @@ static void link_reset_all(unsigned long addr)
char addr_string[16];
u32 i;
- read_lock_bh(&tipc_net_lock);
n_ptr = tipc_node_find((u32)addr);
- if (!n_ptr) {
- read_unlock_bh(&tipc_net_lock);
+ if (!n_ptr)
return; /* node no longer exists */
- }
tipc_node_lock(n_ptr);
@@ -1282,7 +1282,6 @@ static void link_reset_all(unsigned long addr)
}
tipc_node_unlock(n_ptr);
- read_unlock_bh(&tipc_net_lock);
}
static void link_retransmit_failure(struct tipc_link *l_ptr,
@@ -1352,7 +1351,7 @@ void tipc_link_retransmit(struct tipc_link *l_ptr, struct sk_buff *buf,
msg = buf_msg(buf);
msg_set_ack(msg, mod(l_ptr->next_in_no - 1));
msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in);
- tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr);
+ tipc_bearer_send(l_ptr->bearer_id, buf, &l_ptr->media_addr);
buf = buf->next;
retransmits--;
l_ptr->stats.retransmitted++;
@@ -1440,14 +1439,13 @@ static int link_recv_buf_validate(struct sk_buff *buf)
/**
* tipc_rcv - process TIPC packets/messages arriving from off-node
* @head: pointer to message buffer chain
- * @tb_ptr: pointer to bearer message arrived on
+ * @b_ptr: pointer to bearer message arrived on
*
* Invoked with no locks held. Bearer pointer must point to a valid bearer
* structure (i.e. cannot be NULL), but bearer can be inactive.
*/
void tipc_rcv(struct sk_buff *head, struct tipc_bearer *b_ptr)
{
- read_lock_bh(&tipc_net_lock);
while (head) {
struct tipc_node *n_ptr;
struct tipc_link *l_ptr;
@@ -1635,7 +1633,6 @@ unlock_discard:
discard:
kfree_skb(buf);
}
- read_unlock_bh(&tipc_net_lock);
}
/**
@@ -1752,7 +1749,7 @@ void tipc_link_proto_xmit(struct tipc_link *l_ptr, u32 msg_typ, int probe_msg,
/* Create protocol message with "out-of-sequence" sequence number */
msg_set_type(msg, msg_typ);
- msg_set_net_plane(msg, l_ptr->b_ptr->net_plane);
+ msg_set_net_plane(msg, l_ptr->net_plane);
msg_set_bcast_ack(msg, l_ptr->owner->bclink.last_in);
msg_set_last_bcast(msg, tipc_bclink_get_last_sent());
@@ -1818,7 +1815,7 @@ void tipc_link_proto_xmit(struct tipc_link *l_ptr, u32 msg_typ, int probe_msg,
skb_copy_to_linear_data(buf, msg, sizeof(l_ptr->proto_msg));
buf->priority = TC_PRIO_CONTROL;
- tipc_bearer_send(l_ptr->b_ptr, buf, &l_ptr->media_addr);
+ tipc_bearer_send(l_ptr->bearer_id, buf, &l_ptr->media_addr);
l_ptr->unacked_window = 0;
kfree_skb(buf);
}
@@ -1843,9 +1840,9 @@ static void tipc_link_proto_rcv(struct tipc_link *l_ptr, struct sk_buff *buf)
/* record unnumbered packet arrival (force mismatch on next timeout) */
l_ptr->checkpoint--;
- if (l_ptr->b_ptr->net_plane != msg_net_plane(msg))
+ if (l_ptr->net_plane != msg_net_plane(msg))
if (tipc_own_addr > msg_prevnode(msg))
- l_ptr->b_ptr->net_plane = msg_net_plane(msg);
+ l_ptr->net_plane = msg_net_plane(msg);
switch (msg_type(msg)) {
@@ -2397,8 +2394,6 @@ void tipc_link_set_queue_limits(struct tipc_link *l_ptr, u32 window)
/* tipc_link_find_owner - locate owner node of link by link's name
* @name: pointer to link name string
* @bearer_id: pointer to index in 'node->links' array where the link was found.
- * Caller must hold 'tipc_net_lock' to ensure node and bearer are not deleted;
- * this also prevents link deletion.
*
* Returns pointer to node owning the link, or 0 if no matching link is found.
*/
@@ -2460,7 +2455,7 @@ static int link_value_is_valid(u16 cmd, u32 new_value)
* @new_value: new value of link, bearer, or media setting
* @cmd: which link, bearer, or media attribute to set (TIPC_CMD_SET_LINK_*)
*
- * Caller must hold 'tipc_net_lock' to ensure link/bearer/media is not deleted.
+ * Caller must hold RTNL lock to ensure link/bearer/media is not deleted.
*
* Returns 0 if value updated and negative value on error.
*/
@@ -2566,9 +2561,7 @@ struct sk_buff *tipc_link_cmd_config(const void *req_tlv_area, int req_tlv_space
" (cannot change setting on broadcast link)");
}
- read_lock_bh(&tipc_net_lock);
res = link_cmd_set_value(args->name, new_value, cmd);
- read_unlock_bh(&tipc_net_lock);
if (res)
return tipc_cfg_reply_error_string("cannot change link setting");
@@ -2602,22 +2595,18 @@ struct sk_buff *tipc_link_cmd_reset_stats(const void *req_tlv_area, int req_tlv_
return tipc_cfg_reply_error_string("link not found");
return tipc_cfg_reply_none();
}
- read_lock_bh(&tipc_net_lock);
node = tipc_link_find_owner(link_name, &bearer_id);
- if (!node) {
- read_unlock_bh(&tipc_net_lock);
+ if (!node)
return tipc_cfg_reply_error_string("link not found");
- }
+
tipc_node_lock(node);
l_ptr = node->links[bearer_id];
if (!l_ptr) {
tipc_node_unlock(node);
- read_unlock_bh(&tipc_net_lock);
return tipc_cfg_reply_error_string("link not found");
}
link_reset_statistics(l_ptr);
tipc_node_unlock(node);
- read_unlock_bh(&tipc_net_lock);
return tipc_cfg_reply_none();
}
@@ -2650,18 +2639,15 @@ static int tipc_link_stats(const char *name, char *buf, const u32 buf_size)
if (!strcmp(name, tipc_bclink_name))
return tipc_bclink_stats(buf, buf_size);
- read_lock_bh(&tipc_net_lock);
node = tipc_link_find_owner(name, &bearer_id);
- if (!node) {
- read_unlock_bh(&tipc_net_lock);
+ if (!node)
return 0;
- }
+
tipc_node_lock(node);
l = node->links[bearer_id];
if (!l) {
tipc_node_unlock(node);
- read_unlock_bh(&tipc_net_lock);
return 0;
}
@@ -2727,7 +2713,6 @@ static int tipc_link_stats(const char *name, char *buf, const u32 buf_size)
(s->accu_queue_sz / s->queue_sz_counts) : 0);
tipc_node_unlock(node);
- read_unlock_bh(&tipc_net_lock);
return ret;
}
@@ -2778,7 +2763,6 @@ u32 tipc_link_get_max_pkt(u32 dest, u32 selector)
if (dest == tipc_own_addr)
return MAX_MSG_SIZE;
- read_lock_bh(&tipc_net_lock);
n_ptr = tipc_node_find(dest);
if (n_ptr) {
tipc_node_lock(n_ptr);
@@ -2787,13 +2771,18 @@ u32 tipc_link_get_max_pkt(u32 dest, u32 selector)
res = l_ptr->max_pkt;
tipc_node_unlock(n_ptr);
}
- read_unlock_bh(&tipc_net_lock);
return res;
}
static void link_print(struct tipc_link *l_ptr, const char *str)
{
- pr_info("%s Link %x<%s>:", str, l_ptr->addr, l_ptr->b_ptr->name);
+ struct tipc_bearer *b_ptr;
+
+ rcu_read_lock();
+ b_ptr = rcu_dereference_rtnl(bearer_list[l_ptr->bearer_id]);
+ if (b_ptr)
+ pr_info("%s Link %x<%s>:", str, l_ptr->addr, b_ptr->name);
+ rcu_read_unlock();
if (link_working_unknown(l_ptr))
pr_cont(":WU\n");
diff --git a/net/tipc/link.h b/net/tipc/link.h
index 8c0b49b..4b556c1 100644
--- a/net/tipc/link.h
+++ b/net/tipc/link.h
@@ -107,7 +107,7 @@ struct tipc_stats {
* @checkpoint: reference point for triggering link continuity checking
* @peer_session: link session # being used by peer end of link
* @peer_bearer_id: bearer id used by link's peer endpoint
- * @b_ptr: pointer to bearer used by link
+ * @bearer_id: local bearer id used by link
* @tolerance: minimum link continuity loss needed to reset link [in ms]
* @continuity_interval: link continuity testing interval [in ms]
* @abort_limit: # of unacknowledged continuity probes needed to reset link
@@ -116,6 +116,7 @@ struct tipc_stats {
* @proto_msg: template for control messages generated by link
* @pmsg: convenience pointer to "proto_msg" field
* @priority: current link priority
+ * @net_plane: current link network plane ('A' through 'H')
* @queue_limit: outbound message queue congestion thresholds (indexed by user)
* @exp_msg_count: # of tunnelled messages expected during link changeover
* @reset_checkpoint: seq # of last acknowledged message at time of link reset
@@ -155,7 +156,7 @@ struct tipc_link {
u32 checkpoint;
u32 peer_session;
u32 peer_bearer_id;
- struct tipc_bearer *b_ptr;
+ u32 bearer_id;
u32 tolerance;
u32 continuity_interval;
u32 abort_limit;
@@ -167,6 +168,7 @@ struct tipc_link {
} proto_msg;
struct tipc_msg *pmsg;
u32 priority;
+ char net_plane;
u32 queue_limit[15]; /* queue_limit[0]==window limit */
/* Changeover */
diff --git a/net/tipc/name_distr.c b/net/tipc/name_distr.c
index aff8041..974a73f 100644
--- a/net/tipc/name_distr.c
+++ b/net/tipc/name_distr.c
@@ -127,7 +127,7 @@ static struct sk_buff *named_prepare_buf(u32 type, u32 size, u32 dest)
return buf;
}
-static void named_cluster_distribute(struct sk_buff *buf)
+void named_cluster_distribute(struct sk_buff *buf)
{
struct sk_buff *buf_copy;
struct tipc_node *n_ptr;
@@ -156,7 +156,7 @@ static void named_cluster_distribute(struct sk_buff *buf)
/**
* tipc_named_publish - tell other nodes about a new publication by this node
*/
-void tipc_named_publish(struct publication *publ)
+struct sk_buff *tipc_named_publish(struct publication *publ)
{
struct sk_buff *buf;
struct distr_item *item;
@@ -165,23 +165,23 @@ void tipc_named_publish(struct publication *publ)
publ_lists[publ->scope]->size++;
if (publ->scope == TIPC_NODE_SCOPE)
- return;
+ return NULL;
buf = named_prepare_buf(PUBLICATION, ITEM_SIZE, 0);
if (!buf) {
pr_warn("Publication distribution failure\n");
- return;
+ return NULL;
}
item = (struct distr_item *)msg_data(buf_msg(buf));
publ_to_item(item, publ);
- named_cluster_distribute(buf);
+ return buf;
}
/**
* tipc_named_withdraw - tell other nodes about a withdrawn publication by this node
*/
-void tipc_named_withdraw(struct publication *publ)
+struct sk_buff *tipc_named_withdraw(struct publication *publ)
{
struct sk_buff *buf;
struct distr_item *item;
@@ -190,17 +190,17 @@ void tipc_named_withdraw(struct publication *publ)
publ_lists[publ->scope]->size--;
if (publ->scope == TIPC_NODE_SCOPE)
- return;
+ return NULL;
buf = named_prepare_buf(WITHDRAWAL, ITEM_SIZE, 0);
if (!buf) {
pr_warn("Withdrawal distribution failure\n");
- return;
+ return NULL;
}
item = (struct distr_item *)msg_data(buf_msg(buf));
publ_to_item(item, publ);
- named_cluster_distribute(buf);
+ return buf;
}
/*
@@ -248,7 +248,6 @@ void tipc_named_node_up(unsigned long nodearg)
u32 max_item_buf = 0;
/* compute maximum amount of publication data to send per message */
- read_lock_bh(&tipc_net_lock);
n_ptr = tipc_node_find(node);
if (n_ptr) {
tipc_node_lock(n_ptr);
@@ -258,7 +257,6 @@ void tipc_named_node_up(unsigned long nodearg)
ITEM_SIZE) * ITEM_SIZE;
tipc_node_unlock(n_ptr);
}
- read_unlock_bh(&tipc_net_lock);
if (!max_item_buf)
return;
diff --git a/net/tipc/name_distr.h b/net/tipc/name_distr.h
index 9b312cc..47ff829 100644
--- a/net/tipc/name_distr.h
+++ b/net/tipc/name_distr.h
@@ -39,8 +39,9 @@
#include "name_table.h"
-void tipc_named_publish(struct publication *publ);
-void tipc_named_withdraw(struct publication *publ);
+struct sk_buff *tipc_named_publish(struct publication *publ);
+struct sk_buff *tipc_named_withdraw(struct publication *publ);
+void named_cluster_distribute(struct sk_buff *buf);
void tipc_named_node_up(unsigned long node);
void tipc_named_rcv(struct sk_buff *buf);
void tipc_named_reinit(void);
diff --git a/net/tipc/name_table.c b/net/tipc/name_table.c
index 042e8e3..9d7d37d 100644
--- a/net/tipc/name_table.c
+++ b/net/tipc/name_table.c
@@ -664,6 +664,7 @@ struct publication *tipc_nametbl_publish(u32 type, u32 lower, u32 upper,
u32 scope, u32 port_ref, u32 key)
{
struct publication *publ;
+ struct sk_buff *buf = NULL;
if (table.local_publ_count >= TIPC_MAX_PUBLICATIONS) {
pr_warn("Publication failed, local publication limit reached (%u)\n",
@@ -676,9 +677,12 @@ struct publication *tipc_nametbl_publish(u32 type, u32 lower, u32 upper,
tipc_own_addr, port_ref, key);
if (likely(publ)) {
table.local_publ_count++;
- tipc_named_publish(publ);
+ buf = tipc_named_publish(publ);
}
write_unlock_bh(&tipc_nametbl_lock);
+
+ if (buf)
+ named_cluster_distribute(buf);
return publ;
}
@@ -688,15 +692,19 @@ struct publication *tipc_nametbl_publish(u32 type, u32 lower, u32 upper,
int tipc_nametbl_withdraw(u32 type, u32 lower, u32 ref, u32 key)
{
struct publication *publ;
+ struct sk_buff *buf;
write_lock_bh(&tipc_nametbl_lock);
publ = tipc_nametbl_remove_publ(type, lower, tipc_own_addr, ref, key);
if (likely(publ)) {
table.local_publ_count--;
- tipc_named_withdraw(publ);
+ buf = tipc_named_withdraw(publ);
write_unlock_bh(&tipc_nametbl_lock);
list_del_init(&publ->pport_list);
kfree(publ);
+
+ if (buf)
+ named_cluster_distribute(buf);
return 1;
}
write_unlock_bh(&tipc_nametbl_lock);
@@ -961,6 +969,7 @@ static void tipc_purge_publications(struct name_seq *seq)
list_for_each_entry_safe(publ, safe, &info->zone_list, zone_list) {
tipc_nametbl_remove_publ(publ->type, publ->lower, publ->node,
publ->ref, publ->key);
+ kfree(publ);
}
}
@@ -982,7 +991,6 @@ void tipc_nametbl_stop(void)
hlist_for_each_entry_safe(seq, safe, seq_head, ns_list) {
tipc_purge_publications(seq);
}
- continue;
}
kfree(table.types);
table.types = NULL;
diff --git a/net/tipc/net.c b/net/tipc/net.c
index 4c564eb..75bb390 100644
--- a/net/tipc/net.c
+++ b/net/tipc/net.c
@@ -45,39 +45,34 @@
/*
* The TIPC locking policy is designed to ensure a very fine locking
* granularity, permitting complete parallel access to individual
- * port and node/link instances. The code consists of three major
+ * port and node/link instances. The code consists of four major
* locking domains, each protected with their own disjunct set of locks.
*
- * 1: The routing hierarchy.
- * Comprises the structures 'zone', 'cluster', 'node', 'link'
- * and 'bearer'. The whole hierarchy is protected by a big
- * read/write lock, tipc_net_lock, to enssure that nothing is added
- * or removed while code is accessing any of these structures.
- * This layer must not be called from the two others while they
- * hold any of their own locks.
- * Neither must it itself do any upcalls to the other two before
- * it has released tipc_net_lock and other protective locks.
+ * 1: The bearer level.
+ * RTNL lock is used to serialize the process of configuring bearer
+ * on update side, and RCU lock is applied on read side to make
+ * bearer instance valid on both paths of message transmission and
+ * reception.
*
- * Within the tipc_net_lock domain there are two sub-domains;'node' and
- * 'bearer', where local write operations are permitted,
- * provided that those are protected by individual spin_locks
- * per instance. Code holding tipc_net_lock(read) and a node spin_lock
- * is permitted to poke around in both the node itself and its
- * subordinate links. I.e, it can update link counters and queues,
- * change link state, send protocol messages, and alter the
- * "active_links" array in the node; but it can _not_ remove a link
- * or a node from the overall structure.
- * Correspondingly, individual bearers may change status within a
- * tipc_net_lock(read), protected by an individual spin_lock ber bearer
- * instance, but it needs tipc_net_lock(write) to remove/add any bearers.
+ * 2: The node and link level.
+ * All node instances are saved into two tipc_node_list and node_htable
+ * lists. The two lists are protected by node_list_lock on write side,
+ * and they are guarded with RCU lock on read side. Especially node
+ * instance is destroyed only when TIPC module is removed, and we can
+ * confirm that there has no any user who is accessing the node at the
+ * moment. Therefore, Except for iterating the two lists within RCU
+ * protection, it's no needed to hold RCU that we access node instance
+ * in other places.
*
+ * In addition, all members in node structure including link instances
+ * are protected by node spin lock.
*
- * 2: The transport level of the protocol.
- * This consists of the structures port, (and its user level
- * representations, such as user_port and tipc_sock), reference and
- * tipc_user (port.c, reg.c, socket.c).
+ * 3: The transport level of the protocol.
+ * This consists of the structures port, (and its user level
+ * representations, such as user_port and tipc_sock), reference and
+ * tipc_user (port.c, reg.c, socket.c).
*
- * This layer has four different locks:
+ * This layer has four different locks:
* - The tipc_port spin_lock. This is protecting each port instance
* from parallel data access and removal. Since we can not place
* this lock in the port itself, it has been placed in the
@@ -96,7 +91,7 @@
* There are two such lists; 'port_list', which is used for management,
* and 'wait_list', which is used to queue ports during congestion.
*
- * 3: The name table (name_table.c, name_distr.c, subscription.c)
+ * 4: The name table (name_table.c, name_distr.c, subscription.c)
* - There is one big read/write-lock (tipc_nametbl_lock) protecting the
* overall name table structure. Nothing must be added/removed to
* this structure without holding write access to it.
@@ -108,8 +103,6 @@
* - A local spin_lock protecting the queue of subscriber events.
*/
-DEFINE_RWLOCK(tipc_net_lock);
-
static void net_route_named_msg(struct sk_buff *buf)
{
struct tipc_msg *msg = buf_msg(buf);
@@ -175,15 +168,13 @@ void tipc_net_start(u32 addr)
{
char addr_string[16];
- write_lock_bh(&tipc_net_lock);
tipc_own_addr = addr;
tipc_named_reinit();
tipc_port_reinit();
tipc_bclink_init();
- write_unlock_bh(&tipc_net_lock);
-
tipc_nametbl_publish(TIPC_CFG_SRV, tipc_own_addr, tipc_own_addr,
TIPC_ZONE_SCOPE, 0, tipc_own_addr);
+
pr_info("Started in network mode\n");
pr_info("Own node address %s, network identity %u\n",
tipc_addr_string_fill(addr_string, tipc_own_addr), tipc_net_id);
@@ -195,11 +186,11 @@ void tipc_net_stop(void)
return;
tipc_nametbl_withdraw(TIPC_CFG_SRV, tipc_own_addr, 0, tipc_own_addr);
- write_lock_bh(&tipc_net_lock);
+ rtnl_lock();
tipc_bearer_stop();
tipc_bclink_stop();
tipc_node_stop();
- write_unlock_bh(&tipc_net_lock);
+ rtnl_unlock();
pr_info("Left network mode\n");
}
diff --git a/net/tipc/net.h b/net/tipc/net.h
index 079daad..f781cae 100644
--- a/net/tipc/net.h
+++ b/net/tipc/net.h
@@ -37,8 +37,6 @@
#ifndef _TIPC_NET_H
#define _TIPC_NET_H
-extern rwlock_t tipc_net_lock;
-
void tipc_net_route_msg(struct sk_buff *buf);
void tipc_net_start(u32 addr);
diff --git a/net/tipc/node.c b/net/tipc/node.c
index 1d3a499..6d6543e 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -144,11 +144,13 @@ void tipc_node_stop(void)
void tipc_node_link_up(struct tipc_node *n_ptr, struct tipc_link *l_ptr)
{
struct tipc_link **active = &n_ptr->active_links[0];
+ u32 addr = n_ptr->addr;
n_ptr->working_links++;
-
+ tipc_nametbl_publish(TIPC_LINK_STATE, addr, addr, TIPC_NODE_SCOPE,
+ l_ptr->bearer_id, addr);
pr_info("Established link <%s> on network plane %c\n",
- l_ptr->name, l_ptr->b_ptr->net_plane);
+ l_ptr->name, l_ptr->net_plane);
if (!active[0]) {
active[0] = active[1] = l_ptr;
@@ -203,16 +205,18 @@ static void node_select_active_links(struct tipc_node *n_ptr)
void tipc_node_link_down(struct tipc_node *n_ptr, struct tipc_link *l_ptr)
{
struct tipc_link **active;
+ u32 addr = n_ptr->addr;
n_ptr->working_links--;
+ tipc_nametbl_withdraw(TIPC_LINK_STATE, addr, l_ptr->bearer_id, addr);
if (!tipc_link_is_active(l_ptr)) {
pr_info("Lost standby link <%s> on network plane %c\n",
- l_ptr->name, l_ptr->b_ptr->net_plane);
+ l_ptr->name, l_ptr->net_plane);
return;
}
pr_info("Lost link <%s> on network plane %c\n",
- l_ptr->name, l_ptr->b_ptr->net_plane);
+ l_ptr->name, l_ptr->net_plane);
active = &n_ptr->active_links[0];
if (active[0] == l_ptr)
@@ -239,7 +243,7 @@ int tipc_node_is_up(struct tipc_node *n_ptr)
void tipc_node_attach_link(struct tipc_node *n_ptr, struct tipc_link *l_ptr)
{
- n_ptr->links[l_ptr->b_ptr->identity] = l_ptr;
+ n_ptr->links[l_ptr->bearer_id] = l_ptr;
spin_lock_bh(&node_list_lock);
tipc_num_links++;
spin_unlock_bh(&node_list_lock);
@@ -273,14 +277,12 @@ static void node_name_purge_complete(unsigned long node_addr)
{
struct tipc_node *n_ptr;
- read_lock_bh(&tipc_net_lock);
n_ptr = tipc_node_find(node_addr);
if (n_ptr) {
tipc_node_lock(n_ptr);
n_ptr->block_setup &= ~WAIT_NAMES_GONE;
tipc_node_unlock(n_ptr);
}
- read_unlock_bh(&tipc_net_lock);
}
static void node_lost_contact(struct tipc_node *n_ptr)
@@ -436,3 +438,30 @@ struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space)
rcu_read_unlock();
return buf;
}
+
+/**
+ * tipc_node_get_linkname - get the name of a link
+ *
+ * @bearer_id: id of the bearer
+ * @node: peer node address
+ * @linkname: link name output buffer
+ *
+ * Returns 0 on success
+ */
+int tipc_node_get_linkname(u32 bearer_id, u32 addr, char *linkname, size_t len)
+{
+ struct tipc_link *link;
+ struct tipc_node *node = tipc_node_find(addr);
+
+ if ((bearer_id >= MAX_BEARERS) || !node)
+ return -EINVAL;
+ tipc_node_lock(node);
+ link = node->links[bearer_id];
+ if (link) {
+ strncpy(linkname, link->name, len);
+ tipc_node_unlock(node);
+ return 0;
+ }
+ tipc_node_unlock(node);
+ return -EINVAL;
+}
diff --git a/net/tipc/node.h b/net/tipc/node.h
index 7cbb8ce..411b191 100644
--- a/net/tipc/node.h
+++ b/net/tipc/node.h
@@ -118,6 +118,7 @@ int tipc_node_active_links(struct tipc_node *n_ptr);
int tipc_node_is_up(struct tipc_node *n_ptr);
struct sk_buff *tipc_node_get_links(const void *req_tlv_area, int req_tlv_space);
struct sk_buff *tipc_node_get_nodes(const void *req_tlv_area, int req_tlv_space);
+int tipc_node_get_linkname(u32 bearer_id, u32 node, char *linkname, size_t len);
static inline void tipc_node_lock(struct tipc_node *n_ptr)
{
diff --git a/net/tipc/socket.c b/net/tipc/socket.c
index 3c02569..3f9912f 100644
--- a/net/tipc/socket.c
+++ b/net/tipc/socket.c
@@ -36,6 +36,7 @@
#include "core.h"
#include "port.h"
+#include "node.h"
#include <linux/export.h>
@@ -1905,6 +1906,28 @@ static int tipc_getsockopt(struct socket *sock, int lvl, int opt,
return put_user(sizeof(value), ol);
}
+int tipc_ioctl(struct socket *sk, unsigned int cmd, unsigned long arg)
+{
+ struct tipc_sioc_ln_req lnr;
+ void __user *argp = (void __user *)arg;
+
+ switch (cmd) {
+ case SIOCGETLINKNAME:
+ if (copy_from_user(&lnr, argp, sizeof(lnr)))
+ return -EFAULT;
+ if (!tipc_node_get_linkname(lnr.bearer_id, lnr.peer,
+ lnr.linkname, TIPC_MAX_LINK_NAME)) {
+ if (copy_to_user(argp, &lnr, sizeof(lnr)))
+ return -EFAULT;
+ return 0;
+ }
+ return -EADDRNOTAVAIL;
+ break;
+ default:
+ return -ENOIOCTLCMD;
+ }
+}
+
/* Protocol switches for the various types of TIPC sockets */
static const struct proto_ops msg_ops = {
@@ -1917,7 +1940,7 @@ static const struct proto_ops msg_ops = {
.accept = sock_no_accept,
.getname = tipc_getname,
.poll = tipc_poll,
- .ioctl = sock_no_ioctl,
+ .ioctl = tipc_ioctl,
.listen = sock_no_listen,
.shutdown = tipc_shutdown,
.setsockopt = tipc_setsockopt,
@@ -1938,7 +1961,7 @@ static const struct proto_ops packet_ops = {
.accept = tipc_accept,
.getname = tipc_getname,
.poll = tipc_poll,
- .ioctl = sock_no_ioctl,
+ .ioctl = tipc_ioctl,
.listen = tipc_listen,
.shutdown = tipc_shutdown,
.setsockopt = tipc_setsockopt,
@@ -1959,7 +1982,7 @@ static const struct proto_ops stream_ops = {
.accept = tipc_accept,
.getname = tipc_getname,
.poll = tipc_poll,
- .ioctl = sock_no_ioctl,
+ .ioctl = tipc_ioctl,
.listen = tipc_listen,
.shutdown = tipc_shutdown,
.setsockopt = tipc_setsockopt,
diff --git a/security/selinux/include/classmap.h b/security/selinux/include/classmap.h
index 14d04e6..be491a7 100644
--- a/security/selinux/include/classmap.h
+++ b/security/selinux/include/classmap.h
@@ -147,7 +147,7 @@ struct security_class_mapping secclass_map[] = {
{ "peer", { "recv", NULL } },
{ "capability2",
{ "mac_override", "mac_admin", "syslog", "wake_alarm", "block_suspend",
- NULL } },
+ "audit_read", NULL } },
{ "kernel_service", { "use_as_override", "create_files_as", NULL } },
{ "tun_socket",
{ COMMON_SOCK_PERMS, "attach_queue", NULL } },
diff --git a/sound/isa/es18xx.c b/sound/isa/es18xx.c
index 1c16830..6faaac6 100644
--- a/sound/isa/es18xx.c
+++ b/sound/isa/es18xx.c
@@ -520,7 +520,7 @@ static int snd_es18xx_playback1_trigger(struct snd_es18xx *chip,
snd_es18xx_mixer_write(chip, 0x78, 0x93);
#ifdef AVOID_POPS
/* Avoid pops */
- udelay(100000);
+ mdelay(100);
if (chip->caps & ES18XX_PCM2)
/* Restore Audio 2 volume */
snd_es18xx_mixer_write(chip, 0x7C, chip->audio2_vol);
@@ -537,7 +537,7 @@ static int snd_es18xx_playback1_trigger(struct snd_es18xx *chip,
/* Stop DMA */
snd_es18xx_mixer_write(chip, 0x78, 0x00);
#ifdef AVOID_POPS
- udelay(25000);
+ mdelay(25);
if (chip->caps & ES18XX_PCM2)
/* Set Audio 2 volume to 0 */
snd_es18xx_mixer_write(chip, 0x7C, 0);
@@ -596,7 +596,7 @@ static int snd_es18xx_capture_prepare(struct snd_pcm_substream *substream)
snd_es18xx_write(chip, 0xA5, count >> 8);
#ifdef AVOID_POPS
- udelay(100000);
+ mdelay(100);
#endif
/* Set format */
@@ -691,7 +691,7 @@ static int snd_es18xx_playback2_trigger(struct snd_es18xx *chip,
snd_es18xx_write(chip, 0xB8, 0x05);
#ifdef AVOID_POPS
/* Avoid pops */
- udelay(100000);
+ mdelay(100);
/* Enable Audio 1 */
snd_es18xx_dsp_command(chip, 0xD1);
#endif
@@ -705,7 +705,7 @@ static int snd_es18xx_playback2_trigger(struct snd_es18xx *chip,
snd_es18xx_write(chip, 0xB8, 0x00);
#ifdef AVOID_POPS
/* Avoid pops */
- udelay(25000);
+ mdelay(25);
/* Disable Audio 1 */
snd_es18xx_dsp_command(chip, 0xD3);
#endif
diff --git a/sound/pci/hda/patch_realtek.c b/sound/pci/hda/patch_realtek.c
index 14ae979..c643dfc 100644
--- a/sound/pci/hda/patch_realtek.c
+++ b/sound/pci/hda/patch_realtek.c
@@ -4621,6 +4621,7 @@ static const struct snd_pci_quirk alc269_fixup_tbl[] = {
SND_PCI_QUIRK(0x1028, 0x0667, "Dell", ALC269_FIXUP_DELL1_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1028, 0x0668, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1028, 0x0669, "Dell", ALC255_FIXUP_DELL2_MIC_NO_PRESENCE),
+ SND_PCI_QUIRK(0x1028, 0x067f, "Dell", ALC255_FIXUP_DELL1_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1028, 0x15cc, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1028, 0x15cd, "Dell X5 Precision", ALC269_FIXUP_DELL2_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x103c, 0x1586, "HP", ALC269_FIXUP_HP_MUTE_LED_MIC2),
@@ -4912,6 +4913,7 @@ static int patch_alc269(struct hda_codec *codec)
spec->codec_variant = ALC269_TYPE_ALC285;
break;
case 0x10ec0286:
+ case 0x10ec0288:
spec->codec_variant = ALC269_TYPE_ALC286;
break;
case 0x10ec0255:
@@ -5539,6 +5541,8 @@ static const struct snd_pci_quirk alc662_fixup_tbl[] = {
SND_PCI_QUIRK(0x1028, 0x0626, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x1028, 0x0628, "Dell", ALC668_FIXUP_AUTO_MUTE),
SND_PCI_QUIRK(0x1028, 0x064e, "Dell", ALC668_FIXUP_AUTO_MUTE),
+ SND_PCI_QUIRK(0x1028, 0x0696, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
+ SND_PCI_QUIRK(0x1028, 0x0698, "Dell", ALC668_FIXUP_DELL_MIC_NO_PRESENCE),
SND_PCI_QUIRK(0x103c, 0x1632, "HP RP5800", ALC662_FIXUP_HP_RP5800),
SND_PCI_QUIRK(0x1043, 0x11cd, "Asus N550", ALC662_FIXUP_BASS_1A),
SND_PCI_QUIRK(0x1043, 0x1477, "ASUS N56VZ", ALC662_FIXUP_BASS_MODE4_CHMAP),
@@ -5781,6 +5785,7 @@ static const struct hda_codec_preset snd_hda_preset_realtek[] = {
{ .id = 0x10ec0284, .name = "ALC284", .patch = patch_alc269 },
{ .id = 0x10ec0285, .name = "ALC285", .patch = patch_alc269 },
{ .id = 0x10ec0286, .name = "ALC286", .patch = patch_alc269 },
+ { .id = 0x10ec0288, .name = "ALC288", .patch = patch_alc269 },
{ .id = 0x10ec0290, .name = "ALC290", .patch = patch_alc269 },
{ .id = 0x10ec0292, .name = "ALC292", .patch = patch_alc269 },
{ .id = 0x10ec0293, .name = "ALC293", .patch = patch_alc269 },
diff --git a/tools/hv/hv_fcopy_daemon.c b/tools/hv/hv_fcopy_daemon.c
index 4ecc4fd..fba1c75 100644
--- a/tools/hv/hv_fcopy_daemon.c
+++ b/tools/hv/hv_fcopy_daemon.c
@@ -82,8 +82,10 @@ static int hv_start_fcopy(struct hv_start_fcopy *smsg)
if (!access(target_fname, F_OK)) {
syslog(LOG_INFO, "File: %s exists", target_fname);
- if (!smsg->copy_flags & OVER_WRITE)
+ if (!(smsg->copy_flags & OVER_WRITE)) {
+ error = HV_ERROR_ALREADY_EXISTS;
goto done;
+ }
}
target_fd = open(target_fname, O_RDWR | O_CREAT | O_CLOEXEC, 0744);
diff --git a/tools/lib/lockdep/Makefile b/tools/lib/lockdep/Makefile
index 07b0b75..cb09d3f 100644
--- a/tools/lib/lockdep/Makefile
+++ b/tools/lib/lockdep/Makefile
@@ -1,13 +1,8 @@
-# liblockdep version
-LL_VERSION = 0
-LL_PATCHLEVEL = 0
-LL_EXTRAVERSION = 1
-
# file format version
FILE_VERSION = 1
MAKEFLAGS += --no-print-directory
-
+LIBLOCKDEP_VERSION=$(shell make -sC ../../.. kernelversion)
# Makefiles suck: This macro sets a default value of $(2) for the
# variable named by $(1), unless the variable has been set by
@@ -98,7 +93,7 @@ export prefix libdir bindir src obj
libdir_SQ = $(subst ','\'',$(libdir))
bindir_SQ = $(subst ','\'',$(bindir))
-LIB_FILE = liblockdep.a liblockdep.so
+LIB_FILE = liblockdep.a liblockdep.so.$(LIBLOCKDEP_VERSION)
BIN_FILE = lockdep
CONFIG_INCLUDES =
@@ -110,8 +105,6 @@ N =
export Q VERBOSE
-LIBLOCKDEP_VERSION = $(LL_VERSION).$(LL_PATCHLEVEL).$(LL_EXTRAVERSION)
-
INCLUDES = -I. -I/usr/local/include -I./uinclude -I./include $(CONFIG_INCLUDES)
# Set compile option CFLAGS if not set elsewhere
@@ -146,7 +139,7 @@ do_app_build = \
do_compile_shared_library = \
($(print_shared_lib_compile) \
- $(CC) --shared $^ -o $@ -lpthread -ldl)
+ $(CC) --shared $^ -o $@ -lpthread -ldl -Wl,-soname='"$@"';$(shell ln -s $@ liblockdep.so))
do_build_static_lib = \
($(print_static_lib_build) \
@@ -177,7 +170,7 @@ all: all_cmd
all_cmd: $(CMD_TARGETS)
-liblockdep.so: $(PEVENT_LIB_OBJS)
+liblockdep.so.$(LIBLOCKDEP_VERSION): $(PEVENT_LIB_OBJS)
$(Q)$(do_compile_shared_library)
liblockdep.a: $(PEVENT_LIB_OBJS)
diff --git a/tools/lib/lockdep/uinclude/linux/lockdep.h b/tools/lib/lockdep/uinclude/linux/lockdep.h
index d0f5d6e..c1552c2 100644
--- a/tools/lib/lockdep/uinclude/linux/lockdep.h
+++ b/tools/lib/lockdep/uinclude/linux/lockdep.h
@@ -10,6 +10,9 @@
#define MAX_LOCK_DEPTH 2000UL
+#define asmlinkage
+#define __visible
+
#include "../../../include/linux/lockdep.h"
struct task_struct {
diff --git a/tools/lib/traceevent/event-parse.c b/tools/lib/traceevent/event-parse.c
index 1587ea39..baec7d8 100644
--- a/tools/lib/traceevent/event-parse.c
+++ b/tools/lib/traceevent/event-parse.c
@@ -50,6 +50,18 @@ static int show_warning = 1;
warning(fmt, ##__VA_ARGS__); \
} while (0)
+#define do_warning_event(event, fmt, ...) \
+ do { \
+ if (!show_warning) \
+ continue; \
+ \
+ if (event) \
+ warning("[%s:%s] " fmt, event->system, \
+ event->name, ##__VA_ARGS__); \
+ else \
+ warning(fmt, ##__VA_ARGS__); \
+ } while (0)
+
static void init_input_buf(const char *buf, unsigned long long size)
{
input_buf = buf;
@@ -1355,7 +1367,7 @@ static int event_read_fields(struct event_format *event, struct format_field **f
}
if (!field->type) {
- do_warning("%s: no type found", __func__);
+ do_warning_event(event, "%s: no type found", __func__);
goto fail;
}
field->name = last_token;
@@ -1402,7 +1414,7 @@ static int event_read_fields(struct event_format *event, struct format_field **f
free_token(token);
type = read_token(&token);
if (type == EVENT_NONE) {
- do_warning("failed to find token");
+ do_warning_event(event, "failed to find token");
goto fail;
}
}
@@ -1636,7 +1648,7 @@ process_cond(struct event_format *event, struct print_arg *top, char **tok)
right = alloc_arg();
if (!arg || !left || !right) {
- do_warning("%s: not enough memory!", __func__);
+ do_warning_event(event, "%s: not enough memory!", __func__);
/* arg will be freed at out_free */
free_arg(left);
free_arg(right);
@@ -1686,7 +1698,7 @@ process_array(struct event_format *event, struct print_arg *top, char **tok)
arg = alloc_arg();
if (!arg) {
- do_warning("%s: not enough memory!", __func__);
+ do_warning_event(event, "%s: not enough memory!", __func__);
/* '*tok' is set to top->op.op. No need to free. */
*tok = NULL;
return EVENT_ERROR;
@@ -1792,7 +1804,7 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok)
if (arg->type == PRINT_OP && !arg->op.left) {
/* handle single op */
if (token[1]) {
- do_warning("bad op token %s", token);
+ do_warning_event(event, "bad op token %s", token);
goto out_free;
}
switch (token[0]) {
@@ -1802,7 +1814,7 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok)
case '-':
break;
default:
- do_warning("bad op token %s", token);
+ do_warning_event(event, "bad op token %s", token);
goto out_free;
}
@@ -1888,7 +1900,7 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok)
char *new_atom;
if (left->type != PRINT_ATOM) {
- do_warning("bad pointer type");
+ do_warning_event(event, "bad pointer type");
goto out_free;
}
new_atom = realloc(left->atom.atom,
@@ -1930,7 +1942,7 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok)
type = process_array(event, arg, tok);
} else {
- do_warning("unknown op '%s'", token);
+ do_warning_event(event, "unknown op '%s'", token);
event->flags |= EVENT_FL_FAILED;
/* the arg is now the left side */
goto out_free;
@@ -1951,7 +1963,7 @@ process_op(struct event_format *event, struct print_arg *arg, char **tok)
return type;
out_warn_free:
- do_warning("%s: not enough memory!", __func__);
+ do_warning_event(event, "%s: not enough memory!", __func__);
out_free:
free_token(token);
*tok = NULL;
@@ -2385,7 +2397,7 @@ process_flags(struct event_format *event, struct print_arg *arg, char **tok)
field = alloc_arg();
if (!field) {
- do_warning("%s: not enough memory!", __func__);
+ do_warning_event(event, "%s: not enough memory!", __func__);
goto out_free;
}
@@ -2438,7 +2450,7 @@ process_symbols(struct event_format *event, struct print_arg *arg, char **tok)
field = alloc_arg();
if (!field) {
- do_warning("%s: not enough memory!", __func__);
+ do_warning_event(event, "%s: not enough memory!", __func__);
goto out_free;
}
@@ -2477,7 +2489,7 @@ process_hex(struct event_format *event, struct print_arg *arg, char **tok)
field = alloc_arg();
if (!field) {
- do_warning("%s: not enough memory!", __func__);
+ do_warning_event(event, "%s: not enough memory!", __func__);
goto out_free;
}
@@ -2492,7 +2504,7 @@ process_hex(struct event_format *event, struct print_arg *arg, char **tok)
field = alloc_arg();
if (!field) {
- do_warning("%s: not enough memory!", __func__);
+ do_warning_event(event, "%s: not enough memory!", __func__);
*tok = NULL;
return EVENT_ERROR;
}
@@ -2555,7 +2567,7 @@ process_dynamic_array(struct event_format *event, struct print_arg *arg, char **
free_token(token);
arg = alloc_arg();
if (!arg) {
- do_warning("%s: not enough memory!", __func__);
+ do_warning_event(event, "%s: not enough memory!", __func__);
*tok = NULL;
return EVENT_ERROR;
}
@@ -2614,13 +2626,14 @@ process_paren(struct event_format *event, struct print_arg *arg, char **tok)
/* prevous must be an atom */
if (arg->type != PRINT_ATOM) {
- do_warning("previous needed to be PRINT_ATOM");
+ do_warning_event(event, "previous needed to be PRINT_ATOM");
goto out_free;
}
item_arg = alloc_arg();
if (!item_arg) {
- do_warning("%s: not enough memory!", __func__);
+ do_warning_event(event, "%s: not enough memory!",
+ __func__);
goto out_free;
}
@@ -2721,21 +2734,24 @@ process_func_handler(struct event_format *event, struct pevent_function_handler
for (i = 0; i < func->nr_args; i++) {
farg = alloc_arg();
if (!farg) {
- do_warning("%s: not enough memory!", __func__);
+ do_warning_event(event, "%s: not enough memory!",
+ __func__);
return EVENT_ERROR;
}
type = process_arg(event, farg, &token);
if (i < (func->nr_args - 1)) {
if (type != EVENT_DELIM || strcmp(token, ",") != 0) {
- warning("Error: function '%s()' expects %d arguments but event %s only uses %d",
+ do_warning_event(event,
+ "Error: function '%s()' expects %d arguments but event %s only uses %d",
func->name, func->nr_args,
event->name, i + 1);
goto err;
}
} else {
if (type != EVENT_DELIM || strcmp(token, ")") != 0) {
- warning("Error: function '%s()' only expects %d arguments but event %s has more",
+ do_warning_event(event,
+ "Error: function '%s()' only expects %d arguments but event %s has more",
func->name, func->nr_args, event->name);
goto err;
}
@@ -2792,7 +2808,7 @@ process_function(struct event_format *event, struct print_arg *arg,
return process_func_handler(event, func, arg, tok);
}
- do_warning("function %s not defined", token);
+ do_warning_event(event, "function %s not defined", token);
free_token(token);
return EVENT_ERROR;
}
@@ -2878,7 +2894,7 @@ process_arg_token(struct event_format *event, struct print_arg *arg,
case EVENT_ERROR ... EVENT_NEWLINE:
default:
- do_warning("unexpected type %d", type);
+ do_warning_event(event, "unexpected type %d", type);
return EVENT_ERROR;
}
*tok = token;
@@ -2901,7 +2917,8 @@ static int event_read_print_args(struct event_format *event, struct print_arg **
arg = alloc_arg();
if (!arg) {
- do_warning("%s: not enough memory!", __func__);
+ do_warning_event(event, "%s: not enough memory!",
+ __func__);
return -1;
}
@@ -3481,11 +3498,12 @@ eval_num_arg(void *data, int size, struct event_format *event, struct print_arg
return val;
out_warning_op:
- do_warning("%s: unknown op '%s'", __func__, arg->op.op);
+ do_warning_event(event, "%s: unknown op '%s'", __func__, arg->op.op);
return 0;
out_warning_field:
- do_warning("%s: field %s not found", __func__, arg->field.name);
+ do_warning_event(event, "%s: field %s not found",
+ __func__, arg->field.name);
return 0;
}
@@ -3591,7 +3609,8 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
}
str = malloc(len + 1);
if (!str) {
- do_warning("%s: not enough memory!", __func__);
+ do_warning_event(event, "%s: not enough memory!",
+ __func__);
return;
}
memcpy(str, data + field->offset, len);
@@ -3697,7 +3716,8 @@ static void print_str_arg(struct trace_seq *s, void *data, int size,
return;
out_warning_field:
- do_warning("%s: field %s not found", __func__, arg->field.name);
+ do_warning_event(event, "%s: field %s not found",
+ __func__, arg->field.name);
}
static unsigned long long
@@ -3742,14 +3762,16 @@ process_defined_func(struct trace_seq *s, void *data, int size,
trace_seq_terminate(&str);
string = malloc(sizeof(*string));
if (!string) {
- do_warning("%s(%d): malloc str", __func__, __LINE__);
+ do_warning_event(event, "%s(%d): malloc str",
+ __func__, __LINE__);
goto out_free;
}
string->next = strings;
string->str = strdup(str.buffer);
if (!string->str) {
free(string);
- do_warning("%s(%d): malloc str", __func__, __LINE__);
+ do_warning_event(event, "%s(%d): malloc str",
+ __func__, __LINE__);
goto out_free;
}
args[i] = (uintptr_t)string->str;
@@ -3761,7 +3783,7 @@ process_defined_func(struct trace_seq *s, void *data, int size,
* Something went totally wrong, this is not
* an input error, something in this code broke.
*/
- do_warning("Unexpected end of arguments\n");
+ do_warning_event(event, "Unexpected end of arguments\n");
goto out_free;
}
farg = farg->next;
@@ -3811,12 +3833,12 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc
if (!field) {
field = pevent_find_field(event, "buf");
if (!field) {
- do_warning("can't find buffer field for binary printk");
+ do_warning_event(event, "can't find buffer field for binary printk");
return NULL;
}
ip_field = pevent_find_field(event, "ip");
if (!ip_field) {
- do_warning("can't find ip field for binary printk");
+ do_warning_event(event, "can't find ip field for binary printk");
return NULL;
}
pevent->bprint_buf_field = field;
@@ -3830,7 +3852,8 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc
*/
args = alloc_arg();
if (!args) {
- do_warning("%s(%d): not enough memory!", __func__, __LINE__);
+ do_warning_event(event, "%s(%d): not enough memory!",
+ __func__, __LINE__);
return NULL;
}
arg = args;
@@ -3896,7 +3919,7 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc
bptr += vsize;
arg = alloc_arg();
if (!arg) {
- do_warning("%s(%d): not enough memory!",
+ do_warning_event(event, "%s(%d): not enough memory!",
__func__, __LINE__);
goto out_free;
}
@@ -3919,7 +3942,7 @@ static struct print_arg *make_bprint_args(char *fmt, void *data, int size, struc
case 's':
arg = alloc_arg();
if (!arg) {
- do_warning("%s(%d): not enough memory!",
+ do_warning_event(event, "%s(%d): not enough memory!",
__func__, __LINE__);
goto out_free;
}
@@ -3959,7 +3982,7 @@ get_bprint_format(void *data, int size __maybe_unused,
if (!field) {
field = pevent_find_field(event, "fmt");
if (!field) {
- do_warning("can't find format field for binary printk");
+ do_warning_event(event, "can't find format field for binary printk");
return NULL;
}
pevent->bprint_fmt_field = field;
@@ -4003,8 +4026,8 @@ static void print_mac_arg(struct trace_seq *s, int mac, void *data, int size,
arg->field.field =
pevent_find_any_field(event, arg->field.name);
if (!arg->field.field) {
- do_warning("%s: field %s not found",
- __func__, arg->field.name);
+ do_warning_event(event, "%s: field %s not found",
+ __func__, arg->field.name);
return;
}
}
@@ -4176,7 +4199,7 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event
case '*':
/* The argument is the length. */
if (!arg) {
- do_warning("no argument match");
+ do_warning_event(event, "no argument match");
event->flags |= EVENT_FL_FAILED;
goto out_failed;
}
@@ -4213,7 +4236,7 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event
case 'X':
case 'u':
if (!arg) {
- do_warning("no argument match");
+ do_warning_event(event, "no argument match");
event->flags |= EVENT_FL_FAILED;
goto out_failed;
}
@@ -4223,7 +4246,7 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event
/* should never happen */
if (len > 31) {
- do_warning("bad format!");
+ do_warning_event(event, "bad format!");
event->flags |= EVENT_FL_FAILED;
len = 31;
}
@@ -4290,13 +4313,13 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event
trace_seq_printf(s, format, (long long)val);
break;
default:
- do_warning("bad count (%d)", ls);
+ do_warning_event(event, "bad count (%d)", ls);
event->flags |= EVENT_FL_FAILED;
}
break;
case 's':
if (!arg) {
- do_warning("no matching argument");
+ do_warning_event(event, "no matching argument");
event->flags |= EVENT_FL_FAILED;
goto out_failed;
}
@@ -4306,7 +4329,7 @@ static void pretty_print(struct trace_seq *s, void *data, int size, struct event
/* should never happen */
if (len > 31) {
- do_warning("bad format!");
+ do_warning_event(event, "bad format!");
event->flags |= EVENT_FL_FAILED;
len = 31;
}
diff --git a/tools/net/bpf_exp.l b/tools/net/bpf_exp.l
index bf7be77..833a966 100644
--- a/tools/net/bpf_exp.l
+++ b/tools/net/bpf_exp.l
@@ -92,6 +92,7 @@ extern void yyerror(const char *str);
"#"?("cpu") { return K_CPU; }
"#"?("vlan_tci") { return K_VLANT; }
"#"?("vlan_pr") { return K_VLANP; }
+"#"?("rand") { return K_RAND; }
":" { return ':'; }
"," { return ','; }
diff --git a/tools/net/bpf_exp.y b/tools/net/bpf_exp.y
index d15efc9..e6306c5 100644
--- a/tools/net/bpf_exp.y
+++ b/tools/net/bpf_exp.y
@@ -56,7 +56,7 @@ static void bpf_set_jmp_label(char *label, enum jmp_type type);
%token OP_LDXI
%token K_PKT_LEN K_PROTO K_TYPE K_NLATTR K_NLATTR_NEST K_MARK K_QUEUE K_HATYPE
-%token K_RXHASH K_CPU K_IFIDX K_VLANT K_VLANP K_POFF
+%token K_RXHASH K_CPU K_IFIDX K_VLANT K_VLANP K_POFF K_RAND
%token ':' ',' '[' ']' '(' ')' 'x' 'a' '+' 'M' '*' '&' '#' '%'
@@ -164,6 +164,9 @@ ldb
| OP_LDB K_POFF {
bpf_set_curr_instr(BPF_LD | BPF_B | BPF_ABS, 0, 0,
SKF_AD_OFF + SKF_AD_PAY_OFFSET); }
+ | OP_LDB K_RAND {
+ bpf_set_curr_instr(BPF_LD | BPF_B | BPF_ABS, 0, 0,
+ SKF_AD_OFF + SKF_AD_RANDOM); }
;
ldh
@@ -212,6 +215,9 @@ ldh
| OP_LDH K_POFF {
bpf_set_curr_instr(BPF_LD | BPF_H | BPF_ABS, 0, 0,
SKF_AD_OFF + SKF_AD_PAY_OFFSET); }
+ | OP_LDH K_RAND {
+ bpf_set_curr_instr(BPF_LD | BPF_H | BPF_ABS, 0, 0,
+ SKF_AD_OFF + SKF_AD_RANDOM); }
;
ldi
@@ -265,6 +271,9 @@ ld
| OP_LD K_POFF {
bpf_set_curr_instr(BPF_LD | BPF_W | BPF_ABS, 0, 0,
SKF_AD_OFF + SKF_AD_PAY_OFFSET); }
+ | OP_LD K_RAND {
+ bpf_set_curr_instr(BPF_LD | BPF_W | BPF_ABS, 0, 0,
+ SKF_AD_OFF + SKF_AD_RANDOM); }
| OP_LD 'M' '[' number ']' {
bpf_set_curr_instr(BPF_LD | BPF_MEM, 0, 0, $4); }
| OP_LD '[' 'x' '+' number ']' {
diff --git a/tools/perf/Documentation/perf-bench.txt b/tools/perf/Documentation/perf-bench.txt
index 7065cd6..4464ad7 100644
--- a/tools/perf/Documentation/perf-bench.txt
+++ b/tools/perf/Documentation/perf-bench.txt
@@ -48,6 +48,12 @@ SUBSYSTEM
'mem'::
Memory access performance.
+'numa'::
+ NUMA scheduling and MM benchmarks.
+
+'futex'::
+ Futex stressing benchmarks.
+
'all'::
All benchmark subsystems.
@@ -187,6 +193,22 @@ Show only the result with page faults before memset.
--no-prefault::
Show only the result without page faults before memset.
+SUITES FOR 'numa'
+~~~~~~~~~~~~~~~~~
+*mem*::
+Suite for evaluating NUMA workloads.
+
+SUITES FOR 'futex'
+~~~~~~~~~~~~~~~~~~
+*hash*::
+Suite for evaluating hash tables.
+
+*wake*::
+Suite for evaluating wake calls.
+
+*requeue*::
+Suite for evaluating requeue calls.
+
SEE ALSO
--------
linkperf:perf[1]
diff --git a/tools/perf/Documentation/perf-top.txt b/tools/perf/Documentation/perf-top.txt
index cdd8d49..976b00c 100644
--- a/tools/perf/Documentation/perf-top.txt
+++ b/tools/perf/Documentation/perf-top.txt
@@ -87,7 +87,6 @@ Default is to monitor all CPUS.
--realtime=<priority>::
Collect data with this RT SCHED_FIFO priority.
--s <symbol>::
--sym-annotate=<symbol>::
Annotate this symbol.
diff --git a/tools/perf/Makefile.perf b/tools/perf/Makefile.perf
index 50d875d..e969233 100644
--- a/tools/perf/Makefile.perf
+++ b/tools/perf/Makefile.perf
@@ -192,13 +192,13 @@ endif
export PERL_PATH
$(OUTPUT)util/parse-events-flex.c: util/parse-events.l $(OUTPUT)util/parse-events-bison.c
- $(QUIET_FLEX)$(FLEX) --header-file=$(OUTPUT)util/parse-events-flex.h $(PARSER_DEBUG_FLEX) -t util/parse-events.l > $(OUTPUT)util/parse-events-flex.c
+ $(QUIET_FLEX)$(FLEX) -o $@ --header-file=$(OUTPUT)util/parse-events-flex.h $(PARSER_DEBUG_FLEX) util/parse-events.l
$(OUTPUT)util/parse-events-bison.c: util/parse-events.y
$(QUIET_BISON)$(BISON) -v util/parse-events.y -d $(PARSER_DEBUG_BISON) -o $(OUTPUT)util/parse-events-bison.c -p parse_events_
$(OUTPUT)util/pmu-flex.c: util/pmu.l $(OUTPUT)util/pmu-bison.c
- $(QUIET_FLEX)$(FLEX) --header-file=$(OUTPUT)util/pmu-flex.h -t util/pmu.l > $(OUTPUT)util/pmu-flex.c
+ $(QUIET_FLEX)$(FLEX) -o $@ --header-file=$(OUTPUT)util/pmu-flex.h util/pmu.l
$(OUTPUT)util/pmu-bison.c: util/pmu.y
$(QUIET_BISON)$(BISON) -v util/pmu.y -d -o $(OUTPUT)util/pmu-bison.c -p perf_pmu_
diff --git a/tools/perf/bench/numa.c b/tools/perf/bench/numa.c
index 97d86d8..ebfa163 100644
--- a/tools/perf/bench/numa.c
+++ b/tools/perf/bench/numa.c
@@ -1593,6 +1593,10 @@ static void init_params(struct params *p, const char *name, int argc, const char
p->data_rand_walk = true;
p->nr_loops = -1;
p->init_random = true;
+ p->mb_global_str = "1";
+ p->nr_proc = 1;
+ p->nr_threads = 1;
+ p->nr_secs = 5;
p->run_all = argc == 1;
}
diff --git a/tools/perf/builtin-stat.c b/tools/perf/builtin-stat.c
index 8b0e1c9..65a151e 100644
--- a/tools/perf/builtin-stat.c
+++ b/tools/perf/builtin-stat.c
@@ -174,13 +174,20 @@ static inline int perf_evsel__nr_cpus(struct perf_evsel *evsel)
static void perf_evsel__reset_stat_priv(struct perf_evsel *evsel)
{
- memset(evsel->priv, 0, sizeof(struct perf_stat));
+ int i;
+ struct perf_stat *ps = evsel->priv;
+
+ for (i = 0; i < 3; i++)
+ init_stats(&ps->res_stats[i]);
}
static int perf_evsel__alloc_stat_priv(struct perf_evsel *evsel)
{
evsel->priv = zalloc(sizeof(struct perf_stat));
- return evsel->priv == NULL ? -ENOMEM : 0;
+ if (evsel == NULL)
+ return -ENOMEM;
+ perf_evsel__reset_stat_priv(evsel);
+ return 0;
}
static void perf_evsel__free_stat_priv(struct perf_evsel *evsel)
diff --git a/tools/perf/config/Makefile b/tools/perf/config/Makefile
index c234182..ee21fa9 100644
--- a/tools/perf/config/Makefile
+++ b/tools/perf/config/Makefile
@@ -65,10 +65,9 @@ ifndef NO_LIBELF
ifdef LIBDW_DIR
LIBDW_CFLAGS := -I$(LIBDW_DIR)/include
LIBDW_LDFLAGS := -L$(LIBDW_DIR)/lib
-
- FEATURE_CHECK_CFLAGS-libdw-dwarf-unwind := $(LIBDW_CFLAGS)
- FEATURE_CHECK_LDFLAGS-libdw-dwarf-unwind := $(LIBDW_LDFLAGS) -ldw
endif
+ FEATURE_CHECK_CFLAGS-libdw-dwarf-unwind := $(LIBDW_CFLAGS)
+ FEATURE_CHECK_LDFLAGS-libdw-dwarf-unwind := $(LIBDW_LDFLAGS) -ldw
endif
# include ARCH specific config
@@ -278,6 +277,8 @@ else
NO_LIBELF := 1
NO_DWARF := 1
NO_DEMANGLE := 1
+ NO_LIBUNWIND := 1
+ NO_LIBDW_DWARF_UNWIND := 1
else
msg := $(error No gnu/libc-version.h found, please install glibc-dev[el]/glibc-static);
endif
diff --git a/tools/perf/tests/code-reading.c b/tools/perf/tests/code-reading.c
index 653a8fe..bfb1869 100644
--- a/tools/perf/tests/code-reading.c
+++ b/tools/perf/tests/code-reading.c
@@ -504,6 +504,7 @@ static int do_test_code_reading(bool try_kcore)
if (ret < 0) {
if (!excl_kernel) {
excl_kernel = true;
+ perf_evlist__set_maps(evlist, NULL, NULL);
perf_evlist__delete(evlist);
evlist = NULL;
continue;
diff --git a/tools/perf/util/probe-finder.c b/tools/perf/util/probe-finder.c
index df02386..5627621 100644
--- a/tools/perf/util/probe-finder.c
+++ b/tools/perf/util/probe-finder.c
@@ -985,7 +985,7 @@ static int debuginfo__find_probes(struct debuginfo *dbg,
#if _ELFUTILS_PREREQ(0, 142)
/* Get the call frame information from this dwarf */
- pf->cfi = dwarf_getcfi(dbg->dbg);
+ pf->cfi = dwarf_getcfi_elf(dwarf_getelf(dbg->dbg));
#endif
off = 0;
@@ -1441,13 +1441,15 @@ static int line_range_walk_cb(const char *fname, int lineno,
void *data)
{
struct line_finder *lf = data;
+ int err;
if ((strtailcmp(fname, lf->fname) != 0) ||
(lf->lno_s > lineno || lf->lno_e < lineno))
return 0;
- if (line_range_add_line(fname, lineno, lf->lr) < 0)
- return -EINVAL;
+ err = line_range_add_line(fname, lineno, lf->lr);
+ if (err < 0 && err != -EEXIST)
+ return err;
return 0;
}
@@ -1473,14 +1475,15 @@ static int find_line_range_by_line(Dwarf_Die *sp_die, struct line_finder *lf)
static int line_range_inline_cb(Dwarf_Die *in_die, void *data)
{
- find_line_range_by_line(in_die, data);
+ int ret = find_line_range_by_line(in_die, data);
/*
* We have to check all instances of inlined function, because
* some execution paths can be optimized out depends on the
- * function argument of instances
+ * function argument of instances. However, if an error occurs,
+ * it should be handled by the caller.
*/
- return 0;
+ return ret < 0 ? ret : 0;
}
/* Search function definition from function name */
OpenPOWER on IntegriCloud