summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile11
-rw-r--r--README55
-rw-r--r--api/api_net.c2
-rw-r--r--arch/Kconfig9
-rw-r--r--arch/arm/Kconfig58
-rw-r--r--arch/arm/cpu/arm926ejs/spear/cpu.c2
-rw-r--r--arch/arm/cpu/armv7/exynos/Kconfig14
-rw-r--r--arch/arm/cpu/armv7/omap-common/boot-common.c2
-rw-r--r--arch/arm/cpu/armv7/omap-common/sata.c6
-rw-r--r--arch/arm/cpu/armv7/omap3/Kconfig27
-rw-r--r--arch/arm/cpu/armv7/rmobile/Kconfig12
-rw-r--r--arch/arm/cpu/armv7/socfpga/misc.c2
-rw-r--r--arch/arm/dts/Makefile3
-rw-r--r--arch/arm/dts/exynos5250-snow.dts12
-rw-r--r--arch/arm/dts/exynos5420-peach-pit.dts4
-rw-r--r--arch/arm/dts/exynos5800-peach-pi.dts3
-rw-r--r--arch/arm/dts/ls1021a-qds.dts216
-rw-r--r--arch/arm/dts/ls1021a-twr.dts87
-rw-r--r--arch/arm/dts/ls1021a.dtsi381
-rw-r--r--arch/arm/dts/skeleton64.dtsi13
-rw-r--r--arch/arm/dts/tegra124-nyan-big.dts2
-rw-r--r--arch/arm/lib/board.c2
-rw-r--r--arch/arm/lib/bootm.c1
-rw-r--r--arch/arm/mach-at91/Kconfig3
-rw-r--r--arch/arm/mach-bcm283x/Kconfig9
-rw-r--r--arch/arm/mach-davinci/misc.c2
-rw-r--r--arch/arm/mach-tegra/Kconfig18
-rw-r--r--arch/avr32/lib/board.c2
-rw-r--r--arch/mips/mach-au1x00/au1x00_eth.c14
-rw-r--r--arch/nds32/lib/board.c2
-rw-r--r--arch/openrisc/lib/board.c2
-rw-r--r--arch/powerpc/cpu/mpc8260/ether_fcc.c22
-rw-r--r--arch/powerpc/cpu/mpc8260/ether_scc.c4
-rw-r--r--arch/powerpc/cpu/mpc83xx/Kconfig1
-rw-r--r--arch/powerpc/cpu/mpc85xx/ether_fcc.c6
-rw-r--r--arch/powerpc/cpu/mpc8xx/fec.c12
-rw-r--r--arch/powerpc/cpu/mpc8xx/scc.c7
-rw-r--r--arch/powerpc/cpu/ppc4xx/Kconfig2
-rw-r--r--arch/powerpc/lib/board.c2
-rw-r--r--arch/sandbox/Kconfig24
-rw-r--r--arch/sandbox/cpu/Makefile10
-rw-r--r--arch/sandbox/cpu/cpu.c51
-rw-r--r--arch/sandbox/cpu/eth-raw-os.c249
-rw-r--r--arch/sandbox/dts/cros-ec-keyboard.dtsi105
-rw-r--r--arch/sandbox/dts/sandbox.dts191
-rw-r--r--arch/sandbox/include/asm/eth-raw-os.h40
-rw-r--r--arch/sandbox/include/asm/eth.h15
-rw-r--r--arch/sandbox/include/asm/io.h16
-rw-r--r--arch/sandbox/include/asm/processor.h12
-rw-r--r--arch/sandbox/include/asm/test.h7
-rw-r--r--arch/sandbox/include/asm/u-boot-sandbox.h48
-rw-r--r--arch/sandbox/lib/Makefile3
-rw-r--r--arch/sandbox/lib/bootm.c63
-rw-r--r--arch/sandbox/lib/pci_io.c138
-rw-r--r--arch/sh/lib/board.c2
-rw-r--r--arch/sparc/lib/board.c2
-rw-r--r--arch/x86/Kconfig35
-rw-r--r--arch/x86/cpu/baytrail/early_uart.c5
-rw-r--r--arch/x86/cpu/coreboot/pci.c63
-rw-r--r--arch/x86/cpu/coreboot/sdram.c6
-rw-r--r--arch/x86/cpu/cpu.c2
-rw-r--r--arch/x86/cpu/ivybridge/bd82x6x.c47
-rw-r--r--arch/x86/cpu/ivybridge/cpu.c64
-rw-r--r--arch/x86/cpu/ivybridge/early_init.c58
-rw-r--r--arch/x86/cpu/ivybridge/early_me.c12
-rw-r--r--arch/x86/cpu/ivybridge/gma.c4
-rw-r--r--arch/x86/cpu/ivybridge/lpc.c88
-rw-r--r--arch/x86/cpu/ivybridge/mrccache.c7
-rw-r--r--arch/x86/cpu/ivybridge/northbridge.c6
-rw-r--r--arch/x86/cpu/ivybridge/pch.c4
-rw-r--r--arch/x86/cpu/ivybridge/pci.c85
-rw-r--r--arch/x86/cpu/ivybridge/report_platform.c4
-rw-r--r--arch/x86/cpu/ivybridge/sata.c61
-rw-r--r--arch/x86/cpu/ivybridge/sdram.c37
-rw-r--r--arch/x86/cpu/ivybridge/usb_ehci.c4
-rw-r--r--arch/x86/cpu/ivybridge/usb_xhci.c8
-rw-r--r--arch/x86/cpu/pci.c52
-rw-r--r--arch/x86/cpu/quark/quark.c4
-rw-r--r--arch/x86/cpu/queensbay/tnc.c4
-rw-r--r--arch/x86/dts/Makefile1
-rw-r--r--arch/x86/dts/chromebook_link.dts80
-rw-r--r--arch/x86/dts/chromebox_panther.dts64
-rw-r--r--arch/x86/include/asm/arch-ivybridge/bd82x6x.h1
-rw-r--r--arch/x86/include/asm/arch-ivybridge/mrccache.h4
-rw-r--r--arch/x86/include/asm/pci.h20
-rw-r--r--arch/x86/lib/Makefile4
-rw-r--r--arch/x86/lib/bios_interrupts.c12
-rw-r--r--arch/x86/lib/init_helpers.c8
-rw-r--r--arch/x86/lib/lpc-uclass.c28
-rw-r--r--arch/x86/lib/pch-uclass.c28
-rw-r--r--board/BuR/common/common.c4
-rw-r--r--board/BuS/eb_cpux9k2/cpux9k2.c2
-rw-r--r--board/BuS/vl_ma2sc/vl_ma2sc.c2
-rw-r--r--board/ait/cam_enc_4xx/cam_enc_4xx.c2
-rw-r--r--board/alphaproject/ap_sh4a_4a/ap_sh4a_4a.c2
-rw-r--r--board/amcc/canyonlands/Kconfig6
-rw-r--r--board/atmel/at91sam9261ek/at91sam9261ek.c2
-rw-r--r--board/bct-brettl2/bct-brettl2.c2
-rw-r--r--board/bf518f-ezbrd/bf518f-ezbrd.c4
-rw-r--r--board/bf526-ezbrd/bf526-ezbrd.c4
-rw-r--r--board/bf527-ezkit/bf527-ezkit.c4
-rw-r--r--board/bf537-minotaur/bf537-minotaur.c2
-rw-r--r--board/bf537-pnav/bf537-pnav.c2
-rw-r--r--board/bf537-srv1/bf537-srv1.c2
-rw-r--r--board/bf537-stamp/bf537-stamp.c4
-rw-r--r--board/bf609-ezkit/bf609-ezkit.c2
-rw-r--r--board/birdland/bav335x/board.c4
-rw-r--r--board/buffalo/lsxl/lsxl.c2
-rw-r--r--board/cm-bf527/cm-bf527.c4
-rw-r--r--board/cm-bf537e/cm-bf537e.c2
-rw-r--r--board/cm-bf537u/cm-bf537u.c2
-rw-r--r--board/compulab/cm_fx6/cm_fx6.c2
-rw-r--r--board/compulab/cm_t335/Kconfig9
-rw-r--r--board/compulab/cm_t335/cm_t335.c2
-rw-r--r--board/compulab/cm_t35/cm_t35.c2
-rw-r--r--board/compulab/cm_t3517/cm_t3517.c4
-rw-r--r--board/compulab/cm_t54/cm_t54.c4
-rw-r--r--board/coreboot/coreboot/coreboot.c5
-rw-r--r--board/davinci/da8xxevm/da850evm.c6
-rw-r--r--board/dnp5370/dnp5370.c4
-rw-r--r--board/egnite/ethernut5/ethernut5.c2
-rw-r--r--board/genesi/mx51_efikamx/efikamx-usb.c4
-rw-r--r--board/google/chromebook_link/link.c10
-rw-r--r--board/google/chromebox_panther/Kconfig34
-rw-r--r--board/google/chromebox_panther/MAINTAINERS6
-rw-r--r--board/google/chromebox_panther/Makefile7
-rw-r--r--board/google/chromebox_panther/panther.c22
-rw-r--r--board/gumstix/pepper/Kconfig9
-rw-r--r--board/gumstix/pepper/board.c2
-rw-r--r--board/highbank/highbank.c2
-rw-r--r--board/ifm/ac14xx/ac14xx.c2
-rw-r--r--board/ip04/ip04.c2
-rw-r--r--board/isee/igep0033/Kconfig9
-rw-r--r--board/isee/igep0033/board.c2
-rw-r--r--board/phytec/pcm051/Kconfig9
-rw-r--r--board/phytec/pcm051/board.c2
-rw-r--r--board/renesas/r0p7734/r0p7734.c2
-rw-r--r--board/ronetix/pm9261/pm9261.c2
-rw-r--r--board/ronetix/pm9g45/pm9g45.c2
-rw-r--r--board/samsung/common/board.c12
-rw-r--r--board/samsung/goni/Kconfig9
-rw-r--r--board/samsung/smdk5420/Kconfig6
-rw-r--r--board/samsung/smdkc100/Kconfig9
-rw-r--r--board/sandbox/README.sandbox78
-rw-r--r--board/sandbox/sandbox.c12
-rw-r--r--board/siemens/common/factoryset.c4
-rw-r--r--board/siemens/pxm2/board.c2
-rw-r--r--board/silica/pengwyn/Kconfig9
-rw-r--r--board/silica/pengwyn/board.c2
-rw-r--r--board/spear/spear300/spear300.c2
-rw-r--r--board/spear/spear310/spear310.c2
-rw-r--r--board/spear/spear320/spear320.c2
-rw-r--r--board/spear/spear600/spear600.c2
-rw-r--r--board/st/stv0991/stv0991.c2
-rw-r--r--board/sunxi/ahci.c2
-rw-r--r--board/sunxi/gmac.c10
-rw-r--r--board/tcm-bf518/tcm-bf518.c4
-rw-r--r--board/tcm-bf537/tcm-bf537.c2
-rw-r--r--board/ti/am335x/Kconfig9
-rw-r--r--board/ti/am335x/board.c6
-rw-r--r--board/ti/am43xx/board.c4
-rw-r--r--board/ti/beagle_x15/board.c4
-rw-r--r--board/ti/dra7xx/evm.c4
-rw-r--r--board/ti/ti814x/evm.c2
-rw-r--r--common/Kconfig116
-rw-r--r--common/Makefile2
-rw-r--r--common/board_f.c7
-rw-r--r--common/board_r.c8
-rw-r--r--common/bootm.c1
-rw-r--r--common/cmd_bdinfo.c4
-rw-r--r--common/cmd_bootm.c1
-rw-r--r--common/cmd_bootstage.c7
-rw-r--r--common/cmd_demo.c1
-rw-r--r--common/cmd_elf.c2
-rw-r--r--common/cmd_fat.c1
-rw-r--r--common/cmd_fdt.c1
-rw-r--r--common/cmd_host.c175
-rw-r--r--common/cmd_lzmadec.c1
-rw-r--r--common/cmd_md5sum.c1
-rw-r--r--common/cmd_mem.c8
-rw-r--r--common/cmd_net.c178
-rw-r--r--common/cmd_nvedit.c1
-rw-r--r--common/cmd_pci.c14
-rw-r--r--common/cmd_pxe.c91
-rw-r--r--common/cmd_sandbox.c126
-rw-r--r--common/cmd_sf.c3
-rw-r--r--common/cmd_source.c1
-rw-r--r--common/cmd_trace.c1
-rw-r--r--common/cmd_usb.c198
-rw-r--r--common/cmd_ximg.c1
-rw-r--r--common/cros_ec.c35
-rw-r--r--common/hash.c1
-rw-r--r--common/image-fdt.c1
-rw-r--r--common/image-fit.c1
-rw-r--r--common/image.c1
-rw-r--r--common/iotrace.c1
-rw-r--r--common/lcd.c1
-rw-r--r--common/malloc_simple.c1
-rw-r--r--common/miiphyutil.c1
-rw-r--r--common/spl/spl_net.c4
-rw-r--r--common/update.c25
-rw-r--r--common/usb.c324
-rw-r--r--common/usb_hub.c194
-rw-r--r--common/usb_kbd.c119
-rw-r--r--common/usb_storage.c236
-rw-r--r--configs/A20-OLinuXino-Lime2_defconfig3
-rw-r--r--configs/A20-OLinuXino-Lime_defconfig3
-rw-r--r--configs/A20-OLinuXino_MICRO_defconfig3
-rw-r--r--configs/Bananapi_defconfig3
-rw-r--r--configs/Bananapro_defconfig3
-rw-r--r--configs/CSQ_CS908_defconfig3
-rw-r--r--configs/Colombus_defconfig3
-rw-r--r--configs/Cubieboard2_defconfig3
-rw-r--r--configs/Cubietruck_defconfig3
-rw-r--r--configs/Hummingbird_A31_defconfig3
-rw-r--r--configs/Linksprite_pcDuino3_Nano_defconfig3
-rw-r--r--configs/Linksprite_pcDuino3_defconfig11
-rw-r--r--configs/Linksprite_pcDuino3_fdt_defconfig15
-rw-r--r--configs/Mele_I7_defconfig3
-rw-r--r--configs/Mele_M3_defconfig3
-rw-r--r--configs/Mele_M5_defconfig3
-rw-r--r--configs/Mele_M9_defconfig3
-rw-r--r--configs/Orangepi_defconfig3
-rw-r--r--configs/Orangepi_mini_defconfig3
-rw-r--r--configs/Wits_Pro_A20_DKT_defconfig3
-rw-r--r--configs/alt_defconfig2
-rw-r--r--configs/am335x_boneblack_vboot_defconfig1
-rw-r--r--configs/am3517_crane_defconfig3
-rw-r--r--configs/am3517_evm_defconfig3
-rw-r--r--configs/arndale_defconfig6
-rw-r--r--configs/axs101_defconfig3
-rw-r--r--configs/axs103_defconfig3
-rw-r--r--configs/bf609-ezkit_defconfig3
-rw-r--r--configs/birdland_bav335a_defconfig3
-rw-r--r--configs/birdland_bav335b_defconfig3
-rw-r--r--configs/chromebook_link_defconfig2
-rw-r--r--configs/chromebox_panther_defconfig12
-rw-r--r--configs/cm_fx6_defconfig3
-rw-r--r--configs/cm_t3517_defconfig3
-rw-r--r--configs/cm_t35_defconfig3
-rw-r--r--configs/coreboot-x86_defconfig1
-rw-r--r--configs/devkit8000_defconfig3
-rw-r--r--configs/dig297_defconfig3
-rw-r--r--configs/eco5pk_defconfig3
-rw-r--r--configs/galileo_defconfig3
-rw-r--r--configs/gose_defconfig2
-rw-r--r--configs/i12-tvbox_defconfig3
-rw-r--r--configs/ids8313_defconfig1
-rw-r--r--configs/koelsch_defconfig2
-rw-r--r--configs/lager_defconfig2
-rw-r--r--configs/mcx_defconfig3
-rw-r--r--configs/mixtile_loftq_defconfig3
-rw-r--r--configs/mt_ventoux_defconfig3
-rw-r--r--configs/mx6dlsabreauto_defconfig2
-rw-r--r--configs/mx6dlsabresd_defconfig2
-rw-r--r--configs/mx6qsabreauto_defconfig2
-rw-r--r--configs/mx6qsabresd_defconfig2
-rw-r--r--configs/mx6sabresd_spl_defconfig2
-rw-r--r--configs/mx6sxsabresd_defconfig2
-rw-r--r--configs/mx6sxsabresd_spl_defconfig2
-rw-r--r--configs/nokia_rx51_defconfig3
-rw-r--r--configs/omap3_beagle_defconfig3
-rw-r--r--configs/omap3_evm_defconfig3
-rw-r--r--configs/omap3_evm_quick_mmc_defconfig3
-rw-r--r--configs/omap3_evm_quick_nand_defconfig3
-rw-r--r--configs/omap3_ha_defconfig3
-rw-r--r--configs/omap3_logic_defconfig3
-rw-r--r--configs/omap3_mvblx_defconfig3
-rw-r--r--configs/omap3_pandora_defconfig3
-rw-r--r--configs/omap3_sdp3430_defconfig3
-rw-r--r--configs/ph1_ld4_defconfig3
-rw-r--r--configs/ph1_pro4_defconfig3
-rw-r--r--configs/ph1_sld8_defconfig3
-rw-r--r--configs/porter_defconfig2
-rw-r--r--configs/sandbox_defconfig20
-rw-r--r--configs/silk_defconfig2
-rw-r--r--configs/smdk5250_defconfig6
-rw-r--r--configs/snapper9260_defconfig3
-rw-r--r--configs/snapper9g20_defconfig3
-rw-r--r--configs/snow_defconfig7
-rw-r--r--configs/socfpga_arria5_defconfig3
-rw-r--r--configs/socfpga_cyclone5_defconfig6
-rw-r--r--configs/socfpga_socrates_defconfig6
-rw-r--r--configs/spear300_defconfig3
-rw-r--r--configs/spear300_nand_defconfig3
-rw-r--r--configs/spear300_usbtty_defconfig3
-rw-r--r--configs/spear300_usbtty_nand_defconfig3
-rw-r--r--configs/spear310_defconfig3
-rw-r--r--configs/spear310_nand_defconfig3
-rw-r--r--configs/spear310_pnor_defconfig3
-rw-r--r--configs/spear310_usbtty_defconfig3
-rw-r--r--configs/spear310_usbtty_nand_defconfig3
-rw-r--r--configs/spear310_usbtty_pnor_defconfig3
-rw-r--r--configs/spear320_defconfig3
-rw-r--r--configs/spear320_nand_defconfig3
-rw-r--r--configs/spear320_pnor_defconfig3
-rw-r--r--configs/spear320_usbtty_defconfig3
-rw-r--r--configs/spear320_usbtty_nand_defconfig3
-rw-r--r--configs/spear320_usbtty_pnor_defconfig3
-rw-r--r--configs/spear600_defconfig3
-rw-r--r--configs/spear600_nand_defconfig3
-rw-r--r--configs/spear600_usbtty_defconfig3
-rw-r--r--configs/spear600_usbtty_nand_defconfig3
-rw-r--r--configs/stv0991_defconfig5
-rw-r--r--configs/tao3530_defconfig3
-rw-r--r--configs/tb100_defconfig3
-rw-r--r--configs/tricorder_defconfig3
-rw-r--r--configs/tricorder_flash_defconfig3
-rw-r--r--configs/twister_defconfig3
-rw-r--r--configs/x600_defconfig3
-rw-r--r--configs/zynq_microzed_defconfig1
-rw-r--r--configs/zynq_zc70x_defconfig1
-rw-r--r--configs/zynq_zc770_xm010_defconfig1
-rw-r--r--configs/zynq_zc770_xm012_defconfig1
-rw-r--r--configs/zynq_zc770_xm013_defconfig1
-rw-r--r--configs/zynq_zed_defconfig1
-rw-r--r--configs/zynq_zybo_defconfig1
-rw-r--r--doc/README.drivers.eth18
-rw-r--r--doc/README.enetaddr2
-rw-r--r--doc/README.fdt-control16
-rw-r--r--doc/README.link-local4
-rw-r--r--doc/device-tree-bindings/i2c/i2c-gpio.txt37
-rw-r--r--doc/device-tree-bindings/net/allwinner,sun4i-emac.txt19
-rw-r--r--doc/device-tree-bindings/net/allwinner,sun4i-mdio.txt27
-rw-r--r--doc/device-tree-bindings/net/allwinner,sun7i-a20-gmac.txt27
-rw-r--r--doc/device-tree-bindings/net/ethernet.txt25
-rw-r--r--doc/device-tree-bindings/net/stmmac.txt63
-rw-r--r--doc/driver-model/pci-info.txt70
-rw-r--r--doc/driver-model/usb-info.txt415
-rw-r--r--drivers/block/ahci.c11
-rw-r--r--drivers/block/dwc_ahsata.c2
-rw-r--r--drivers/core/device-remove.c4
-rw-r--r--drivers/core/device.c85
-rw-r--r--drivers/core/lists.c2
-rw-r--r--drivers/core/uclass.c10
-rw-r--r--drivers/demo/demo-simple.c1
-rw-r--r--drivers/gpio/Kconfig21
-rw-r--r--drivers/gpio/at91_gpio.c2
-rw-r--r--drivers/gpio/bcm2835_gpio.c2
-rw-r--r--drivers/gpio/gpio-uclass.c40
-rw-r--r--drivers/gpio/intel_ich6_gpio.c18
-rw-r--r--drivers/gpio/mxc_gpio.c2
-rw-r--r--drivers/gpio/omap_gpio.c2
-rw-r--r--drivers/gpio/s5p_gpio.c2
-rw-r--r--drivers/gpio/sandbox.c6
-rw-r--r--drivers/gpio/sunxi_gpio.c2
-rw-r--r--drivers/gpio/tegra_gpio.c2
-rw-r--r--drivers/i2c/Kconfig56
-rw-r--r--drivers/i2c/Makefile1
-rw-r--r--drivers/i2c/i2c-gpio.c346
-rw-r--r--drivers/i2c/i2c-uclass.c6
-rw-r--r--drivers/i2c/i2c-uniphier-f.c1
-rw-r--r--drivers/i2c/i2c-uniphier.c1
-rw-r--r--drivers/i2c/s3c24x0_i2c.c2
-rw-r--r--drivers/i2c/sandbox_i2c.c2
-rw-r--r--drivers/i2c/tegra_i2c.c6
-rw-r--r--drivers/input/cros_ec_keyb.c2
-rw-r--r--drivers/input/i8042.c7
-rw-r--r--drivers/misc/Kconfig19
-rw-r--r--drivers/misc/Makefile1
-rw-r--r--drivers/misc/cros_ec.c254
-rw-r--r--drivers/misc/cros_ec_i2c.c6
-rw-r--r--drivers/misc/cros_ec_lpc.c29
-rw-r--r--drivers/misc/cros_ec_sandbox.c79
-rw-r--r--drivers/misc/cros_ec_spi.c8
-rw-r--r--drivers/misc/swap_case.c285
-rw-r--r--drivers/mtd/spi/Kconfig12
-rw-r--r--drivers/mtd/spi/sf-uclass.c18
-rw-r--r--drivers/mtd/spi/sf_probe.c9
-rw-r--r--drivers/net/4xx_enet.c21
-rw-r--r--drivers/net/Kconfig49
-rw-r--r--drivers/net/Makefile4
-rw-r--r--drivers/net/altera_tse.c15
-rw-r--r--drivers/net/armada100_fec.c7
-rw-r--r--drivers/net/at91_emac.c4
-rw-r--r--drivers/net/ax88180.c6
-rw-r--r--drivers/net/bcm-sf2-eth.c6
-rw-r--r--drivers/net/bfin_mac.c4
-rw-r--r--drivers/net/calxedaxgmac.c2
-rw-r--r--drivers/net/cpsw.c17
-rw-r--r--drivers/net/cs8900.c5
-rw-r--r--drivers/net/davinci_emac.c5
-rw-r--r--drivers/net/dc2114x.c9
-rw-r--r--drivers/net/designware.c250
-rw-r--r--drivers/net/designware.h3
-rw-r--r--drivers/net/dm9000x.c9
-rw-r--r--drivers/net/dnet.c5
-rw-r--r--drivers/net/e1000.c4
-rw-r--r--drivers/net/eepro100.c3
-rw-r--r--drivers/net/enc28j60.c13
-rw-r--r--drivers/net/ep93xx_eth.c11
-rw-r--r--drivers/net/ethoc.c4
-rw-r--r--drivers/net/fec_mxc.c4
-rw-r--r--drivers/net/fm/eth.c2
-rw-r--r--drivers/net/fsl_mcdmafec.c23
-rw-r--r--drivers/net/ftgmac100.c4
-rw-r--r--drivers/net/ftmac100.c4
-rw-r--r--drivers/net/ftmac110.c4
-rw-r--r--drivers/net/greth.c2
-rw-r--r--drivers/net/keystone_net.c2
-rw-r--r--drivers/net/ks8851_mll.c6
-rw-r--r--drivers/net/lan91c96.c19
-rw-r--r--drivers/net/lpc32xx_eth.c10
-rw-r--r--drivers/net/macb.c10
-rw-r--r--drivers/net/mcffec.c5
-rw-r--r--drivers/net/mpc512x_fec.c3
-rw-r--r--drivers/net/mpc5xxx_fec.c2
-rw-r--r--drivers/net/mvgbe.c41
-rw-r--r--drivers/net/mvneta.c2
-rw-r--r--drivers/net/natsemi.c3
-rw-r--r--drivers/net/ne2000_base.c2
-rw-r--r--drivers/net/netconsole.c98
-rw-r--r--drivers/net/ns8382x.c6
-rw-r--r--drivers/net/pch_gbe.c2
-rw-r--r--drivers/net/pcnet.c2
-rw-r--r--drivers/net/phy/phy.c22
-rw-r--r--drivers/net/rtl8139.c4
-rw-r--r--drivers/net/rtl8169.c2
-rw-r--r--drivers/net/sandbox-raw.c165
-rw-r--r--drivers/net/sandbox.c208
-rw-r--r--drivers/net/sh_eth.c2
-rw-r--r--drivers/net/smc91111.c18
-rw-r--r--drivers/net/smc911x.c4
-rw-r--r--drivers/net/sunxi_emac.c4
-rw-r--r--drivers/net/tsec.c7
-rw-r--r--drivers/net/tsi108_eth.c8
-rw-r--r--drivers/net/uli526x.c5
-rw-r--r--drivers/net/xilinx_axi_emac.c2
-rw-r--r--drivers/net/xilinx_emaclite.c2
-rw-r--r--drivers/net/xilinx_ll_temac_fifo.c4
-rw-r--r--drivers/net/xilinx_ll_temac_sdma.c4
-rw-r--r--drivers/net/zynq_gem.c2
-rw-r--r--drivers/pci/Kconfig22
-rw-r--r--drivers/pci/Makefile11
-rw-r--r--drivers/pci/pci-emul-uclass.c67
-rw-r--r--drivers/pci/pci-uclass.c639
-rw-r--r--drivers/pci/pci.c281
-rw-r--r--drivers/pci/pci_auto.c16
-rw-r--r--drivers/pci/pci_common.c292
-rw-r--r--drivers/pci/pci_compat.c43
-rw-r--r--drivers/pci/pci_sandbox.c79
-rw-r--r--drivers/pci/pci_x86.c24
-rw-r--r--drivers/qe/uec.c2
-rw-r--r--drivers/serial/ns16550.c1
-rw-r--r--drivers/serial/serial-uclass.c4
-rw-r--r--drivers/serial/serial_uniphier.c1
-rw-r--r--drivers/sound/Kconfig55
-rw-r--r--drivers/spi/Kconfig25
-rw-r--r--drivers/spi/Makefile1
-rw-r--r--drivers/spi/fsl_dspi.c737
-rw-r--r--drivers/spi/fsl_qspi.c985
-rw-r--r--drivers/spi/ich.c522
-rw-r--r--drivers/spi/spi-uclass.c4
-rw-r--r--drivers/tpm/Kconfig7
-rw-r--r--drivers/usb/Kconfig16
-rw-r--r--drivers/usb/emul/Kconfig8
-rw-r--r--drivers/usb/emul/Makefile10
-rw-r--r--drivers/usb/emul/sandbox_flash.c423
-rw-r--r--drivers/usb/emul/sandbox_hub.c303
-rw-r--r--drivers/usb/emul/usb-emul-uclass.c263
-rw-r--r--drivers/usb/eth/asix.c3
-rw-r--r--drivers/usb/eth/asix88179.c2
-rw-r--r--drivers/usb/eth/mcs7830.c2
-rw-r--r--drivers/usb/eth/smsc95xx.c5
-rw-r--r--drivers/usb/eth/usb_ether.c52
-rw-r--r--drivers/usb/gadget/ci_udc.c4
-rw-r--r--drivers/usb/gadget/ether.c13
-rw-r--r--drivers/usb/host/Makefile5
-rw-r--r--drivers/usb/host/ehci-exynos.c112
-rw-r--r--drivers/usb/host/ehci-faraday.c112
-rw-r--r--drivers/usb/host/ehci-hcd.c385
-rw-r--r--drivers/usb/host/ehci-mx5.c12
-rw-r--r--drivers/usb/host/ehci-tegra.c322
-rw-r--r--drivers/usb/host/ehci.h47
-rw-r--r--drivers/usb/host/usb-sandbox.c117
-rw-r--r--drivers/usb/host/usb-uclass.c645
-rw-r--r--drivers/usb/host/xhci-exynos5.c120
-rw-r--r--drivers/usb/host/xhci-mem.c24
-rw-r--r--drivers/usb/host/xhci-ring.c8
-rw-r--r--drivers/usb/host/xhci.c312
-rw-r--r--drivers/usb/host/xhci.h31
-rw-r--r--drivers/usb/musb-new/musb_uboot.c4
-rw-r--r--drivers/video/cfb_console.c29
-rw-r--r--fs/fs.c1
-rw-r--r--fs/sandbox/sandboxfs.c6
-rw-r--r--include/ahci.h6
-rw-r--r--include/bootstage.h2
-rw-r--r--include/common.h30
-rw-r--r--include/config_distro_bootcmd.h13
-rw-r--r--include/config_distro_defaults.h4
-rw-r--r--include/configs/axs101.h1
-rw-r--r--include/configs/bf609-ezkit.h1
-rw-r--r--include/configs/chromebook_link.h61
-rw-r--r--include/configs/chromebox_panther.h17
-rw-r--r--include/configs/exynos5250-common.h10
-rw-r--r--include/configs/exynos5420-common.h2
-rw-r--r--include/configs/sandbox.h78
-rw-r--r--include/configs/smdk5250.h1
-rw-r--r--include/configs/snow.h3
-rw-r--r--include/configs/socfpga_common.h1
-rw-r--r--include/configs/spear-common.h1
-rw-r--r--include/configs/stv0991.h1
-rw-r--r--include/configs/sunxi-common.h1
-rw-r--r--include/configs/tb100.h1
-rw-r--r--include/configs/x600.h1
-rw-r--r--include/configs/x86-chromebook.h68
-rw-r--r--include/configs/x86-common.h5
-rw-r--r--include/cros_ec.h137
-rw-r--r--include/dm/device-internal.h2
-rw-r--r--include/dm/device.h61
-rw-r--r--include/dm/test.h8
-rw-r--r--include/dm/uclass-id.h11
-rw-r--r--include/dm/uclass-internal.h7
-rw-r--r--include/dm/uclass.h2
-rw-r--r--include/fdtdec.h19
-rw-r--r--include/fsl_dspi.h150
-rw-r--r--include/i2c.h8
-rw-r--r--include/linker_lists.h10
-rw-r--r--include/linux/usb/ch9.h18
-rw-r--r--include/linux/usb/gadget.h13
-rw-r--r--include/mapmem.h32
-rw-r--r--include/net.h470
-rw-r--r--include/os.h2
-rw-r--r--include/pci.h411
-rw-r--r--include/pci_ids.h2
-rw-r--r--include/phy.h23
-rw-r--r--include/spi_flash.h47
-rw-r--r--include/usb.h494
-rw-r--r--include/usb_defs.h68
-rw-r--r--lib/Kconfig9
-rw-r--r--lib/fdtdec.c10
-rw-r--r--lib/net_utils.c16
-rw-r--r--lib/trace.c1
-rw-r--r--net/arp.c137
-rw-r--r--net/arp.h22
-rw-r--r--net/bootp.c373
-rw-r--r--net/bootp.h39
-rw-r--r--net/cdp.c88
-rw-r--r--net/cdp.h2
-rw-r--r--net/dns.c72
-rw-r--r--net/dns.h2
-rw-r--r--net/eth.c666
-rw-r--r--net/link_local.c83
-rw-r--r--net/net.c493
-rw-r--r--net/nfs.c241
-rw-r--r--net/nfs.h2
-rw-r--r--net/ping.c49
-rw-r--r--net/rarp.c45
-rw-r--r--net/rarp.h6
-rw-r--r--net/sntp.c48
-rw-r--r--net/sntp.h2
-rw-r--r--net/tftp.c595
-rw-r--r--net/tftp.h8
-rw-r--r--post/cpu/mpc8xx/ether.c6
-rw-r--r--scripts/Makefile.spl9
-rw-r--r--test/compression.c1
-rw-r--r--test/dm/Makefile7
-rw-r--r--test/dm/bus.c16
-rw-r--r--test/dm/cmd_dm.c16
-rw-r--r--test/dm/core.c9
-rw-r--r--test/dm/eth.c156
-rw-r--r--test/dm/pci.c59
-rwxr-xr-xtest/dm/test-dm.sh3
-rw-r--r--test/dm/test-main.c7
-rw-r--r--test/dm/test-uclass.c17
-rw-r--r--test/dm/test.dts78
-rw-r--r--test/dm/usb.c50
-rw-r--r--tools/buildman/builder.py185
-rw-r--r--tools/buildman/builderthread.py65
-rw-r--r--tools/buildman/cmdline.py4
-rw-r--r--tools/buildman/control.py3
-rw-r--r--tools/patman/patchstream.py7
572 files changed, 16677 insertions, 5416 deletions
diff --git a/Makefile b/Makefile
index 0f7d58388e..1e52008385 100644
--- a/Makefile
+++ b/Makefile
@@ -651,6 +651,7 @@ libs-$(CONFIG_FMAN_ENET) += drivers/net/fm/
libs-$(CONFIG_SYS_FSL_DDR) += drivers/ddr/fsl/
libs-y += drivers/serial/
libs-y += drivers/usb/dwc3/
+libs-y += drivers/usb/emul/
libs-y += drivers/usb/eth/
libs-y += drivers/usb/gadget/
libs-y += drivers/usb/gadget/udc/
@@ -728,7 +729,7 @@ DO_STATIC_RELA =
endif
# Always append ALL so that arch config.mk's can add custom ones
-ALL-y += u-boot.srec u-boot.bin System.map binary_size_check
+ALL-y += u-boot.srec u-boot.bin System.map u-boot.cfg binary_size_check
ALL-$(CONFIG_ONENAND_U_BOOT) += u-boot-onenand.bin
ifeq ($(CONFIG_SPL_FSL_PBL),y)
@@ -870,6 +871,11 @@ ifndef CONFIG_SYS_UBOOT_START
CONFIG_SYS_UBOOT_START := 0
endif
+# Create a file containing the configuration options the image was built with
+quiet_cmd_cpp_cfg = CFG $@
+cmd_cpp_cfg = $(CPP) -Wp,-MD,$(depfile) $(cpp_flags) $(LDPPFLAGS) -ansi \
+ -D__ASSEMBLY__ -x assembler-with-cpp -P -dM -E -o $@ $<
+
MKIMAGEFLAGS_u-boot.img = -A $(ARCH) -T firmware -C none -O u-boot \
-a $(CONFIG_SYS_TEXT_BASE) -e $(CONFIG_SYS_UBOOT_START) \
-n "U-Boot $(UBOOTRELEASE) for $(BOARD) board"
@@ -900,6 +906,9 @@ u-boot.sha1: u-boot.bin
u-boot.dis: u-boot
$(OBJDUMP) -d $< > $@
+u-boot.cfg: include/config.h
+ $(call if_changed,cpp_cfg)
+
ifdef CONFIG_TPL
SPL_PAYLOAD := tpl/u-boot-with-tpl.bin
else
diff --git a/README b/README
index b662eb9836..fc1fd52f53 100644
--- a/README
+++ b/README
@@ -3218,55 +3218,6 @@ CBFS (Coreboot Filesystem) support
example, some LED's) on your board. At the moment,
the following checkpoints are implemented:
-- Detailed boot stage timing
- CONFIG_BOOTSTAGE
- Define this option to get detailed timing of each stage
- of the boot process.
-
- CONFIG_BOOTSTAGE_USER_COUNT
- This is the number of available user bootstage records.
- Each time you call bootstage_mark(BOOTSTAGE_ID_ALLOC, ...)
- a new ID will be allocated from this stash. If you exceed
- the limit, recording will stop.
-
- CONFIG_BOOTSTAGE_REPORT
- Define this to print a report before boot, similar to this:
-
- Timer summary in microseconds:
- Mark Elapsed Stage
- 0 0 reset
- 3,575,678 3,575,678 board_init_f start
- 3,575,695 17 arch_cpu_init A9
- 3,575,777 82 arch_cpu_init done
- 3,659,598 83,821 board_init_r start
- 3,910,375 250,777 main_loop
- 29,916,167 26,005,792 bootm_start
- 30,361,327 445,160 start_kernel
-
- CONFIG_CMD_BOOTSTAGE
- Add a 'bootstage' command which supports printing a report
- and un/stashing of bootstage data.
-
- CONFIG_BOOTSTAGE_FDT
- Stash the bootstage information in the FDT. A root 'bootstage'
- node is created with each bootstage id as a child. Each child
- has a 'name' property and either 'mark' containing the
- mark time in microsecond, or 'accum' containing the
- accumulated time for that bootstage id in microseconds.
- For example:
-
- bootstage {
- 154 {
- name = "board_init_f";
- mark = <3575678>;
- };
- 170 {
- name = "lcd";
- accum = <33482>;
- };
- };
-
- Code in the Linux kernel can find this in /proc/devicetree.
Legacy uImage format:
@@ -3360,9 +3311,9 @@ Legacy uImage format:
65 net/eth.c Ethernet found.
-80 common/cmd_net.c usage wrong
- 80 common/cmd_net.c before calling NetLoop()
- -81 common/cmd_net.c some error in NetLoop() occurred
- 81 common/cmd_net.c NetLoop() back without error
+ 80 common/cmd_net.c before calling net_loop()
+ -81 common/cmd_net.c some error in net_loop() occurred
+ 81 common/cmd_net.c net_loop() back without error
-82 common/cmd_net.c size == 0 (File with size 0 loaded)
82 common/cmd_net.c trying automatic boot
83 common/cmd_net.c running "source" command
diff --git a/api/api_net.c b/api/api_net.c
index 7b3805e8fd..04e4f4a44e 100644
--- a/api/api_net.c
+++ b/api/api_net.c
@@ -37,7 +37,7 @@ int dev_open_net(void *cookie)
if (!dev_valid_net(cookie))
return API_ENODEV;
- if (eth_init(gd->bd) < 0)
+ if (eth_init() < 0)
return API_EIO;
return 0;
diff --git a/arch/Kconfig b/arch/Kconfig
index 2ca530525e..1102346220 100644
--- a/arch/Kconfig
+++ b/arch/Kconfig
@@ -70,6 +70,12 @@ config SANDBOX
select HAVE_GENERIC_BOARD
select SYS_GENERIC_BOARD
select SUPPORT_OF_CONTROL
+ select DM
+ select DM_SPI_FLASH
+ select DM_SERIAL
+ select DM_I2C
+ select DM_SPI
+ select DM_GPIO
config SH
bool "SuperH architecture"
@@ -84,6 +90,9 @@ config X86
select HAVE_GENERIC_BOARD
select SYS_GENERIC_BOARD
select SUPPORT_OF_CONTROL
+ select DM
+ select DM_SERIAL
+ select DM_GPIO
endchoice
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 7ed0e20521..3702bb084f 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -235,6 +235,8 @@ config TARGET_SPEAR600
config TARGET_STV0991
bool "Support stv0991"
select CPU_V7
+ select DM
+ select DM_SERIAL
config TARGET_X600
bool "Support x600"
@@ -293,6 +295,9 @@ config TARGET_MX35PDK
config ARCH_BCM283X
bool "Broadcom BCM283X family"
+ select DM
+ select DM_SERIAL
+ select DM_GPIO
config TARGET_INTEGRATORAP_CM946ES
bool "Support integratorap_cm946es"
@@ -330,21 +335,33 @@ config TARGET_CM_T335
bool "Support cm_t335"
select CPU_V7
select SUPPORT_SPL
+ select DM
+ select DM_SERIAL
+ select DM_GPIO
config TARGET_PEPPER
bool "Support pepper"
select CPU_V7
select SUPPORT_SPL
+ select DM
+ select DM_SERIAL
+ select DM_GPIO
config TARGET_AM335X_IGEP0033
bool "Support am335x_igep0033"
select CPU_V7
select SUPPORT_SPL
+ select DM
+ select DM_SERIAL
+ select DM_GPIO
config TARGET_PCM051
bool "Support pcm051"
select CPU_V7
select SUPPORT_SPL
+ select DM
+ select DM_SERIAL
+ select DM_GPIO
config TARGET_DRACO
bool "Support draco"
@@ -370,11 +387,17 @@ config TARGET_PENGWYN
bool "Support pengwyn"
select CPU_V7
select SUPPORT_SPL
+ select DM
+ select DM_SERIAL
+ select DM_GPIO
config TARGET_AM335X_EVM
bool "Support am335x_evm"
select CPU_V7
select SUPPORT_SPL
+ select DM
+ select DM_SERIAL
+ select DM_GPIO
config TARGET_AM43XX_EVM
bool "Support am43xx_evm"
@@ -385,6 +408,8 @@ config TARGET_BAV335X
bool "Support bav335x"
select CPU_V7
select SUPPORT_SPL
+ select DM
+ select DM_SERIAL
help
The BAV335x OEM Network Processor integrates all the functions of an
embedded network computer in a small, easy to use SODIMM module which
@@ -419,10 +444,18 @@ config TARGET_BCMNSP
config ARCH_EXYNOS
bool "Samsung EXYNOS"
select CPU_V7
+ select DM
+ select DM_SPI_FLASH
+ select DM_SERIAL
+ select DM_SPI
+ select DM_GPIO
config ARCH_S5PC1XX
bool "Samsung S5PC1XX"
select CPU_V7
+ select DM
+ select DM_SERIAL
+ select DM_GPIO
config ARCH_HIGHBANK
bool "Calxeda Highbank"
@@ -517,11 +550,15 @@ config TARGET_MX6QARM2
config TARGET_MX6QSABREAUTO
bool "Support mx6qsabreauto"
select CPU_V7
+ select DM
+ select DM_THERMAL
config TARGET_MX6SABRESD
bool "Support mx6sabresd"
select CPU_V7
select SUPPORT_SPL
+ select DM
+ select DM_THERMAL
config TARGET_MX6SLEVK
bool "Support mx6slevk"
@@ -531,6 +568,8 @@ config TARGET_MX6SXSABRESD
bool "Support mx6sxsabresd"
select CPU_V7
select SUPPORT_SPL
+ select DM
+ select DM_THERMAL
config TARGET_GW_VENTANA
bool "Support gw_ventana"
@@ -591,16 +630,25 @@ config TARGET_CM_FX6
bool "Support cm_fx6"
select CPU_V7
select SUPPORT_SPL
+ select DM
+ select DM_SERIAL
+ select DM_GPIO
config TARGET_SOCFPGA_ARRIA5
bool "Support socfpga_arria5"
select CPU_V7
select SUPPORT_SPL
+ select DM
+ select DM_SPI_FLASH
+ select DM_SPI
config TARGET_SOCFPGA_CYCLONE5
bool "Support socfpga_cyclone5"
select CPU_V7
select SUPPORT_SPL
+ select DM
+ select DM_SPI_FLASH
+ select DM_SPI
config ARCH_SUNXI
bool "Support sunxi (Allwinner) SoCs"
@@ -621,6 +669,7 @@ config ZYNQ
bool "Xilinx Zynq Platform"
select CPU_V7
select SUPPORT_SPL
+ select DM
config TARGET_XILINX_ZYNQMP
bool "Support Xilinx ZynqMP Platform"
@@ -632,6 +681,12 @@ config TEGRA
select SPL
select OF_CONTROL
select CPU_V7
+ select DM
+ select DM_SPI_FLASH
+ select DM_SERIAL
+ select DM_I2C
+ select DM_SPI
+ select DM_GPIO
config TARGET_VEXPRESS64_AEMV8A
bool "Support vexpress_aemv8a"
@@ -726,6 +781,9 @@ config ARCH_UNIPHIER
select SUPPORT_SPL
select SPL
select OF_CONTROL
+ select DM
+ select DM_SERIAL
+ select DM_I2C
endchoice
diff --git a/arch/arm/cpu/arm926ejs/spear/cpu.c b/arch/arm/cpu/arm926ejs/spear/cpu.c
index 697e0945d7..1ce9db7a7d 100644
--- a/arch/arm/cpu/arm926ejs/spear/cpu.c
+++ b/arch/arm/cpu/arm926ejs/spear/cpu.c
@@ -32,7 +32,7 @@ int arch_cpu_init(void)
periph_clk_cfg |= CONFIG_SPEAR_UART48M;
writel(periph_clk_cfg, &misc_p->periph_clk_cfg);
#endif
-#if defined(CONFIG_DESIGNWARE_ETH)
+#if defined(CONFIG_ETH_DESIGNWARE)
periph1_clken |= MISC_ETHENB;
#endif
#if defined(CONFIG_DW_UDC)
diff --git a/arch/arm/cpu/armv7/exynos/Kconfig b/arch/arm/cpu/armv7/exynos/Kconfig
index bd7540ac61..f6084ac476 100644
--- a/arch/arm/cpu/armv7/exynos/Kconfig
+++ b/arch/arm/cpu/armv7/exynos/Kconfig
@@ -65,19 +65,7 @@ endchoice
config SYS_SOC
default "exynos"
-config DM
- default y
-
-config DM_SERIAL
- default y
-
-config DM_SPI
- default y
-
-config DM_SPI_FLASH
- default y
-
-config DM_GPIO
+config DM_USB
default y
source "board/samsung/smdkv310/Kconfig"
diff --git a/arch/arm/cpu/armv7/omap-common/boot-common.c b/arch/arm/cpu/armv7/omap-common/boot-common.c
index 17500f2315..f2f6897eb6 100644
--- a/arch/arm/cpu/armv7/omap-common/boot-common.c
+++ b/arch/arm/cpu/armv7/omap-common/boot-common.c
@@ -159,6 +159,6 @@ void __noreturn jump_to_image_no_args(struct spl_image_info *spl_image)
#ifdef CONFIG_SCSI_AHCI_PLAT
void arch_preboot_os(void)
{
- ahci_reset(DWC_AHSATA_BASE);
+ ahci_reset((void __iomem *)DWC_AHSATA_BASE);
}
#endif
diff --git a/arch/arm/cpu/armv7/omap-common/sata.c b/arch/arm/cpu/armv7/omap-common/sata.c
index d18bc50c5a..2c2d1bce36 100644
--- a/arch/arm/cpu/armv7/omap-common/sata.c
+++ b/arch/arm/cpu/armv7/omap-common/sata.c
@@ -69,7 +69,7 @@ int init_sata(int dev)
val = TI_SATA_IDLE_NO | TI_SATA_STANDBY_NO;
writel(val, TI_SATA_WRAPPER_BASE + TI_SATA_SYSCONFIG);
- ret = ahci_init(DWC_AHSATA_BASE);
+ ret = ahci_init((void __iomem *)DWC_AHSATA_BASE);
return ret;
}
@@ -88,6 +88,6 @@ void scsi_init(void)
void scsi_bus_reset(void)
{
- ahci_reset(DWC_AHSATA_BASE);
- ahci_init(DWC_AHSATA_BASE);
+ ahci_reset((void __iomem *)DWC_AHSATA_BASE);
+ ahci_init((void __iomem *)DWC_AHSATA_BASE);
}
diff --git a/arch/arm/cpu/armv7/omap3/Kconfig b/arch/arm/cpu/armv7/omap3/Kconfig
index 1f96498fb8..cc82c5000e 100644
--- a/arch/arm/cpu/armv7/omap3/Kconfig
+++ b/arch/arm/cpu/armv7/omap3/Kconfig
@@ -17,6 +17,9 @@ config TARGET_OMAP3_SDP3430
config TARGET_OMAP3_BEAGLE
bool "TI OMAP3 BeagleBoard"
select SUPPORT_SPL
+ select DM
+ select DM_SERIAL
+ select DM_GPIO
config TARGET_CM_T35
bool "CompuLab CM-T3530 and CM-T3730 boards"
@@ -28,6 +31,9 @@ config TARGET_CM_T3517
config TARGET_DEVKIT8000
bool "TimLL OMAP3 Devkit8000"
select SUPPORT_SPL
+ select DM
+ select DM_SERIAL
+ select DM_GPIO
config TARGET_OMAP3_EVM
bool "TI OMAP3 EVM"
@@ -44,13 +50,22 @@ config TARGET_OMAP3_EVM_QUICK_NAND
config TARGET_OMAP3_IGEP00X0
bool "IGEP"
select SUPPORT_SPL
+ select DM
+ select DM_SERIAL
+ select DM_GPIO
config TARGET_OMAP3_OVERO
bool "OMAP35xx Gumstix Overo"
select SUPPORT_SPL
+ select DM
+ select DM_SERIAL
+ select DM_GPIO
config TARGET_OMAP3_ZOOM1
bool "TI Zoom1"
+ select DM
+ select DM_SERIAL
+ select DM_GPIO
config TARGET_AM3517_CRANE
bool "am3517_crane"
@@ -94,18 +109,12 @@ config TARGET_TWISTER
config TARGET_OMAP3_CAIRO
bool "QUIPOS CAIRO"
select SUPPORT_SPL
+ select DM
+ select DM_SERIAL
+ select DM_GPIO
endchoice
-config DM
- default y
-
-config DM_GPIO
- default y if DM
-
-config DM_SERIAL
- default y if DM
-
config SYS_SOC
default "omap3"
diff --git a/arch/arm/cpu/armv7/rmobile/Kconfig b/arch/arm/cpu/armv7/rmobile/Kconfig
index 2b333a3d46..57dcceccc7 100644
--- a/arch/arm/cpu/armv7/rmobile/Kconfig
+++ b/arch/arm/cpu/armv7/rmobile/Kconfig
@@ -8,24 +8,36 @@ config TARGET_ARMADILLO_800EVA
config TARGET_GOSE
bool "Gose board"
+ select DM
+ select DM_SERIAL
config TARGET_KOELSCH
bool "Koelsch board"
+ select DM
+ select DM_SERIAL
config TARGET_LAGER
bool "Lager board"
+ select DM
+ select DM_SERIAL
config TARGET_KZM9G
bool "KZM9D board"
config TARGET_ALT
bool "Alt board"
+ select DM
+ select DM_SERIAL
config TARGET_SILK
bool "Silk board"
+ select DM
+ select DM_SERIAL
config TARGET_PORTER
bool "Porter board"
+ select DM
+ select DM_SERIAL
endchoice
diff --git a/arch/arm/cpu/armv7/socfpga/misc.c b/arch/arm/cpu/armv7/socfpga/misc.c
index 7873c38e2b..0f8b4d095d 100644
--- a/arch/arm/cpu/armv7/socfpga/misc.c
+++ b/arch/arm/cpu/armv7/socfpga/misc.c
@@ -49,7 +49,7 @@ void enable_caches(void)
/*
* DesignWare Ethernet initialization
*/
-#ifdef CONFIG_DESIGNWARE_ETH
+#ifdef CONFIG_ETH_DESIGNWARE
int cpu_eth_init(bd_t *bis)
{
#if CONFIG_EMAC_BASE == SOCFPGA_EMAC0_ADDRESS
diff --git a/arch/arm/dts/Makefile b/arch/arm/dts/Makefile
index f897e6d969..09708d9a41 100644
--- a/arch/arm/dts/Makefile
+++ b/arch/arm/dts/Makefile
@@ -54,6 +54,9 @@ dtb-$(CONFIG_SOCFPGA) += \
socfpga_cyclone5_socdk.dtb \
socfpga_cyclone5_socrates.dtb
+dtb-$(CONFIG_LS102XA) += ls1021a-qds.dtb \
+ ls1021a-twr.dtb
+
targets += $(dtb-y)
DTC_FLAGS += -R 4 -p 0x1000
diff --git a/arch/arm/dts/exynos5250-snow.dts b/arch/arm/dts/exynos5250-snow.dts
index 7d8be69d73..e89a94fce2 100644
--- a/arch/arm/dts/exynos5250-snow.dts
+++ b/arch/arm/dts/exynos5250-snow.dts
@@ -40,9 +40,9 @@
};
i2c4: i2c@12ca0000 {
- cros-ec@1e {
+ cros_ec: cros-ec@1e {
reg = <0x1e>;
- compatible = "google,cros-ec";
+ compatible = "google,cros-ec-i2c";
i2c-max-frequency = <100000>;
u-boot,i2c-offset-len = <0>;
ec-interrupt = <&gpx1 6 GPIO_ACTIVE_LOW>;
@@ -65,9 +65,10 @@
spi@131b0000 {
spi-max-frequency = <1000000>;
spi-deactivate-delay = <100>;
- cros_ec: cros-ec@0 {
- reg = <0>;
- compatible = "google,cros-ec";
+
+ embedded-controller {
+ compatible = "google,cros-ec-i2c";
+ reg = <0x1e>;
spi-max-frequency = <5000000>;
ec-interrupt = <&gpx1 6 GPIO_ACTIVE_LOW>;
optimise-flash-write;
@@ -133,6 +134,7 @@
ehci@12110000 {
samsung,vbus-gpio = <&gpx1 1 GPIO_ACTIVE_HIGH>;
+ status = "okay";
};
xhci@12000000 {
diff --git a/arch/arm/dts/exynos5420-peach-pit.dts b/arch/arm/dts/exynos5420-peach-pit.dts
index 3ad4728138..7d8fa28d16 100644
--- a/arch/arm/dts/exynos5420-peach-pit.dts
+++ b/arch/arm/dts/exynos5420-peach-pit.dts
@@ -104,12 +104,12 @@
spi@12d40000 { /* spi2 */
spi-max-frequency = <4000000>;
spi-deactivate-delay = <200>;
+
cros_ec: cros-ec@0 {
+ compatible = "google,cros-ec-spi";
reg = <0>;
- compatible = "google,cros-ec";
spi-half-duplex;
spi-max-timeout-ms = <1100>;
- spi-frame-header = <0xec>;
ec-interrupt = <&gpx1 5 GPIO_ACTIVE_LOW>;
/*
diff --git a/arch/arm/dts/exynos5800-peach-pi.dts b/arch/arm/dts/exynos5800-peach-pi.dts
index 494f7641e7..8c1f616885 100644
--- a/arch/arm/dts/exynos5800-peach-pi.dts
+++ b/arch/arm/dts/exynos5800-peach-pi.dts
@@ -97,11 +97,10 @@
spi-max-frequency = <4000000>;
spi-deactivate-delay = <200>;
cros_ec: cros-ec@0 {
+ compatible = "google,cros-ec-spi";
reg = <0>;
- compatible = "google,cros-ec";
spi-half-duplex;
spi-max-timeout-ms = <1100>;
- spi-frame-header = <0xec>;
ec-interrupt = <&gpx1 5 GPIO_ACTIVE_LOW>;
/*
diff --git a/arch/arm/dts/ls1021a-qds.dts b/arch/arm/dts/ls1021a-qds.dts
new file mode 100644
index 0000000000..836781153d
--- /dev/null
+++ b/arch/arm/dts/ls1021a-qds.dts
@@ -0,0 +1,216 @@
+/*
+ * Freescale ls1021a QDS board device tree source
+ *
+ * Copyright 2013-2015 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/dts-v1/;
+#include "ls1021a.dtsi"
+
+/ {
+ model = "LS1021A QDS Board";
+
+ aliases {
+ enet0_rgmii_phy = &rgmii_phy1;
+ enet1_rgmii_phy = &rgmii_phy2;
+ enet2_rgmii_phy = &rgmii_phy3;
+ enet0_sgmii_phy = &sgmii_phy1c;
+ enet1_sgmii_phy = &sgmii_phy1d;
+ spi0 = &qspi;
+ spi1 = &dspi0;
+ };
+};
+
+&dspi0 {
+ bus-num = <0>;
+ status = "okay";
+
+ dspiflash: at45db021d@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spi-flash";
+ spi-max-frequency = <16000000>;
+ spi-cpol;
+ spi-cpha;
+ reg = <0>;
+ };
+};
+
+&qspi {
+ bus-num = <0>;
+ status = "okay";
+
+ qflash0: s25fl128s@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spi-flash";
+ spi-max-frequency = <20000000>;
+ reg = <0>;
+ };
+};
+
+&i2c0 {
+ status = "okay";
+
+ pca9547: mux@77 {
+ reg = <0x77>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x0>;
+
+ ds3232: rtc@68 {
+ compatible = "dallas,ds3232";
+ reg = <0x68>;
+ interrupts = <GIC_SPI 169 IRQ_TYPE_LEVEL_HIGH>;
+ };
+ };
+
+ i2c@2 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x2>;
+
+ ina220@40 {
+ compatible = "ti,ina220";
+ reg = <0x40>;
+ shunt-resistor = <1000>;
+ };
+
+ ina220@41 {
+ compatible = "ti,ina220";
+ reg = <0x41>;
+ shunt-resistor = <1000>;
+ };
+ };
+
+ i2c@3 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x3>;
+
+ eeprom@56 {
+ compatible = "atmel,24c512";
+ reg = <0x56>;
+ };
+
+ eeprom@57 {
+ compatible = "atmel,24c512";
+ reg = <0x57>;
+ };
+
+ adt7461a@4c {
+ compatible = "adi,adt7461a";
+ reg = <0x4c>;
+ };
+ };
+ };
+};
+
+&ifc {
+ #address-cells = <2>;
+ #size-cells = <1>;
+ /* NOR, NAND Flashes and FPGA on board */
+ ranges = <0x0 0x0 0x60000000 0x08000000
+ 0x2 0x0 0x7e800000 0x00010000
+ 0x3 0x0 0x7fb00000 0x00000100>;
+ status = "okay";
+
+ nor@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "cfi-flash";
+ reg = <0x0 0x0 0x8000000>;
+ bank-width = <2>;
+ device-width = <1>;
+ };
+
+ fpga: board-control@3,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "simple-bus";
+ reg = <0x3 0x0 0x0000100>;
+ bank-width = <1>;
+ device-width = <1>;
+ ranges = <0 3 0 0x100>;
+
+ mdio-mux-emi1 {
+ compatible = "mdio-mux-mmioreg";
+ mdio-parent-bus = <&mdio0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x54 1>; /* BRDCFG4 */
+ mux-mask = <0xe0>; /* EMI1[2:0] */
+
+ /* Onboard PHYs */
+ ls1021amdio0: mdio@0 {
+ reg = <0>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ rgmii_phy1: ethernet-phy@1 {
+ reg = <0x1>;
+ };
+ };
+
+ ls1021amdio1: mdio@20 {
+ reg = <0x20>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ rgmii_phy2: ethernet-phy@2 {
+ reg = <0x2>;
+ };
+ };
+
+ ls1021amdio2: mdio@40 {
+ reg = <0x40>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ rgmii_phy3: ethernet-phy@3 {
+ reg = <0x3>;
+ };
+ };
+
+ ls1021amdio3: mdio@60 {
+ reg = <0x60>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ sgmii_phy1c: ethernet-phy@1c {
+ reg = <0x1c>;
+ };
+ };
+
+ ls1021amdio4: mdio@80 {
+ reg = <0x80>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+ sgmii_phy1d: ethernet-phy@1d {
+ reg = <0x1d>;
+ };
+ };
+ };
+ };
+};
+
+&lpuart0 {
+ status = "okay";
+};
+
+&mdio0 {
+ tbi0: tbi-phy@8 {
+ reg = <0x8>;
+ device_type = "tbi-phy";
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&uart1 {
+ status = "okay";
+};
diff --git a/arch/arm/dts/ls1021a-twr.dts b/arch/arm/dts/ls1021a-twr.dts
new file mode 100644
index 0000000000..0e61c07c5a
--- /dev/null
+++ b/arch/arm/dts/ls1021a-twr.dts
@@ -0,0 +1,87 @@
+/*
+ * Freescale ls1021a TWR board device tree source
+ *
+ * Copyright 2013-2015 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/dts-v1/;
+#include "ls1021a.dtsi"
+
+/ {
+ model = "LS1021A TWR Board";
+
+ aliases {
+ enet2_rgmii_phy = &rgmii_phy1;
+ enet0_sgmii_phy = &sgmii_phy2;
+ enet1_sgmii_phy = &sgmii_phy0;
+ spi0 = &qspi;
+ };
+};
+
+&qspi {
+ bus-num = <0>;
+ status = "okay";
+
+ qflash0: n25q128a13@0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "spi-flash";
+ spi-max-frequency = <20000000>;
+ reg = <0>;
+ };
+};
+
+&i2c0 {
+ status = "okay";
+};
+
+&i2c1 {
+ status = "okay";
+};
+
+&ifc {
+ #address-cells = <2>;
+ #size-cells = <1>;
+ /* NOR Flash on board */
+ ranges = <0x0 0x0 0x60000000 0x08000000>;
+ status = "okay";
+
+ nor@0,0 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ compatible = "cfi-flash";
+ reg = <0x0 0x0 0x8000000>;
+ bank-width = <2>;
+ device-width = <1>;
+ };
+};
+
+&lpuart0 {
+ status = "okay";
+};
+
+&mdio0 {
+ sgmii_phy0: ethernet-phy@0 {
+ reg = <0x0>;
+ };
+ rgmii_phy1: ethernet-phy@1 {
+ reg = <0x1>;
+ };
+ sgmii_phy2: ethernet-phy@2 {
+ reg = <0x2>;
+ };
+ tbi1: tbi-phy@1f {
+ reg = <0x1f>;
+ device_type = "tbi-phy";
+ };
+};
+
+&uart0 {
+ status = "okay";
+};
+
+&uart1 {
+ status = "okay";
+};
diff --git a/arch/arm/dts/ls1021a.dtsi b/arch/arm/dts/ls1021a.dtsi
new file mode 100644
index 0000000000..7fadd7ca57
--- /dev/null
+++ b/arch/arm/dts/ls1021a.dtsi
@@ -0,0 +1,381 @@
+/*
+ * Freescale ls1021a SOC common device tree source
+ *
+ * Copyright 2013-2015 Freescale Semiconductor, Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include "skeleton.dtsi"
+#include <dt-bindings/interrupt-controller/arm-gic.h>
+
+/ {
+ compatible = "fsl,ls1021a";
+ interrupt-parent = <&gic>;
+
+ aliases {
+ serial0 = &lpuart0;
+ serial1 = &lpuart1;
+ serial2 = &lpuart2;
+ serial3 = &lpuart3;
+ serial4 = &lpuart4;
+ serial5 = &lpuart5;
+ sysclk = &sysclk;
+ };
+
+ cpus {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ cpu@f00 {
+ compatible = "arm,cortex-a7";
+ device_type = "cpu";
+ reg = <0xf00>;
+ clocks = <&cluster1_clk>;
+ };
+
+ cpu@f01 {
+ compatible = "arm,cortex-a7";
+ device_type = "cpu";
+ reg = <0xf01>;
+ clocks = <&cluster1_clk>;
+ };
+ };
+
+ timer {
+ compatible = "arm,armv7-timer";
+ interrupts = <GIC_PPI 13 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 14 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 11 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>,
+ <GIC_PPI 10 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_LOW)>;
+ };
+
+ pmu {
+ compatible = "arm,cortex-a7-pmu";
+ interrupts = <GIC_SPI 138 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 139 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ soc {
+ compatible = "simple-bus";
+ #address-cells = <1>;
+ #size-cells = <1>;
+ device_type = "soc";
+ interrupt-parent = <&gic>;
+ ranges;
+
+ gic: interrupt-controller@1400000 {
+ compatible = "arm,cortex-a7-gic";
+ #interrupt-cells = <3>;
+ interrupt-controller;
+ reg = <0x1401000 0x1000>,
+ <0x1402000 0x1000>,
+ <0x1404000 0x2000>,
+ <0x1406000 0x2000>;
+ interrupts = <GIC_PPI 9 (GIC_CPU_MASK_SIMPLE(2) | IRQ_TYPE_LEVEL_HIGH)>;
+
+ };
+
+ ifc: ifc@1530000 {
+ compatible = "fsl,ifc", "simple-bus";
+ reg = <0x1530000 0x10000>;
+ interrupts = <GIC_SPI 75 IRQ_TYPE_LEVEL_HIGH>;
+ };
+
+ dcfg: dcfg@1ee0000 {
+ compatible = "fsl,ls1021a-dcfg", "syscon";
+ reg = <0x1ee0000 0x10000>;
+ big-endian;
+ };
+
+ esdhc: esdhc@1560000 {
+ compatible = "fsl,esdhc";
+ reg = <0x1560000 0x10000>;
+ interrupts = <GIC_SPI 94 IRQ_TYPE_LEVEL_HIGH>;
+ clock-frequency = <0>;
+ voltage-ranges = <1800 1800 3300 3300>;
+ sdhci,auto-cmd12;
+ big-endian;
+ bus-width = <4>;
+ status = "disabled";
+ };
+
+ scfg: scfg@1570000 {
+ compatible = "fsl,ls1021a-scfg", "syscon";
+ reg = <0x1570000 0x10000>;
+ big-endian;
+ };
+
+ clockgen: clocking@1ee1000 {
+ #address-cells = <1>;
+ #size-cells = <1>;
+ ranges = <0x0 0x1ee1000 0x10000>;
+
+ sysclk: sysclk {
+ compatible = "fixed-clock";
+ #clock-cells = <0>;
+ clock-output-names = "sysclk";
+ };
+
+ cga_pll1: pll@800 {
+ compatible = "fsl,qoriq-core-pll-2.0";
+ #clock-cells = <1>;
+ reg = <0x800 0x10>;
+ clocks = <&sysclk>;
+ clock-output-names = "cga-pll1", "cga-pll1-div2",
+ "cga-pll1-div4";
+ };
+
+ platform_clk: pll@c00 {
+ compatible = "fsl,qoriq-core-pll-2.0";
+ #clock-cells = <1>;
+ reg = <0xc00 0x10>;
+ clocks = <&sysclk>;
+ clock-output-names = "platform-clk", "platform-clk-div2";
+ };
+
+ cluster1_clk: clk0c0@0 {
+ compatible = "fsl,qoriq-core-mux-2.0";
+ #clock-cells = <0>;
+ reg = <0x0 0x10>;
+ clock-names = "pll1cga", "pll1cga-div2", "pll1cga-div4";
+ clocks = <&cga_pll1 0>, <&cga_pll1 1>, <&cga_pll1 2>;
+ clock-output-names = "cluster1-clk";
+ };
+ };
+
+ dspi0: dspi@2100000 {
+ compatible = "fsl,vf610-dspi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x2100000 0x10000>;
+ interrupts = <GIC_SPI 96 IRQ_TYPE_LEVEL_HIGH>;
+ clock-names = "dspi";
+ clocks = <&platform_clk 1>;
+ num-cs = <6>;
+ big-endian;
+ status = "disabled";
+ };
+
+ dspi1: dspi@2110000 {
+ compatible = "fsl,vf610-dspi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x2110000 0x10000>;
+ interrupts = <GIC_SPI 97 IRQ_TYPE_LEVEL_HIGH>;
+ clock-names = "dspi";
+ clocks = <&platform_clk 1>;
+ num-cs = <6>;
+ big-endian;
+ status = "disabled";
+ };
+
+ qspi: quadspi@1550000 {
+ compatible = "fsl,vf610-qspi";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x1550000 0x10000>,
+ <0x40000000 0x4000000>;
+ num-cs = <2>;
+ big-endian;
+ status = "disabled";
+ };
+
+ i2c0: i2c@2180000 {
+ compatible = "fsl,vf610-i2c";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x2180000 0x10000>;
+ interrupts = <GIC_SPI 88 IRQ_TYPE_LEVEL_HIGH>;
+ clock-names = "i2c";
+ clocks = <&platform_clk 1>;
+ status = "disabled";
+ };
+
+ i2c1: i2c@2190000 {
+ compatible = "fsl,vf610-i2c";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x2190000 0x10000>;
+ interrupts = <GIC_SPI 89 IRQ_TYPE_LEVEL_HIGH>;
+ clock-names = "i2c";
+ clocks = <&platform_clk 1>;
+ status = "disabled";
+ };
+
+ i2c2: i2c@21a0000 {
+ compatible = "fsl,vf610-i2c";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x21a0000 0x10000>;
+ interrupts = <GIC_SPI 90 IRQ_TYPE_LEVEL_HIGH>;
+ clock-names = "i2c";
+ clocks = <&platform_clk 1>;
+ status = "disabled";
+ };
+
+ uart0: serial@21c0500 {
+ compatible = "fsl,16550-FIFO64", "ns16550a";
+ reg = <0x21c0500 0x100>;
+ interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+ clock-frequency = <0>;
+ fifo-size = <15>;
+ status = "disabled";
+ };
+
+ uart1: serial@21c0600 {
+ compatible = "fsl,16550-FIFO64", "ns16550a";
+ reg = <0x21c0600 0x100>;
+ interrupts = <GIC_SPI 86 IRQ_TYPE_LEVEL_HIGH>;
+ clock-frequency = <0>;
+ fifo-size = <15>;
+ status = "disabled";
+ };
+
+ uart2: serial@21d0500 {
+ compatible = "fsl,16550-FIFO64", "ns16550a";
+ reg = <0x21d0500 0x100>;
+ interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>;
+ clock-frequency = <0>;
+ fifo-size = <15>;
+ status = "disabled";
+ };
+
+ uart3: serial@21d0600 {
+ compatible = "fsl,16550-FIFO64", "ns16550a";
+ reg = <0x21d0600 0x100>;
+ interrupts = <GIC_SPI 87 IRQ_TYPE_LEVEL_HIGH>;
+ clock-frequency = <0>;
+ fifo-size = <15>;
+ status = "disabled";
+ };
+
+ lpuart0: serial@2950000 {
+ compatible = "fsl,ls1021a-lpuart";
+ reg = <0x2950000 0x1000>;
+ interrupts = <GIC_SPI 80 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&sysclk>;
+ clock-names = "ipg";
+ status = "disabled";
+ };
+
+ lpuart1: serial@2960000 {
+ compatible = "fsl,ls1021a-lpuart";
+ reg = <0x2960000 0x1000>;
+ interrupts = <GIC_SPI 81 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&platform_clk 1>;
+ clock-names = "ipg";
+ status = "disabled";
+ };
+
+ lpuart2: serial@2970000 {
+ compatible = "fsl,ls1021a-lpuart";
+ reg = <0x2970000 0x1000>;
+ interrupts = <GIC_SPI 82 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&platform_clk 1>;
+ clock-names = "ipg";
+ status = "disabled";
+ };
+
+ lpuart3: serial@2980000 {
+ compatible = "fsl,ls1021a-lpuart";
+ reg = <0x2980000 0x1000>;
+ interrupts = <GIC_SPI 83 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&platform_clk 1>;
+ clock-names = "ipg";
+ status = "disabled";
+ };
+
+ lpuart4: serial@2990000 {
+ compatible = "fsl,ls1021a-lpuart";
+ reg = <0x2990000 0x1000>;
+ interrupts = <GIC_SPI 84 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&platform_clk 1>;
+ clock-names = "ipg";
+ status = "disabled";
+ };
+
+ lpuart5: serial@29a0000 {
+ compatible = "fsl,ls1021a-lpuart";
+ reg = <0x29a0000 0x1000>;
+ interrupts = <GIC_SPI 85 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&platform_clk 1>;
+ clock-names = "ipg";
+ status = "disabled";
+ };
+
+ wdog0: watchdog@2ad0000 {
+ compatible = "fsl,imx21-wdt";
+ reg = <0x2ad0000 0x10000>;
+ interrupts = <GIC_SPI 115 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&platform_clk 1>;
+ clock-names = "wdog-en";
+ big-endian;
+ };
+
+ sai1: sai@2b50000 {
+ compatible = "fsl,vf610-sai";
+ reg = <0x2b50000 0x10000>;
+ interrupts = <GIC_SPI 132 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&platform_clk 1>;
+ clock-names = "sai";
+ dma-names = "tx", "rx";
+ dmas = <&edma0 1 47>,
+ <&edma0 1 46>;
+ big-endian;
+ status = "disabled";
+ };
+
+ sai2: sai@2b60000 {
+ compatible = "fsl,vf610-sai";
+ reg = <0x2b60000 0x10000>;
+ interrupts = <GIC_SPI 133 IRQ_TYPE_LEVEL_HIGH>;
+ clocks = <&platform_clk 1>;
+ clock-names = "sai";
+ dma-names = "tx", "rx";
+ dmas = <&edma0 1 45>,
+ <&edma0 1 44>;
+ big-endian;
+ status = "disabled";
+ };
+
+ edma0: edma@2c00000 {
+ #dma-cells = <2>;
+ compatible = "fsl,vf610-edma";
+ reg = <0x2c00000 0x10000>,
+ <0x2c10000 0x10000>,
+ <0x2c20000 0x10000>;
+ interrupts = <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>,
+ <GIC_SPI 135 IRQ_TYPE_LEVEL_HIGH>;
+ interrupt-names = "edma-tx", "edma-err";
+ dma-channels = <32>;
+ big-endian;
+ clock-names = "dmamux0", "dmamux1";
+ clocks = <&platform_clk 1>,
+ <&platform_clk 1>;
+ };
+
+ mdio0: mdio@2d24000 {
+ compatible = "gianfar";
+ device_type = "mdio";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0x2d24000 0x4000>;
+ };
+
+ usb@8600000 {
+ compatible = "fsl-usb2-dr-v2.5", "fsl-usb2-dr";
+ reg = <0x8600000 0x1000>;
+ interrupts = <GIC_SPI 171 IRQ_TYPE_LEVEL_HIGH>;
+ dr_mode = "host";
+ phy_type = "ulpi";
+ };
+
+ usb3@3100000 {
+ compatible = "snps,dwc3";
+ reg = <0x3100000 0x10000>;
+ interrupts = <GIC_SPI 93 IRQ_TYPE_LEVEL_HIGH>;
+ dr_mode = "host";
+ };
+ };
+};
diff --git a/arch/arm/dts/skeleton64.dtsi b/arch/arm/dts/skeleton64.dtsi
new file mode 100644
index 0000000000..b5d7f36f33
--- /dev/null
+++ b/arch/arm/dts/skeleton64.dtsi
@@ -0,0 +1,13 @@
+/*
+ * Skeleton device tree in the 64 bits version; the bare minimum
+ * needed to boot; just include and add a compatible value. The
+ * bootloader will typically populate the memory node.
+ */
+
+/ {
+ #address-cells = <2>;
+ #size-cells = <2>;
+ chosen { };
+ aliases { };
+ memory { device_type = "memory"; reg = <0 0 0 0>; };
+};
diff --git a/arch/arm/dts/tegra124-nyan-big.dts b/arch/arm/dts/tegra124-nyan-big.dts
index c1f35a07bd..9367193a24 100644
--- a/arch/arm/dts/tegra124-nyan-big.dts
+++ b/arch/arm/dts/tegra124-nyan-big.dts
@@ -230,6 +230,7 @@
usb@7d000000 { /* Rear external USB port. */
status = "okay";
+ nvidia,vbus-gpio = <&gpio TEGRA_GPIO(N, 4) GPIO_ACTIVE_HIGH>;
};
usb-phy@7d000000 {
@@ -246,6 +247,7 @@
usb@7d008000 { /* Left external USB port. */
status = "okay";
+ nvidia,vbus-gpio = <&gpio TEGRA_GPIO(N, 5) GPIO_ACTIVE_HIGH>;
};
usb-phy@7d008000 {
diff --git a/arch/arm/lib/board.c b/arch/arm/lib/board.c
index f6062557e6..37ea6e90ec 100644
--- a/arch/arm/lib/board.c
+++ b/arch/arm/lib/board.c
@@ -644,7 +644,7 @@ void board_init_r(gd_t *id, ulong dest_addr)
#endif
#if defined(CONFIG_CMD_NET)
puts("Net: ");
- eth_initialize(gd->bd);
+ eth_initialize();
#if defined(CONFIG_RESET_PHY_R)
debug("Reset Ethernet PHY\n");
reset_phy();
diff --git a/arch/arm/lib/bootm.c b/arch/arm/lib/bootm.c
index 2d6b676154..b1bff8ce26 100644
--- a/arch/arm/lib/bootm.c
+++ b/arch/arm/lib/bootm.c
@@ -18,6 +18,7 @@
#include <u-boot/zlib.h>
#include <asm/byteorder.h>
#include <libfdt.h>
+#include <mapmem.h>
#include <fdt_support.h>
#include <asm/bootm.h>
#include <asm/secure.h>
diff --git a/arch/arm/mach-at91/Kconfig b/arch/arm/mach-at91/Kconfig
index 30c4e17ec9..b660a5b9eb 100644
--- a/arch/arm/mach-at91/Kconfig
+++ b/arch/arm/mach-at91/Kconfig
@@ -30,6 +30,9 @@ config TARGET_TNY_A9260
config TARGET_SNAPPER9260
bool "Support snapper9260"
select CPU_ARM926EJS
+ select DM
+ select DM_SERIAL
+ select DM_GPIO
config TARGET_AFEB9260
bool "Support afeb9260"
diff --git a/arch/arm/mach-bcm283x/Kconfig b/arch/arm/mach-bcm283x/Kconfig
index 0c04c301b2..c740180e68 100644
--- a/arch/arm/mach-bcm283x/Kconfig
+++ b/arch/arm/mach-bcm283x/Kconfig
@@ -14,15 +14,6 @@ config TARGET_RPI_2
endchoice
-config DM
- default y
-
-config DM_SERIAL
- default y
-
-config DM_GPIO
- default y
-
config PHYS_TO_BUS
default y
diff --git a/arch/arm/mach-davinci/misc.c b/arch/arm/mach-davinci/misc.c
index e18bdfc729..e699d61874 100644
--- a/arch/arm/mach-davinci/misc.c
+++ b/arch/arm/mach-davinci/misc.c
@@ -49,7 +49,7 @@ int dvevm_read_mac_address(uint8_t *buf)
goto i2cerr;
/* Check that MAC address is valid. */
- if (!is_valid_ether_addr(buf))
+ if (!is_valid_ethaddr(buf))
goto err;
return 1; /* Found */
diff --git a/arch/arm/mach-tegra/Kconfig b/arch/arm/mach-tegra/Kconfig
index fce1c1dc87..8bab594f49 100644
--- a/arch/arm/mach-tegra/Kconfig
+++ b/arch/arm/mach-tegra/Kconfig
@@ -23,27 +23,9 @@ config SYS_MALLOC_F_LEN
config USE_PRIVATE_LIBGCC
default y
-config DM
- default y
-
config SPL_DM
default y
-config DM_SERIAL
- default y
-
-config DM_SPI
- default y
-
-config DM_SPI_FLASH
- default y
-
-config DM_I2C
- default y
-
-config DM_GPIO
- default y
-
source "arch/arm/mach-tegra/tegra20/Kconfig"
source "arch/arm/mach-tegra/tegra30/Kconfig"
source "arch/arm/mach-tegra/tegra114/Kconfig"
diff --git a/arch/avr32/lib/board.c b/arch/avr32/lib/board.c
index 99aa96e23f..aacfcbf69a 100644
--- a/arch/avr32/lib/board.c
+++ b/arch/avr32/lib/board.c
@@ -244,7 +244,7 @@ void board_init_r(gd_t *new_gd, ulong dest_addr)
#endif
#if defined(CONFIG_CMD_NET)
puts("Net: ");
- eth_initialize(gd->bd);
+ eth_initialize();
#endif
#ifdef CONFIG_GENERIC_ATMEL_MCI
diff --git a/arch/mips/mach-au1x00/au1x00_eth.c b/arch/mips/mach-au1x00/au1x00_eth.c
index 39c5b6bc4a..d6ebe07643 100644
--- a/arch/mips/mach-au1x00/au1x00_eth.c
+++ b/arch/mips/mach-au1x00/au1x00_eth.c
@@ -187,13 +187,14 @@ static int au1x00_recv(struct eth_device* dev){
if(status&RX_ERROR){
printf("Rx error 0x%x\n", status);
- }
- else{
+ } else {
/* Pass the packet up to the protocol layers. */
- NetReceive(NetRxPackets[next_rx], length - 4);
+ net_process_received_packet(net_rx_packets[next_rx],
+ length - 4);
}
- fifo_rx[next_rx].addr = (virt_to_phys(NetRxPackets[next_rx]))|RX_DMA_ENABLE;
+ fifo_rx[next_rx].addr =
+ (virt_to_phys(net_rx_packets[next_rx])) | RX_DMA_ENABLE;
next_rx++;
if(next_rx>=NO_OF_FIFOS){
@@ -234,11 +235,12 @@ static int au1x00_init(struct eth_device* dev, bd_t * bd){
for(i=0;i<NO_OF_FIFOS;i++){
fifo_tx[i].len = 0;
fifo_tx[i].addr = virt_to_phys(&txbuf[0]);
- fifo_rx[i].addr = (virt_to_phys(NetRxPackets[i]))|RX_DMA_ENABLE;
+ fifo_rx[i].addr = (virt_to_phys(net_rx_packets[i])) |
+ RX_DMA_ENABLE;
}
/* Put mac addr in little endian */
-#define ea eth_get_dev()->enetaddr
+#define ea eth_get_ethaddr()
*mac_addr_high = (ea[5] << 8) | (ea[4] ) ;
*mac_addr_low = (ea[3] << 24) | (ea[2] << 16) |
(ea[1] << 8) | (ea[0] ) ;
diff --git a/arch/nds32/lib/board.c b/arch/nds32/lib/board.c
index 4c06a4866b..24a09bc3c2 100644
--- a/arch/nds32/lib/board.c
+++ b/arch/nds32/lib/board.c
@@ -383,7 +383,7 @@ void board_init_r(gd_t *id, ulong dest_addr)
#if defined(CONFIG_CMD_NET)
puts("Net: ");
- eth_initialize(gd->bd);
+ eth_initialize();
#if defined(CONFIG_RESET_PHY_R)
debug("Reset Ethernet PHY\n");
reset_phy();
diff --git a/arch/openrisc/lib/board.c b/arch/openrisc/lib/board.c
index 234668538c..c26cc8f503 100644
--- a/arch/openrisc/lib/board.c
+++ b/arch/openrisc/lib/board.c
@@ -128,7 +128,7 @@ void board_init(void)
#if defined(CONFIG_CMD_NET)
puts("NET: ");
- eth_initialize(bd);
+ eth_initialize();
#endif
/* main_loop */
diff --git a/arch/powerpc/cpu/mpc8260/ether_fcc.c b/arch/powerpc/cpu/mpc8260/ether_fcc.c
index f9f15b59e5..30ea3de9cf 100644
--- a/arch/powerpc/cpu/mpc8260/ether_fcc.c
+++ b/arch/powerpc/cpu/mpc8260/ether_fcc.c
@@ -183,7 +183,7 @@ static int fec_recv(struct eth_device* dev)
}
else {
/* Pass the packet up to the protocol layers. */
- NetReceive(NetRxPackets[rxIdx], length - 4);
+ net_process_received_packet(net_rx_packets[rxIdx], length - 4);
}
@@ -243,7 +243,7 @@ static int fec_init(struct eth_device* dev, bd_t *bis)
{
rtx.rxbd[i].cbd_sc = BD_ENET_RX_EMPTY;
rtx.rxbd[i].cbd_datlen = 0;
- rtx.rxbd[i].cbd_bufaddr = (uint)NetRxPackets[i];
+ rtx.rxbd[i].cbd_bufaddr = (uint)net_rx_packets[i];
}
rtx.rxbd[PKTBUFSRX - 1].cbd_sc |= BD_ENET_RX_WRAP;
@@ -299,7 +299,7 @@ static int fec_init(struct eth_device* dev, bd_t *bis)
* it unique by setting a few bits in the upper byte of the
* non-static part of the address.
*/
-#define ea eth_get_dev()->enetaddr
+#define ea eth_get_ethaddr()
pram_ptr->fen_paddrh = (ea[5] << 8) + ea[4];
pram_ptr->fen_paddrm = (ea[3] << 8) + ea[2];
pram_ptr->fen_paddrl = (ea[1] << 8) + ea[0];
@@ -637,7 +637,7 @@ eth_loopback_test (void)
puts ("FCC Ethernet External loopback test\n");
- eth_getenv_enetaddr("ethaddr", NetOurEther);
+ eth_getenv_enetaddr("ethaddr", net_ethaddr);
/*
* global initialisations for all FCC channels
@@ -720,8 +720,8 @@ eth_loopback_test (void)
bdp->cbd_sc = BD_ENET_TX_READY | BD_ENET_TX_PAD | \
BD_ENET_TX_LAST | BD_ENET_TX_TC;
- memset ((void *)bp, patbytes[i], ELBT_BUFSZ);
- NetSetEther (bp, NetBcastAddr, 0x8000);
+ memset((void *)bp, patbytes[i], ELBT_BUFSZ);
+ net_set_ether(bp, net_bcast_ethaddr, 0x8000);
}
ecp->txbd[ELBT_NTXBD - 1].cbd_sc |= BD_ENET_TX_WRAP;
@@ -799,11 +799,9 @@ eth_loopback_test (void)
* So, far we have only been given one Ethernet address. We use
* the same address for all channels
*/
-#define ea NetOurEther
- fpp->fen_paddrh = (ea[5] << 8) + ea[4];
- fpp->fen_paddrm = (ea[3] << 8) + ea[2];
- fpp->fen_paddrl = (ea[1] << 8) + ea[0];
-#undef ea
+ fpp->fen_paddrh = (net_ethaddr[5] << 8) + net_ethaddr[4];
+ fpp->fen_paddrm = (net_ethaddr[3] << 8) + net_ethaddr[2];
+ fpp->fen_paddrl = (net_ethaddr[1] << 8) + net_ethaddr[0];
fpp->fen_minflr = PKT_MINBUF_SIZE; /* min frame len register */
/*
@@ -1016,7 +1014,7 @@ eth_loopback_test (void)
&ecp->rxbufs[i][0];
ours = memcmp (ehp->et_src, \
- NetOurEther, 6);
+ net_ethaddr, 6);
prot = swap16 (ehp->et_protlen);
tb = prot & 0x8000;
diff --git a/arch/powerpc/cpu/mpc8260/ether_scc.c b/arch/powerpc/cpu/mpc8260/ether_scc.c
index c988def9b4..5ba8bed20d 100644
--- a/arch/powerpc/cpu/mpc8260/ether_scc.c
+++ b/arch/powerpc/cpu/mpc8260/ether_scc.c
@@ -146,7 +146,7 @@ static int sec_rx(struct eth_device *dev)
else
{
/* Pass the packet up to the protocol layers. */
- NetReceive(NetRxPackets[rxIdx], length - 4);
+ net_process_received_packet(net_rx_packets[rxIdx], length - 4);
}
@@ -263,7 +263,7 @@ static int sec_init(struct eth_device *dev, bd_t *bis)
{
rtx->rxbd[i].cbd_sc = BD_ENET_RX_EMPTY;
rtx->rxbd[i].cbd_datlen = 0; /* Reset */
- rtx->rxbd[i].cbd_bufaddr = (uint)NetRxPackets[i];
+ rtx->rxbd[i].cbd_bufaddr = (uint)net_rx_packets[i];
}
rtx->rxbd[PKTBUFSRX - 1].cbd_sc |= BD_ENET_RX_WRAP;
diff --git a/arch/powerpc/cpu/mpc83xx/Kconfig b/arch/powerpc/cpu/mpc83xx/Kconfig
index 4d6cb0964b..88a3bd6814 100644
--- a/arch/powerpc/cpu/mpc83xx/Kconfig
+++ b/arch/powerpc/cpu/mpc83xx/Kconfig
@@ -49,6 +49,7 @@ config TARGET_MPC837XERDB
config TARGET_IDS8313
bool "Support ids8313"
+ select DM
config TARGET_KM8360
bool "Support km8360"
diff --git a/arch/powerpc/cpu/mpc85xx/ether_fcc.c b/arch/powerpc/cpu/mpc85xx/ether_fcc.c
index 166dc9ed17..14358aeb03 100644
--- a/arch/powerpc/cpu/mpc85xx/ether_fcc.c
+++ b/arch/powerpc/cpu/mpc85xx/ether_fcc.c
@@ -186,7 +186,7 @@ static int fec_recv(struct eth_device* dev)
}
else {
/* Pass the packet up to the protocol layers. */
- NetReceive(NetRxPackets[rxIdx], length - 4);
+ net_process_received_packet(net_rx_packets[rxIdx], length - 4);
}
@@ -263,7 +263,7 @@ static int fec_init(struct eth_device* dev, bd_t *bis)
{
rtx.rxbd[i].cbd_sc = BD_ENET_RX_EMPTY;
rtx.rxbd[i].cbd_datlen = 0;
- rtx.rxbd[i].cbd_bufaddr = (uint)NetRxPackets[i];
+ rtx.rxbd[i].cbd_bufaddr = (uint)net_rx_packets[i];
}
rtx.rxbd[PKTBUFSRX - 1].cbd_sc |= BD_ENET_RX_WRAP;
@@ -338,7 +338,7 @@ static int fec_init(struct eth_device* dev, bd_t *bis)
* it unique by setting a few bits in the upper byte of the
* non-static part of the address.
*/
-#define ea eth_get_dev()->enetaddr
+#define ea eth_get_ethaddr()
pram_ptr->fen_paddrh = (ea[5] << 8) + ea[4];
pram_ptr->fen_paddrm = (ea[3] << 8) + ea[2];
pram_ptr->fen_paddrl = (ea[1] << 8) + ea[0];
diff --git a/arch/powerpc/cpu/mpc8xx/fec.c b/arch/powerpc/cpu/mpc8xx/fec.c
index 22b8ec752b..2e196033c2 100644
--- a/arch/powerpc/cpu/mpc8xx/fec.c
+++ b/arch/powerpc/cpu/mpc8xx/fec.c
@@ -247,21 +247,21 @@ static int fec_recv (struct eth_device *dev)
rtx->rxbd[rxIdx].cbd_sc);
#endif
} else {
- uchar *rx = NetRxPackets[rxIdx];
+ uchar *rx = net_rx_packets[rxIdx];
length -= 4;
#if defined(CONFIG_CMD_CDP)
- if ((rx[0] & 1) != 0
- && memcmp ((uchar *) rx, NetBcastAddr, 6) != 0
- && !is_cdp_packet((uchar *)rx))
+ if ((rx[0] & 1) != 0 &&
+ memcmp((uchar *)rx, net_bcast_ethaddr, 6) != 0 &&
+ !is_cdp_packet((uchar *)rx))
rx = NULL;
#endif
/*
* Pass the packet up to the protocol layers.
*/
if (rx != NULL)
- NetReceive (rx, length);
+ net_process_received_packet(rx, length);
}
/* Give the buffer back to the FEC. */
@@ -576,7 +576,7 @@ static int fec_init (struct eth_device *dev, bd_t * bd)
for (i = 0; i < PKTBUFSRX; i++) {
rtx->rxbd[i].cbd_sc = BD_ENET_RX_EMPTY;
rtx->rxbd[i].cbd_datlen = 0; /* Reset */
- rtx->rxbd[i].cbd_bufaddr = (uint) NetRxPackets[i];
+ rtx->rxbd[i].cbd_bufaddr = (uint) net_rx_packets[i];
}
rtx->rxbd[PKTBUFSRX - 1].cbd_sc |= BD_ENET_RX_WRAP;
diff --git a/arch/powerpc/cpu/mpc8xx/scc.c b/arch/powerpc/cpu/mpc8xx/scc.c
index 251966b4a0..549844032b 100644
--- a/arch/powerpc/cpu/mpc8xx/scc.c
+++ b/arch/powerpc/cpu/mpc8xx/scc.c
@@ -159,7 +159,8 @@ static int scc_recv (struct eth_device *dev)
#endif
} else {
/* Pass the packet up to the protocol layers. */
- NetReceive (NetRxPackets[rxIdx], length - 4);
+ net_process_received_packet(net_rx_packets[rxIdx],
+ length - 4);
}
@@ -280,7 +281,7 @@ static int scc_init (struct eth_device *dev, bd_t * bis)
for (i = 0; i < PKTBUFSRX; i++) {
rtx->rxbd[i].cbd_sc = BD_ENET_RX_EMPTY;
rtx->rxbd[i].cbd_datlen = 0; /* Reset */
- rtx->rxbd[i].cbd_bufaddr = (uint) NetRxPackets[i];
+ rtx->rxbd[i].cbd_bufaddr = (uint) net_rx_packets[i];
}
rtx->rxbd[PKTBUFSRX - 1].cbd_sc |= BD_ENET_RX_WRAP;
@@ -339,7 +340,7 @@ static int scc_init (struct eth_device *dev, bd_t * bis)
pram_ptr->sen_gaddr3 = 0x0; /* Group Address Filter 3 (unused) */
pram_ptr->sen_gaddr4 = 0x0; /* Group Address Filter 4 (unused) */
-#define ea eth_get_dev()->enetaddr
+#define ea eth_get_ethaddr()
pram_ptr->sen_paddrh = (ea[5] << 8) + ea[4];
pram_ptr->sen_paddrm = (ea[3] << 8) + ea[2];
pram_ptr->sen_paddrl = (ea[1] << 8) + ea[0];
diff --git a/arch/powerpc/cpu/ppc4xx/Kconfig b/arch/powerpc/cpu/ppc4xx/Kconfig
index 9e52d3f22d..89cb3e9c4e 100644
--- a/arch/powerpc/cpu/ppc4xx/Kconfig
+++ b/arch/powerpc/cpu/ppc4xx/Kconfig
@@ -43,6 +43,8 @@ config TARGET_BUBINGA
config TARGET_CANYONLANDS
bool "Support canyonlands"
+ select DM
+ select DM_SERIAL
config TARGET_EBONY
bool "Support ebony"
diff --git a/arch/powerpc/lib/board.c b/arch/powerpc/lib/board.c
index 91645d36ee..5ea29cc974 100644
--- a/arch/powerpc/lib/board.c
+++ b/arch/powerpc/lib/board.c
@@ -890,7 +890,7 @@ void board_init_r(gd_t *id, ulong dest_addr)
#if defined(CONFIG_CMD_NET)
WATCHDOG_RESET();
puts("Net: ");
- eth_initialize(bd);
+ eth_initialize();
#endif
#if defined(CONFIG_CMD_NET) && defined(CONFIG_RESET_PHY_R)
diff --git a/arch/sandbox/Kconfig b/arch/sandbox/Kconfig
index 2098b9c323..8aac96f8d9 100644
--- a/arch/sandbox/Kconfig
+++ b/arch/sandbox/Kconfig
@@ -10,28 +10,26 @@ config SYS_BOARD
config SYS_CONFIG_NAME
default "sandbox"
-config DM
- default y
-
-config DM_GPIO
- default y
-
-config DM_SERIAL
+config DM_TEST
default y
-config DM_CROS_EC
- default y
+config PCI
+ bool "PCI support"
+ help
+ Enable support for PCI (Peripheral Interconnect Bus), a type of bus
+ used on some devices to allow the CPU to communicate with its
+ peripherals.
-config DM_SPI
+config NET
default y
-config DM_SPI_FLASH
+config NETDEVICES
default y
-config DM_I2C
+config DM_ETH
default y
-config DM_TEST
+config ETH_SANDBOX_RAW
default y
endmenu
diff --git a/arch/sandbox/cpu/Makefile b/arch/sandbox/cpu/Makefile
index 7d4410c42a..1b42fee141 100644
--- a/arch/sandbox/cpu/Makefile
+++ b/arch/sandbox/cpu/Makefile
@@ -8,6 +8,7 @@
#
obj-y := cpu.o os.o start.o state.o
+obj-$(CONFIG_ETH_SANDBOX_RAW) += eth-raw-os.o
obj-$(CONFIG_SANDBOX_SDL) += sdl.o
# os.c is build in the system environment, so needs standard includes
@@ -20,3 +21,12 @@ $(obj)/os.o: $(src)/os.c FORCE
$(call if_changed_dep,cc_os.o)
$(obj)/sdl.o: $(src)/sdl.c FORCE
$(call if_changed_dep,cc_os.o)
+
+# eth-raw-os.c is built in the system env, so needs standard includes
+# CFLAGS_REMOVE_eth-raw-os.o cannot be used to drop header include path
+quiet_cmd_cc_eth-raw-os.o = CC $(quiet_modtag) $@
+cmd_cc_eth-raw-os.o = $(CC) $(filter-out -nostdinc, \
+ $(patsubst -I%,-idirafter%,$(c_flags))) -c -o $@ $<
+
+$(obj)/eth-raw-os.o: $(src)/eth-raw-os.c FORCE
+ $(call if_changed_dep,cc_eth-raw-os.o)
diff --git a/arch/sandbox/cpu/cpu.c b/arch/sandbox/cpu/cpu.c
index 1aa397c5e7..f0dafedc25 100644
--- a/arch/sandbox/cpu/cpu.c
+++ b/arch/sandbox/cpu/cpu.c
@@ -2,7 +2,7 @@
* Copyright (c) 2011 The Chromium OS Authors.
* SPDX-License-Identifier: GPL-2.0+
*/
-
+#define DEBUG
#include <common.h>
#include <dm/root.h>
#include <os.h>
@@ -10,6 +10,15 @@
DECLARE_GLOBAL_DATA_PTR;
+/* Enable access to PCI memory with map_sysmem() */
+static bool enable_pci_map;
+
+#ifdef CONFIG_PCI
+/* Last device that was mapped into memory, and length of mapping */
+static struct udevice *map_dev;
+unsigned long map_len;
+#endif
+
void reset_cpu(ulong ignored)
{
if (state_uninit())
@@ -40,26 +49,44 @@ unsigned long __attribute__((no_instrument_function)) timer_get_us(void)
return os_get_nsec() / 1000;
}
-int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
+int cleanup_before_linux(void)
+{
+ return 0;
+}
+
+void *map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags)
{
- if (flag & (BOOTM_STATE_OS_GO | BOOTM_STATE_OS_FAKE_GO)) {
- bootstage_mark(BOOTSTAGE_ID_RUN_OS);
- printf("## Transferring control to Linux (at address %08lx)...\n",
- images->ep);
- reset_cpu(0);
+#ifdef CONFIG_PCI
+ unsigned long plen = len;
+ void *ptr;
+
+ map_dev = NULL;
+ if (enable_pci_map && !pci_map_physmem(paddr, &len, &map_dev, &ptr)) {
+ if (plen != len) {
+ printf("%s: Warning: partial map at %x, wanted %lx, got %lx\n",
+ __func__, paddr, len, plen);
+ }
+ map_len = len;
+ return ptr;
}
+#endif
- return 0;
+ return (void *)(gd->arch.ram_buf + paddr);
}
-int cleanup_before_linux(void)
+void unmap_physmem(const void *vaddr, unsigned long flags)
{
- return 0;
+#ifdef CONFIG_PCI
+ if (map_dev) {
+ pci_unmap_physmem(vaddr, map_len, map_dev);
+ map_dev = NULL;
+ }
+#endif
}
-void *map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags)
+void sandbox_set_enable_pci_map(int enable)
{
- return (void *)(gd->arch.ram_buf + paddr);
+ enable_pci_map = enable;
}
phys_addr_t map_to_sysmem(const void *ptr)
diff --git a/arch/sandbox/cpu/eth-raw-os.c b/arch/sandbox/cpu/eth-raw-os.c
new file mode 100644
index 0000000000..b76a7319ae
--- /dev/null
+++ b/arch/sandbox/cpu/eth-raw-os.c
@@ -0,0 +1,249 @@
+/*
+ * Copyright (c) 2015 National Instruments
+ *
+ * (C) Copyright 2015
+ * Joe Hershberger <joe.hershberger@ni.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <asm/eth-raw-os.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <net/if.h>
+#include <netinet/in.h>
+#include <netinet/ip.h>
+#include <netinet/udp.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/ioctl.h>
+#include <sys/socket.h>
+#include <unistd.h>
+
+#include <arpa/inet.h>
+#include <linux/if_ether.h>
+#include <linux/if_packet.h>
+
+static int _raw_packet_start(const char *ifname, unsigned char *ethmac,
+ struct eth_sandbox_raw_priv *priv)
+{
+ struct sockaddr_ll *device;
+ struct packet_mreq mr;
+ int ret;
+ int flags;
+
+ /* Prepare device struct */
+ priv->device = malloc(sizeof(struct sockaddr_ll));
+ if (priv->device == NULL)
+ return -ENOMEM;
+ device = priv->device;
+ memset(device, 0, sizeof(struct sockaddr_ll));
+ device->sll_ifindex = if_nametoindex(ifname);
+ device->sll_family = AF_PACKET;
+ memcpy(device->sll_addr, ethmac, 6);
+ device->sll_halen = htons(6);
+
+ /* Open socket */
+ priv->sd = socket(PF_PACKET, SOCK_RAW, htons(ETH_P_ALL));
+ if (priv->sd < 0) {
+ printf("Failed to open socket: %d %s\n", errno,
+ strerror(errno));
+ return -errno;
+ }
+ /* Bind to the specified interface */
+ ret = setsockopt(priv->sd, SOL_SOCKET, SO_BINDTODEVICE, ifname,
+ strlen(ifname) + 1);
+ if (ret < 0) {
+ printf("Failed to bind to '%s': %d %s\n", ifname, errno,
+ strerror(errno));
+ return -errno;
+ }
+
+ /* Make the socket non-blocking */
+ flags = fcntl(priv->sd, F_GETFL, 0);
+ fcntl(priv->sd, F_SETFL, flags | O_NONBLOCK);
+
+ /* Enable promiscuous mode to receive responses meant for us */
+ mr.mr_ifindex = device->sll_ifindex;
+ mr.mr_type = PACKET_MR_PROMISC;
+ ret = setsockopt(priv->sd, SOL_PACKET, PACKET_ADD_MEMBERSHIP,
+ &mr, sizeof(mr));
+ if (ret < 0) {
+ struct ifreq ifr;
+
+ printf("Failed to set promiscuous mode: %d %s\n"
+ "Falling back to the old \"flags\" way...\n",
+ errno, strerror(errno));
+ strncpy(ifr.ifr_name, ifname, IFNAMSIZ);
+ if (ioctl(priv->sd, SIOCGIFFLAGS, &ifr) < 0) {
+ printf("Failed to read flags: %d %s\n", errno,
+ strerror(errno));
+ return -errno;
+ }
+ ifr.ifr_flags |= IFF_PROMISC;
+ if (ioctl(priv->sd, SIOCSIFFLAGS, &ifr) < 0) {
+ printf("Failed to write flags: %d %s\n", errno,
+ strerror(errno));
+ return -errno;
+ }
+ }
+ return 0;
+}
+
+static int _local_inet_start(struct eth_sandbox_raw_priv *priv)
+{
+ struct sockaddr_in *device;
+ int ret;
+ int flags;
+ int one = 1;
+
+ /* Prepare device struct */
+ priv->device = malloc(sizeof(struct sockaddr_in));
+ if (priv->device == NULL)
+ return -ENOMEM;
+ device = priv->device;
+ memset(device, 0, sizeof(struct sockaddr_in));
+ device->sin_family = AF_INET;
+ device->sin_addr.s_addr = htonl(INADDR_LOOPBACK);
+
+ /**
+ * Open socket
+ * Since we specify UDP here, any incoming ICMP packets will
+ * not be received, so things like ping will not work on this
+ * localhost interface.
+ */
+ priv->sd = socket(AF_INET, SOCK_RAW, IPPROTO_UDP);
+ if (priv->sd < 0) {
+ printf("Failed to open socket: %d %s\n", errno,
+ strerror(errno));
+ return -errno;
+ }
+
+ /* Make the socket non-blocking */
+ flags = fcntl(priv->sd, F_GETFL, 0);
+ fcntl(priv->sd, F_SETFL, flags | O_NONBLOCK);
+
+ /* Include the UDP/IP headers on send and receive */
+ ret = setsockopt(priv->sd, IPPROTO_IP, IP_HDRINCL, &one,
+ sizeof(one));
+ if (ret < 0) {
+ printf("Failed to set header include option: %d %s\n", errno,
+ strerror(errno));
+ return -errno;
+ }
+ priv->local_bind_sd = -1;
+ priv->local_bind_udp_port = 0;
+ return 0;
+}
+
+int sandbox_eth_raw_os_start(const char *ifname, unsigned char *ethmac,
+ struct eth_sandbox_raw_priv *priv)
+{
+ if (priv->local)
+ return _local_inet_start(priv);
+ else
+ return _raw_packet_start(ifname, ethmac, priv);
+}
+
+int sandbox_eth_raw_os_send(void *packet, int length,
+ struct eth_sandbox_raw_priv *priv)
+{
+ int retval;
+ struct udphdr *udph = packet + sizeof(struct iphdr);
+
+ if (!priv->sd || !priv->device)
+ return -EINVAL;
+
+ /*
+ * This block of code came about when testing tftp on the localhost
+ * interface. When using the RAW AF_INET API, the network stack is still
+ * in play responding to incoming traffic based on open "ports". Since
+ * it is raw (at the IP layer, no Ethernet) the network stack tells the
+ * TFTP server that the port it responded to is closed. This causes the
+ * TFTP transfer to be aborted. This block of code inspects the outgoing
+ * packet as formulated by the u-boot network stack to determine the
+ * source port (that the TFTP server will send packets back to) and
+ * opens a typical UDP socket on that port, thus preventing the network
+ * stack from sending that ICMP message claiming that the port has no
+ * bound socket.
+ */
+ if (priv->local && (priv->local_bind_sd == -1 ||
+ priv->local_bind_udp_port != udph->source)) {
+ struct iphdr *iph = packet;
+ struct sockaddr_in addr;
+
+ if (priv->local_bind_sd != -1)
+ close(priv->local_bind_sd);
+
+ /* A normal UDP socket is required to bind */
+ priv->local_bind_sd = socket(AF_INET, SOCK_DGRAM, 0);
+ if (priv->local_bind_sd < 0) {
+ printf("Failed to open bind sd: %d %s\n", errno,
+ strerror(errno));
+ return -errno;
+ }
+ priv->local_bind_udp_port = udph->source;
+
+ /**
+ * Bind the UDP port that we intend to use as our source port
+ * so that the kernel will not send an ICMP port unreachable
+ * message to the server
+ */
+ addr.sin_family = AF_INET;
+ addr.sin_port = udph->source;
+ addr.sin_addr.s_addr = iph->saddr;
+ retval = bind(priv->local_bind_sd, &addr, sizeof(addr));
+ if (retval < 0)
+ printf("Failed to bind: %d %s\n", errno,
+ strerror(errno));
+ }
+
+ retval = sendto(priv->sd, packet, length, 0,
+ (struct sockaddr *)priv->device,
+ sizeof(struct sockaddr_ll));
+ if (retval < 0) {
+ printf("Failed to send packet: %d %s\n", errno,
+ strerror(errno));
+ return -errno;
+ }
+ return retval;
+}
+
+int sandbox_eth_raw_os_recv(void *packet, int *length,
+ const struct eth_sandbox_raw_priv *priv)
+{
+ int retval;
+ int saddr_size;
+
+ if (!priv->sd || !priv->device)
+ return -EINVAL;
+ saddr_size = sizeof(struct sockaddr);
+ retval = recvfrom(priv->sd, packet, 1536, 0,
+ (struct sockaddr *)priv->device,
+ (socklen_t *)&saddr_size);
+ *length = 0;
+ if (retval >= 0) {
+ *length = retval;
+ return 0;
+ }
+ /* The socket is non-blocking, so expect EAGAIN when there is no data */
+ if (errno == EAGAIN)
+ return 0;
+ return -errno;
+}
+
+void sandbox_eth_raw_os_stop(struct eth_sandbox_raw_priv *priv)
+{
+ free(priv->device);
+ priv->device = NULL;
+ close(priv->sd);
+ priv->sd = -1;
+ if (priv->local) {
+ if (priv->local_bind_sd != -1)
+ close(priv->local_bind_sd);
+ priv->local_bind_sd = -1;
+ priv->local_bind_udp_port = 0;
+ }
+}
diff --git a/arch/sandbox/dts/cros-ec-keyboard.dtsi b/arch/sandbox/dts/cros-ec-keyboard.dtsi
new file mode 100644
index 0000000000..9c7fb0acae
--- /dev/null
+++ b/arch/sandbox/dts/cros-ec-keyboard.dtsi
@@ -0,0 +1,105 @@
+/*
+ * Keyboard dts fragment for devices that use cros-ec-keyboard
+ *
+ * Copyright (c) 2014 Google, Inc
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+*/
+
+#include <dt-bindings/input/input.h>
+
+&cros_ec {
+ keyboard-controller {
+ compatible = "google,cros-ec-keyb";
+ keypad,num-rows = <8>;
+ keypad,num-columns = <13>;
+ google,needs-ghost-filter;
+
+ linux,keymap = <
+ MATRIX_KEY(0x00, 0x01, KEY_LEFTMETA)
+ MATRIX_KEY(0x00, 0x02, KEY_F1)
+ MATRIX_KEY(0x00, 0x03, KEY_B)
+ MATRIX_KEY(0x00, 0x04, KEY_F10)
+ MATRIX_KEY(0x00, 0x06, KEY_N)
+ MATRIX_KEY(0x00, 0x08, KEY_EQUAL)
+ MATRIX_KEY(0x00, 0x0a, KEY_RIGHTALT)
+
+ MATRIX_KEY(0x01, 0x01, KEY_ESC)
+ MATRIX_KEY(0x01, 0x02, KEY_F4)
+ MATRIX_KEY(0x01, 0x03, KEY_G)
+ MATRIX_KEY(0x01, 0x04, KEY_F7)
+ MATRIX_KEY(0x01, 0x06, KEY_H)
+ MATRIX_KEY(0x01, 0x08, KEY_APOSTROPHE)
+ MATRIX_KEY(0x01, 0x09, KEY_F9)
+ MATRIX_KEY(0x01, 0x0b, KEY_BACKSPACE)
+
+ MATRIX_KEY(0x02, 0x00, KEY_LEFTCTRL)
+ MATRIX_KEY(0x02, 0x01, KEY_TAB)
+ MATRIX_KEY(0x02, 0x02, KEY_F3)
+ MATRIX_KEY(0x02, 0x03, KEY_T)
+ MATRIX_KEY(0x02, 0x04, KEY_F6)
+ MATRIX_KEY(0x02, 0x05, KEY_RIGHTBRACE)
+ MATRIX_KEY(0x02, 0x06, KEY_Y)
+ MATRIX_KEY(0x02, 0x07, KEY_102ND)
+ MATRIX_KEY(0x02, 0x08, KEY_LEFTBRACE)
+ MATRIX_KEY(0x02, 0x09, KEY_F8)
+
+ MATRIX_KEY(0x03, 0x01, KEY_GRAVE)
+ MATRIX_KEY(0x03, 0x02, KEY_F2)
+ MATRIX_KEY(0x03, 0x03, KEY_5)
+ MATRIX_KEY(0x03, 0x04, KEY_F5)
+ MATRIX_KEY(0x03, 0x06, KEY_6)
+ MATRIX_KEY(0x03, 0x08, KEY_MINUS)
+ MATRIX_KEY(0x03, 0x0b, KEY_BACKSLASH)
+
+ MATRIX_KEY(0x04, 0x00, KEY_RIGHTCTRL)
+ MATRIX_KEY(0x04, 0x01, KEY_A)
+ MATRIX_KEY(0x04, 0x02, KEY_D)
+ MATRIX_KEY(0x04, 0x03, KEY_F)
+ MATRIX_KEY(0x04, 0x04, KEY_S)
+ MATRIX_KEY(0x04, 0x05, KEY_K)
+ MATRIX_KEY(0x04, 0x06, KEY_J)
+ MATRIX_KEY(0x04, 0x08, KEY_SEMICOLON)
+ MATRIX_KEY(0x04, 0x09, KEY_L)
+ MATRIX_KEY(0x04, 0x0a, KEY_BACKSLASH)
+ MATRIX_KEY(0x04, 0x0b, KEY_ENTER)
+
+ MATRIX_KEY(0x05, 0x01, KEY_Z)
+ MATRIX_KEY(0x05, 0x02, KEY_C)
+ MATRIX_KEY(0x05, 0x03, KEY_V)
+ MATRIX_KEY(0x05, 0x04, KEY_X)
+ MATRIX_KEY(0x05, 0x05, KEY_COMMA)
+ MATRIX_KEY(0x05, 0x06, KEY_M)
+ MATRIX_KEY(0x05, 0x07, KEY_LEFTSHIFT)
+ MATRIX_KEY(0x05, 0x08, KEY_SLASH)
+ MATRIX_KEY(0x05, 0x09, KEY_DOT)
+ MATRIX_KEY(0x05, 0x0b, KEY_SPACE)
+
+ MATRIX_KEY(0x06, 0x01, KEY_1)
+ MATRIX_KEY(0x06, 0x02, KEY_3)
+ MATRIX_KEY(0x06, 0x03, KEY_4)
+ MATRIX_KEY(0x06, 0x04, KEY_2)
+ MATRIX_KEY(0x06, 0x05, KEY_8)
+ MATRIX_KEY(0x06, 0x06, KEY_7)
+ MATRIX_KEY(0x06, 0x08, KEY_0)
+ MATRIX_KEY(0x06, 0x09, KEY_9)
+ MATRIX_KEY(0x06, 0x0a, KEY_LEFTALT)
+ MATRIX_KEY(0x06, 0x0b, KEY_DOWN)
+ MATRIX_KEY(0x06, 0x0c, KEY_RIGHT)
+
+ MATRIX_KEY(0x07, 0x01, KEY_Q)
+ MATRIX_KEY(0x07, 0x02, KEY_E)
+ MATRIX_KEY(0x07, 0x03, KEY_R)
+ MATRIX_KEY(0x07, 0x04, KEY_W)
+ MATRIX_KEY(0x07, 0x05, KEY_I)
+ MATRIX_KEY(0x07, 0x06, KEY_U)
+ MATRIX_KEY(0x07, 0x07, KEY_RIGHTSHIFT)
+ MATRIX_KEY(0x07, 0x08, KEY_P)
+ MATRIX_KEY(0x07, 0x09, KEY_O)
+ MATRIX_KEY(0x07, 0x0b, KEY_UP)
+ MATRIX_KEY(0x07, 0x0c, KEY_LEFT)
+ >;
+ };
+};
diff --git a/arch/sandbox/dts/sandbox.dts b/arch/sandbox/dts/sandbox.dts
index 9ce31bf075..efa2097b2d 100644
--- a/arch/sandbox/dts/sandbox.dts
+++ b/arch/sandbox/dts/sandbox.dts
@@ -1,8 +1,15 @@
/dts-v1/;
+#define USB_CLASS_HUB 9
+
/ {
#address-cells = <1>;
- #size-cells = <0>;
+ #size-cells = <1>;
+
+ aliases {
+ eth5 = "/eth@90000000";
+ pci0 = &pci;
+ };
chosen {
stdout-path = "/serial";
@@ -32,36 +39,31 @@
sides = <6>;
};
- host@0 {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "sandbox,host-emulation";
- cros-ec@0 {
- reg = <0>;
- compatible = "google,cros-ec";
+ cros_ec: cros-ec@0 {
+ reg = <0 0>;
+ compatible = "google,cros-ec-sandbox";
- /*
- * This describes the flash memory within the EC. Note
- * that the STM32L flash erases to 0, not 0xff.
- */
+ /*
+ * This describes the flash memory within the EC. Note
+ * that the STM32L flash erases to 0, not 0xff.
+ */
+ #address-cells = <1>;
+ #size-cells = <1>;
+ flash@8000000 {
+ reg = <0x08000000 0x20000>;
+ erase-value = <0>;
#address-cells = <1>;
#size-cells = <1>;
- flash@8000000 {
- reg = <0x08000000 0x20000>;
- erase-value = <0>;
- #address-cells = <1>;
- #size-cells = <1>;
- /* Information for sandbox */
- ro {
- reg = <0 0xf000>;
- };
- wp-ro {
- reg = <0xf000 0x1000>;
- };
- rw {
- reg = <0x10000 0x10000>;
- };
+ /* Information for sandbox */
+ ro {
+ reg = <0 0xf000>;
+ };
+ wp-ro {
+ reg = <0xf000 0x1000>;
+ };
+ rw {
+ reg = <0x10000 0x10000>;
};
};
};
@@ -72,59 +74,6 @@
yres = <600>;
};
- cros-ec-keyb {
- compatible = "google,cros-ec-keyb";
- keypad,num-rows = <8>;
- keypad,num-columns = <13>;
- google,ghost-filter;
- /*
- * Keymap entries take the form of 0xRRCCKKKK where
- * RR=Row CC=Column KKKK=Key Code
- * The values below are for a US keyboard layout and
- * are taken from the Linux driver. Note that the
- * 102ND key is not used for US keyboards.
- */
- linux,keymap = <
- /* CAPSLCK F1 B F10 */
- 0x0001003a 0x0002003b 0x00030030 0x00040044
- /* N = R_ALT ESC */
- 0x00060031 0x0008000d 0x000a0064 0x01010001
- /* F4 G F7 H */
- 0x0102003e 0x01030022 0x01040041 0x01060023
- /* ' F9 BKSPACE L_CTRL */
- 0x01080028 0x01090043 0x010b000e 0x0200001d
- /* TAB F3 T F6 */
- 0x0201000f 0x0202003d 0x02030014 0x02040040
- /* ] Y 102ND [ */
- 0x0205001b 0x02060015 0x02070056 0x0208001a
- /* F8 GRAVE F2 5 */
- 0x02090042 0x03010029 0x0302003c 0x03030006
- /* F5 6 - \ */
- 0x0304003f 0x03060007 0x0308000c 0x030b002b
- /* R_CTRL A D F */
- 0x04000061 0x0401001e 0x04020020 0x04030021
- /* S K J ; */
- 0x0404001f 0x04050025 0x04060024 0x04080027
- /* L ENTER Z C */
- 0x04090026 0x040b001c 0x0501002c 0x0502002e
- /* V X , M */
- 0x0503002f 0x0504002d 0x05050033 0x05060032
- /* L_SHIFT / . SPACE */
- 0x0507002a 0x05080035 0x05090034 0x050B0039
- /* 1 3 4 2 */
- 0x06010002 0x06020004 0x06030005 0x06040003
- /* 8 7 0 9 */
- 0x06050009 0x06060008 0x0608000b 0x0609000a
- /* L_ALT DOWN RIGHT Q */
- 0x060a0038 0x060b006c 0x060c006a 0x07010010
- /* E R W I */
- 0x07020012 0x07030013 0x07040011 0x07050017
- /* U R_SHIFT P O */
- 0x07060016 0x07070036 0x07080019 0x07090018
- /* UP LEFT */
- 0x070b0067 0x070c0069>;
- };
-
gpio_a: gpios@0 {
gpio-controller;
compatible = "sandbox,gpio";
@@ -144,7 +93,7 @@
i2c@0 {
#address-cells = <1>;
#size-cells = <0>;
- reg = <0>;
+ reg = <0 0>;
compatible = "sandbox,i2c";
clock-frequency = <400000>;
eeprom@2c {
@@ -161,10 +110,10 @@
spi@0 {
#address-cells = <1>;
#size-cells = <0>;
- reg = <0>;
+ reg = <0 0>;
compatible = "sandbox,spi";
cs-gpios = <0>, <&gpio_a 0>;
- flash@0 {
+ firmware_storage_spi: flash@0 {
reg = <0>;
compatible = "spansion,m25p16", "sandbox,spi-flash";
spi-max-frequency = <40000000>;
@@ -172,13 +121,77 @@
};
};
- cros-ec@0 {
- compatible = "google,cros-ec";
- #address-cells = <1>;
- #size-cells = <1>;
- firmware_storage_spi: flash@0 {
- reg = <0 0x400000>;
+ pci: pci-controller {
+ compatible = "sandbox,pci";
+ device_type = "pci";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges = <0x02000000 0 0x10000000 0x10000000 0 0x2000
+ 0x01000000 0 0x20000000 0x20000000 0 0x2000>;
+ pci@1f,0 {
+ compatible = "pci-generic";
+ reg = <0xf800 0 0 0 0>;
+ emul@1f,0 {
+ compatible = "sandbox,swap-case";
+ };
+ };
+ };
+
+ eth@10002000 {
+ compatible = "sandbox,eth";
+ reg = <0x10002000 0x1000>;
+ fake-host-hwaddr = [00 00 66 44 22 00];
+ };
+
+ eth@80000000 {
+ compatible = "sandbox,eth-raw";
+ reg = <0x80000000 0x1000>;
+ host-raw-interface = "eth0";
+ };
+
+ eth@90000000 {
+ compatible = "sandbox,eth-raw";
+ reg = <0x90000000 0x1000>;
+ host-raw-interface = "lo";
+ };
+
+ usb@0 {
+ compatible = "sandbox,usb";
+ status = "disabled";
+ hub {
+ compatible = "sandbox,usb-hub";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ flash-stick {
+ reg = <0>;
+ compatible = "sandbox,usb-flash";
+ };
};
};
+ usb@1 {
+ compatible = "sandbox,usb";
+ hub {
+ compatible = "usb-hub";
+ usb,device-class = <USB_CLASS_HUB>;
+ hub-emul {
+ compatible = "sandbox,usb-hub";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ flash-stick {
+ reg = <0>;
+ compatible = "sandbox,usb-flash";
+ sandbox,filepath = "flash.bin";
+ };
+ };
+ };
+ };
+
+ usb@2 {
+ compatible = "sandbox,usb";
+ status = "disabled";
+ };
+
};
+
+#include "cros-ec-keyboard.dtsi"
diff --git a/arch/sandbox/include/asm/eth-raw-os.h b/arch/sandbox/include/asm/eth-raw-os.h
new file mode 100644
index 0000000000..ed4b2e2649
--- /dev/null
+++ b/arch/sandbox/include/asm/eth-raw-os.h
@@ -0,0 +1,40 @@
+/*
+ * Copyright (c) 2015 National Instruments
+ *
+ * (C) Copyright 2015
+ * Joe Hershberger <joe.hershberger@ni.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef __ETH_RAW_OS_H
+#define __ETH_RAW_OS_H
+
+/**
+ * struct eth_sandbox_raw_priv - raw socket session
+ *
+ * sd: socket descriptor - the open socket during a session
+ * device: struct sockaddr_ll - the host interface packets move to/from
+ * local: 1 or 0 to select the local interface ('lo') or not
+ * local_bindsd: socket descriptor to prevent the kernel from sending
+ * a message to the server claiming the port is
+ * unreachable
+ * local_bind_udp_port: The UDP port number that we bound to
+ */
+struct eth_sandbox_raw_priv {
+ int sd;
+ void *device;
+ int local;
+ int local_bind_sd;
+ unsigned short local_bind_udp_port;
+};
+
+int sandbox_eth_raw_os_start(const char *ifname, unsigned char *ethmac,
+ struct eth_sandbox_raw_priv *priv);
+int sandbox_eth_raw_os_send(void *packet, int length,
+ struct eth_sandbox_raw_priv *priv);
+int sandbox_eth_raw_os_recv(void *packet, int *length,
+ const struct eth_sandbox_raw_priv *priv);
+void sandbox_eth_raw_os_stop(struct eth_sandbox_raw_priv *priv);
+
+#endif /* __ETH_RAW_OS_H */
diff --git a/arch/sandbox/include/asm/eth.h b/arch/sandbox/include/asm/eth.h
new file mode 100644
index 0000000000..4b79ede9b9
--- /dev/null
+++ b/arch/sandbox/include/asm/eth.h
@@ -0,0 +1,15 @@
+/*
+ * Copyright (c) 2015 National Instruments
+ *
+ * (C) Copyright 2015
+ * Joe Hershberger <joe.hershberger@ni.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef __ETH_H
+#define __ETH_H
+
+void sandbox_eth_disable_response(int index, bool disable);
+
+#endif /* __ETH_H */
diff --git a/arch/sandbox/include/asm/io.h b/arch/sandbox/include/asm/io.h
index 895fcb872f..5b87fde116 100644
--- a/arch/sandbox/include/asm/io.h
+++ b/arch/sandbox/include/asm/io.h
@@ -22,10 +22,7 @@ void *map_physmem(phys_addr_t paddr, unsigned long len, unsigned long flags);
/*
* Take down a mapping set up by map_physmem().
*/
-static inline void unmap_physmem(void *vaddr, unsigned long flags)
-{
-
-}
+void unmap_physmem(const void *vaddr, unsigned long flags);
/* For sandbox, we want addresses to point into our RAM buffer */
static inline void *map_sysmem(phys_addr_t paddr, unsigned long len)
@@ -33,8 +30,10 @@ static inline void *map_sysmem(phys_addr_t paddr, unsigned long len)
return map_physmem(paddr, len, MAP_WRBACK);
}
+/* Remove a previous mapping */
static inline void unmap_sysmem(const void *vaddr)
{
+ unmap_physmem(vaddr, MAP_WRBACK);
}
/* Map from a pointer to our RAM buffer */
@@ -48,6 +47,15 @@ phys_addr_t map_to_sysmem(const void *ptr);
#define writew(v, addr)
#define writel(v, addr)
+/* I/O access functions */
+int inl(unsigned int addr);
+int inw(unsigned int addr);
+int inb(unsigned int addr);
+
+void outl(unsigned int value, unsigned int addr);
+void outw(unsigned int value, unsigned int addr);
+void outb(unsigned int value, unsigned int addr);
+
#include <iotrace.h>
#endif
diff --git a/arch/sandbox/include/asm/processor.h b/arch/sandbox/include/asm/processor.h
new file mode 100644
index 0000000000..3c1794e92d
--- /dev/null
+++ b/arch/sandbox/include/asm/processor.h
@@ -0,0 +1,12 @@
+/*
+ * Copyright (c) 2014 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _ASM_PROCESSOR_H
+#define _ASM_PROCESSOR_H
+
+/* This file is required for PCI */
+
+#endif
diff --git a/arch/sandbox/include/asm/test.h b/arch/sandbox/include/asm/test.h
index 25a0c85971..8e490e96d7 100644
--- a/arch/sandbox/include/asm/test.h
+++ b/arch/sandbox/include/asm/test.h
@@ -10,7 +10,12 @@
#define __ASM_TEST_H
/* The sandbox driver always permits an I2C device with this address */
-#define SANDBOX_I2C_TEST_ADDR 0x59
+#define SANDBOX_I2C_TEST_ADDR 0x59
+
+#define SANDBOX_PCI_VENDOR_ID 0x1234
+#define SANDBOX_PCI_DEVICE_ID 0x5678
+#define SANDBOX_PCI_CLASS_CODE PCI_CLASS_CODE_COMM
+#define SANDBOX_PCI_CLASS_SUB_CODE PCI_CLASS_SUB_CODE_COMM_SERIAL
enum sandbox_i2c_eeprom_test_mode {
SIE_TEST_MODE_NONE,
diff --git a/arch/sandbox/include/asm/u-boot-sandbox.h b/arch/sandbox/include/asm/u-boot-sandbox.h
index 770ab5c9cc..d5b9361683 100644
--- a/arch/sandbox/include/asm/u-boot-sandbox.h
+++ b/arch/sandbox/include/asm/u-boot-sandbox.h
@@ -27,4 +27,52 @@ int cleanup_before_linux(void);
/* drivers/video/sandbox_sdl.c */
int sandbox_lcd_sdl_early_init(void);
+/**
+ * pci_map_physmem() - map a PCI device into memory
+ *
+ * This is used on sandbox to map a device into memory so that it can be
+ * used with normal memory access. After this call, some part of the device's
+ * internal structure becomes visible.
+ *
+ * This function is normally called from sandbox's map_sysmem() automatically.
+ *
+ * @paddr: Physical memory address, normally corresponding to a PCI BAR
+ * @lenp: On entry, the size of the area to map, On exit it is updated
+ * to the size actually mapped, which may be less if the device
+ * has less space
+ * @devp: Returns the device which mapped into this space
+ * @ptrp: Returns a pointer to the mapped address. The device's space
+ * can be accessed as @lenp bytes starting here
+ * @return 0 if OK, -ve on error
+ */
+int pci_map_physmem(phys_addr_t paddr, unsigned long *lenp,
+ struct udevice **devp, void **ptrp);
+
+/**
+ * pci_unmap_physmem() - undo a memory mapping
+ *
+ * This must be called after pci_map_physmem() to undo the mapping.
+ *
+ * @paddr: Physical memory address, as passed to pci_map_physmem()
+ * @len: Size of area mapped, as returned by pci_map_physmem()
+ * @dev: Device to unmap, as returned by pci_map_physmem()
+ * @return 0 if OK, -ve on error
+ */
+int pci_unmap_physmem(const void *addr, unsigned long len,
+ struct udevice *dev);
+
+/**
+ * sandbox_set_enable_pci_map() - Enable / disable PCI address mapping
+ *
+ * Since address mapping involves calling every driver, provide a way to
+ * enable and disable this. It can be handled automatically by the emulator
+ * uclass, which knows if any emulators are currently active.
+ *
+ * If this is disabled, pci_map_physmem() will not be called from
+ * map_sysmem().
+ *
+ * @enable: 0 to disable, 1 to enable
+ */
+void sandbox_set_enable_pci_map(int enable);
+
#endif /* _U_BOOT_SANDBOX_H_ */
diff --git a/arch/sandbox/lib/Makefile b/arch/sandbox/lib/Makefile
index 4c1a38d6bc..96761e27f7 100644
--- a/arch/sandbox/lib/Makefile
+++ b/arch/sandbox/lib/Makefile
@@ -7,5 +7,6 @@
# SPDX-License-Identifier: GPL-2.0+
#
-
obj-y += interrupts.o
+obj-$(CONFIG_PCI) += pci_io.o
+obj-$(CONFIG_CMD_BOOTM) += bootm.o
diff --git a/arch/sandbox/lib/bootm.c b/arch/sandbox/lib/bootm.c
new file mode 100644
index 0000000000..d49c927b34
--- /dev/null
+++ b/arch/sandbox/lib/bootm.c
@@ -0,0 +1,63 @@
+/*
+ * Copyright (c) 2011 The Chromium OS Authors.
+ * Copyright (c) 2015 Sjoerd Simons <sjoerd.simons@collabora.co.uk>
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/io.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+#define LINUX_ARM_ZIMAGE_MAGIC 0x016f2818
+
+struct arm_z_header {
+ uint32_t code[9];
+ uint32_t zi_magic;
+ uint32_t zi_start;
+ uint32_t zi_end;
+} __attribute__ ((__packed__));
+
+int bootz_setup(ulong image, ulong *start, ulong *end)
+{
+ uint8_t *zimage = map_sysmem(image, 0);
+ struct arm_z_header *arm_hdr = (struct arm_z_header *)zimage;
+ int ret = 0;
+
+ if (memcmp(zimage + 0x202, "HdrS", 4) == 0) {
+ uint8_t setup_sects = *(zimage + 0x1f1);
+ uint32_t syssize =
+ le32_to_cpu(*(uint32_t *)(zimage + 0x1f4));
+
+ *start = 0;
+ *end = (setup_sects + 1) * 512 + syssize * 16;
+
+ printf("setting up X86 zImage [ %ld - %ld ]\n",
+ *start, *end);
+ } else if (le32_to_cpu(arm_hdr->zi_magic) == LINUX_ARM_ZIMAGE_MAGIC) {
+ *start = le32_to_cpu(arm_hdr->zi_start);
+ *end = le32_to_cpu(arm_hdr->zi_end);
+
+ printf("setting up ARM zImage [ %ld - %ld ]\n",
+ *start, *end);
+ } else {
+ printf("Unrecognized zImage\n");
+ ret = 1;
+ }
+
+ unmap_sysmem((void *)image);
+
+ return ret;
+}
+
+int do_bootm_linux(int flag, int argc, char *argv[], bootm_headers_t *images)
+{
+ if (flag & (BOOTM_STATE_OS_GO | BOOTM_STATE_OS_FAKE_GO)) {
+ bootstage_mark(BOOTSTAGE_ID_RUN_OS);
+ printf("## Transferring control to Linux (at address %08lx)...\n",
+ images->ep);
+ reset_cpu(0);
+ }
+
+ return 0;
+}
diff --git a/arch/sandbox/lib/pci_io.c b/arch/sandbox/lib/pci_io.c
new file mode 100644
index 0000000000..0de124f315
--- /dev/null
+++ b/arch/sandbox/lib/pci_io.c
@@ -0,0 +1,138 @@
+/*
+ * Copyright (c) 2014 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+/*
+ * IO space access commands.
+ */
+
+#include <common.h>
+#include <command.h>
+#include <dm.h>
+#include <asm/io.h>
+
+int pci_map_physmem(phys_addr_t paddr, unsigned long *lenp,
+ struct udevice **devp, void **ptrp)
+{
+ struct udevice *dev;
+ int ret;
+
+ *ptrp = 0;
+ for (uclass_first_device(UCLASS_PCI_EMUL, &dev);
+ dev;
+ uclass_next_device(&dev)) {
+ struct dm_pci_emul_ops *ops = pci_get_emul_ops(dev);
+
+ if (!ops || !ops->map_physmem)
+ continue;
+ ret = (ops->map_physmem)(dev, paddr, lenp, ptrp);
+ if (ret)
+ continue;
+ *devp = dev;
+ return 0;
+ }
+
+ debug("%s: failed: addr=%x\n", __func__, paddr);
+ return -ENOSYS;
+}
+
+int pci_unmap_physmem(const void *vaddr, unsigned long len,
+ struct udevice *dev)
+{
+ struct dm_pci_emul_ops *ops = pci_get_emul_ops(dev);
+
+ if (!ops || !ops->unmap_physmem)
+ return -ENOSYS;
+ return (ops->unmap_physmem)(dev, vaddr, len);
+}
+
+static int pci_io_read(unsigned int addr, ulong *valuep, pci_size_t size)
+{
+ struct udevice *dev;
+ int ret;
+
+ *valuep = pci_get_ff(size);
+ for (uclass_first_device(UCLASS_PCI_EMUL, &dev);
+ dev;
+ uclass_next_device(&dev)) {
+ struct dm_pci_emul_ops *ops = pci_get_emul_ops(dev);
+
+ if (ops && ops->read_io) {
+ ret = (ops->read_io)(dev, addr, valuep, size);
+ if (!ret)
+ return 0;
+ }
+ }
+
+ debug("%s: failed: addr=%x\n", __func__, addr);
+ return -ENOSYS;
+}
+
+static int pci_io_write(unsigned int addr, ulong value, pci_size_t size)
+{
+ struct udevice *dev;
+ int ret;
+
+ for (uclass_first_device(UCLASS_PCI_EMUL, &dev);
+ dev;
+ uclass_next_device(&dev)) {
+ struct dm_pci_emul_ops *ops = pci_get_emul_ops(dev);
+
+ if (ops && ops->write_io) {
+ ret = (ops->write_io)(dev, addr, value, size);
+ if (!ret)
+ return 0;
+ }
+ }
+
+ debug("%s: failed: addr=%x, value=%lx\n", __func__, addr, value);
+ return -ENOSYS;
+}
+
+int inl(unsigned int addr)
+{
+ unsigned long value;
+ int ret;
+
+ ret = pci_io_read(addr, &value, PCI_SIZE_32);
+
+ return ret ? 0 : value;
+}
+
+int inw(unsigned int addr)
+{
+ unsigned long value;
+ int ret;
+
+ ret = pci_io_read(addr, &value, PCI_SIZE_16);
+
+ return ret ? 0 : value;
+}
+
+int inb(unsigned int addr)
+{
+ unsigned long value;
+ int ret;
+
+ ret = pci_io_read(addr, &value, PCI_SIZE_8);
+
+ return ret ? 0 : value;
+}
+
+void outl(unsigned int value, unsigned int addr)
+{
+ pci_io_write(addr, value, PCI_SIZE_32);
+}
+
+void outw(unsigned int value, unsigned int addr)
+{
+ pci_io_write(addr, value, PCI_SIZE_16);
+}
+
+void outb(unsigned int value, unsigned int addr)
+{
+ pci_io_write(addr, value, PCI_SIZE_8);
+}
diff --git a/arch/sh/lib/board.c b/arch/sh/lib/board.c
index 1eb7afb89e..6dad3c7dbf 100644
--- a/arch/sh/lib/board.c
+++ b/arch/sh/lib/board.c
@@ -178,7 +178,7 @@ void sh_generic_init(void)
#endif
#if defined(CONFIG_CMD_NET)
puts("Net: ");
- eth_initialize(gd->bd);
+ eth_initialize();
#endif /* CONFIG_CMD_NET */
while (1) {
diff --git a/arch/sparc/lib/board.c b/arch/sparc/lib/board.c
index b311a946c0..d2ac6bcaca 100644
--- a/arch/sparc/lib/board.c
+++ b/arch/sparc/lib/board.c
@@ -351,7 +351,7 @@ void board_init_f(ulong bootflag)
#if defined(CONFIG_CMD_NET)
WATCHDOG_RESET();
puts("Net: ");
- eth_initialize(bd);
+ eth_initialize();
#endif
#if defined(CONFIG_CMD_NET) && defined(CONFIG_RESET_PHY_R)
diff --git a/arch/x86/Kconfig b/arch/x86/Kconfig
index da271158f1..3f1401ae4d 100644
--- a/arch/x86/Kconfig
+++ b/arch/x86/Kconfig
@@ -7,6 +7,9 @@ config SYS_ARCH
config USE_PRIVATE_LIBGCC
default y
+config SYS_VSNPRINTF
+ default y
+
choice
prompt "Target select"
@@ -32,6 +35,20 @@ config TARGET_CHROMEBOOK_LINK
and it provides a 2560x1700 high resolution touch-enabled LCD
display.
+config TARGET_CHROMEBOX_PANTHER
+ bool "Support Chromebox panther (not available)"
+ select n
+ help
+ Note: At present this must be used with Coreboot. See README.x86
+ for instructions.
+
+ This is the Asus Chromebox CN60 released in 2014. It uses an Intel
+ Haswell Celeron 2955U Dual Core CPU with 2GB of SDRAM. It has a
+ Lynx Point platform controller hub, PCIe WiFi and Bluetooth. It also
+ includes a USB SD reader, four USB3 ports, display port and HDMI
+ video output and a 16GB SATA solid state drive. There is no Chrome
+ OS EC on this model.
+
config TARGET_CROWNBAY
bool "Support Intel Crown Bay CRB"
help
@@ -67,13 +84,10 @@ config TARGET_GALILEO
endchoice
-config DM
- default y
-
-config DM_GPIO
+config DM_SPI
default y
-config DM_SERIAL
+config DM_SPI_FLASH
default y
config SYS_MALLOC_F_LEN
@@ -432,6 +446,8 @@ source "board/coreboot/coreboot/Kconfig"
source "board/google/chromebook_link/Kconfig"
+source "board/google/chromebox_panther/Kconfig"
+
source "board/intel/crownbay/Kconfig"
source "board/intel/minnowmax/Kconfig"
@@ -452,4 +468,13 @@ config PCIE_ECAM_BASE
assigned to PCI devices - i.e. the memory and prefetch regions, as
passed to pci_set_region().
+config BOOTSTAGE
+ default y
+
+config BOOTSTAGE_REPORT
+ default y
+
+config CMD_BOOTSTAGE
+ default y
+
endmenu
diff --git a/arch/x86/cpu/baytrail/early_uart.c b/arch/x86/cpu/baytrail/early_uart.c
index 41992105fe..b64a3a90db 100644
--- a/arch/x86/cpu/baytrail/early_uart.c
+++ b/arch/x86/cpu/baytrail/early_uart.c
@@ -50,7 +50,7 @@ static void score_select_func(int pad, int func)
writel(reg, pconf0_addr);
}
-static void pci_write_config32(int dev, unsigned int where, u32 value)
+static void x86_pci_write_config32(int dev, unsigned int where, u32 value)
{
unsigned long addr;
@@ -62,7 +62,8 @@ static void pci_write_config32(int dev, unsigned int where, u32 value)
int setup_early_uart(void)
{
/* Enable the legacy UART hardware. */
- pci_write_config32(PCI_DEV_CONFIG(0, LPC_DEV, LPC_FUNC), UART_CONT, 1);
+ x86_pci_write_config32(PCI_DEV_CONFIG(0, LPC_DEV, LPC_FUNC), UART_CONT,
+ 1);
/*
* Set up the pads to the UART function. This allows the signals to
diff --git a/arch/x86/cpu/coreboot/pci.c b/arch/x86/cpu/coreboot/pci.c
index c9983f1588..fa415dd42b 100644
--- a/arch/x86/cpu/coreboot/pci.c
+++ b/arch/x86/cpu/coreboot/pci.c
@@ -10,58 +10,27 @@
*/
#include <common.h>
+#include <dm.h>
+#include <errno.h>
#include <pci.h>
+#include <asm/io.h>
#include <asm/pci.h>
DECLARE_GLOBAL_DATA_PTR;
-static void config_pci_bridge(struct pci_controller *hose, pci_dev_t dev,
- struct pci_config_table *table)
-{
- u8 secondary;
- hose->read_byte(hose, dev, PCI_SECONDARY_BUS, &secondary);
- hose->last_busno = max(hose->last_busno, (int)secondary);
- pci_hose_scan_bus(hose, secondary);
-}
-
-static struct pci_config_table pci_coreboot_config_table[] = {
- /* vendor, device, class, bus, dev, func */
- { PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_BRIDGE_PCI,
- PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, &config_pci_bridge },
- {}
+static const struct dm_pci_ops pci_x86_ops = {
+ .read_config = pci_x86_read_config,
+ .write_config = pci_x86_write_config,
};
-void board_pci_setup_hose(struct pci_controller *hose)
-{
- hose->config_table = pci_coreboot_config_table;
- hose->first_busno = 0;
- hose->last_busno = 0;
-
- /* PCI memory space */
- pci_set_region(hose->regions + 0,
- CONFIG_PCI_MEM_BUS,
- CONFIG_PCI_MEM_PHYS,
- CONFIG_PCI_MEM_SIZE,
- PCI_REGION_MEM);
-
- /* PCI IO space */
- pci_set_region(hose->regions + 1,
- CONFIG_PCI_IO_BUS,
- CONFIG_PCI_IO_PHYS,
- CONFIG_PCI_IO_SIZE,
- PCI_REGION_IO);
-
- pci_set_region(hose->regions + 2,
- CONFIG_PCI_PREF_BUS,
- CONFIG_PCI_PREF_PHYS,
- CONFIG_PCI_PREF_SIZE,
- PCI_REGION_PREFETCH);
-
- pci_set_region(hose->regions + 3,
- 0,
- 0,
- gd->ram_size,
- PCI_REGION_MEM | PCI_REGION_SYS_MEMORY);
+static const struct udevice_id pci_x86_ids[] = {
+ { .compatible = "pci-x86" },
+ { }
+};
- hose->region_count = 4;
-}
+U_BOOT_DRIVER(pci_x86_drv) = {
+ .name = "pci_x86",
+ .id = UCLASS_PCI,
+ .of_match = pci_x86_ids,
+ .ops = &pci_x86_ops,
+};
diff --git a/arch/x86/cpu/coreboot/sdram.c b/arch/x86/cpu/coreboot/sdram.c
index e98a2302e7..9c3ab81734 100644
--- a/arch/x86/cpu/coreboot/sdram.c
+++ b/arch/x86/cpu/coreboot/sdram.c
@@ -90,7 +90,8 @@ int dram_init(void)
struct memrange *memrange = &lib_sysinfo.memrange[i];
unsigned long long end = memrange->base + memrange->size;
- if (memrange->type == CB_MEM_RAM && end > ram_size)
+ if (memrange->type == CB_MEM_RAM && end > ram_size &&
+ memrange->base < (1ULL << 32))
ram_size = end;
}
gd->ram_size = ram_size;
@@ -108,7 +109,8 @@ void dram_init_banksize(void)
for (i = 0, j = 0; i < lib_sysinfo.n_memranges; i++) {
struct memrange *memrange = &lib_sysinfo.memrange[i];
- if (memrange->type == CB_MEM_RAM) {
+ if (memrange->type == CB_MEM_RAM &&
+ memrange->base < (1ULL << 32)) {
gd->bd->bi_dram[j].start = memrange->base;
gd->bd->bi_dram[j].size = memrange->size;
j++;
diff --git a/arch/x86/cpu/cpu.c b/arch/x86/cpu/cpu.c
index ed7905c1d7..a9ca50b1e4 100644
--- a/arch/x86/cpu/cpu.c
+++ b/arch/x86/cpu/cpu.c
@@ -163,7 +163,7 @@ void setup_gdt(gd_t *id, u64 *gdt_addr)
int __weak x86_cleanup_before_linux(void)
{
#ifdef CONFIG_BOOTSTAGE_STASH
- bootstage_stash((void *)CONFIG_BOOTSTAGE_STASH,
+ bootstage_stash((void *)CONFIG_BOOTSTAGE_STASH_ADDR,
CONFIG_BOOTSTAGE_STASH_SIZE);
#endif
diff --git a/arch/x86/cpu/ivybridge/bd82x6x.c b/arch/x86/cpu/ivybridge/bd82x6x.c
index 65a17d3e7f..ca8cccff94 100644
--- a/arch/x86/cpu/ivybridge/bd82x6x.c
+++ b/arch/x86/cpu/ivybridge/bd82x6x.c
@@ -5,6 +5,7 @@
*/
#include <common.h>
+#include <dm.h>
#include <errno.h>
#include <fdtdec.h>
#include <malloc.h>
@@ -22,36 +23,36 @@ void bd82x6x_pci_init(pci_dev_t dev)
debug("bd82x6x PCI init.\n");
/* Enable Bus Master */
- reg16 = pci_read_config16(dev, PCI_COMMAND);
+ reg16 = x86_pci_read_config16(dev, PCI_COMMAND);
reg16 |= PCI_COMMAND_MASTER;
- pci_write_config16(dev, PCI_COMMAND, reg16);
+ x86_pci_write_config16(dev, PCI_COMMAND, reg16);
/* This device has no interrupt */
- pci_write_config8(dev, INTR, 0xff);
+ x86_pci_write_config8(dev, INTR, 0xff);
/* disable parity error response and SERR */
- reg16 = pci_read_config16(dev, BCTRL);
+ reg16 = x86_pci_read_config16(dev, BCTRL);
reg16 &= ~(1 << 0);
reg16 &= ~(1 << 1);
- pci_write_config16(dev, BCTRL, reg16);
+ x86_pci_write_config16(dev, BCTRL, reg16);
/* Master Latency Count must be set to 0x04! */
- reg8 = pci_read_config8(dev, SMLT);
+ reg8 = x86_pci_read_config8(dev, SMLT);
reg8 &= 0x07;
reg8 |= (0x04 << 3);
- pci_write_config8(dev, SMLT, reg8);
+ x86_pci_write_config8(dev, SMLT, reg8);
/* Will this improve throughput of bus masters? */
- pci_write_config8(dev, PCI_MIN_GNT, 0x06);
+ x86_pci_write_config8(dev, PCI_MIN_GNT, 0x06);
/* Clear errors in status registers */
- reg16 = pci_read_config16(dev, PSTS);
+ reg16 = x86_pci_read_config16(dev, PSTS);
/* reg16 |= 0xf900; */
- pci_write_config16(dev, PSTS, reg16);
+ x86_pci_write_config16(dev, PSTS, reg16);
- reg16 = pci_read_config16(dev, SECSTS);
+ reg16 = x86_pci_read_config16(dev, SECSTS);
/* reg16 |= 0xf900; */
- pci_write_config16(dev, SECSTS, reg16);
+ x86_pci_write_config16(dev, SECSTS, reg16);
}
#define PCI_BRIDGE_UPDATE_COMMAND
@@ -59,7 +60,7 @@ void bd82x6x_pci_dev_enable_resources(pci_dev_t dev)
{
uint16_t command;
- command = pci_read_config16(dev, PCI_COMMAND);
+ command = x86_pci_read_config16(dev, PCI_COMMAND);
command |= PCI_COMMAND_IO;
#ifdef PCI_BRIDGE_UPDATE_COMMAND
/*
@@ -67,7 +68,7 @@ void bd82x6x_pci_dev_enable_resources(pci_dev_t dev)
* ROM and APICs to become invisible.
*/
debug("%x cmd <- %02x\n", dev, command);
- pci_write_config16(dev, PCI_COMMAND, command);
+ x86_pci_write_config16(dev, PCI_COMMAND, command);
#else
printf("%s cmd <- %02x (NOT WRITTEN!)\n", dev_path(dev), command);
#endif
@@ -77,16 +78,16 @@ void bd82x6x_pci_bus_enable_resources(pci_dev_t dev)
{
uint16_t ctrl;
- ctrl = pci_read_config16(dev, PCI_BRIDGE_CONTROL);
+ ctrl = x86_pci_read_config16(dev, PCI_BRIDGE_CONTROL);
ctrl |= PCI_COMMAND_IO;
ctrl |= PCI_BRIDGE_CTL_VGA;
debug("%x bridge ctrl <- %04x\n", dev, ctrl);
- pci_write_config16(dev, PCI_BRIDGE_CONTROL, ctrl);
+ x86_pci_write_config16(dev, PCI_BRIDGE_CONTROL, ctrl);
bd82x6x_pci_dev_enable_resources(dev);
}
-int bd82x6x_init_pci_devices(void)
+static int bd82x6x_probe(struct udevice *dev)
{
const void *blob = gd->fdt_blob;
struct pci_controller *hose;
@@ -144,3 +145,15 @@ int bd82x6x_init(void)
return 0;
}
+
+static const struct udevice_id bd82x6x_ids[] = {
+ { .compatible = "intel,bd82x6x" },
+ { }
+};
+
+U_BOOT_DRIVER(bd82x6x_drv) = {
+ .name = "bd82x6x",
+ .id = UCLASS_PCH,
+ .of_match = bd82x6x_ids,
+ .probe = bd82x6x_probe,
+};
diff --git a/arch/x86/cpu/ivybridge/cpu.c b/arch/x86/cpu/ivybridge/cpu.c
index e9253100f6..37f373148c 100644
--- a/arch/x86/cpu/ivybridge/cpu.c
+++ b/arch/x86/cpu/ivybridge/cpu.c
@@ -12,6 +12,7 @@
*/
#include <common.h>
+#include <dm.h>
#include <errno.h>
#include <fdtdec.h>
#include <asm/cpu.h>
@@ -116,23 +117,32 @@ static void set_spi_speed(void)
int arch_cpu_init(void)
{
+ post_code(POST_CPU_INIT);
+ timer_set_base(rdtsc());
+
+ return x86_cpu_init_f();
+}
+
+int arch_cpu_init_dm(void)
+{
const void *blob = gd->fdt_blob;
struct pci_controller *hose;
+ struct udevice *bus;
int node;
int ret;
- post_code(POST_CPU_INIT);
- timer_set_base(rdtsc());
-
- ret = x86_cpu_init_f();
+ post_code(0x70);
+ ret = uclass_get_device(UCLASS_PCI, 0, &bus);
+ post_code(0x71);
if (ret)
return ret;
+ post_code(0x72);
+ hose = dev_get_uclass_priv(bus);
- ret = pci_early_init_hose(&hose);
- if (ret)
- return ret;
+ /* TODO(sjg@chromium.org): Get rid of gd->hose */
+ gd->hose = hose;
- node = fdtdec_next_compatible(blob, 0, COMPAT_INTEL_LPC);
+ node = fdtdec_next_compatible(blob, 0, COMPAT_INTEL_PCH);
if (node < 0)
return -ENOENT;
ret = lpc_early_init(gd->fdt_blob, node, PCH_LPC_DEV);
@@ -167,21 +177,21 @@ static int enable_smbus(void)
dev = PCI_BDF(0x0, 0x1f, 0x3);
/* Check to make sure we've got the right device. */
- value = pci_read_config16(dev, 0x0);
+ value = x86_pci_read_config16(dev, 0x0);
if (value != 0x8086) {
printf("SMBus controller not found\n");
return -ENOSYS;
}
/* Set SMBus I/O base. */
- pci_write_config32(dev, SMB_BASE,
- SMBUS_IO_BASE | PCI_BASE_ADDRESS_SPACE_IO);
+ x86_pci_write_config32(dev, SMB_BASE,
+ SMBUS_IO_BASE | PCI_BASE_ADDRESS_SPACE_IO);
/* Set SMBus enable. */
- pci_write_config8(dev, HOSTC, HST_EN);
+ x86_pci_write_config8(dev, HOSTC, HST_EN);
/* Set SMBus I/O space enable. */
- pci_write_config16(dev, PCI_COMMAND, PCI_COMMAND_IO);
+ x86_pci_write_config16(dev, PCI_COMMAND, PCI_COMMAND_IO);
/* Disable interrupt generation. */
outb(0, SMBUS_IO_BASE + SMBHSTCTL);
@@ -214,25 +224,25 @@ static void enable_usb_bar(void)
u32 cmd;
/* USB Controller 1 */
- pci_write_config32(usb0, PCI_BASE_ADDRESS_0,
- PCH_EHCI0_TEMP_BAR0);
- cmd = pci_read_config32(usb0, PCI_COMMAND);
+ x86_pci_write_config32(usb0, PCI_BASE_ADDRESS_0,
+ PCH_EHCI0_TEMP_BAR0);
+ cmd = x86_pci_read_config32(usb0, PCI_COMMAND);
cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
- pci_write_config32(usb0, PCI_COMMAND, cmd);
+ x86_pci_write_config32(usb0, PCI_COMMAND, cmd);
/* USB Controller 1 */
- pci_write_config32(usb1, PCI_BASE_ADDRESS_0,
- PCH_EHCI1_TEMP_BAR0);
- cmd = pci_read_config32(usb1, PCI_COMMAND);
+ x86_pci_write_config32(usb1, PCI_BASE_ADDRESS_0,
+ PCH_EHCI1_TEMP_BAR0);
+ cmd = x86_pci_read_config32(usb1, PCI_COMMAND);
cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
- pci_write_config32(usb1, PCI_COMMAND, cmd);
+ x86_pci_write_config32(usb1, PCI_COMMAND, cmd);
/* USB3 Controller */
- pci_write_config32(usb3, PCI_BASE_ADDRESS_0,
- PCH_XHCI_TEMP_BAR0);
- cmd = pci_read_config32(usb3, PCI_COMMAND);
+ x86_pci_write_config32(usb3, PCI_BASE_ADDRESS_0,
+ PCH_XHCI_TEMP_BAR0);
+ cmd = x86_pci_read_config32(usb3, PCI_COMMAND);
cmd |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
- pci_write_config32(usb3, PCI_COMMAND, cmd);
+ x86_pci_write_config32(usb3, PCI_COMMAND, cmd);
}
static int report_bist_failure(void)
@@ -320,8 +330,8 @@ int print_cpuinfo(void)
gd->arch.pei_boot_mode = boot_mode;
/* TODO: Move this to the board or driver */
- pci_write_config32(PCH_LPC_DEV, GPIO_BASE, DEFAULT_GPIOBASE | 1);
- pci_write_config32(PCH_LPC_DEV, GPIO_CNTL, 0x10);
+ x86_pci_write_config32(PCH_LPC_DEV, GPIO_BASE, DEFAULT_GPIOBASE | 1);
+ x86_pci_write_config32(PCH_LPC_DEV, GPIO_CNTL, 0x10);
/* Print processor name */
name = cpu_get_name(processor_name);
diff --git a/arch/x86/cpu/ivybridge/early_init.c b/arch/x86/cpu/ivybridge/early_init.c
index eb8f6139fe..9ca008e345 100644
--- a/arch/x86/cpu/ivybridge/early_init.c
+++ b/arch/x86/cpu/ivybridge/early_init.c
@@ -17,10 +17,10 @@ static void sandybridge_setup_bars(pci_dev_t pch_dev, pci_dev_t lpc_dev)
{
/* Setting up Southbridge. In the northbridge code. */
debug("Setting up static southbridge registers\n");
- pci_write_config32(lpc_dev, PCH_RCBA_BASE, DEFAULT_RCBA | 1);
+ x86_pci_write_config32(lpc_dev, PCH_RCBA_BASE, DEFAULT_RCBA | 1);
- pci_write_config32(lpc_dev, PMBASE, DEFAULT_PMBASE | 1);
- pci_write_config8(lpc_dev, ACPI_CNTL, 0x80); /* Enable ACPI BAR */
+ x86_pci_write_config32(lpc_dev, PMBASE, DEFAULT_PMBASE | 1);
+ x86_pci_write_config8(lpc_dev, ACPI_CNTL, 0x80); /* Enable ACPI BAR */
debug("Disabling watchdog reboot\n");
setbits_le32(RCB_REG(GCS), 1 >> 5); /* No reset */
@@ -28,25 +28,27 @@ static void sandybridge_setup_bars(pci_dev_t pch_dev, pci_dev_t lpc_dev)
/* Set up all hardcoded northbridge BARs */
debug("Setting up static registers\n");
- pci_write_config32(pch_dev, EPBAR, DEFAULT_EPBAR | 1);
- pci_write_config32(pch_dev, EPBAR + 4, (0LL + DEFAULT_EPBAR) >> 32);
- pci_write_config32(pch_dev, MCHBAR, DEFAULT_MCHBAR | 1);
- pci_write_config32(pch_dev, MCHBAR + 4, (0LL + DEFAULT_MCHBAR) >> 32);
+ x86_pci_write_config32(pch_dev, EPBAR, DEFAULT_EPBAR | 1);
+ x86_pci_write_config32(pch_dev, EPBAR + 4, (0LL + DEFAULT_EPBAR) >> 32);
+ x86_pci_write_config32(pch_dev, MCHBAR, DEFAULT_MCHBAR | 1);
+ x86_pci_write_config32(pch_dev, MCHBAR + 4,
+ (0LL + DEFAULT_MCHBAR) >> 32);
/* 64MB - busses 0-63 */
- pci_write_config32(pch_dev, PCIEXBAR, DEFAULT_PCIEXBAR | 5);
- pci_write_config32(pch_dev, PCIEXBAR + 4,
- (0LL + DEFAULT_PCIEXBAR) >> 32);
- pci_write_config32(pch_dev, DMIBAR, DEFAULT_DMIBAR | 1);
- pci_write_config32(pch_dev, DMIBAR + 4, (0LL + DEFAULT_DMIBAR) >> 32);
+ x86_pci_write_config32(pch_dev, PCIEXBAR, DEFAULT_PCIEXBAR | 5);
+ x86_pci_write_config32(pch_dev, PCIEXBAR + 4,
+ (0LL + DEFAULT_PCIEXBAR) >> 32);
+ x86_pci_write_config32(pch_dev, DMIBAR, DEFAULT_DMIBAR | 1);
+ x86_pci_write_config32(pch_dev, DMIBAR + 4,
+ (0LL + DEFAULT_DMIBAR) >> 32);
/* Set C0000-FFFFF to access RAM on both reads and writes */
- pci_write_config8(pch_dev, PAM0, 0x30);
- pci_write_config8(pch_dev, PAM1, 0x33);
- pci_write_config8(pch_dev, PAM2, 0x33);
- pci_write_config8(pch_dev, PAM3, 0x33);
- pci_write_config8(pch_dev, PAM4, 0x33);
- pci_write_config8(pch_dev, PAM5, 0x33);
- pci_write_config8(pch_dev, PAM6, 0x33);
+ x86_pci_write_config8(pch_dev, PAM0, 0x30);
+ x86_pci_write_config8(pch_dev, PAM1, 0x33);
+ x86_pci_write_config8(pch_dev, PAM2, 0x33);
+ x86_pci_write_config8(pch_dev, PAM3, 0x33);
+ x86_pci_write_config8(pch_dev, PAM4, 0x33);
+ x86_pci_write_config8(pch_dev, PAM5, 0x33);
+ x86_pci_write_config8(pch_dev, PAM6, 0x33);
}
static void sandybridge_setup_graphics(pci_dev_t pch_dev, pci_dev_t video_dev)
@@ -55,7 +57,7 @@ static void sandybridge_setup_graphics(pci_dev_t pch_dev, pci_dev_t video_dev)
u16 reg16;
u8 reg8;
- reg16 = pci_read_config16(video_dev, PCI_DEVICE_ID);
+ reg16 = x86_pci_read_config16(video_dev, PCI_DEVICE_ID);
switch (reg16) {
case 0x0102: /* GT1 Desktop */
case 0x0106: /* GT1 Mobile */
@@ -75,7 +77,7 @@ static void sandybridge_setup_graphics(pci_dev_t pch_dev, pci_dev_t video_dev)
debug("Initialising Graphics\n");
/* Setup IGD memory by setting GGC[7:3] = 1 for 32MB */
- reg16 = pci_read_config16(pch_dev, GGC);
+ reg16 = x86_pci_read_config16(pch_dev, GGC);
reg16 &= ~0x00f8;
reg16 |= 1 << 3;
/* Program GTT memory by setting GGC[9:8] = 2MB */
@@ -83,13 +85,13 @@ static void sandybridge_setup_graphics(pci_dev_t pch_dev, pci_dev_t video_dev)
reg16 |= 2 << 8;
/* Enable VGA decode */
reg16 &= ~0x0002;
- pci_write_config16(pch_dev, GGC, reg16);
+ x86_pci_write_config16(pch_dev, GGC, reg16);
/* Enable 256MB aperture */
- reg8 = pci_read_config8(video_dev, MSAC);
+ reg8 = x86_pci_read_config8(video_dev, MSAC);
reg8 &= ~0x06;
reg8 |= 0x02;
- pci_write_config8(video_dev, MSAC, reg8);
+ x86_pci_write_config8(video_dev, MSAC, reg8);
/* Erratum workarounds */
reg32 = readl(MCHBAR_REG(0x5f00));
@@ -124,22 +126,22 @@ void sandybridge_early_init(int chipset_type)
u8 reg8;
/* Device ID Override Enable should be done very early */
- capid0_a = pci_read_config32(pch_dev, 0xe4);
+ capid0_a = x86_pci_read_config32(pch_dev, 0xe4);
if (capid0_a & (1 << 10)) {
- reg8 = pci_read_config8(pch_dev, 0xf3);
+ reg8 = x86_pci_read_config8(pch_dev, 0xf3);
reg8 &= ~7; /* Clear 2:0 */
if (chipset_type == SANDYBRIDGE_MOBILE)
reg8 |= 1; /* Set bit 0 */
- pci_write_config8(pch_dev, 0xf3, reg8);
+ x86_pci_write_config8(pch_dev, 0xf3, reg8);
}
/* Setup all BARs required for early PCIe and raminit */
sandybridge_setup_bars(pch_dev, lpc_dev);
/* Device Enable */
- pci_write_config32(pch_dev, DEVEN, DEVEN_HOST | DEVEN_IGD);
+ x86_pci_write_config32(pch_dev, DEVEN, DEVEN_HOST | DEVEN_IGD);
sandybridge_setup_graphics(pch_dev, video_dev);
}
diff --git a/arch/x86/cpu/ivybridge/early_me.c b/arch/x86/cpu/ivybridge/early_me.c
index b24dea10b1..356bbb4a38 100644
--- a/arch/x86/cpu/ivybridge/early_me.c
+++ b/arch/x86/cpu/ivybridge/early_me.c
@@ -29,7 +29,7 @@ static inline void pci_read_dword_ptr(void *ptr, int offset)
{
u32 dword;
- dword = pci_read_config32(PCH_ME_DEV, offset);
+ dword = x86_pci_read_config32(PCH_ME_DEV, offset);
memcpy(ptr, &dword, sizeof(dword));
}
@@ -37,7 +37,7 @@ static inline void pci_write_dword_ptr(void *ptr, int offset)
{
u32 dword = 0;
memcpy(&dword, ptr, sizeof(dword));
- pci_write_config32(PCH_ME_DEV, offset, dword);
+ x86_pci_write_config32(PCH_ME_DEV, offset, dword);
}
void intel_early_me_status(void)
@@ -101,7 +101,7 @@ static inline void set_global_reset(int enable)
{
u32 etr3;
- etr3 = pci_read_config32(PCH_LPC_DEV, ETR3);
+ etr3 = x86_pci_read_config32(PCH_LPC_DEV, ETR3);
/* Clear CF9 Without Resume Well Reset Enable */
etr3 &= ~ETR3_CWORWRE;
@@ -112,7 +112,7 @@ static inline void set_global_reset(int enable)
else
etr3 &= ~ETR3_CF9GR;
- pci_write_config32(PCH_LPC_DEV, ETR3, etr3);
+ x86_pci_write_config32(PCH_LPC_DEV, ETR3, etr3);
}
int intel_early_me_init_done(u8 status)
@@ -127,8 +127,8 @@ int intel_early_me_init_done(u8 status)
};
/* MEBASE from MESEG_BASE[35:20] */
- mebase_l = pci_read_config32(PCH_DEV, PCI_CPU_MEBASE_L);
- mebase_h = pci_read_config32(PCH_DEV, PCI_CPU_MEBASE_H);
+ mebase_l = x86_pci_read_config32(PCH_DEV, PCI_CPU_MEBASE_L);
+ mebase_h = x86_pci_read_config32(PCH_DEV, PCI_CPU_MEBASE_H);
mebase_h &= 0xf;
did.uma_base = (mebase_l >> 20) | (mebase_h << 12);
diff --git a/arch/x86/cpu/ivybridge/gma.c b/arch/x86/cpu/ivybridge/gma.c
index 821ea25019..ea169b05e9 100644
--- a/arch/x86/cpu/ivybridge/gma.c
+++ b/arch/x86/cpu/ivybridge/gma.c
@@ -741,9 +741,9 @@ int gma_func0_init(pci_dev_t dev, struct pci_controller *hose,
int ret;
/* IGD needs to be Bus Master */
- reg32 = pci_read_config32(dev, PCI_COMMAND);
+ reg32 = x86_pci_read_config32(dev, PCI_COMMAND);
reg32 |= PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY | PCI_COMMAND_IO;
- pci_write_config32(dev, PCI_COMMAND, reg32);
+ x86_pci_write_config32(dev, PCI_COMMAND, reg32);
/* Use write-combining for the graphics memory, 256MB */
base = pci_read_bar32(hose, dev, 2);
diff --git a/arch/x86/cpu/ivybridge/lpc.c b/arch/x86/cpu/ivybridge/lpc.c
index 43fdd31428..bc1a0f06fb 100644
--- a/arch/x86/cpu/ivybridge/lpc.c
+++ b/arch/x86/cpu/ivybridge/lpc.c
@@ -7,6 +7,7 @@
*/
#include <common.h>
+#include <dm.h>
#include <errno.h>
#include <fdtdec.h>
#include <rtc.h>
@@ -29,7 +30,7 @@ static int pch_enable_apic(pci_dev_t dev)
int i;
/* Enable ACPI I/O and power management. Set SCI IRQ to IRQ9 */
- pci_write_config8(dev, ACPI_CNTL, 0x80);
+ x86_pci_write_config8(dev, ACPI_CNTL, 0x80);
writel(0, IO_APIC_INDEX);
writel(1 << 25, IO_APIC_DATA);
@@ -72,9 +73,9 @@ static void pch_enable_serial_irqs(pci_dev_t dev)
/* Set packet length and toggle silent mode bit for one frame. */
value = (1 << 7) | (1 << 6) | ((21 - 17) << 2) | (0 << 0);
#ifdef CONFIG_SERIRQ_CONTINUOUS_MODE
- pci_write_config8(dev, SERIRQ_CNTL, value);
+ x86_pci_write_config8(dev, SERIRQ_CNTL, value);
#else
- pci_write_config8(dev, SERIRQ_CNTL, value | (1 << 6));
+ x86_pci_write_config8(dev, SERIRQ_CNTL, value | (1 << 6));
#endif
}
@@ -86,15 +87,15 @@ static int pch_pirq_init(const void *blob, int node, pci_dev_t dev)
sizeof(route)))
return -EINVAL;
ptr = route;
- pci_write_config8(dev, PIRQA_ROUT, *ptr++);
- pci_write_config8(dev, PIRQB_ROUT, *ptr++);
- pci_write_config8(dev, PIRQC_ROUT, *ptr++);
- pci_write_config8(dev, PIRQD_ROUT, *ptr++);
+ x86_pci_write_config8(dev, PIRQA_ROUT, *ptr++);
+ x86_pci_write_config8(dev, PIRQB_ROUT, *ptr++);
+ x86_pci_write_config8(dev, PIRQC_ROUT, *ptr++);
+ x86_pci_write_config8(dev, PIRQD_ROUT, *ptr++);
- pci_write_config8(dev, PIRQE_ROUT, *ptr++);
- pci_write_config8(dev, PIRQF_ROUT, *ptr++);
- pci_write_config8(dev, PIRQG_ROUT, *ptr++);
- pci_write_config8(dev, PIRQH_ROUT, *ptr++);
+ x86_pci_write_config8(dev, PIRQE_ROUT, *ptr++);
+ x86_pci_write_config8(dev, PIRQF_ROUT, *ptr++);
+ x86_pci_write_config8(dev, PIRQG_ROUT, *ptr++);
+ x86_pci_write_config8(dev, PIRQH_ROUT, *ptr++);
/*
* TODO(sjg@chromium.org): U-Boot does not set up the interrupts
@@ -116,7 +117,7 @@ static int pch_gpi_routing(const void *blob, int node, pci_dev_t dev)
for (reg = 0, gpi = 0; gpi < ARRAY_SIZE(route); gpi++)
reg |= route[gpi] << (gpi * 2);
- pci_write_config32(dev, 0xb8, reg);
+ x86_pci_write_config32(dev, 0xb8, reg);
return 0;
}
@@ -141,7 +142,7 @@ static int pch_power_options(const void *blob, int node, pci_dev_t dev)
*/
pwr_on = MAINBOARD_POWER_ON;
- reg16 = pci_read_config16(dev, GEN_PMCON_3);
+ reg16 = x86_pci_read_config16(dev, GEN_PMCON_3);
reg16 &= 0xfffe;
switch (pwr_on) {
case MAINBOARD_POWER_OFF:
@@ -168,7 +169,7 @@ static int pch_power_options(const void *blob, int node, pci_dev_t dev)
reg16 |= (1 << 12); /* Disable SLP stretch after SUS well */
- pci_write_config16(dev, GEN_PMCON_3, reg16);
+ x86_pci_write_config16(dev, GEN_PMCON_3, reg16);
debug("Set power %s after power failure.\n", state);
/* Set up NMI on errors. */
@@ -192,21 +193,21 @@ static int pch_power_options(const void *blob, int node, pci_dev_t dev)
outb(reg8, 0x70);
/* Enable CPU_SLP# and Intel Speedstep, set SMI# rate down */
- reg16 = pci_read_config16(dev, GEN_PMCON_1);
+ reg16 = x86_pci_read_config16(dev, GEN_PMCON_1);
reg16 &= ~(3 << 0); /* SMI# rate 1 minute */
reg16 &= ~(1 << 10); /* Disable BIOS_PCI_EXP_EN for native PME */
#if DEBUG_PERIODIC_SMIS
/* Set DEBUG_PERIODIC_SMIS in pch.h to debug using periodic SMIs */
reg16 |= (3 << 0); /* Periodic SMI every 8s */
#endif
- pci_write_config16(dev, GEN_PMCON_1, reg16);
+ x86_pci_write_config16(dev, GEN_PMCON_1, reg16);
/* Set the board's GPI routing. */
ret = pch_gpi_routing(blob, node, dev);
if (ret)
return ret;
- pmbase = pci_read_config16(dev, 0x40) & 0xfffe;
+ pmbase = x86_pci_read_config16(dev, 0x40) & 0xfffe;
writel(pmbase + GPE0_EN, fdtdec_get_int(blob, node,
"intel,gpe0-enable", 0));
@@ -231,11 +232,11 @@ static void pch_rtc_init(pci_dev_t dev)
int rtc_failed;
u8 reg8;
- reg8 = pci_read_config8(dev, GEN_PMCON_3);
+ reg8 = x86_pci_read_config8(dev, GEN_PMCON_3);
rtc_failed = reg8 & RTC_BATTERY_DEAD;
if (rtc_failed) {
reg8 &= ~RTC_BATTERY_DEAD;
- pci_write_config8(dev, GEN_PMCON_3, reg8);
+ x86_pci_write_config8(dev, GEN_PMCON_3, reg8);
}
debug("rtc_failed = 0x%x\n", rtc_failed);
@@ -258,7 +259,7 @@ static void pch_rtc_init(pci_dev_t dev)
static void cpt_pm_init(pci_dev_t dev)
{
debug("CougarPoint PM init\n");
- pci_write_config8(dev, 0xa9, 0x47);
+ x86_pci_write_config8(dev, 0xa9, 0x47);
setbits_le32(RCB_REG(0x2238), (1 << 6) | (1 << 0));
setbits_le32(RCB_REG(0x228c), 1 << 0);
@@ -302,7 +303,7 @@ static void cpt_pm_init(pci_dev_t dev)
static void ppt_pm_init(pci_dev_t dev)
{
debug("PantherPoint PM init\n");
- pci_write_config8(dev, 0xa9, 0x47);
+ x86_pci_write_config8(dev, 0xa9, 0x47);
setbits_le32(RCB_REG(0x2238), 1 << 0);
setbits_le32(RCB_REG(0x228c), 1 << 0);
setbits_le16(RCB_REG(0x1100), (1 << 13) | (1 << 14));
@@ -356,9 +357,9 @@ static void enable_clock_gating(pci_dev_t dev)
setbits_le32(RCB_REG(0x2234), 0xf);
- reg16 = pci_read_config16(dev, GEN_PMCON_1);
+ reg16 = x86_pci_read_config16(dev, GEN_PMCON_1);
reg16 |= (1 << 2) | (1 << 11);
- pci_write_config16(dev, GEN_PMCON_1, reg16);
+ x86_pci_write_config16(dev, GEN_PMCON_1, reg16);
pch_iobp_update(0xEB007F07, ~0UL, (1 << 31));
pch_iobp_update(0xEB004000, ~0UL, (1 << 7));
@@ -412,15 +413,15 @@ static void pch_lock_smm(pci_dev_t dev)
#if TEST_SMM_FLASH_LOCKDOWN
/* Now try this: */
debug("Locking BIOS to RO... ");
- reg8 = pci_read_config8(dev, 0xdc); /* BIOS_CNTL */
+ reg8 = x86_pci_read_config8(dev, 0xdc); /* BIOS_CNTL */
debug(" BLE: %s; BWE: %s\n", (reg8 & 2) ? "on" : "off",
(reg8 & 1) ? "rw" : "ro");
reg8 &= ~(1 << 0); /* clear BIOSWE */
- pci_write_config8(dev, 0xdc, reg8);
+ x86_pci_write_config8(dev, 0xdc, reg8);
reg8 |= (1 << 1); /* set BLE */
- pci_write_config8(dev, 0xdc, reg8);
+ x86_pci_write_config8(dev, 0xdc, reg8);
debug("ok.\n");
- reg8 = pci_read_config8(dev, 0xdc); /* BIOS_CNTL */
+ reg8 = x86_pci_read_config8(dev, 0xdc); /* BIOS_CNTL */
debug(" BLE: %s; BWE: %s\n", (reg8 & 2) ? "on" : "off",
(reg8 & 1) ? "rw" : "ro");
@@ -428,9 +429,9 @@ static void pch_lock_smm(pci_dev_t dev)
writeb(0, 0xfff00000);
debug("Testing:\n");
reg8 |= (1 << 0); /* set BIOSWE */
- pci_write_config8(dev, 0xdc, reg8);
+ x86_pci_write_config8(dev, 0xdc, reg8);
- reg8 = pci_read_config8(dev, 0xdc); /* BIOS_CNTL */
+ reg8 = x86_pci_read_config8(dev, 0xdc); /* BIOS_CNTL */
debug(" BLE: %s; BWE: %s\n", (reg8 & 2) ? "on" : "off",
(reg8 & 1) ? "rw" : "ro");
debug("Done.\n");
@@ -443,9 +444,9 @@ static void pch_disable_smm_only_flashing(pci_dev_t dev)
u8 reg8;
debug("Enabling BIOS updates outside of SMM... ");
- reg8 = pci_read_config8(dev, 0xdc); /* BIOS_CNTL */
+ reg8 = x86_pci_read_config8(dev, 0xdc); /* BIOS_CNTL */
reg8 &= ~(1 << 5);
- pci_write_config8(dev, 0xdc, reg8);
+ x86_pci_write_config8(dev, 0xdc, reg8);
}
static void pch_fixups(pci_dev_t dev)
@@ -453,9 +454,9 @@ static void pch_fixups(pci_dev_t dev)
u8 gen_pmcon_2;
/* Indicate DRAM init done for MRC S3 to know it can resume */
- gen_pmcon_2 = pci_read_config8(dev, GEN_PMCON_2);
+ gen_pmcon_2 = x86_pci_read_config8(dev, GEN_PMCON_2);
gen_pmcon_2 |= (1 << 7);
- pci_write_config8(dev, GEN_PMCON_2, gen_pmcon_2);
+ x86_pci_write_config8(dev, GEN_PMCON_2, gen_pmcon_2);
/* Enable DMI ASPM in the PCH */
clrbits_le32(RCB_REG(0x2304), 1 << 10);
@@ -478,10 +479,10 @@ int lpc_early_init(const void *blob, int node, pci_dev_t dev)
return -EINVAL;
/* Set COM1/COM2 decode range */
- pci_write_config16(dev, LPC_IO_DEC, 0x0010);
+ x86_pci_write_config16(dev, LPC_IO_DEC, 0x0010);
/* Enable PS/2 Keyboard/Mouse, EC areas and COM1 */
- pci_write_config16(dev, LPC_EN, KBC_LPC_EN | MC_LPC_EN |
+ x86_pci_write_config16(dev, LPC_EN, KBC_LPC_EN | MC_LPC_EN |
GAMEL_LPC_EN | COMA_LPC_EN);
/* Write all registers but use 0 if we run out of data */
@@ -491,7 +492,7 @@ int lpc_early_init(const void *blob, int node, pci_dev_t dev)
if (i < count)
reg = ptr->base | PCI_COMMAND_IO | (ptr->size << 16);
- pci_write_config32(dev, LPC_GENX_DEC(i), reg);
+ x86_pci_write_config32(dev, LPC_GENX_DEC(i), reg);
}
return 0;
@@ -509,12 +510,12 @@ int lpc_init(struct pci_controller *hose, pci_dev_t dev)
pci_write_bar32(hose, dev, 3, 0x800);
pci_write_bar32(hose, dev, 4, 0x900);
- node = fdtdec_next_compatible(blob, 0, COMPAT_INTEL_LPC);
+ node = fdtdec_next_compatible(blob, 0, COMPAT_INTEL_PCH);
if (node < 0)
return -ENOENT;
/* Set the value for PCI command register. */
- pci_write_config16(dev, PCI_COMMAND, 0x000f);
+ x86_pci_write_config16(dev, PCI_COMMAND, 0x000f);
/* IO APIC initialization. */
pch_enable_apic(dev);
@@ -567,3 +568,14 @@ void lpc_enable(pci_dev_t dev)
writew(0x0010, RCB_REG(DISPBDF));
setbits_le32(RCB_REG(FD2), PCH_ENABLE_DBDF);
}
+
+static const struct udevice_id bd82x6x_lpc_ids[] = {
+ { .compatible = "intel,bd82x6x-lpc" },
+ { }
+};
+
+U_BOOT_DRIVER(bd82x6x_lpc_drv) = {
+ .name = "lpc",
+ .id = UCLASS_LPC,
+ .of_match = bd82x6x_lpc_ids,
+};
diff --git a/arch/x86/cpu/ivybridge/mrccache.c b/arch/x86/cpu/ivybridge/mrccache.c
index 0f1a64b268..92054948eb 100644
--- a/arch/x86/cpu/ivybridge/mrccache.c
+++ b/arch/x86/cpu/ivybridge/mrccache.c
@@ -105,7 +105,7 @@ static struct mrc_data_container *find_next_mrc_cache(struct fmap_entry *entry,
return cache;
}
-int mrccache_update(struct spi_flash *sf, struct fmap_entry *entry,
+int mrccache_update(struct udevice *sf, struct fmap_entry *entry,
struct mrc_data_container *cur)
{
struct mrc_data_container *cache;
@@ -135,7 +135,7 @@ int mrccache_update(struct spi_flash *sf, struct fmap_entry *entry,
debug("Erasing the MRC cache region of %x bytes at %x\n",
entry->length, entry->offset);
- ret = spi_flash_erase(sf, entry->offset, entry->length);
+ ret = spi_flash_erase_dm(sf, entry->offset, entry->length);
if (ret) {
debug("Failed to erase flash region\n");
return ret;
@@ -146,7 +146,8 @@ int mrccache_update(struct spi_flash *sf, struct fmap_entry *entry,
/* Write the data out */
offset = (ulong)cache - base_addr + entry->offset;
debug("Write MRC cache update to flash at %lx\n", offset);
- ret = spi_flash_write(sf, offset, cur->data_size + sizeof(*cur), cur);
+ ret = spi_flash_write_dm(sf, offset, cur->data_size + sizeof(*cur),
+ cur);
if (ret) {
debug("Failed to write to SPI flash\n");
return ret;
diff --git a/arch/x86/cpu/ivybridge/northbridge.c b/arch/x86/cpu/ivybridge/northbridge.c
index c50b5ded83..e95e60e519 100644
--- a/arch/x86/cpu/ivybridge/northbridge.c
+++ b/arch/x86/cpu/ivybridge/northbridge.c
@@ -30,7 +30,7 @@ int bridge_silicon_revision(void)
result = cpuid(1);
stepping = result.eax & 0xf;
dev = PCI_BDF(0, 0, 0);
- bridge_id = pci_read_config16(dev, PCI_DEVICE_ID) & 0xf0;
+ bridge_id = x86_pci_read_config16(dev, PCI_DEVICE_ID) & 0xf0;
bridge_revision_id = bridge_id | stepping;
}
@@ -55,7 +55,7 @@ static int get_pcie_bar(u32 *base, u32 *len)
*base = 0;
*len = 0;
- pciexbar_reg = pci_read_config32(dev, PCIEXBAR);
+ pciexbar_reg = x86_pci_read_config32(dev, PCIEXBAR);
if (!(pciexbar_reg & (1 << 0)))
return 0;
@@ -170,7 +170,7 @@ void northbridge_init(pci_dev_t dev)
void northbridge_enable(pci_dev_t dev)
{
#if CONFIG_HAVE_ACPI_RESUME
- switch (pci_read_config32(dev, SKPAD)) {
+ switch (x86_pci_read_config32(dev, SKPAD)) {
case 0xcafebabe:
debug("Normal boot.\n");
apci_set_slp_type(0);
diff --git a/arch/x86/cpu/ivybridge/pch.c b/arch/x86/cpu/ivybridge/pch.c
index fa04d488f3..bbab64699e 100644
--- a/arch/x86/cpu/ivybridge/pch.c
+++ b/arch/x86/cpu/ivybridge/pch.c
@@ -21,7 +21,7 @@ int pch_silicon_revision(void)
dev = PCH_LPC_DEV;
if (pch_revision_id < 0)
- pch_revision_id = pci_read_config8(dev, PCI_REVISION_ID);
+ pch_revision_id = x86_pci_read_config8(dev, PCI_REVISION_ID);
return pch_revision_id;
}
@@ -32,7 +32,7 @@ int pch_silicon_type(void)
dev = PCH_LPC_DEV;
if (pch_type < 0)
- pch_type = pci_read_config8(dev, PCI_DEVICE_ID + 1);
+ pch_type = x86_pci_read_config8(dev, PCI_DEVICE_ID + 1);
return pch_type;
}
diff --git a/arch/x86/cpu/ivybridge/pci.c b/arch/x86/cpu/ivybridge/pci.c
index 452d1c3a15..5e90f30e08 100644
--- a/arch/x86/cpu/ivybridge/pci.c
+++ b/arch/x86/cpu/ivybridge/pci.c
@@ -10,69 +10,30 @@
*/
#include <common.h>
+#include <dm.h>
#include <pci.h>
#include <asm/pci.h>
+#include <asm/post.h>
#include <asm/arch/bd82x6x.h>
#include <asm/arch/pch.h>
-static void config_pci_bridge(struct pci_controller *hose, pci_dev_t dev,
- struct pci_config_table *table)
-{
- u8 secondary;
-
- hose->read_byte(hose, dev, PCI_SECONDARY_BUS, &secondary);
- if (secondary != 0)
- pci_hose_scan_bus(hose, secondary);
-}
-
-static struct pci_config_table pci_ivybridge_config_table[] = {
- /* vendor, device, class, bus, dev, func */
- { PCI_ANY_ID, PCI_ANY_ID, PCI_CLASS_BRIDGE_PCI,
- PCI_ANY_ID, PCI_ANY_ID, PCI_ANY_ID, &config_pci_bridge },
- {}
-};
-
-void board_pci_setup_hose(struct pci_controller *hose)
-{
- hose->config_table = pci_ivybridge_config_table;
- hose->first_busno = 0;
- hose->last_busno = 0;
-
- /* PCI memory space */
- pci_set_region(hose->regions + 0,
- CONFIG_PCI_MEM_BUS,
- CONFIG_PCI_MEM_PHYS,
- CONFIG_PCI_MEM_SIZE,
- PCI_REGION_MEM);
-
- /* PCI IO space */
- pci_set_region(hose->regions + 1,
- CONFIG_PCI_IO_BUS,
- CONFIG_PCI_IO_PHYS,
- CONFIG_PCI_IO_SIZE,
- PCI_REGION_IO);
-
- pci_set_region(hose->regions + 2,
- CONFIG_PCI_PREF_BUS,
- CONFIG_PCI_PREF_PHYS,
- CONFIG_PCI_PREF_SIZE,
- PCI_REGION_PREFETCH);
-
- hose->region_count = 3;
-}
-
-int board_pci_pre_scan(struct pci_controller *hose)
+static int pci_ivybridge_probe(struct udevice *bus)
{
+ struct pci_controller *hose = dev_get_uclass_priv(bus);
pci_dev_t dev;
u16 reg16;
+ if (!(gd->flags & GD_FLG_RELOC))
+ return 0;
+ post_code(0x50);
bd82x6x_init();
+ post_code(0x51);
reg16 = 0xff;
dev = PCH_DEV;
- reg16 = pci_read_config16(dev, PCI_COMMAND);
+ reg16 = x86_pci_read_config16(dev, PCI_COMMAND);
reg16 |= PCI_COMMAND_SERR | PCI_COMMAND_MASTER | PCI_COMMAND_MEMORY;
- pci_write_config16(dev, PCI_COMMAND, reg16);
+ x86_pci_write_config16(dev, PCI_COMMAND, reg16);
/*
* Clear non-reserved bits in status register.
@@ -82,19 +43,25 @@ int board_pci_pre_scan(struct pci_controller *hose)
pci_hose_write_config_byte(hose, dev, PCI_CACHE_LINE_SIZE, 0x08);
pci_write_bar32(hose, dev, 0, 0xf0000000);
+ post_code(0x52);
return 0;
}
-int board_pci_post_scan(struct pci_controller *hose)
-{
- int ret;
+static const struct dm_pci_ops pci_ivybridge_ops = {
+ .read_config = pci_x86_read_config,
+ .write_config = pci_x86_write_config,
+};
- ret = bd82x6x_init_pci_devices();
- if (ret) {
- printf("bd82x6x_init_pci_devices() failed: %d\n", ret);
- return ret;
- }
+static const struct udevice_id pci_ivybridge_ids[] = {
+ { .compatible = "intel,pci-ivybridge" },
+ { }
+};
- return 0;
-}
+U_BOOT_DRIVER(pci_ivybridge_drv) = {
+ .name = "pci_ivybridge",
+ .id = UCLASS_PCI,
+ .of_match = pci_ivybridge_ids,
+ .ops = &pci_ivybridge_ops,
+ .probe = pci_ivybridge_probe,
+};
diff --git a/arch/x86/cpu/ivybridge/report_platform.c b/arch/x86/cpu/ivybridge/report_platform.c
index 69e31b3ca2..44938709c9 100644
--- a/arch/x86/cpu/ivybridge/report_platform.c
+++ b/arch/x86/cpu/ivybridge/report_platform.c
@@ -70,14 +70,14 @@ static void report_pch_info(void)
u16 dev_id;
uint8_t rev_id;
- dev_id = pci_read_config16(PCH_LPC_DEV, 2);
+ dev_id = x86_pci_read_config16(PCH_LPC_DEV, 2);
for (i = 0; i < ARRAY_SIZE(pch_table); i++) {
if (pch_table[i].dev_id == dev_id) {
pch_type = pch_table[i].dev_name;
break;
}
}
- rev_id = pci_read_config8(PCH_LPC_DEV, 8);
+ rev_id = x86_pci_read_config8(PCH_LPC_DEV, 8);
debug("PCH type: %s, device id: %x, rev id %x\n", pch_type, dev_id,
rev_id);
}
diff --git a/arch/x86/cpu/ivybridge/sata.c b/arch/x86/cpu/ivybridge/sata.c
index bbcd47da60..e7bf03c1dc 100644
--- a/arch/x86/cpu/ivybridge/sata.c
+++ b/arch/x86/cpu/ivybridge/sata.c
@@ -14,14 +14,14 @@
static inline u32 sir_read(pci_dev_t dev, int idx)
{
- pci_write_config32(dev, SATA_SIRI, idx);
- return pci_read_config32(dev, SATA_SIRD);
+ x86_pci_write_config32(dev, SATA_SIRI, idx);
+ return x86_pci_read_config32(dev, SATA_SIRD);
}
static inline void sir_write(pci_dev_t dev, int idx, u32 value)
{
- pci_write_config32(dev, SATA_SIRI, idx);
- pci_write_config32(dev, SATA_SIRD, value);
+ x86_pci_write_config32(dev, SATA_SIRI, idx);
+ x86_pci_write_config32(dev, SATA_SIRD, value);
}
static void common_sata_init(pci_dev_t dev, unsigned int port_map)
@@ -31,17 +31,17 @@ static void common_sata_init(pci_dev_t dev, unsigned int port_map)
/* Set IDE I/O Configuration */
reg32 = SIG_MODE_PRI_NORMAL | FAST_PCB1 | FAST_PCB0 | PCB1 | PCB0;
- pci_write_config32(dev, IDE_CONFIG, reg32);
+ x86_pci_write_config32(dev, IDE_CONFIG, reg32);
/* Port enable */
- reg16 = pci_read_config16(dev, 0x92);
+ reg16 = x86_pci_read_config16(dev, 0x92);
reg16 &= ~0x3f;
reg16 |= port_map;
- pci_write_config16(dev, 0x92, reg16);
+ x86_pci_write_config16(dev, 0x92, reg16);
/* SATA Initialization register */
port_map &= 0xff;
- pci_write_config32(dev, 0x94, ((port_map ^ 0x3f) << 24) | 0x183);
+ x86_pci_write_config32(dev, 0x94, ((port_map ^ 0x3f) << 24) | 0x183);
}
void bd82x6x_sata_init(pci_dev_t dev, const void *blob, int node)
@@ -60,7 +60,7 @@ void bd82x6x_sata_init(pci_dev_t dev, const void *blob, int node)
"sata_interface_speed_support", 0);
/* Enable BARs */
- pci_write_config16(dev, PCI_COMMAND, 0x0007);
+ x86_pci_write_config16(dev, PCI_COMMAND, 0x0007);
mode = fdt_getprop(blob, node, "intel,sata-mode", NULL);
if (!mode || !strcmp(mode, "ahci")) {
@@ -69,18 +69,18 @@ void bd82x6x_sata_init(pci_dev_t dev, const void *blob, int node)
debug("SATA: Controller in AHCI mode\n");
/* Set Interrupt Line, Interrupt Pin is set by D31IP.PIP */
- pci_write_config8(dev, INTR_LN, 0x0a);
+ x86_pci_write_config8(dev, INTR_LN, 0x0a);
/* Set timings */
- pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE |
+ x86_pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE |
IDE_ISP_3_CLOCKS | IDE_RCT_1_CLOCKS |
IDE_PPE0 | IDE_IE0 | IDE_TIME0);
- pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE |
+ x86_pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE |
IDE_ISP_5_CLOCKS | IDE_RCT_4_CLOCKS);
/* Sync DMA */
- pci_write_config16(dev, IDE_SDMA_CNT, IDE_PSDE0);
- pci_write_config16(dev, IDE_SDMA_TIM, 0x0001);
+ x86_pci_write_config16(dev, IDE_SDMA_CNT, IDE_PSDE0);
+ x86_pci_write_config16(dev, IDE_SDMA_TIM, 0x0001);
common_sata_init(dev, 0x8000 | port_map);
@@ -115,22 +115,22 @@ void bd82x6x_sata_init(pci_dev_t dev, const void *blob, int node)
/* No AHCI: clear AHCI base */
pci_write_bar32(hose, dev, 5, 0x00000000);
/* And without AHCI BAR no memory decoding */
- reg16 = pci_read_config16(dev, PCI_COMMAND);
+ reg16 = x86_pci_read_config16(dev, PCI_COMMAND);
reg16 &= ~PCI_COMMAND_MEMORY;
- pci_write_config16(dev, PCI_COMMAND, reg16);
+ x86_pci_write_config16(dev, PCI_COMMAND, reg16);
- pci_write_config8(dev, 0x09, 0x80);
+ x86_pci_write_config8(dev, 0x09, 0x80);
/* Set timings */
- pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE |
+ x86_pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE |
IDE_ISP_5_CLOCKS | IDE_RCT_4_CLOCKS);
- pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE |
+ x86_pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE |
IDE_ISP_3_CLOCKS | IDE_RCT_1_CLOCKS |
IDE_PPE0 | IDE_IE0 | IDE_TIME0);
/* Sync DMA */
- pci_write_config16(dev, IDE_SDMA_CNT, IDE_SSDE0);
- pci_write_config16(dev, IDE_SDMA_TIM, 0x0200);
+ x86_pci_write_config16(dev, IDE_SDMA_CNT, IDE_SSDE0);
+ x86_pci_write_config16(dev, IDE_SDMA_TIM, 0x0200);
common_sata_init(dev, port_map);
} else {
@@ -140,31 +140,32 @@ void bd82x6x_sata_init(pci_dev_t dev, const void *blob, int node)
pci_write_bar32(hose, dev, 5, 0x00000000);
/* And without AHCI BAR no memory decoding */
- reg16 = pci_read_config16(dev, PCI_COMMAND);
+ reg16 = x86_pci_read_config16(dev, PCI_COMMAND);
reg16 &= ~PCI_COMMAND_MEMORY;
- pci_write_config16(dev, PCI_COMMAND, reg16);
+ x86_pci_write_config16(dev, PCI_COMMAND, reg16);
/*
* Native mode capable on both primary and secondary (0xa)
* OR'ed with enabled (0x50) = 0xf
*/
- pci_write_config8(dev, 0x09, 0x8f);
+ x86_pci_write_config8(dev, 0x09, 0x8f);
/* Set Interrupt Line */
/* Interrupt Pin is set by D31IP.PIP */
- pci_write_config8(dev, INTR_LN, 0xff);
+ x86_pci_write_config8(dev, INTR_LN, 0xff);
/* Set timings */
- pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE |
+ x86_pci_write_config16(dev, IDE_TIM_PRI, IDE_DECODE_ENABLE |
IDE_ISP_3_CLOCKS | IDE_RCT_1_CLOCKS |
IDE_PPE0 | IDE_IE0 | IDE_TIME0);
- pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE |
+ x86_pci_write_config16(dev, IDE_TIM_SEC, IDE_DECODE_ENABLE |
IDE_SITRE | IDE_ISP_3_CLOCKS |
IDE_RCT_1_CLOCKS | IDE_IE0 | IDE_TIME0);
/* Sync DMA */
- pci_write_config16(dev, IDE_SDMA_CNT, IDE_SSDE0 | IDE_PSDE0);
- pci_write_config16(dev, IDE_SDMA_TIM, 0x0201);
+ x86_pci_write_config16(dev, IDE_SDMA_CNT,
+ IDE_SSDE0 | IDE_PSDE0);
+ x86_pci_write_config16(dev, IDE_SDMA_TIM, 0x0201);
common_sata_init(dev, port_map);
}
@@ -221,5 +222,5 @@ void bd82x6x_sata_enable(pci_dev_t dev, const void *blob, int node)
port_map = fdtdec_get_int(blob, node, "intel,sata-port-map", 0);
map |= (port_map ^ 0x3f) << 8;
- pci_write_config16(dev, 0x90, map);
+ x86_pci_write_config16(dev, 0x90, map);
}
diff --git a/arch/x86/cpu/ivybridge/sdram.c b/arch/x86/cpu/ivybridge/sdram.c
index 766b385c25..9a6da37d09 100644
--- a/arch/x86/cpu/ivybridge/sdram.c
+++ b/arch/x86/cpu/ivybridge/sdram.c
@@ -89,11 +89,12 @@ void dram_init_banksize(void)
}
}
-static int get_mrc_entry(struct spi_flash **sfp, struct fmap_entry *entry)
+static int get_mrc_entry(struct udevice **devp, struct fmap_entry *entry)
{
const void *blob = gd->fdt_blob;
int node, spi_node, mrc_node;
int upto;
+ int ret;
/* Find the flash chip within the SPI controller node */
upto = 0;
@@ -112,10 +113,13 @@ static int get_mrc_entry(struct spi_flash **sfp, struct fmap_entry *entry)
if (fdtdec_read_fmap_entry(blob, mrc_node, "rm-mrc-cache", entry))
return -EINVAL;
- if (sfp) {
- *sfp = spi_flash_probe_fdt(blob, node, spi_node);
- if (!*sfp)
- return -EBADF;
+ if (devp) {
+ debug("getting sf\n");
+ ret = uclass_get_device_by_of_offset(UCLASS_SPI_FLASH, node,
+ devp);
+ debug("ret = %d\n", ret);
+ if (ret)
+ return ret;
}
return 0;
@@ -246,7 +250,7 @@ static int sdram_save_mrc_data(void)
{
struct mrc_data_container *data;
struct fmap_entry entry;
- struct spi_flash *sf;
+ struct udevice *sf;
int ret;
if (!gd->arch.mrc_output_len)
@@ -266,7 +270,6 @@ static int sdram_save_mrc_data(void)
free(data);
err_data:
- spi_flash_free(sf);
err_entry:
if (ret)
debug("%s: Failed: %d\n", __func__, ret);
@@ -444,7 +447,7 @@ int sdram_initialise(struct pei_data *pei_data)
* Send ME init done for SandyBridge here. This is done inside the
* SystemAgent binary on IvyBridge
*/
- done = pci_read_config32(PCH_DEV, PCI_DEVICE_ID);
+ done = x86_pci_read_config32(PCH_DEV, PCI_DEVICE_ID);
done &= BASE_REV_MASK;
if (BASE_REV_SNB == done)
intel_early_me_init_done(ME_INIT_STATUS_SUCCESS);
@@ -615,24 +618,24 @@ static int sdram_find(pci_dev_t dev)
*/
/* Top of Upper Usable DRAM, including remap */
- touud = pci_read_config32(dev, TOUUD+4);
+ touud = x86_pci_read_config32(dev, TOUUD+4);
touud <<= 32;
- touud |= pci_read_config32(dev, TOUUD);
+ touud |= x86_pci_read_config32(dev, TOUUD);
/* Top of Lower Usable DRAM */
- tolud = pci_read_config32(dev, TOLUD);
+ tolud = x86_pci_read_config32(dev, TOLUD);
/* Top of Memory - does not account for any UMA */
- tom = pci_read_config32(dev, 0xa4);
+ tom = x86_pci_read_config32(dev, 0xa4);
tom <<= 32;
- tom |= pci_read_config32(dev, 0xa0);
+ tom |= x86_pci_read_config32(dev, 0xa0);
debug("TOUUD %llx TOLUD %08x TOM %llx\n", touud, tolud, tom);
/* ME UMA needs excluding if total memory <4GB */
- me_base = pci_read_config32(dev, 0x74);
+ me_base = x86_pci_read_config32(dev, 0x74);
me_base <<= 32;
- me_base |= pci_read_config32(dev, 0x70);
+ me_base |= x86_pci_read_config32(dev, 0x70);
debug("MEBASE %llx\n", me_base);
@@ -650,7 +653,7 @@ static int sdram_find(pci_dev_t dev)
}
/* Graphics memory comes next */
- ggc = pci_read_config16(dev, GGC);
+ ggc = x86_pci_read_config16(dev, GGC);
if (!(ggc & 2)) {
debug("IGD decoded, subtracting ");
@@ -670,7 +673,7 @@ static int sdram_find(pci_dev_t dev)
}
/* Calculate TSEG size from its base which must be below GTT */
- tseg_base = pci_read_config32(dev, 0xb8);
+ tseg_base = x86_pci_read_config32(dev, 0xb8);
uma_size = (uma_memory_base - tseg_base) >> 10;
tomk -= uma_size;
uma_memory_base = tomk * 1024ULL;
diff --git a/arch/x86/cpu/ivybridge/usb_ehci.c b/arch/x86/cpu/ivybridge/usb_ehci.c
index 291c971a2f..da11aee94d 100644
--- a/arch/x86/cpu/ivybridge/usb_ehci.c
+++ b/arch/x86/cpu/ivybridge/usb_ehci.c
@@ -20,10 +20,10 @@ void bd82x6x_usb_ehci_init(pci_dev_t dev)
writel(reg32, RCB_REG(0x35b0));
debug("EHCI: Setting up controller.. ");
- reg32 = pci_read_config32(dev, PCI_COMMAND);
+ reg32 = x86_pci_read_config32(dev, PCI_COMMAND);
reg32 |= PCI_COMMAND_MASTER;
/* reg32 |= PCI_COMMAND_SERR; */
- pci_write_config32(dev, PCI_COMMAND, reg32);
+ x86_pci_write_config32(dev, PCI_COMMAND, reg32);
debug("done.\n");
}
diff --git a/arch/x86/cpu/ivybridge/usb_xhci.c b/arch/x86/cpu/ivybridge/usb_xhci.c
index 4a32a7eb31..f77b80489b 100644
--- a/arch/x86/cpu/ivybridge/usb_xhci.c
+++ b/arch/x86/cpu/ivybridge/usb_xhci.c
@@ -16,17 +16,17 @@ void bd82x6x_usb_xhci_init(pci_dev_t dev)
debug("XHCI: Setting up controller.. ");
/* lock overcurrent map */
- reg32 = pci_read_config32(dev, 0x44);
+ reg32 = x86_pci_read_config32(dev, 0x44);
reg32 |= 1;
- pci_write_config32(dev, 0x44, reg32);
+ x86_pci_write_config32(dev, 0x44, reg32);
/* Enable clock gating */
- reg32 = pci_read_config32(dev, 0x40);
+ reg32 = x86_pci_read_config32(dev, 0x40);
reg32 &= ~((1 << 20) | (1 << 21));
reg32 |= (1 << 19) | (1 << 18) | (1 << 17);
reg32 |= (1 << 10) | (1 << 9) | (1 << 8);
reg32 |= (1 << 31); /* lock */
- pci_write_config32(dev, 0x40, reg32);
+ x86_pci_write_config32(dev, 0x40, reg32);
debug("done.\n");
}
diff --git a/arch/x86/cpu/pci.c b/arch/x86/cpu/pci.c
index ab1aaaa059..e23b233961 100644
--- a/arch/x86/cpu/pci.c
+++ b/arch/x86/cpu/pci.c
@@ -10,9 +10,11 @@
*/
#include <common.h>
+#include <dm.h>
#include <errno.h>
#include <malloc.h>
#include <pci.h>
+#include <asm/io.h>
#include <asm/pci.h>
DECLARE_GLOBAL_DATA_PTR;
@@ -70,7 +72,7 @@ static struct pci_controller *get_hose(void)
return pci_bus_to_hose(0);
}
-unsigned int pci_read_config8(pci_dev_t dev, unsigned where)
+unsigned int x86_pci_read_config8(pci_dev_t dev, unsigned where)
{
uint8_t value;
@@ -79,7 +81,7 @@ unsigned int pci_read_config8(pci_dev_t dev, unsigned where)
return value;
}
-unsigned int pci_read_config16(pci_dev_t dev, unsigned where)
+unsigned int x86_pci_read_config16(pci_dev_t dev, unsigned where)
{
uint16_t value;
@@ -88,7 +90,7 @@ unsigned int pci_read_config16(pci_dev_t dev, unsigned where)
return value;
}
-unsigned int pci_read_config32(pci_dev_t dev, unsigned where)
+unsigned int x86_pci_read_config32(pci_dev_t dev, unsigned where)
{
uint32_t value;
@@ -97,17 +99,55 @@ unsigned int pci_read_config32(pci_dev_t dev, unsigned where)
return value;
}
-void pci_write_config8(pci_dev_t dev, unsigned where, unsigned value)
+void x86_pci_write_config8(pci_dev_t dev, unsigned where, unsigned value)
{
pci_hose_write_config_byte(get_hose(), dev, where, value);
}
-void pci_write_config16(pci_dev_t dev, unsigned where, unsigned value)
+void x86_pci_write_config16(pci_dev_t dev, unsigned where, unsigned value)
{
pci_hose_write_config_word(get_hose(), dev, where, value);
}
-void pci_write_config32(pci_dev_t dev, unsigned where, unsigned value)
+void x86_pci_write_config32(pci_dev_t dev, unsigned where, unsigned value)
{
pci_hose_write_config_dword(get_hose(), dev, where, value);
}
+
+int pci_x86_read_config(struct udevice *bus, pci_dev_t bdf, uint offset,
+ ulong *valuep, enum pci_size_t size)
+{
+ outl(bdf | (offset & 0xfc) | PCI_CFG_EN, PCI_REG_ADDR);
+ switch (size) {
+ case PCI_SIZE_8:
+ *valuep = inb(PCI_REG_DATA + (offset & 3));
+ break;
+ case PCI_SIZE_16:
+ *valuep = inw(PCI_REG_DATA + (offset & 2));
+ break;
+ case PCI_SIZE_32:
+ *valuep = inl(PCI_REG_DATA);
+ break;
+ }
+
+ return 0;
+}
+
+int pci_x86_write_config(struct udevice *bus, pci_dev_t bdf, uint offset,
+ ulong value, enum pci_size_t size)
+{
+ outl(bdf | (offset & 0xfc) | PCI_CFG_EN, PCI_REG_ADDR);
+ switch (size) {
+ case PCI_SIZE_8:
+ outb(value, PCI_REG_DATA + (offset & 3));
+ break;
+ case PCI_SIZE_16:
+ outw(value, PCI_REG_DATA + (offset & 2));
+ break;
+ case PCI_SIZE_32:
+ outl(value, PCI_REG_DATA);
+ break;
+ }
+
+ return 0;
+}
diff --git a/arch/x86/cpu/quark/quark.c b/arch/x86/cpu/quark/quark.c
index 25edcf71cb..e4b19c2759 100644
--- a/arch/x86/cpu/quark/quark.c
+++ b/arch/x86/cpu/quark/quark.c
@@ -30,9 +30,9 @@ static void unprotect_spi_flash(void)
{
u32 bc;
- bc = pci_read_config32(QUARK_LEGACY_BRIDGE, 0xd8);
+ bc = x86_pci_read_config32(QUARK_LEGACY_BRIDGE, 0xd8);
bc |= 0x1; /* unprotect the flash */
- pci_write_config32(QUARK_LEGACY_BRIDGE, 0xd8, bc);
+ x86_pci_write_config32(QUARK_LEGACY_BRIDGE, 0xd8, bc);
}
static void quark_setup_bars(void)
diff --git a/arch/x86/cpu/queensbay/tnc.c b/arch/x86/cpu/queensbay/tnc.c
index 30ab725bb9..b7236e7b60 100644
--- a/arch/x86/cpu/queensbay/tnc.c
+++ b/arch/x86/cpu/queensbay/tnc.c
@@ -16,9 +16,9 @@ static void unprotect_spi_flash(void)
{
u32 bc;
- bc = pci_read_config32(PCH_LPC_DEV, 0xd8);
+ bc = x86_pci_read_config32(PCH_LPC_DEV, 0xd8);
bc |= 0x1; /* unprotect the flash */
- pci_write_config32(PCH_LPC_DEV, 0xd8, bc);
+ x86_pci_write_config32(PCH_LPC_DEV, 0xd8, bc);
}
int arch_cpu_init(void)
diff --git a/arch/x86/dts/Makefile b/arch/x86/dts/Makefile
index 7a66133555..431bbd8a0d 100644
--- a/arch/x86/dts/Makefile
+++ b/arch/x86/dts/Makefile
@@ -1,4 +1,5 @@
dtb-y += chromebook_link.dtb \
+ chromebox_panther.dtb \
crownbay.dtb \
galileo.dtb \
minnowmax.dtb
diff --git a/arch/x86/dts/chromebook_link.dts b/arch/x86/dts/chromebook_link.dts
index 45ada610b3..b450c3c55f 100644
--- a/arch/x86/dts/chromebook_link.dts
+++ b/arch/x86/dts/chromebook_link.dts
@@ -8,7 +8,7 @@
compatible = "google,link", "intel,celeron-ivybridge";
aliases {
- spi0 = "/spi";
+ spi0 = "/pci/pch/spi";
};
config {
@@ -151,27 +151,14 @@
};
};
- spi {
- #address-cells = <1>;
- #size-cells = <0>;
- compatible = "intel,ich-spi";
- spi-flash@0 {
- #size-cells = <1>;
- #address-cells = <1>;
- reg = <0>;
- compatible = "winbond,w25q64", "spi-flash";
- memory-map = <0xff800000 0x00800000>;
- rw-mrc-cache {
- label = "rw-mrc-cache";
- /* Alignment: 4k (for updating) */
- reg = <0x003e0000 0x00010000>;
- type = "wiped";
- wipe-value = [ff];
- };
- };
- };
-
pci {
+ compatible = "intel,pci-ivybridge", "pci-x86";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ u-boot,dm-pre-reloc;
+ ranges = <0x02000000 0x0 0xe0000000 0xe0000000 0 0x10000000
+ 0x42000000 0x0 0xd0000000 0xd0000000 0 0x10000000
+ 0x01000000 0x0 0x1000 0x1000 0 0xefff>;
sata {
compatible = "intel,pantherpoint-ahci";
intel,sata-mode = "ahci";
@@ -192,8 +179,10 @@
intel,pch-backlight = <0x04000000>;
};
- lpc {
- compatible = "intel,lpc";
+ pch {
+ reg = <0x0000f800 0 0 0 0>;
+ compatible = "intel,bd82x6x";
+ u-boot,dm-pre-reloc;
#address-cells = <1>;
#size-cells = <1>;
gen-dec = <0x800 0xfc 0x900 0xfc>;
@@ -204,17 +193,44 @@
1 0 0 0 0 0 0 0>;
/* Enable EC SMI source */
intel,alt-gp-smi-enable = <0x0100>;
+ spi {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "intel,ich-spi";
+ spi-flash@0 {
+ #size-cells = <1>;
+ #address-cells = <1>;
+ reg = <0>;
+ compatible = "winbond,w25q64",
+ "spi-flash";
+ memory-map = <0xff800000 0x00800000>;
+ rw-mrc-cache {
+ label = "rw-mrc-cache";
+ reg = <0x003e0000 0x00010000>;
+ type = "wiped";
+ wipe-value = [ff];
+ };
+ };
+ };
- cros-ec@200 {
- compatible = "google,cros-ec";
- reg = <0x204 1 0x200 1 0x880 0x80>;
-
- /* Describes the flash memory within the EC */
+ lpc {
+ compatible = "intel,bd82x6x-lpc";
#address-cells = <1>;
- #size-cells = <1>;
- flash@8000000 {
- reg = <0x08000000 0x20000>;
- erase-value = <0xff>;
+ #size-cells = <0>;
+ cros-ec@200 {
+ compatible = "google,cros-ec";
+ reg = <0x204 1 0x200 1 0x880 0x80>;
+
+ /*
+ * Describes the flash memory within
+ * the EC
+ */
+ #address-cells = <1>;
+ #size-cells = <1>;
+ flash@8000000 {
+ reg = <0x08000000 0x20000>;
+ erase-value = <0xff>;
+ };
};
};
};
diff --git a/arch/x86/dts/chromebox_panther.dts b/arch/x86/dts/chromebox_panther.dts
new file mode 100644
index 0000000000..4eccefdb8c
--- /dev/null
+++ b/arch/x86/dts/chromebox_panther.dts
@@ -0,0 +1,64 @@
+/dts-v1/;
+
+/include/ "skeleton.dtsi"
+/include/ "serial.dtsi"
+
+/ {
+ model = "Google Panther";
+ compatible = "google,panther", "intel,haswell";
+
+ aliases {
+ spi0 = "/spi";
+ };
+
+ config {
+ silent-console = <0>;
+ no-keyboard;
+ };
+
+ gpioa {
+ compatible = "intel,ich6-gpio";
+ u-boot,dm-pre-reloc;
+ reg = <0 0x10>;
+ bank-name = "A";
+ };
+
+ gpiob {
+ compatible = "intel,ich6-gpio";
+ u-boot,dm-pre-reloc;
+ reg = <0x30 0x10>;
+ bank-name = "B";
+ };
+
+ gpioc {
+ compatible = "intel,ich6-gpio";
+ u-boot,dm-pre-reloc;
+ reg = <0x40 0x10>;
+ bank-name = "C";
+ };
+
+ chosen {
+ stdout-path = "/serial";
+ };
+
+ spi {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ compatible = "intel,ich-spi";
+ spi-flash@0 {
+ #size-cells = <1>;
+ #address-cells = <1>;
+ reg = <0>;
+ compatible = "winbond,w25q64", "spi-flash";
+ memory-map = <0xff800000 0x00800000>;
+ rw-mrc-cache {
+ label = "rw-mrc-cache";
+ /* Alignment: 4k (for updating) */
+ reg = <0x003e0000 0x00010000>;
+ type = "wiped";
+ wipe-value = [ff];
+ };
+ };
+ };
+
+};
diff --git a/arch/x86/include/asm/arch-ivybridge/bd82x6x.h b/arch/x86/include/asm/arch-ivybridge/bd82x6x.h
index e1d9a9b7b2..5ae32f7883 100644
--- a/arch/x86/include/asm/arch-ivybridge/bd82x6x.h
+++ b/arch/x86/include/asm/arch-ivybridge/bd82x6x.h
@@ -12,7 +12,6 @@ void bd82x6x_sata_enable(pci_dev_t dev, const void *blob, int node);
void bd82x6x_pci_init(pci_dev_t dev);
void bd82x6x_usb_ehci_init(pci_dev_t dev);
void bd82x6x_usb_xhci_init(pci_dev_t dev);
-int bd82x6x_init_pci_devices(void);
int gma_func0_init(pci_dev_t dev, struct pci_controller *hose,
const void *blob, int node);
int bd82x6x_init(void);
diff --git a/arch/x86/include/asm/arch-ivybridge/mrccache.h b/arch/x86/include/asm/arch-ivybridge/mrccache.h
index 968b2eff9e..1d50ebb85a 100644
--- a/arch/x86/include/asm/arch-ivybridge/mrccache.h
+++ b/arch/x86/include/asm/arch-ivybridge/mrccache.h
@@ -20,7 +20,7 @@ __packed struct mrc_data_container {
};
struct fmap_entry;
-struct spi_flash;
+struct udevice;
/**
* mrccache_find_current() - find the latest MRC cache record
@@ -45,7 +45,7 @@ struct mrc_data_container *mrccache_find_current(struct fmap_entry *entry);
* @return 0 if updated, -EEXIST if the record is the same as the latest
* record, other error if SPI write failed
*/
-int mrccache_update(struct spi_flash *sf, struct fmap_entry *entry,
+int mrccache_update(struct udevice *sf, struct fmap_entry *entry,
struct mrc_data_container *cur);
#endif
diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h
index a153dd1622..a1969ede27 100644
--- a/arch/x86/include/asm/pci.h
+++ b/arch/x86/include/asm/pci.h
@@ -8,6 +8,8 @@
#ifndef _PCI_I386_H_
#define _PCI_I386_H_
+#include <pci.h>
+
/* bus mapping constants (used for PCI core initialization) */
#define PCI_REG_ADDR 0xcf8
#define PCI_REG_DATA 0xcfc
@@ -48,13 +50,19 @@ int board_pci_post_scan(struct pci_controller *hose);
* Simple PCI access routines - these work from either the early PCI hose
* or the 'real' one, created after U-Boot has memory available
*/
-unsigned int pci_read_config8(pci_dev_t dev, unsigned where);
-unsigned int pci_read_config16(pci_dev_t dev, unsigned where);
-unsigned int pci_read_config32(pci_dev_t dev, unsigned where);
+unsigned int x86_pci_read_config8(pci_dev_t dev, unsigned where);
+unsigned int x86_pci_read_config16(pci_dev_t dev, unsigned where);
+unsigned int x86_pci_read_config32(pci_dev_t dev, unsigned where);
+
+void x86_pci_write_config8(pci_dev_t dev, unsigned where, unsigned value);
+void x86_pci_write_config16(pci_dev_t dev, unsigned where, unsigned value);
+void x86_pci_write_config32(pci_dev_t dev, unsigned where, unsigned value);
+
+int pci_x86_read_config(struct udevice *bus, pci_dev_t bdf, uint offset,
+ ulong *valuep, enum pci_size_t size);
-void pci_write_config8(pci_dev_t dev, unsigned where, unsigned value);
-void pci_write_config16(pci_dev_t dev, unsigned where, unsigned value);
-void pci_write_config32(pci_dev_t dev, unsigned where, unsigned value);
+int pci_x86_write_config(struct udevice *bus, pci_dev_t bdf, uint offset,
+ ulong value, enum pci_size_t size);
#endif /* __ASSEMBLY__ */
diff --git a/arch/x86/lib/Makefile b/arch/x86/lib/Makefile
index c17f7f088b..6c571dd9c1 100644
--- a/arch/x86/lib/Makefile
+++ b/arch/x86/lib/Makefile
@@ -14,10 +14,14 @@ obj-$(CONFIG_HAVE_FSP) += cmd_hob.o
obj-y += gcc.o
obj-y += init_helpers.o
obj-y += interrupts.o
+obj-y += lpc-uclass.o
obj-y += cmd_mtrr.o
obj-$(CONFIG_SYS_PCAT_INTERRUPTS) += pcat_interrupts.o
obj-$(CONFIG_SYS_PCAT_TIMER) += pcat_timer.o
+ifndef CONFIG_DM_PCI
obj-$(CONFIG_PCI) += pci_type1.o
+endif
+obj-y += pch-uclass.o
obj-y += relocate.o
obj-y += physmem.o
obj-$(CONFIG_X86_RAMTEST) += ramtest.o
diff --git a/arch/x86/lib/bios_interrupts.c b/arch/x86/lib/bios_interrupts.c
index b0e2ecbbca..290990a8bd 100644
--- a/arch/x86/lib/bios_interrupts.c
+++ b/arch/x86/lib/bios_interrupts.c
@@ -172,28 +172,28 @@ int int1a_handler(void)
}
switch (func) {
case 0xb108: /* Read Config Byte */
- byte = pci_read_config8(dev, reg);
+ byte = x86_pci_read_config8(dev, reg);
M.x86.R_ECX = byte;
break;
case 0xb109: /* Read Config Word */
- word = pci_read_config16(dev, reg);
+ word = x86_pci_read_config16(dev, reg);
M.x86.R_ECX = word;
break;
case 0xb10a: /* Read Config Dword */
- dword = pci_read_config32(dev, reg);
+ dword = x86_pci_read_config32(dev, reg);
M.x86.R_ECX = dword;
break;
case 0xb10b: /* Write Config Byte */
byte = M.x86.R_ECX;
- pci_write_config8(dev, reg, byte);
+ x86_pci_write_config8(dev, reg, byte);
break;
case 0xb10c: /* Write Config Word */
word = M.x86.R_ECX;
- pci_write_config16(dev, reg, word);
+ x86_pci_write_config16(dev, reg, word);
break;
case 0xb10d: /* Write Config Dword */
dword = M.x86.R_ECX;
- pci_write_config32(dev, reg, dword);
+ x86_pci_write_config32(dev, reg, dword);
break;
}
diff --git a/arch/x86/lib/init_helpers.c b/arch/x86/lib/init_helpers.c
index 5097ca274a..4fd47fc036 100644
--- a/arch/x86/lib/init_helpers.c
+++ b/arch/x86/lib/init_helpers.c
@@ -89,11 +89,3 @@ int init_bd_struct_r(void)
return 0;
}
-
-int init_func_spi(void)
-{
- puts("SPI: ");
- spi_init();
- puts("ready\n");
- return 0;
-}
diff --git a/arch/x86/lib/lpc-uclass.c b/arch/x86/lib/lpc-uclass.c
new file mode 100644
index 0000000000..6aeb4d461a
--- /dev/null
+++ b/arch/x86/lib/lpc-uclass.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <dm/root.h>
+
+static int lpc_uclass_post_bind(struct udevice *bus)
+{
+ /*
+ * Scan the device tree for devices
+ *
+ * Before relocation, only bind devices marked for pre-relocation
+ * use.
+ */
+ return dm_scan_fdt_node(bus, gd->fdt_blob, bus->of_offset,
+ gd->flags & GD_FLG_RELOC ? false : true);
+}
+
+UCLASS_DRIVER(lpc) = {
+ .id = UCLASS_LPC,
+ .name = "lpc",
+ .post_bind = lpc_uclass_post_bind,
+};
diff --git a/arch/x86/lib/pch-uclass.c b/arch/x86/lib/pch-uclass.c
new file mode 100644
index 0000000000..d1082e1a47
--- /dev/null
+++ b/arch/x86/lib/pch-uclass.c
@@ -0,0 +1,28 @@
+/*
+ * Copyright (c) 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <dm/root.h>
+
+static int pch_uclass_post_bind(struct udevice *bus)
+{
+ /*
+ * Scan the device tree for devices
+ *
+ * Before relocation, only bind devices marked for pre-relocation
+ * use.
+ */
+ return dm_scan_fdt_node(bus, gd->fdt_blob, bus->of_offset,
+ gd->flags & GD_FLG_RELOC ? false : true);
+}
+
+UCLASS_DRIVER(pch) = {
+ .id = UCLASS_PCH,
+ .name = "pch",
+ .post_bind = pch_uclass_post_bind,
+};
diff --git a/board/BuR/common/common.c b/board/BuR/common/common.c
index ccaa9c6845..13f23fd7ce 100644
--- a/board/BuR/common/common.c
+++ b/board/BuR/common/common.c
@@ -216,7 +216,7 @@ static const char *dtbmacaddr(u32 ifno)
node = fdt_path_offset((void *)dtbaddr, path);
mac = fdt_getprop((void *)dtbaddr, node, "mac-address", &len);
- if (mac && is_valid_ether_addr((u8 *)mac))
+ if (mac && is_valid_ethaddr((u8 *)mac))
return mac;
return NULL;
@@ -595,7 +595,7 @@ int board_eth_init(bd_t *bis)
#endif
if (!mac) {
printf("<ethaddr> not set. validating E-fuse MAC ... ");
- if (is_valid_ether_addr((const u8 *)mac_addr))
+ if (is_valid_ethaddr((const u8 *)mac_addr))
mac = (const char *)mac_addr;
}
diff --git a/board/BuS/eb_cpux9k2/cpux9k2.c b/board/BuS/eb_cpux9k2/cpux9k2.c
index 76ad7c443b..3880a06897 100644
--- a/board/BuS/eb_cpux9k2/cpux9k2.c
+++ b/board/BuS/eb_cpux9k2/cpux9k2.c
@@ -111,7 +111,7 @@ int misc_init_r(void)
void reset_phy(void)
{
udelay(10000);
- eth_init(gd->bd);
+ eth_init();
}
#endif
diff --git a/board/BuS/vl_ma2sc/vl_ma2sc.c b/board/BuS/vl_ma2sc/vl_ma2sc.c
index da39c86258..e4e1a8572f 100644
--- a/board/BuS/vl_ma2sc/vl_ma2sc.c
+++ b/board/BuS/vl_ma2sc/vl_ma2sc.c
@@ -280,7 +280,7 @@ void reset_phy(void)
* Initialize ethernet HW addr prior to starting Linux,
* needed for nfsroot
*/
- eth_init(gd->bd);
+ eth_init();
#endif
}
#endif
diff --git a/board/ait/cam_enc_4xx/cam_enc_4xx.c b/board/ait/cam_enc_4xx/cam_enc_4xx.c
index 290dc1984a..c5687bab7d 100644
--- a/board/ait/cam_enc_4xx/cam_enc_4xx.c
+++ b/board/ait/cam_enc_4xx/cam_enc_4xx.c
@@ -70,7 +70,7 @@ static int cam_enc_4xx_check_network(void)
if (!s)
return -EINVAL;
- if (!is_valid_ether_addr((const u8 *)s))
+ if (!is_valid_ethaddr((const u8 *)s))
return -EINVAL;
s = getenv("ipaddr");
diff --git a/board/alphaproject/ap_sh4a_4a/ap_sh4a_4a.c b/board/alphaproject/ap_sh4a_4a/ap_sh4a_4a.c
index b81a68d63d..e65befc3ba 100644
--- a/board/alphaproject/ap_sh4a_4a/ap_sh4a_4a.c
+++ b/board/alphaproject/ap_sh4a_4a/ap_sh4a_4a.c
@@ -167,7 +167,7 @@ int board_late_init(void)
/* Read MAC address */
i2c_read(0x50, 0x0, 0, mac, 6);
- if (is_valid_ether_addr(mac))
+ if (is_valid_ethaddr(mac))
eth_setenv_enetaddr("ethaddr", mac);
return 0;
diff --git a/board/amcc/canyonlands/Kconfig b/board/amcc/canyonlands/Kconfig
index 46efa7a79f..ef66ad4909 100644
--- a/board/amcc/canyonlands/Kconfig
+++ b/board/amcc/canyonlands/Kconfig
@@ -33,10 +33,4 @@ config DISPLAY_BOARDINFO
bool
default y
-config DM
- default y
-
-config DM_SERIAL
- default y
-
endif
diff --git a/board/atmel/at91sam9261ek/at91sam9261ek.c b/board/atmel/at91sam9261ek/at91sam9261ek.c
index a301d72e8c..52504742cd 100644
--- a/board/atmel/at91sam9261ek/at91sam9261ek.c
+++ b/board/atmel/at91sam9261ek/at91sam9261ek.c
@@ -275,7 +275,7 @@ void reset_phy(void)
* Initialize ethernet HW addr prior to starting Linux,
* needed for nfsroot
*/
- eth_init(gd->bd);
+ eth_init();
#endif
}
#endif
diff --git a/board/bct-brettl2/bct-brettl2.c b/board/bct-brettl2/bct-brettl2.c
index 6be9b18015..1f0dfb4d40 100644
--- a/board/bct-brettl2/bct-brettl2.c
+++ b/board/bct-brettl2/bct-brettl2.c
@@ -32,7 +32,7 @@ int checkboard(void)
static void board_init_enetaddr(uchar *mac_addr)
{
puts("Warning: Generating 'random' MAC address\n");
- eth_random_addr(mac_addr);
+ net_random_ethaddr(mac_addr);
eth_setenv_enetaddr("ethaddr", mac_addr);
}
diff --git a/board/bf518f-ezbrd/bf518f-ezbrd.c b/board/bf518f-ezbrd/bf518f-ezbrd.c
index 3a94a572eb..8ecfbb28c9 100644
--- a/board/bf518f-ezbrd/bf518f-ezbrd.c
+++ b/board/bf518f-ezbrd/bf518f-ezbrd.c
@@ -39,7 +39,7 @@ static void board_init_enetaddr(uchar *mac_addr)
if (USE_MAC_IN_FLASH) {
/* we cram the MAC in the last flash sector */
uchar *board_mac_addr = (uchar *)0x203F0096;
- if (is_valid_ether_addr(board_mac_addr)) {
+ if (is_valid_ethaddr(board_mac_addr)) {
memcpy(mac_addr, board_mac_addr, 6);
valid_mac = true;
}
@@ -47,7 +47,7 @@ static void board_init_enetaddr(uchar *mac_addr)
if (!valid_mac) {
puts("Warning: Generating 'random' MAC address\n");
- eth_random_addr(mac_addr);
+ net_random_ethaddr(mac_addr);
}
eth_setenv_enetaddr("ethaddr", mac_addr);
diff --git a/board/bf526-ezbrd/bf526-ezbrd.c b/board/bf526-ezbrd/bf526-ezbrd.c
index 368d6be25f..0a88491e90 100644
--- a/board/bf526-ezbrd/bf526-ezbrd.c
+++ b/board/bf526-ezbrd/bf526-ezbrd.c
@@ -36,7 +36,7 @@ static void board_init_enetaddr(uchar *mac_addr)
if (USE_MAC_IN_FLASH) {
/* we cram the MAC in the last flash sector */
uchar *board_mac_addr = (uchar *)0x203F0096;
- if (is_valid_ether_addr(board_mac_addr)) {
+ if (is_valid_ethaddr(board_mac_addr)) {
memcpy(mac_addr, board_mac_addr, 6);
valid_mac = true;
}
@@ -44,7 +44,7 @@ static void board_init_enetaddr(uchar *mac_addr)
if (!valid_mac) {
puts("Warning: Generating 'random' MAC address\n");
- eth_random_addr(mac_addr);
+ net_random_ethaddr(mac_addr);
}
eth_setenv_enetaddr("ethaddr", mac_addr);
diff --git a/board/bf527-ezkit/bf527-ezkit.c b/board/bf527-ezkit/bf527-ezkit.c
index 88e18690e0..257775f3c8 100644
--- a/board/bf527-ezkit/bf527-ezkit.c
+++ b/board/bf527-ezkit/bf527-ezkit.c
@@ -40,13 +40,13 @@ static void board_init_enetaddr(uchar *mac_addr)
for (ret = 0; ret < 6; ++ret)
mac_addr[ret] = otp_mac_p[5 - ret];
- if (is_valid_ether_addr(mac_addr))
+ if (is_valid_ethaddr(mac_addr))
valid_mac = true;
}
if (!valid_mac) {
puts("Warning: Generating 'random' MAC address\n");
- eth_random_addr(mac_addr);
+ net_random_ethaddr(mac_addr);
}
eth_setenv_enetaddr("ethaddr", mac_addr);
diff --git a/board/bf537-minotaur/bf537-minotaur.c b/board/bf537-minotaur/bf537-minotaur.c
index ca61ef97b8..71b4293ad6 100644
--- a/board/bf537-minotaur/bf537-minotaur.c
+++ b/board/bf537-minotaur/bf537-minotaur.c
@@ -26,7 +26,7 @@ int checkboard(void)
static void board_init_enetaddr(uchar *mac_addr)
{
puts("Warning: Generating 'random' MAC address\n");
- eth_random_addr(mac_addr);
+ net_random_ethaddr(mac_addr);
eth_setenv_enetaddr("ethaddr", mac_addr);
}
diff --git a/board/bf537-pnav/bf537-pnav.c b/board/bf537-pnav/bf537-pnav.c
index df0011026a..93522df56c 100644
--- a/board/bf537-pnav/bf537-pnav.c
+++ b/board/bf537-pnav/bf537-pnav.c
@@ -26,7 +26,7 @@ int checkboard(void)
static void board_init_enetaddr(uchar *mac_addr)
{
puts("Warning: Generating 'random' MAC address\n");
- eth_random_addr(mac_addr);
+ net_random_ethaddr(mac_addr);
eth_setenv_enetaddr("ethaddr", mac_addr);
}
diff --git a/board/bf537-srv1/bf537-srv1.c b/board/bf537-srv1/bf537-srv1.c
index 725296a416..6581028294 100644
--- a/board/bf537-srv1/bf537-srv1.c
+++ b/board/bf537-srv1/bf537-srv1.c
@@ -26,7 +26,7 @@ int checkboard(void)
static void board_init_enetaddr(uchar *mac_addr)
{
puts("Warning: Generating 'random' MAC address\n");
- eth_random_addr(mac_addr);
+ net_random_ethaddr(mac_addr);
eth_setenv_enetaddr("ethaddr", mac_addr);
}
diff --git a/board/bf537-stamp/bf537-stamp.c b/board/bf537-stamp/bf537-stamp.c
index 32045a9e47..66e54925da 100644
--- a/board/bf537-stamp/bf537-stamp.c
+++ b/board/bf537-stamp/bf537-stamp.c
@@ -39,7 +39,7 @@ static void board_init_enetaddr(uchar *mac_addr)
if (USE_MAC_IN_FLASH) {
/* we cram the MAC in the last flash sector */
uchar *board_mac_addr = (uchar *)0x203F0000;
- if (is_valid_ether_addr(board_mac_addr)) {
+ if (is_valid_ethaddr(board_mac_addr)) {
memcpy(mac_addr, board_mac_addr, 6);
valid_mac = true;
}
@@ -47,7 +47,7 @@ static void board_init_enetaddr(uchar *mac_addr)
if (!valid_mac) {
puts("Warning: Generating 'random' MAC address\n");
- eth_random_addr(mac_addr);
+ net_random_ethaddr(mac_addr);
}
eth_setenv_enetaddr("ethaddr", mac_addr);
diff --git a/board/bf609-ezkit/bf609-ezkit.c b/board/bf609-ezkit/bf609-ezkit.c
index 43a43306bb..86da028bce 100644
--- a/board/bf609-ezkit/bf609-ezkit.c
+++ b/board/bf609-ezkit/bf609-ezkit.c
@@ -33,7 +33,7 @@ int board_early_init_f(void)
return 0;
}
-#ifdef CONFIG_DESIGNWARE_ETH
+#ifdef CONFIG_ETH_DESIGNWARE
int board_eth_init(bd_t *bis)
{
int ret = 0;
diff --git a/board/birdland/bav335x/board.c b/board/birdland/bav335x/board.c
index d1e1c8cbd3..32ff7a4f9e 100644
--- a/board/birdland/bav335x/board.c
+++ b/board/birdland/bav335x/board.c
@@ -384,7 +384,7 @@ int board_eth_init(bd_t *bis)
ecode = read_eeprom(&header);
/* if we have a valid EE, get mac address from there */
if ((ecode == 0) &&
- is_valid_ether_addr((const u8 *)&header.mac_addr[0][0])) {
+ is_valid_ethaddr((const u8 *)&header.mac_addr[0][0])) {
memcpy(mac_addr, (const void *)&header.mac_addr[0][0], 6);
}
@@ -395,7 +395,7 @@ int board_eth_init(bd_t *bis)
if (!getenv("ethaddr")) {
printf("<ethaddr> not set. Validating first E-fuse MAC\n");
- if (is_valid_ether_addr(mac_addr))
+ if (is_valid_ethaddr(mac_addr))
eth_setenv_enetaddr("ethaddr", mac_addr);
}
diff --git a/board/buffalo/lsxl/lsxl.c b/board/buffalo/lsxl/lsxl.c
index b0d49c4ee6..487875c23a 100644
--- a/board/buffalo/lsxl/lsxl.c
+++ b/board/buffalo/lsxl/lsxl.c
@@ -232,7 +232,7 @@ static void rescue_mode(void)
printf("Entering rescue mode..\n");
#ifdef CONFIG_RANDOM_MACADDR
if (!eth_getenv_enetaddr("ethaddr", enetaddr)) {
- eth_random_addr(enetaddr);
+ net_random_ethaddr(enetaddr);
if (eth_setenv_enetaddr("ethaddr", enetaddr)) {
printf("Failed to set ethernet address\n");
set_led(LED_ALARM_BLINKING);
diff --git a/board/cm-bf527/cm-bf527.c b/board/cm-bf527/cm-bf527.c
index 1533eb9c7a..2871fa2d6a 100644
--- a/board/cm-bf527/cm-bf527.c
+++ b/board/cm-bf527/cm-bf527.c
@@ -39,13 +39,13 @@ static void board_init_enetaddr(uchar *mac_addr)
for (ret = 0; ret < 6; ++ret)
mac_addr[ret] = otp_mac_p[5 - ret];
- if (is_valid_ether_addr(mac_addr))
+ if (is_valid_ethaddr(mac_addr))
valid_mac = true;
}
if (!valid_mac) {
puts("Warning: Generating 'random' MAC address\n");
- eth_random_addr(mac_addr);
+ net_random_ethaddr(mac_addr);
}
eth_setenv_enetaddr("ethaddr", mac_addr);
diff --git a/board/cm-bf537e/cm-bf537e.c b/board/cm-bf537e/cm-bf537e.c
index e79f90f95b..902611ec01 100644
--- a/board/cm-bf537e/cm-bf537e.c
+++ b/board/cm-bf537e/cm-bf537e.c
@@ -31,7 +31,7 @@ static void board_init_enetaddr(char *var)
return;
printf("Warning: %s: generating 'random' MAC address\n", var);
- eth_random_addr(enetaddr);
+ net_random_ethaddr(enetaddr);
eth_setenv_enetaddr(var, enetaddr);
}
diff --git a/board/cm-bf537u/cm-bf537u.c b/board/cm-bf537u/cm-bf537u.c
index 632cbda5c0..69bffd76de 100644
--- a/board/cm-bf537u/cm-bf537u.c
+++ b/board/cm-bf537u/cm-bf537u.c
@@ -31,7 +31,7 @@ static void board_init_enetaddr(char *var)
return;
printf("Warning: %s: generating 'random' MAC address\n", var);
- eth_random_addr(enetaddr);
+ net_random_ethaddr(enetaddr);
eth_setenv_enetaddr(var, enetaddr);
}
diff --git a/board/compulab/cm_fx6/cm_fx6.c b/board/compulab/cm_fx6/cm_fx6.c
index ae6945ba9c..7a1bbafaa5 100644
--- a/board/compulab/cm_fx6/cm_fx6.c
+++ b/board/compulab/cm_fx6/cm_fx6.c
@@ -425,7 +425,7 @@ static int handle_mac_address(char *env_var, uint eeprom_bus)
if (rc)
return rc;
- if (!is_valid_ether_addr(enetaddr))
+ if (!is_valid_ethaddr(enetaddr))
return -1;
return eth_setenv_enetaddr(env_var, enetaddr);
diff --git a/board/compulab/cm_t335/Kconfig b/board/compulab/cm_t335/Kconfig
index 3a8f304bd9..683efde764 100644
--- a/board/compulab/cm_t335/Kconfig
+++ b/board/compulab/cm_t335/Kconfig
@@ -12,13 +12,4 @@ config SYS_SOC
config SYS_CONFIG_NAME
default "cm_t335"
-config DM
- default y
-
-config DM_GPIO
- default y
-
-config DM_SERIAL
- default y
-
endif
diff --git a/board/compulab/cm_t335/cm_t335.c b/board/compulab/cm_t335/cm_t335.c
index 592ef3d30f..428aee6d24 100644
--- a/board/compulab/cm_t335/cm_t335.c
+++ b/board/compulab/cm_t335/cm_t335.c
@@ -114,7 +114,7 @@ static int handle_mac_address(void)
if (rv)
get_efuse_mac_addr(enetaddr);
- if (!is_valid_ether_addr(enetaddr))
+ if (!is_valid_ethaddr(enetaddr))
return -1;
return eth_setenv_enetaddr("ethaddr", enetaddr);
diff --git a/board/compulab/cm_t35/cm_t35.c b/board/compulab/cm_t35/cm_t35.c
index c4ea8ea875..374edbcffc 100644
--- a/board/compulab/cm_t35/cm_t35.c
+++ b/board/compulab/cm_t35/cm_t35.c
@@ -441,7 +441,7 @@ static int handle_mac_address(void)
if (rc)
return rc;
- if (!is_valid_ether_addr(enetaddr))
+ if (!is_valid_ethaddr(enetaddr))
return -1;
return eth_setenv_enetaddr("ethaddr", enetaddr);
diff --git a/board/compulab/cm_t3517/cm_t3517.c b/board/compulab/cm_t3517/cm_t3517.c
index 624cf4c034..03b2badd02 100644
--- a/board/compulab/cm_t3517/cm_t3517.c
+++ b/board/compulab/cm_t3517/cm_t3517.c
@@ -132,7 +132,7 @@ static int am3517_get_efuse_enetaddr(u8 *enetaddr)
enetaddr[4] = (u8)((lsb >> 8) & 0xff);
enetaddr[5] = (u8)(lsb & 0xff);
- return is_valid_ether_addr(enetaddr);
+ return is_valid_ethaddr(enetaddr);
}
static inline int cm_t3517_init_emac(bd_t *bis)
@@ -170,7 +170,7 @@ static int cm_t3517_handle_mac_address(void)
return ret;
}
- if (!is_valid_ether_addr(enetaddr))
+ if (!is_valid_ethaddr(enetaddr))
return -1;
return eth_setenv_enetaddr("ethaddr", enetaddr);
diff --git a/board/compulab/cm_t54/cm_t54.c b/board/compulab/cm_t54/cm_t54.c
index fdea909ff7..fad0551498 100644
--- a/board/compulab/cm_t54/cm_t54.c
+++ b/board/compulab/cm_t54/cm_t54.c
@@ -166,10 +166,10 @@ static int handle_mac_address(void)
return 0;
ret = cl_eeprom_read_mac_addr(enetaddr, CONFIG_SYS_I2C_EEPROM_BUS);
- if (ret || !is_valid_ether_addr(enetaddr))
+ if (ret || !is_valid_ethaddr(enetaddr))
generate_mac_addr(enetaddr);
- if (!is_valid_ether_addr(enetaddr))
+ if (!is_valid_ethaddr(enetaddr))
return -1;
return eth_setenv_enetaddr("usbethaddr", enetaddr);
diff --git a/board/coreboot/coreboot/coreboot.c b/board/coreboot/coreboot/coreboot.c
index e076ea69cf..7110f350d5 100644
--- a/board/coreboot/coreboot/coreboot.c
+++ b/board/coreboot/coreboot/coreboot.c
@@ -10,11 +10,6 @@
int arch_early_init_r(void)
{
-#ifdef CONFIG_CROS_EC
- if (cros_ec_board_init())
- return -1;
-#endif
-
return 0;
}
diff --git a/board/davinci/da8xxevm/da850evm.c b/board/davinci/da8xxevm/da850evm.c
index b9ca38e929..b82385a918 100644
--- a/board/davinci/da8xxevm/da850evm.c
+++ b/board/davinci/da8xxevm/da850evm.c
@@ -145,7 +145,7 @@ int misc_init_r(void)
*/
if (!enetaddr_found) {
if (!spi_mac_read) {
- if (is_valid_ether_addr(buff)) {
+ if (is_valid_ethaddr(buff)) {
if (eth_setenv_enetaddr("ethaddr", buff)) {
printf("Warning: Failed to "
"set MAC address from SPI flash\n");
@@ -160,8 +160,8 @@ int misc_init_r(void)
* MAC address present in environment compare it with
* the MAC address in SPI flash and warn on mismatch
*/
- if (!spi_mac_read && is_valid_ether_addr(buff) &&
- memcmp(env_enetaddr, buff, 6))
+ if (!spi_mac_read && is_valid_ethaddr(buff) &&
+ memcmp(env_enetaddr, buff, 6))
printf("Warning: MAC address in SPI flash don't match "
"with the MAC address in the environment\n");
printf("Default using MAC address from environment\n");
diff --git a/board/dnp5370/dnp5370.c b/board/dnp5370/dnp5370.c
index df721c9944..655fcace2b 100644
--- a/board/dnp5370/dnp5370.c
+++ b/board/dnp5370/dnp5370.c
@@ -46,7 +46,7 @@ static void board_init_enetaddr(uchar *mac_addr)
if (USE_MAC_IN_FLASH) {
/* we cram the MAC in the last flash sector */
uchar *board_mac_addr = (uchar *)0x202F0000;
- if (is_valid_ether_addr(board_mac_addr)) {
+ if (is_valid_ethaddr(board_mac_addr)) {
memcpy(mac_addr, board_mac_addr, 6);
valid_mac = true;
}
@@ -54,7 +54,7 @@ static void board_init_enetaddr(uchar *mac_addr)
if (!valid_mac) {
puts("Warning: Generating 'random' MAC address\n");
- eth_random_addr(mac_addr);
+ net_random_ethaddr(mac_addr);
}
eth_setenv_enetaddr("ethaddr", mac_addr);
diff --git a/board/egnite/ethernut5/ethernut5.c b/board/egnite/ethernut5/ethernut5.c
index b45213c245..67d39844ac 100644
--- a/board/egnite/ethernut5/ethernut5.c
+++ b/board/egnite/ethernut5/ethernut5.c
@@ -204,7 +204,7 @@ int board_eth_init(bd_t *bis)
miiphy_write(devname, 0, MII_BMCR, BMCR_RESET);
}
/* Sync environment with network devices, needed for nfsroot. */
- return eth_init(gd->bd);
+ return eth_init();
}
#endif
diff --git a/board/genesi/mx51_efikamx/efikamx-usb.c b/board/genesi/mx51_efikamx/efikamx-usb.c
index 0b43101910..9dfd24961a 100644
--- a/board/genesi/mx51_efikamx/efikamx-usb.c
+++ b/board/genesi/mx51_efikamx/efikamx-usb.c
@@ -173,7 +173,9 @@ int board_ehci_hcd_init(int port)
return 0;
}
-void ehci_powerup_fixup(uint32_t *status_reg, uint32_t *reg)
+/* This overrides a weak function */
+void mx5_ehci_powerup_fixup(struct ehci_ctrl *ctrl, uint32_t *status_reg,
+ uint32_t *reg)
{
uint32_t port = OTG_BASE_ADDR + (0x200 * CONFIG_MXC_USB_PORT);
struct usb_ehci *ehci = (struct usb_ehci *)port;
diff --git a/board/google/chromebook_link/link.c b/board/google/chromebook_link/link.c
index 9978e92006..1b97a8fea8 100644
--- a/board/google/chromebook_link/link.c
+++ b/board/google/chromebook_link/link.c
@@ -6,6 +6,7 @@
#include <common.h>
#include <cros_ec.h>
+#include <dm.h>
#include <asm/gpio.h>
#include <asm/io.h>
#include <asm/pci.h>
@@ -13,8 +14,13 @@
int arch_early_init_r(void)
{
- if (cros_ec_board_init())
- return -1;
+ struct udevice *dev;
+ int ret;
+
+ /* Make sure the platform controller hub is up and running */
+ ret = uclass_get_device(UCLASS_PCH, 0, &dev);
+ if (ret)
+ return ret;
return 0;
}
diff --git a/board/google/chromebox_panther/Kconfig b/board/google/chromebox_panther/Kconfig
new file mode 100644
index 0000000000..11df55a13c
--- /dev/null
+++ b/board/google/chromebox_panther/Kconfig
@@ -0,0 +1,34 @@
+if TARGET_CHROMEBOX_PANTHER
+
+config SYS_BOARD
+ default "chromebox_panther"
+
+config SYS_VENDOR
+ default "google"
+
+config SYS_SOC
+ default "ivybridge"
+
+config SYS_CONFIG_NAME
+ default "chromebox_panther"
+
+# Panther actually uses haswell, not ivybridge, so this is just a placeholder
+config BOARD_SPECIFIC_OPTIONS # dummy
+ def_bool y
+ select X86_RESET_VECTOR
+ select CPU_INTEL_SOCKET_RPGA989
+ select NORTHBRIDGE_INTEL_IVYBRIDGE
+ select SOUTHBRIDGE_INTEL_C216
+ select HAVE_ACPI_RESUME
+ select MARK_GRAPHICS_MEM_WRCOMB
+ select BOARD_ROMSIZE_KB_8192
+
+config SYS_CAR_ADDR
+ hex
+ default 0xff7e0000
+
+config SYS_CAR_SIZE
+ hex
+ default 0x20000
+
+endif
diff --git a/board/google/chromebox_panther/MAINTAINERS b/board/google/chromebox_panther/MAINTAINERS
new file mode 100644
index 0000000000..c88774bc86
--- /dev/null
+++ b/board/google/chromebox_panther/MAINTAINERS
@@ -0,0 +1,6 @@
+CHROMEBOX PANTHER BOARD
+M: Simon Glass <sjg@chromium.org>
+S: Maintained
+F: board/google/chromebook_panther/
+F: include/configs/chromebox_panther.h
+F: configs/chromebox_panther_defconfig
diff --git a/board/google/chromebox_panther/Makefile b/board/google/chromebox_panther/Makefile
new file mode 100644
index 0000000000..ce8820f73f
--- /dev/null
+++ b/board/google/chromebox_panther/Makefile
@@ -0,0 +1,7 @@
+#
+# Copyright (c) 2015 Google, Inc
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-y += panther.o
diff --git a/board/google/chromebox_panther/panther.c b/board/google/chromebox_panther/panther.c
new file mode 100644
index 0000000000..d492a0383f
--- /dev/null
+++ b/board/google/chromebox_panther/panther.c
@@ -0,0 +1,22 @@
+/*
+ * Copyright (C) 2015 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <asm/arch/pch.h>
+
+int arch_early_init_r(void)
+{
+ return 0;
+}
+
+int board_early_init_f(void)
+{
+ return 0;
+}
+
+void setup_pch_gpios(u16 gpiobase, const struct pch_gpio_map *gpio)
+{
+}
diff --git a/board/gumstix/pepper/Kconfig b/board/gumstix/pepper/Kconfig
index 750db8585d..6f94612fe2 100644
--- a/board/gumstix/pepper/Kconfig
+++ b/board/gumstix/pepper/Kconfig
@@ -12,13 +12,4 @@ config SYS_SOC
config SYS_CONFIG_NAME
default "pepper"
-config DM
- default y
-
-config DM_GPIO
- default y
-
-config DM_SERIAL
- default y
-
endif
diff --git a/board/gumstix/pepper/board.c b/board/gumstix/pepper/board.c
index f644f8188b..beb2fac374 100644
--- a/board/gumstix/pepper/board.c
+++ b/board/gumstix/pepper/board.c
@@ -165,7 +165,7 @@ int board_eth_init(bd_t *bis)
mac_addr[3] = (mac_hi & 0xFF000000) >> 24;
mac_addr[4] = mac_lo & 0xFF;
mac_addr[5] = (mac_lo & 0xFF00) >> 8;
- if (is_valid_ether_addr(mac_addr))
+ if (is_valid_ethaddr(mac_addr))
eth_setenv_enetaddr("ethaddr", mac_addr);
}
diff --git a/board/highbank/highbank.c b/board/highbank/highbank.c
index fc2385cf31..ba1beb5bbc 100644
--- a/board/highbank/highbank.c
+++ b/board/highbank/highbank.c
@@ -57,7 +57,7 @@ void scsi_init(void)
u32 reg = readl(HB_SREG_A9_PWRDOM_STAT);
if (reg & PWRDOM_STAT_SATA) {
- ahci_init(HB_AHCI_BASE);
+ ahci_init((void __iomem *)HB_AHCI_BASE);
scsi_scan(1);
}
}
diff --git a/board/ifm/ac14xx/ac14xx.c b/board/ifm/ac14xx/ac14xx.c
index 5d2ab2fad3..72932ca69f 100644
--- a/board/ifm/ac14xx/ac14xx.c
+++ b/board/ifm/ac14xx/ac14xx.c
@@ -225,7 +225,7 @@ int mac_read_from_eeprom(void)
break;
}
- if (mac && is_valid_ether_addr(mac)) {
+ if (mac && is_valid_ethaddr(mac)) {
eth_setenv_enetaddr("ethaddr", mac);
if (mac_diag) {
mac_txt = getenv("ethaddr");
diff --git a/board/ip04/ip04.c b/board/ip04/ip04.c
index ae52633426..d20500f4df 100644
--- a/board/ip04/ip04.c
+++ b/board/ip04/ip04.c
@@ -32,7 +32,7 @@ int misc_init_r(void)
uchar enetaddr[6];
if (!eth_getenv_enetaddr("ethaddr", enetaddr)) {
puts("Warning: Generating 'random' MAC address\n");
- eth_random_addr(enetaddr);
+ net_random_ethaddr(enetaddr);
eth_setenv_enetaddr("ethaddr", enetaddr);
}
diff --git a/board/isee/igep0033/Kconfig b/board/isee/igep0033/Kconfig
index 9a8421eb7a..e989e4b15c 100644
--- a/board/isee/igep0033/Kconfig
+++ b/board/isee/igep0033/Kconfig
@@ -12,13 +12,4 @@ config SYS_SOC
config SYS_CONFIG_NAME
default "am335x_igep0033"
-config DM
- default y
-
-config DM_GPIO
- default y
-
-config DM_SERIAL
- default y
-
endif
diff --git a/board/isee/igep0033/board.c b/board/isee/igep0033/board.c
index 9f8fcf2c1c..5fea7ffaef 100644
--- a/board/isee/igep0033/board.c
+++ b/board/isee/igep0033/board.c
@@ -156,7 +156,7 @@ int board_eth_init(bd_t *bis)
mac_addr[3] = (mac_hi & 0xFF000000) >> 24;
mac_addr[4] = mac_lo & 0xFF;
mac_addr[5] = (mac_lo & 0xFF00) >> 8;
- if (is_valid_ether_addr(mac_addr))
+ if (is_valid_ethaddr(mac_addr))
eth_setenv_enetaddr("ethaddr", mac_addr);
}
diff --git a/board/phytec/pcm051/Kconfig b/board/phytec/pcm051/Kconfig
index bb987156e6..2cc0d8872d 100644
--- a/board/phytec/pcm051/Kconfig
+++ b/board/phytec/pcm051/Kconfig
@@ -12,13 +12,4 @@ config SYS_SOC
config SYS_CONFIG_NAME
default "pcm051"
-config DM
- default y
-
-config DM_GPIO
- default y
-
-config DM_SERIAL
- default y
-
endif
diff --git a/board/phytec/pcm051/board.c b/board/phytec/pcm051/board.c
index 1071662ea9..1bf9d730e5 100644
--- a/board/phytec/pcm051/board.c
+++ b/board/phytec/pcm051/board.c
@@ -228,7 +228,7 @@ int board_eth_init(bd_t *bis)
mac_addr[4] = mac_lo & 0xFF;
mac_addr[5] = (mac_lo & 0xFF00) >> 8;
- if (is_valid_ether_addr(mac_addr))
+ if (is_valid_ethaddr(mac_addr))
eth_setenv_enetaddr("ethaddr", mac_addr);
else
goto try_usbether;
diff --git a/board/renesas/r0p7734/r0p7734.c b/board/renesas/r0p7734/r0p7734.c
index 5687ad4766..2e31ba6731 100644
--- a/board/renesas/r0p7734/r0p7734.c
+++ b/board/renesas/r0p7734/r0p7734.c
@@ -55,7 +55,7 @@ int board_late_init(void)
/* Read MAC address */
i2c_read(0x50, 0x10, 0, mac, 6);
- if (is_valid_ether_addr(mac))
+ if (is_valid_ethaddr(mac))
eth_setenv_enetaddr("ethaddr", mac);
return 0;
diff --git a/board/ronetix/pm9261/pm9261.c b/board/ronetix/pm9261/pm9261.c
index 1f7679a240..b96f745773 100644
--- a/board/ronetix/pm9261/pm9261.c
+++ b/board/ronetix/pm9261/pm9261.c
@@ -288,7 +288,7 @@ void reset_phy(void)
* Initialize ethernet HW addr prior to starting Linux,
* needed for nfsroot
*/
- eth_init(gd->bd);
+ eth_init();
#endif
}
#endif
diff --git a/board/ronetix/pm9g45/pm9g45.c b/board/ronetix/pm9g45/pm9g45.c
index 15aa4acd11..efc4133bbf 100644
--- a/board/ronetix/pm9g45/pm9g45.c
+++ b/board/ronetix/pm9g45/pm9g45.c
@@ -166,7 +166,7 @@ void reset_phy(void)
* Initialize ethernet HW addr prior to starting Linux,
* needed for nfsroot
*/
- eth_init(gd->bd);
+ eth_init();
#endif
}
#endif
diff --git a/board/samsung/common/board.c b/board/samsung/common/board.c
index 0979868211..9be295038b 100644
--- a/board/samsung/common/board.c
+++ b/board/samsung/common/board.c
@@ -330,18 +330,6 @@ int board_late_init(void)
}
#endif
-int arch_early_init_r(void)
-{
-#ifdef CONFIG_CROS_EC
- if (cros_ec_board_init()) {
- printf("%s: Failed to init EC\n", __func__);
- return 0;
- }
-#endif
-
- return 0;
-}
-
#ifdef CONFIG_MISC_INIT_R
int misc_init_r(void)
{
diff --git a/board/samsung/goni/Kconfig b/board/samsung/goni/Kconfig
index 006e864e0b..cbbf5a9315 100644
--- a/board/samsung/goni/Kconfig
+++ b/board/samsung/goni/Kconfig
@@ -12,13 +12,4 @@ config SYS_SOC
config SYS_CONFIG_NAME
default "s5p_goni"
-config DM
- default y
-
-config DM_GPIO
- default y
-
-config DM_SERIAL
- default y
-
endif
diff --git a/board/samsung/smdk5420/Kconfig b/board/samsung/smdk5420/Kconfig
index 576abaea69..a9d62fffa5 100644
--- a/board/samsung/smdk5420/Kconfig
+++ b/board/samsung/smdk5420/Kconfig
@@ -22,9 +22,6 @@ config SYS_VENDOR
config SYS_CONFIG_NAME
default "peach-pi"
-config DM_CROS_EC
- default y
-
endif
if TARGET_PEACH_PIT
@@ -38,9 +35,6 @@ config SYS_VENDOR
config SYS_CONFIG_NAME
default "peach-pit"
-config DM_CROS_EC
- default y
-
endif
if TARGET_SMDK5420
diff --git a/board/samsung/smdkc100/Kconfig b/board/samsung/smdkc100/Kconfig
index ea87166d03..d2157b4d05 100644
--- a/board/samsung/smdkc100/Kconfig
+++ b/board/samsung/smdkc100/Kconfig
@@ -12,13 +12,4 @@ config SYS_SOC
config SYS_CONFIG_NAME
default "smdkc100"
-config DM
- default y
-
-config DM_GPIO
- default y
-
-config DM_SERIAL
- default y
-
endif
diff --git a/board/sandbox/README.sandbox b/board/sandbox/README.sandbox
index 3c0df17845..08489e3880 100644
--- a/board/sandbox/README.sandbox
+++ b/board/sandbox/README.sandbox
@@ -173,16 +173,16 @@ U-Boot sandbox supports these emulations:
- Chrome OS EC
- GPIO
- Host filesystem (access files on the host from within U-Boot)
+- I2C
- Keyboard (Chrome OS)
- LCD
+- Network
- Serial (for console only)
- Sound (incomplete - see sandbox_sdl_sound_init() for details)
- SPI
- SPI flash
- TPM (Trusted Platform Module)
-Notable omissions are networking and I2C.
-
A wide range of commands is implemented. Filesystems which use a block
device are supported.
@@ -190,6 +190,80 @@ Also sandbox uses generic board (CONFIG_SYS_GENERIC_BOARD) and supports
driver model (CONFIG_DM) and associated commands.
+Linux RAW Networking Bridge
+---------------------------
+
+The sandbox_eth_raw driver bridges traffic between the bottom of the network
+stack and the RAW sockets API in Linux. This allows much of the U-Boot network
+functionality to be tested in sandbox against real network traffic.
+
+For Ethernet network adapters, the bridge utilizes the RAW AF_PACKET API. This
+is needed to get access to the lowest level of the network stack in Linux. This
+means that all of the Ethernet frame is included. This allows the U-Boot network
+stack to be fully used. In other words, nothing about the Linux network stack is
+involved in forming the packets that end up on the wire. To receive the
+responses to packets sent from U-Boot the network interface has to be set to
+promiscuous mode so that the network card won't filter out packets not destined
+for its configured (on Linux) MAC address.
+
+The RAW sockets Ethernet API requires elevated privileges in Linux. You can
+either run as root, or you can add the capability needed like so:
+
+sudo /sbin/setcap "CAP_NET_RAW+ep" /path/to/u-boot
+
+The default device tree for sandbox includes an entry for eth0 on the sandbox
+host machine whose alias is "eth1". The following are a few examples of network
+operations being tested on the eth0 interface.
+
+sudo /path/to/u-boot -D
+
+DHCP
+....
+
+set autoload no
+set ethact eth1
+dhcp
+
+PING
+....
+
+set autoload no
+set ethact eth1
+dhcp
+ping $gatewayip
+
+TFTP
+....
+
+set autoload no
+set ethact eth1
+dhcp
+set serverip WWW.XXX.YYY.ZZZ
+tftpboot u-boot.bin
+
+The bridge also support (to a lesser extent) the localhost inderface, 'lo'.
+
+The 'lo' interface cannot use the RAW AF_PACKET API because the lo interface
+doesn't support Ethernet-level traffic. It is a higher-level interface that is
+expected only to be used at the AF_INET level of the API. As such, the most raw
+we can get on that interface is the RAW AF_INET API on UDP. This allows us to
+set the IP_HDRINCL option to include everything except the Ethernet header in
+the packets we send and receive.
+
+Because only UDP is supported, ICMP traffic will not work, so expect that ping
+commands will time out.
+
+The default device tree for sandbox includes an entry for lo on the sandbox
+host machine whose alias is "eth5". The following is an example of a network
+operation being tested on the lo interface.
+
+TFTP
+....
+
+set ethact eth5
+tftpboot u-boot.bin
+
+
SPI Emulation
-------------
diff --git a/board/sandbox/sandbox.c b/board/sandbox/sandbox.c
index e4d4e021bc..2227f1c121 100644
--- a/board/sandbox/sandbox.c
+++ b/board/sandbox/sandbox.c
@@ -53,18 +53,6 @@ int board_early_init_f(void)
}
#endif
-int arch_early_init_r(void)
-{
-#ifdef CONFIG_CROS_EC
- if (cros_ec_board_init()) {
- printf("%s: Failed to init EC\n", __func__);
- return 0;
- }
-#endif
-
- return 0;
-}
-
#ifdef CONFIG_BOARD_LATE_INIT
int board_late_init(void)
{
diff --git a/board/siemens/common/factoryset.c b/board/siemens/common/factoryset.c
index 7baac3dda6..d81f5481a7 100644
--- a/board/siemens/common/factoryset.c
+++ b/board/siemens/common/factoryset.c
@@ -271,7 +271,7 @@ static int factoryset_mac_setenv(void)
uint8_t mac_addr[6];
debug("FactorySet: Set mac address\n");
- if (is_valid_ether_addr(factory_dat.mac)) {
+ if (is_valid_ethaddr(factory_dat.mac)) {
memcpy(mac_addr, factory_dat.mac, 6);
} else {
uint32_t mac_hi, mac_lo;
@@ -286,7 +286,7 @@ static int factoryset_mac_setenv(void)
mac_addr[3] = (mac_hi & 0xFF000000) >> 24;
mac_addr[4] = mac_lo & 0xFF;
mac_addr[5] = (mac_lo & 0xFF00) >> 8;
- if (!is_valid_ether_addr(mac_addr)) {
+ if (!is_valid_ethaddr(mac_addr)) {
printf("Warning: ethaddr not set by FactorySet or E-fuse. Set <ethaddr> variable to overcome this.\n");
return -1;
}
diff --git a/board/siemens/pxm2/board.c b/board/siemens/pxm2/board.c
index 264ba025b7..4d8ba3cd80 100644
--- a/board/siemens/pxm2/board.c
+++ b/board/siemens/pxm2/board.c
@@ -222,7 +222,7 @@ int board_eth_init(bd_t *bis)
struct ctrl_dev *cdev = (struct ctrl_dev *)CTRL_DEVICE_BASE;
#ifdef CONFIG_FACTORYSET
int rv;
- if (!is_valid_ether_addr(factory_dat.mac))
+ if (!is_valid_ethaddr(factory_dat.mac))
printf("Error: no valid mac address\n");
else
eth_setenv_enetaddr("ethaddr", factory_dat.mac);
diff --git a/board/silica/pengwyn/Kconfig b/board/silica/pengwyn/Kconfig
index 2e9a2b303f..f2e1098f62 100644
--- a/board/silica/pengwyn/Kconfig
+++ b/board/silica/pengwyn/Kconfig
@@ -12,13 +12,4 @@ config SYS_SOC
config SYS_CONFIG_NAME
default "pengwyn"
-config DM
- default y
-
-config DM_GPIO
- default y
-
-config DM_SERIAL
- default y
-
endif
diff --git a/board/silica/pengwyn/board.c b/board/silica/pengwyn/board.c
index ee88b6f399..815c9a7d15 100644
--- a/board/silica/pengwyn/board.c
+++ b/board/silica/pengwyn/board.c
@@ -189,7 +189,7 @@ int board_eth_init(bd_t *bis)
mac_addr[4] = mac_lo & 0xFF;
mac_addr[5] = (mac_lo & 0xFF00) >> 8;
- if (is_valid_ether_addr(mac_addr))
+ if (is_valid_ethaddr(mac_addr))
eth_setenv_enetaddr("ethaddr", mac_addr);
else
return n;
diff --git a/board/spear/spear300/spear300.c b/board/spear/spear300/spear300.c
index 6b6bd9f29d..396b5bdf60 100644
--- a/board/spear/spear300/spear300.c
+++ b/board/spear/spear300/spear300.c
@@ -51,7 +51,7 @@ int board_eth_init(bd_t *bis)
{
int ret = 0;
-#if defined(CONFIG_DESIGNWARE_ETH)
+#if defined(CONFIG_ETH_DESIGNWARE)
u32 interface = PHY_INTERFACE_MODE_MII;
if (designware_initialize(CONFIG_SPEAR_ETHBASE, interface) >= 0)
ret++;
diff --git a/board/spear/spear310/spear310.c b/board/spear/spear310/spear310.c
index a4c6a8edb0..6f39ef1b40 100644
--- a/board/spear/spear310/spear310.c
+++ b/board/spear/spear310/spear310.c
@@ -52,7 +52,7 @@ int board_eth_init(bd_t *bis)
{
int ret = 0;
-#if defined(CONFIG_DESIGNWARE_ETH)
+#if defined(CONFIG_ETH_DESIGNWARE)
u32 interface = PHY_INTERFACE_MODE_MII;
if (designware_initialize(CONFIG_SPEAR_ETHBASE, interface) >= 0)
ret++;
diff --git a/board/spear/spear320/spear320.c b/board/spear/spear320/spear320.c
index ab732a724c..52196afd17 100644
--- a/board/spear/spear320/spear320.c
+++ b/board/spear/spear320/spear320.c
@@ -63,7 +63,7 @@ int board_eth_init(bd_t *bis)
{
int ret = 0;
-#if defined(CONFIG_DESIGNWARE_ETH)
+#if defined(CONFIG_ETH_DESIGNWARE)
u32 interface = PHY_INTERFACE_MODE_MII;
if (designware_initialize(CONFIG_SPEAR_ETHBASE, interface) >= 0)
ret++;
diff --git a/board/spear/spear600/spear600.c b/board/spear/spear600/spear600.c
index 8472002f74..fc0918f91d 100644
--- a/board/spear/spear600/spear600.c
+++ b/board/spear/spear600/spear600.c
@@ -46,7 +46,7 @@ int board_eth_init(bd_t *bis)
{
int ret = 0;
-#if defined(CONFIG_DESIGNWARE_ETH)
+#if defined(CONFIG_ETH_DESIGNWARE)
u32 interface = PHY_INTERFACE_MODE_MII;
#if defined(CONFIG_DW_AUTONEG)
interface = PHY_INTERFACE_MODE_GMII;
diff --git a/board/st/stv0991/stv0991.c b/board/st/stv0991/stv0991.c
index f465699b55..38f6e1da83 100644
--- a/board/st/stv0991/stv0991.c
+++ b/board/st/stv0991/stv0991.c
@@ -94,7 +94,7 @@ int board_eth_init(bd_t *bis)
{
int ret = 0;
-#if defined(CONFIG_DESIGNWARE_ETH)
+#if defined(CONFIG_ETH_DESIGNWARE)
u32 interface = PHY_INTERFACE_MODE_MII;
if (designware_initialize(GMAC_BASE_ADDR, interface) >= 0)
ret++;
diff --git a/board/sunxi/ahci.c b/board/sunxi/ahci.c
index b7f0dda205..6d51b9b8e9 100644
--- a/board/sunxi/ahci.c
+++ b/board/sunxi/ahci.c
@@ -83,5 +83,5 @@ void scsi_init(void)
if (sunxi_ahci_phy_init(SUNXI_SATA_BASE) < 0)
return;
- ahci_init(SUNXI_SATA_BASE);
+ ahci_init((void __iomem *)SUNXI_SATA_BASE);
}
diff --git a/board/sunxi/gmac.c b/board/sunxi/gmac.c
index 63a7360b6d..d90eed48f7 100644
--- a/board/sunxi/gmac.c
+++ b/board/sunxi/gmac.c
@@ -80,11 +80,15 @@ int sunxi_gmac_initialize(bd_t *bis)
sunxi_gpio_set_cfgpin(pin, SUN6I_GPA_GMAC);
#endif
-#ifdef CONFIG_RGMII
+#ifdef CONFIG_DM_ETH
+ return 0;
+#else
+# ifdef CONFIG_RGMII
return designware_initialize(SUNXI_GMAC_BASE, PHY_INTERFACE_MODE_RGMII);
-#elif defined CONFIG_GMII
+# elif defined CONFIG_GMII
return designware_initialize(SUNXI_GMAC_BASE, PHY_INTERFACE_MODE_GMII);
-#else
+# else
return designware_initialize(SUNXI_GMAC_BASE, PHY_INTERFACE_MODE_MII);
+# endif
#endif
}
diff --git a/board/tcm-bf518/tcm-bf518.c b/board/tcm-bf518/tcm-bf518.c
index 5d25fcd0a9..3fa7d972ea 100644
--- a/board/tcm-bf518/tcm-bf518.c
+++ b/board/tcm-bf518/tcm-bf518.c
@@ -39,14 +39,14 @@ static void board_init_enetaddr(uchar *mac_addr)
for (ret = 0; ret < 6; ++ret)
mac_addr[ret] = otp_mac_p[5 - ret];
- if (is_valid_ether_addr(mac_addr))
+ if (is_valid_ethaddr(mac_addr))
valid_mac = true;
}
#endif
if (!valid_mac) {
puts("Warning: Generating 'random' MAC address\n");
- eth_random_addr(mac_addr);
+ net_random_ethaddr(mac_addr);
}
eth_setenv_enetaddr("ethaddr", mac_addr);
diff --git a/board/tcm-bf537/tcm-bf537.c b/board/tcm-bf537/tcm-bf537.c
index a4f0f7121b..2531a44336 100644
--- a/board/tcm-bf537/tcm-bf537.c
+++ b/board/tcm-bf537/tcm-bf537.c
@@ -31,7 +31,7 @@ static void board_init_enetaddr(char *var)
return;
printf("Warning: %s: generating 'random' MAC address\n", var);
- eth_random_addr(enetaddr);
+ net_random_ethaddr(enetaddr);
eth_setenv_enetaddr(var, enetaddr);
}
diff --git a/board/ti/am335x/Kconfig b/board/ti/am335x/Kconfig
index 7cb006f99c..49b73abc20 100644
--- a/board/ti/am335x/Kconfig
+++ b/board/ti/am335x/Kconfig
@@ -38,13 +38,4 @@ config NOR_BOOT
as the ROM only partially sets up pinmux. We also default to using
NOR for environment.
-config DM
- default y
-
-config DM_GPIO
- default y if DM
-
-config DM_SERIAL
- default y if DM
-
endif
diff --git a/board/ti/am335x/board.c b/board/ti/am335x/board.c
index 0739e6021a..96245a3306 100644
--- a/board/ti/am335x/board.c
+++ b/board/ti/am335x/board.c
@@ -593,7 +593,7 @@ int board_eth_init(bd_t *bis)
if (!getenv("ethaddr")) {
printf("<ethaddr> not set. Validating first E-fuse MAC\n");
- if (is_valid_ether_addr(mac_addr))
+ if (is_valid_ethaddr(mac_addr))
eth_setenv_enetaddr("ethaddr", mac_addr);
}
@@ -609,7 +609,7 @@ int board_eth_init(bd_t *bis)
mac_addr[5] = (mac_lo & 0xFF00) >> 8;
if (!getenv("eth1addr")) {
- if (is_valid_ether_addr(mac_addr))
+ if (is_valid_ethaddr(mac_addr))
eth_setenv_enetaddr("eth1addr", mac_addr);
}
@@ -658,7 +658,7 @@ int board_eth_init(bd_t *bis)
#endif
#if defined(CONFIG_USB_ETHER) && \
(!defined(CONFIG_SPL_BUILD) || defined(CONFIG_SPL_USBETH_SUPPORT))
- if (is_valid_ether_addr(mac_addr))
+ if (is_valid_ethaddr(mac_addr))
eth_setenv_enetaddr("usbnet_devaddr", mac_addr);
rv = usb_eth_initialize(bis);
diff --git a/board/ti/am43xx/board.c b/board/ti/am43xx/board.c
index ddf4c5fc13..4aae230608 100644
--- a/board/ti/am43xx/board.c
+++ b/board/ti/am43xx/board.c
@@ -802,7 +802,7 @@ int board_eth_init(bd_t *bis)
if (!getenv("ethaddr")) {
puts("<ethaddr> not set. Validating first E-fuse MAC\n");
- if (is_valid_ether_addr(mac_addr))
+ if (is_valid_ethaddr(mac_addr))
eth_setenv_enetaddr("ethaddr", mac_addr);
}
@@ -816,7 +816,7 @@ int board_eth_init(bd_t *bis)
mac_addr[5] = (mac_lo & 0xFF00) >> 8;
if (!getenv("eth1addr")) {
- if (is_valid_ether_addr(mac_addr))
+ if (is_valid_ethaddr(mac_addr))
eth_setenv_enetaddr("eth1addr", mac_addr);
}
diff --git a/board/ti/beagle_x15/board.c b/board/ti/beagle_x15/board.c
index ac0d22c9ed..ffcd53185b 100644
--- a/board/ti/beagle_x15/board.c
+++ b/board/ti/beagle_x15/board.c
@@ -356,7 +356,7 @@ int board_eth_init(bd_t *bis)
if (!getenv("ethaddr")) {
printf("<ethaddr> not set. Validating first E-fuse MAC\n");
- if (is_valid_ether_addr(mac_addr))
+ if (is_valid_ethaddr(mac_addr))
eth_setenv_enetaddr("ethaddr", mac_addr);
}
@@ -370,7 +370,7 @@ int board_eth_init(bd_t *bis)
mac_addr[5] = mac_lo & 0xFF;
if (!getenv("eth1addr")) {
- if (is_valid_ether_addr(mac_addr))
+ if (is_valid_ethaddr(mac_addr))
eth_setenv_enetaddr("eth1addr", mac_addr);
}
diff --git a/board/ti/dra7xx/evm.c b/board/ti/dra7xx/evm.c
index 3089fa2334..c1019289ba 100644
--- a/board/ti/dra7xx/evm.c
+++ b/board/ti/dra7xx/evm.c
@@ -341,7 +341,7 @@ int board_eth_init(bd_t *bis)
if (!getenv("ethaddr")) {
printf("<ethaddr> not set. Validating first E-fuse MAC\n");
- if (is_valid_ether_addr(mac_addr))
+ if (is_valid_ethaddr(mac_addr))
eth_setenv_enetaddr("ethaddr", mac_addr);
}
@@ -355,7 +355,7 @@ int board_eth_init(bd_t *bis)
mac_addr[5] = mac_lo & 0xFF;
if (!getenv("eth1addr")) {
- if (is_valid_ether_addr(mac_addr))
+ if (is_valid_ethaddr(mac_addr))
eth_setenv_enetaddr("eth1addr", mac_addr);
}
diff --git a/board/ti/ti814x/evm.c b/board/ti/ti814x/evm.c
index 54b3dfb82c..e406dabfc0 100644
--- a/board/ti/ti814x/evm.c
+++ b/board/ti/ti814x/evm.c
@@ -178,7 +178,7 @@ int board_eth_init(bd_t *bis)
mac_addr[4] = mac_lo & 0xFF;
mac_addr[5] = (mac_lo & 0xFF00) >> 8;
- if (is_valid_ether_addr(mac_addr))
+ if (is_valid_ethaddr(mac_addr))
eth_setenv_enetaddr("ethaddr", mac_addr);
else
printf("Unable to read MAC address. Set <ethaddr>\n");
diff --git a/common/Kconfig b/common/Kconfig
index 4cde4b0048..17930a4ff3 100644
--- a/common/Kconfig
+++ b/common/Kconfig
@@ -339,6 +339,122 @@ config CMD_SETGETDCR
getidcr - Get a register value via indirect DCR addressing
setidcr - Set a register value via indirect DCR addressing
+config CMD_SOUND
+ bool "sound"
+ depends on SOUND
+ help
+ This provides basic access to the U-Boot's sound support. The main
+ feature is to play a beep.
+
+ sound init - set up sound system
+ sound play - play a sound
+
+endmenu
+
+menu "Boot timing"
+
+config BOOTSTAGE
+ bool "Boot timing and reporting"
+ help
+ Enable recording of boot time while booting. To use it, insert
+ calls to bootstage_mark() with a suitable BOOTSTAGE_ID from
+ bootstage.h. Only a single entry is recorded for each ID. You can
+ give the entry a name with bootstage_mark_name(). You can also
+ record elapsed time in a particular stage using bootstage_start()
+ before starting and bootstage_accum() when finished. Bootstage will
+ add up all the accumated time and report it.
+
+ Normally, IDs are defined in bootstage.h but a small number of
+ additional 'user' IDs can be used but passing BOOTSTAGE_ID_ALLOC
+ as the ID.
+
+ Calls to show_boot_progress() wil also result in log entries but
+ these will not have names.
+
+config BOOTSTAGE_REPORT
+ bool "Display a detailed boot timing report before booting the OS"
+ depends on BOOTSTAGE
+ help
+ Enable output of a boot time report just before the OS is booted.
+ This shows how long it took U-Boot to go through each stage of the
+ boot process. The report looks something like this:
+
+ Timer summary in microseconds:
+ Mark Elapsed Stage
+ 0 0 reset
+ 3,575,678 3,575,678 board_init_f start
+ 3,575,695 17 arch_cpu_init A9
+ 3,575,777 82 arch_cpu_init done
+ 3,659,598 83,821 board_init_r start
+ 3,910,375 250,777 main_loop
+ 29,916,167 26,005,792 bootm_start
+ 30,361,327 445,160 start_kernel
+
+config BOOTSTAGE_USER_COUNT
+ hex "Number of boot ID numbers available for user use"
+ default 20
+ help
+ This is the number of available user bootstage records.
+ Each time you call bootstage_mark(BOOTSTAGE_ID_ALLOC, ...)
+ a new ID will be allocated from this stash. If you exceed
+ the limit, recording will stop.
+
+config CMD_BOOTSTAGE
+ bool "Enable the 'bootstage' command"
+ depends on BOOTSTAGE
+ help
+ Add a 'bootstage' command which supports printing a report
+ and un/stashing of bootstage data.
+
+config BOOTSTAGE_FDT
+ bool "Store boot timing information in the OS device tree"
+ depends on BOOTSTAGE
+ help
+ Stash the bootstage information in the FDT. A root 'bootstage'
+ node is created with each bootstage id as a child. Each child
+ has a 'name' property and either 'mark' containing the
+ mark time in microsecond, or 'accum' containing the
+ accumulated time for that bootstage id in microseconds.
+ For example:
+
+ bootstage {
+ 154 {
+ name = "board_init_f";
+ mark = <3575678>;
+ };
+ 170 {
+ name = "lcd";
+ accum = <33482>;
+ };
+ };
+
+ Code in the Linux kernel can find this in /proc/devicetree.
+
+config BOOTSTAGE_STASH
+ bool "Stash the boot timing information in memory before booting OS"
+ depends on BOOTSTAGE
+ help
+ Some OSes do not support device tree. Bootstage can instead write
+ the boot timing information in a binary format at a given address.
+ This happens through a call to bootstage_stash(), typically in
+ the CPU's cleanup_before_linux() function. You can use the
+ 'bootstage stash' and 'bootstage unstash' commands to do this on
+ the command line.
+
+config BOOTSTAGE_STASH_ADDR
+ hex "Address to stash boot timing information"
+ default 0
+ help
+ Provide an address which will not be overwritten by the OS when it
+ starts, so that it can read this information when ready.
+
+config BOOTSTAGE_STASH_SIZE
+ hex "Size of boot timing stash region"
+ default 4096
+ help
+ This should be large enough to hold the bootstage stash. A value of
+ 4096 (4KiB) is normally plenty.
+
endmenu
endmenu
diff --git a/common/Makefile b/common/Makefile
index e545458578..fba3830f1d 100644
--- a/common/Makefile
+++ b/common/Makefile
@@ -152,7 +152,7 @@ obj-$(CONFIG_CMD_PXE) += cmd_pxe.o
obj-$(CONFIG_CMD_READ) += cmd_read.o
obj-$(CONFIG_CMD_REGINFO) += cmd_reginfo.o
obj-$(CONFIG_CMD_REISER) += cmd_reiser.o
-obj-$(CONFIG_SANDBOX) += cmd_sandbox.o
+obj-$(CONFIG_SANDBOX) += cmd_host.o
obj-$(CONFIG_CMD_SATA) += cmd_sata.o
obj-$(CONFIG_CMD_SF) += cmd_sf.o
obj-$(CONFIG_CMD_SCSI) += cmd_scsi.o
diff --git a/common/board_f.c b/common/board_f.c
index cb956b853c..775df1419e 100644
--- a/common/board_f.c
+++ b/common/board_f.c
@@ -23,6 +23,7 @@
#include <i2c.h>
#include <initcall.h>
#include <logbuff.h>
+#include <mapmem.h>
/* TODO: Can we move these into arch/ headers? */
#ifdef CONFIG_8xx
@@ -815,6 +816,11 @@ __weak int reserve_arch(void)
return 0;
}
+__weak int arch_cpu_init_dm(void)
+{
+ return 0;
+}
+
static init_fnc_t init_sequence_f[] = {
#ifdef CONFIG_SANDBOX
setup_ram_buf,
@@ -835,6 +841,7 @@ static init_fnc_t init_sequence_f[] = {
fdtdec_check_fdt,
#endif
initf_dm,
+ arch_cpu_init_dm,
#if defined(CONFIG_BOARD_EARLY_INIT_F)
board_early_init_f,
#endif
diff --git a/common/board_r.c b/common/board_r.c
index 0335f6bde6..42ff18c219 100644
--- a/common/board_r.c
+++ b/common/board_r.c
@@ -33,6 +33,7 @@
#endif
#include <logbuff.h>
#include <malloc.h>
+#include <mapmem.h>
#ifdef CONFIG_BITBANGMII
#include <miiphy.h>
#endif
@@ -230,7 +231,9 @@ static int initr_unlock_ram_in_cache(void)
#ifdef CONFIG_PCI
static int initr_pci(void)
{
+#ifndef CONFIG_DM_PCI
pci_init();
+#endif
return 0;
}
@@ -587,7 +590,7 @@ static int initr_bbmii(void)
static int initr_net(void)
{
puts("Net: ");
- eth_initialize(gd->bd);
+ eth_initialize();
#if defined(CONFIG_RESET_PHY_R)
debug("Reset Ethernet PHY\n");
reset_phy();
@@ -777,9 +780,6 @@ init_fnc_t init_sequence_r[] = {
#ifdef CONFIG_PPC
initr_spi,
#endif
-#if defined(CONFIG_X86) && defined(CONFIG_SPI)
- init_func_spi,
-#endif
#ifdef CONFIG_CMD_NAND
initr_nand,
#endif
diff --git a/common/bootm.c b/common/bootm.c
index 34f60bbb53..6842029dfb 100644
--- a/common/bootm.c
+++ b/common/bootm.c
@@ -13,6 +13,7 @@
#include <fdt_support.h>
#include <lmb.h>
#include <malloc.h>
+#include <mapmem.h>
#include <asm/io.h>
#include <linux/lzo.h>
#include <lzma/LzmaTypes.h>
diff --git a/common/cmd_bdinfo.c b/common/cmd_bdinfo.c
index aa81da227b..f16d5c719f 100644
--- a/common/cmd_bdinfo.c
+++ b/common/cmd_bdinfo.c
@@ -34,6 +34,7 @@ static void print_eth(int idx)
printf("%-12s= %s\n", name, val);
}
+#ifndef CONFIG_DM_ETH
__maybe_unused
static void print_eths(void)
{
@@ -52,6 +53,7 @@ static void print_eths(void)
printf("current eth = %s\n", eth_get_name());
printf("ip_addr = %s\n", getenv("ipaddr"));
}
+#endif
__maybe_unused
static void print_lnum(const char *name, unsigned long long value)
@@ -375,7 +377,7 @@ static int do_bdinfo(cmd_tbl_t *cmdtp, int flag, int argc,
print_num("-> size", bd->bi_dram[i].size);
}
-#if defined(CONFIG_CMD_NET)
+#if defined(CONFIG_CMD_NET) && !defined(CONFIG_DM_ETH)
print_eths();
#endif
printf("baudrate = %u bps\n", gd->baudrate);
diff --git a/common/cmd_bootm.c b/common/cmd_bootm.c
index 4f77f22f94..6b6aca66fd 100644
--- a/common/cmd_bootm.c
+++ b/common/cmd_bootm.c
@@ -16,6 +16,7 @@
#include <image.h>
#include <lmb.h>
#include <malloc.h>
+#include <mapmem.h>
#include <nand.h>
#include <asm/byteorder.h>
#include <linux/compiler.h>
diff --git a/common/cmd_bootstage.c b/common/cmd_bootstage.c
index 106894aa51..788ab16436 100644
--- a/common/cmd_bootstage.c
+++ b/common/cmd_bootstage.c
@@ -6,11 +6,6 @@
#include <common.h>
-#ifndef CONFIG_BOOTSTAGE_STASH
-#define CONFIG_BOOTSTAGE_STASH -1UL
-#define CONFIG_BOOTSTAGE_STASH_SIZE -1
-#endif
-
static int do_bootstage_report(cmd_tbl_t *cmdtp, int flag, int argc,
char * const argv[])
{
@@ -24,7 +19,7 @@ static int get_base_size(int argc, char * const argv[], ulong *basep,
{
char *endp;
- *basep = CONFIG_BOOTSTAGE_STASH;
+ *basep = CONFIG_BOOTSTAGE_STASH_ADDR;
*sizep = CONFIG_BOOTSTAGE_STASH_SIZE;
if (argc < 2)
return 0;
diff --git a/common/cmd_demo.c b/common/cmd_demo.c
index 8a10bdf42a..209dc4a57c 100644
--- a/common/cmd_demo.c
+++ b/common/cmd_demo.c
@@ -9,6 +9,7 @@
#include <common.h>
#include <dm-demo.h>
+#include <mapmem.h>
#include <asm/io.h>
struct udevice *demo_dev;
diff --git a/common/cmd_elf.c b/common/cmd_elf.c
index c745371506..22475dc3cb 100644
--- a/common/cmd_elf.c
+++ b/common/cmd_elf.c
@@ -170,7 +170,7 @@ int do_bootvx(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
* Check to see if we need to tftp the image ourselves before starting
*/
if ((argc == 2) && (strcmp(argv[1], "tftp") == 0)) {
- if (NetLoop(TFTPGET) <= 0)
+ if (net_loop(TFTPGET) <= 0)
return 1;
printf("Automatic boot of VxWorks image at address 0x%08lx ...\n",
addr);
diff --git a/common/cmd_fat.c b/common/cmd_fat.c
index c00fb28b62..aae993d2b9 100644
--- a/common/cmd_fat.c
+++ b/common/cmd_fat.c
@@ -14,6 +14,7 @@
#include <net.h>
#include <ata.h>
#include <asm/io.h>
+#include <mapmem.h>
#include <part.h>
#include <fat.h>
#include <fs.h>
diff --git a/common/cmd_fdt.c b/common/cmd_fdt.c
index 48b3e70415..682b655395 100644
--- a/common/cmd_fdt.c
+++ b/common/cmd_fdt.c
@@ -15,6 +15,7 @@
#include <asm/global_data.h>
#include <libfdt.h>
#include <fdt_support.h>
+#include <mapmem.h>
#include <asm/io.h>
#define MAX_LEVEL 32 /* how deeply nested we will go */
diff --git a/common/cmd_host.c b/common/cmd_host.c
new file mode 100644
index 0000000000..ba1460ea1c
--- /dev/null
+++ b/common/cmd_host.c
@@ -0,0 +1,175 @@
+/*
+ * Copyright (c) 2012, Google Inc.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <fs.h>
+#include <part.h>
+#include <sandboxblockdev.h>
+#include <asm/errno.h>
+
+static int host_curr_device = -1;
+
+static int do_host_load(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[])
+{
+ return do_load(cmdtp, flag, argc, argv, FS_TYPE_SANDBOX);
+}
+
+static int do_host_ls(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[])
+{
+ return do_ls(cmdtp, flag, argc, argv, FS_TYPE_SANDBOX);
+}
+
+static int do_host_save(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[])
+{
+ return do_save(cmdtp, flag, argc, argv, FS_TYPE_SANDBOX);
+}
+
+static int do_host_bind(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[])
+{
+ if (argc < 2 || argc > 3)
+ return CMD_RET_USAGE;
+ char *ep;
+ char *dev_str = argv[1];
+ char *file = argc >= 3 ? argv[2] : NULL;
+ int dev = simple_strtoul(dev_str, &ep, 16);
+ if (*ep) {
+ printf("** Bad device specification %s **\n", dev_str);
+ return CMD_RET_USAGE;
+ }
+ return host_dev_bind(dev, file);
+}
+
+static int do_host_info(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[])
+{
+ if (argc < 1 || argc > 2)
+ return CMD_RET_USAGE;
+ int min_dev = 0;
+ int max_dev = CONFIG_HOST_MAX_DEVICES - 1;
+ if (argc >= 2) {
+ char *ep;
+ char *dev_str = argv[1];
+ int dev = simple_strtoul(dev_str, &ep, 16);
+ if (*ep) {
+ printf("** Bad device specification %s **\n", dev_str);
+ return CMD_RET_USAGE;
+ }
+ min_dev = dev;
+ max_dev = dev;
+ }
+ int dev;
+ printf("%3s %12s %s\n", "dev", "blocks", "path");
+ for (dev = min_dev; dev <= max_dev; dev++) {
+ block_dev_desc_t *blk_dev;
+ int ret;
+
+ printf("%3d ", dev);
+ ret = host_get_dev_err(dev, &blk_dev);
+ if (ret) {
+ if (ret == -ENOENT)
+ puts("Not bound to a backing file\n");
+ else if (ret == -ENODEV)
+ puts("Invalid host device number\n");
+
+ continue;
+ }
+ struct host_block_dev *host_dev = blk_dev->priv;
+ printf("%12lu %s\n", (unsigned long)blk_dev->lba,
+ host_dev->filename);
+ }
+ return 0;
+}
+
+static int do_host_dev(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[])
+{
+ int dev;
+ char *ep;
+ block_dev_desc_t *blk_dev;
+ int ret;
+
+ if (argc < 1 || argc > 3)
+ return CMD_RET_USAGE;
+
+ if (argc == 1) {
+ if (host_curr_device < 0) {
+ printf("No current host device\n");
+ return 1;
+ }
+ printf("Current host device %d\n", host_curr_device);
+ return 0;
+ }
+
+ dev = simple_strtoul(argv[1], &ep, 16);
+ if (*ep) {
+ printf("** Bad device specification %s **\n", argv[2]);
+ return CMD_RET_USAGE;
+ }
+
+ ret = host_get_dev_err(dev, &blk_dev);
+ if (ret) {
+ if (ret == -ENOENT)
+ puts("Not bound to a backing file\n");
+ else if (ret == -ENODEV)
+ puts("Invalid host device number\n");
+
+ return 1;
+ }
+
+ host_curr_device = dev;
+ return 0;
+}
+
+static cmd_tbl_t cmd_host_sub[] = {
+ U_BOOT_CMD_MKENT(load, 7, 0, do_host_load, "", ""),
+ U_BOOT_CMD_MKENT(ls, 3, 0, do_host_ls, "", ""),
+ U_BOOT_CMD_MKENT(save, 6, 0, do_host_save, "", ""),
+ U_BOOT_CMD_MKENT(bind, 3, 0, do_host_bind, "", ""),
+ U_BOOT_CMD_MKENT(info, 3, 0, do_host_info, "", ""),
+ U_BOOT_CMD_MKENT(dev, 0, 1, do_host_dev, "", ""),
+};
+
+static int do_host(cmd_tbl_t *cmdtp, int flag, int argc,
+ char * const argv[])
+{
+ cmd_tbl_t *c;
+
+ /* Skip past 'host' */
+ argc--;
+ argv++;
+
+ c = find_cmd_tbl(argv[0], cmd_host_sub,
+ ARRAY_SIZE(cmd_host_sub));
+
+ if (c)
+ return c->cmd(cmdtp, flag, argc, argv);
+ else
+ return CMD_RET_USAGE;
+}
+
+U_BOOT_CMD(
+ sb, 8, 1, do_host,
+ "Deprecated: use 'host' command instead.", ""
+);
+
+U_BOOT_CMD(
+ host, 8, 1, do_host,
+ "Miscellaneous host commands",
+ "load hostfs - <addr> <filename> [<bytes> <offset>] - "
+ "load a file from host\n"
+ "host ls hostfs - <filename> - list files on host\n"
+ "host save hostfs - <addr> <filename> <bytes> [<offset>] - "
+ "save a file to host\n"
+ "host bind <dev> [<filename>] - bind \"host\" device to file\n"
+ "host info [<dev>] - show device binding & info\n"
+ "host dev [<dev>] - Set or retrieve the current host device\n"
+ "host commands use the \"hostfs\" device. The \"host\" device is used\n"
+ "with standard IO commands such as fatls or ext2load"
+);
diff --git a/common/cmd_lzmadec.c b/common/cmd_lzmadec.c
index 7b0b3fdd90..1ad9ed6ce9 100644
--- a/common/cmd_lzmadec.c
+++ b/common/cmd_lzmadec.c
@@ -12,6 +12,7 @@
#include <common.h>
#include <command.h>
+#include <mapmem.h>
#include <asm/io.h>
#include <lzma/LzmaTools.h>
diff --git a/common/cmd_md5sum.c b/common/cmd_md5sum.c
index d22ace5220..23bb81e88c 100644
--- a/common/cmd_md5sum.c
+++ b/common/cmd_md5sum.c
@@ -10,6 +10,7 @@
#include <common.h>
#include <command.h>
+#include <mapmem.h>
#include <u-boot/md5.h>
#include <asm/io.h>
diff --git a/common/cmd_mem.c b/common/cmd_mem.c
index 3f85c1aa85..45e471ca82 100644
--- a/common/cmd_mem.c
+++ b/common/cmd_mem.c
@@ -20,6 +20,7 @@
#endif
#include <hash.h>
#include <inttypes.h>
+#include <mapmem.h>
#include <watchdog.h>
#include <asm/io.h>
#include <linux/compiler.h>
@@ -165,7 +166,7 @@ static int do_mem_mw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
#endif
ulong addr, count;
int size;
- void *buf;
+ void *buf, *start;
ulong bytes;
if ((argc < 3) || (argc > 4))
@@ -197,7 +198,8 @@ static int do_mem_mw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
}
bytes = size * count;
- buf = map_sysmem(addr, bytes);
+ start = map_sysmem(addr, bytes);
+ buf = start;
while (count-- > 0) {
if (size == 4)
*((u32 *)buf) = (u32)writeval;
@@ -211,7 +213,7 @@ static int do_mem_mw(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
*((u8 *)buf) = (u8)writeval;
buf += size;
}
- unmap_sysmem(buf);
+ unmap_sysmem(start);
return 0;
}
diff --git a/common/cmd_net.c b/common/cmd_net.c
index 09489d404e..b2f3c7b709 100644
--- a/common/cmd_net.c
+++ b/common/cmd_net.c
@@ -44,10 +44,7 @@ U_BOOT_CMD(
#ifdef CONFIG_CMD_TFTPPUT
int do_tftpput(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
- int ret;
-
- ret = netboot_common(TFTPPUT, cmdtp, argc, argv);
- return ret;
+ return netboot_common(TFTPPUT, cmdtp, argc, argv);
}
U_BOOT_CMD(
@@ -117,24 +114,24 @@ static void netboot_update_env(void)
{
char tmp[22];
- if (NetOurGatewayIP) {
- ip_to_string(NetOurGatewayIP, tmp);
+ if (net_gateway.s_addr) {
+ ip_to_string(net_gateway, tmp);
setenv("gatewayip", tmp);
}
- if (NetOurSubnetMask) {
- ip_to_string(NetOurSubnetMask, tmp);
+ if (net_netmask.s_addr) {
+ ip_to_string(net_netmask, tmp);
setenv("netmask", tmp);
}
- if (NetOurHostName[0])
- setenv("hostname", NetOurHostName);
+ if (net_hostname[0])
+ setenv("hostname", net_hostname);
- if (NetOurRootPath[0])
- setenv("rootpath", NetOurRootPath);
+ if (net_root_path[0])
+ setenv("rootpath", net_root_path);
- if (NetOurIP) {
- ip_to_string(NetOurIP, tmp);
+ if (net_ip.s_addr) {
+ ip_to_string(net_ip, tmp);
setenv("ipaddr", tmp);
}
#if !defined(CONFIG_BOOTP_SERVERIP)
@@ -142,35 +139,33 @@ static void netboot_update_env(void)
* Only attempt to change serverip if net/bootp.c:BootpCopyNetParams()
* could have set it
*/
- if (NetServerIP) {
- ip_to_string(NetServerIP, tmp);
+ if (net_server_ip.s_addr) {
+ ip_to_string(net_server_ip, tmp);
setenv("serverip", tmp);
}
#endif
- if (NetOurDNSIP) {
- ip_to_string(NetOurDNSIP, tmp);
+ if (net_dns_server.s_addr) {
+ ip_to_string(net_dns_server, tmp);
setenv("dnsip", tmp);
}
#if defined(CONFIG_BOOTP_DNS2)
- if (NetOurDNS2IP) {
- ip_to_string(NetOurDNS2IP, tmp);
+ if (net_dns_server2.s_addr) {
+ ip_to_string(net_dns_server2, tmp);
setenv("dnsip2", tmp);
}
#endif
- if (NetOurNISDomain[0])
- setenv("domain", NetOurNISDomain);
+ if (net_nis_domain[0])
+ setenv("domain", net_nis_domain);
-#if defined(CONFIG_CMD_SNTP) \
- && defined(CONFIG_BOOTP_TIMEOFFSET)
- if (NetTimeOffset) {
- sprintf(tmp, "%d", NetTimeOffset);
+#if defined(CONFIG_CMD_SNTP) && defined(CONFIG_BOOTP_TIMEOFFSET)
+ if (net_ntp_time_offset) {
+ sprintf(tmp, "%d", net_ntp_time_offset);
setenv("timeoffset", tmp);
}
#endif
-#if defined(CONFIG_CMD_SNTP) \
- && defined(CONFIG_BOOTP_NTPSERVER)
- if (NetNtpServerIP) {
- ip_to_string(NetNtpServerIP, tmp);
+#if defined(CONFIG_CMD_SNTP) && defined(CONFIG_BOOTP_NTPSERVER)
+ if (net_ntp_server.s_addr) {
+ ip_to_string(net_ntp_server, tmp);
setenv("ntpserverip", tmp);
}
#endif
@@ -186,9 +181,9 @@ static int netboot_common(enum proto_t proto, cmd_tbl_t *cmdtp, int argc,
ulong addr;
/* pre-set load_addr */
- if ((s = getenv("loadaddr")) != NULL) {
+ s = getenv("loadaddr");
+ if (s != NULL)
load_addr = simple_strtoul(s, NULL, 16);
- }
switch (argc) {
case 1:
@@ -204,22 +199,26 @@ static int netboot_common(enum proto_t proto, cmd_tbl_t *cmdtp, int argc,
if (end == (argv[1] + strlen(argv[1])))
load_addr = addr;
else
- copy_filename(BootFile, argv[1], sizeof(BootFile));
+ copy_filename(net_boot_file_name, argv[1],
+ sizeof(net_boot_file_name));
break;
- case 3: load_addr = simple_strtoul(argv[1], NULL, 16);
- copy_filename(BootFile, argv[2], sizeof(BootFile));
+ case 3:
+ load_addr = simple_strtoul(argv[1], NULL, 16);
+ copy_filename(net_boot_file_name, argv[2],
+ sizeof(net_boot_file_name));
break;
#ifdef CONFIG_CMD_TFTPPUT
case 4:
if (strict_strtoul(argv[1], 16, &save_addr) < 0 ||
- strict_strtoul(argv[2], 16, &save_size) < 0) {
+ strict_strtoul(argv[2], 16, &save_size) < 0) {
printf("Invalid address/size\n");
- return cmd_usage(cmdtp);
+ return CMD_RET_USAGE;
}
- copy_filename(BootFile, argv[3], sizeof(BootFile));
+ copy_filename(net_boot_file_name, argv[3],
+ sizeof(net_boot_file_name));
break;
#endif
default:
@@ -228,19 +227,20 @@ static int netboot_common(enum proto_t proto, cmd_tbl_t *cmdtp, int argc,
}
bootstage_mark(BOOTSTAGE_ID_NET_START);
- if ((size = NetLoop(proto)) < 0) {
+ size = net_loop(proto);
+ if (size < 0) {
bootstage_error(BOOTSTAGE_ID_NET_NETLOOP_OK);
- return 1;
+ return CMD_RET_FAILURE;
}
bootstage_mark(BOOTSTAGE_ID_NET_NETLOOP_OK);
- /* NetLoop ok, update environment */
+ /* net_loop ok, update environment */
netboot_update_env();
/* done if no file was loaded (no errors though) */
if (size == 0) {
bootstage_error(BOOTSTAGE_ID_NET_LOADED);
- return 0;
+ return CMD_RET_SUCCESS;
}
/* flush cache */
@@ -250,10 +250,10 @@ static int netboot_common(enum proto_t proto, cmd_tbl_t *cmdtp, int argc,
rcode = bootm_maybe_autostart(cmdtp, argv[0]);
- if (rcode < 0)
- bootstage_error(BOOTSTAGE_ID_NET_DONE_ERR);
- else
+ if (rcode == CMD_RET_SUCCESS)
bootstage_mark(BOOTSTAGE_ID_NET_DONE);
+ else
+ bootstage_error(BOOTSTAGE_ID_NET_DONE_ERR);
return rcode;
}
@@ -261,20 +261,20 @@ static int netboot_common(enum proto_t proto, cmd_tbl_t *cmdtp, int argc,
static int do_ping(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
if (argc < 2)
- return -1;
+ return CMD_RET_USAGE;
- NetPingIP = string_to_ip(argv[1]);
- if (NetPingIP == 0)
+ net_ping_ip = string_to_ip(argv[1]);
+ if (net_ping_ip.s_addr == 0)
return CMD_RET_USAGE;
- if (NetLoop(PING) < 0) {
+ if (net_loop(PING) < 0) {
printf("ping failed; host %s is not alive\n", argv[1]);
- return 1;
+ return CMD_RET_FAILURE;
}
printf("host %s is alive\n", argv[1]);
- return 0;
+ return CMD_RET_SUCCESS;
}
U_BOOT_CMD(
@@ -290,35 +290,35 @@ static void cdp_update_env(void)
{
char tmp[16];
- if (CDPApplianceVLAN != htons(-1)) {
- printf("CDP offered appliance VLAN %d\n", ntohs(CDPApplianceVLAN));
- VLAN_to_string(CDPApplianceVLAN, tmp);
+ if (cdp_appliance_vlan != htons(-1)) {
+ printf("CDP offered appliance VLAN %d\n",
+ ntohs(cdp_appliance_vlan));
+ vlan_to_string(cdp_appliance_vlan, tmp);
setenv("vlan", tmp);
- NetOurVLAN = CDPApplianceVLAN;
+ net_our_vlan = cdp_appliance_vlan;
}
- if (CDPNativeVLAN != htons(-1)) {
- printf("CDP offered native VLAN %d\n", ntohs(CDPNativeVLAN));
- VLAN_to_string(CDPNativeVLAN, tmp);
+ if (cdp_native_vlan != htons(-1)) {
+ printf("CDP offered native VLAN %d\n", ntohs(cdp_native_vlan));
+ vlan_to_string(cdp_native_vlan, tmp);
setenv("nvlan", tmp);
- NetOurNativeVLAN = CDPNativeVLAN;
+ net_native_vlan = cdp_native_vlan;
}
-
}
int do_cdp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
int r;
- r = NetLoop(CDP);
+ r = net_loop(CDP);
if (r < 0) {
printf("cdp failed; perhaps not a CISCO switch?\n");
- return 1;
+ return CMD_RET_FAILURE;
}
cdp_update_env();
- return 0;
+ return CMD_RET_SUCCESS;
}
U_BOOT_CMD(
@@ -334,32 +334,32 @@ int do_sntp(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
char *toff;
if (argc < 2) {
- NetNtpServerIP = getenv_IPaddr("ntpserverip");
- if (NetNtpServerIP == 0) {
+ net_ntp_server = getenv_ip("ntpserverip");
+ if (net_ntp_server.s_addr == 0) {
printf("ntpserverip not set\n");
- return (1);
+ return CMD_RET_FAILURE;
}
} else {
- NetNtpServerIP = string_to_ip(argv[1]);
- if (NetNtpServerIP == 0) {
+ net_ntp_server = string_to_ip(argv[1]);
+ if (net_ntp_server.s_addr == 0) {
printf("Bad NTP server IP address\n");
- return (1);
+ return CMD_RET_FAILURE;
}
}
toff = getenv("timeoffset");
if (toff == NULL)
- NetTimeOffset = 0;
+ net_ntp_time_offset = 0;
else
- NetTimeOffset = simple_strtol(toff, NULL, 10);
+ net_ntp_time_offset = simple_strtol(toff, NULL, 10);
- if (NetLoop(SNTP) < 0) {
+ if (net_loop(SNTP) < 0) {
printf("SNTP failed: host %pI4 not responding\n",
- &NetNtpServerIP);
- return 1;
+ &net_ntp_server);
+ return CMD_RET_FAILURE;
}
- return 0;
+ return CMD_RET_SUCCESS;
}
U_BOOT_CMD(
@@ -389,22 +389,22 @@ int do_dns(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
*/
if (strlen(argv[1]) >= 255) {
printf("dns error: hostname too long\n");
- return 1;
+ return CMD_RET_FAILURE;
}
- NetDNSResolve = argv[1];
+ net_dns_resolve = argv[1];
if (argc == 3)
- NetDNSenvvar = argv[2];
+ net_dns_env_var = argv[2];
else
- NetDNSenvvar = NULL;
+ net_dns_env_var = NULL;
- if (NetLoop(DNS) < 0) {
+ if (net_loop(DNS) < 0) {
printf("dns lookup of %s failed, check setup\n", argv[1]);
- return 1;
+ return CMD_RET_FAILURE;
}
- return 0;
+ return CMD_RET_SUCCESS;
}
U_BOOT_CMD(
@@ -421,21 +421,21 @@ static int do_link_local(cmd_tbl_t *cmdtp, int flag, int argc,
{
char tmp[22];
- if (NetLoop(LINKLOCAL) < 0)
- return 1;
+ if (net_loop(LINKLOCAL) < 0)
+ return CMD_RET_FAILURE;
- NetOurGatewayIP = 0;
- ip_to_string(NetOurGatewayIP, tmp);
+ net_gateway.s_addr = 0;
+ ip_to_string(net_gateway, tmp);
setenv("gatewayip", tmp);
- ip_to_string(NetOurSubnetMask, tmp);
+ ip_to_string(net_netmask, tmp);
setenv("netmask", tmp);
- ip_to_string(NetOurIP, tmp);
+ ip_to_string(net_ip, tmp);
setenv("ipaddr", tmp);
setenv("llipaddr", tmp); /* store this for next time */
- return 0;
+ return CMD_RET_SUCCESS;
}
U_BOOT_CMD(
diff --git a/common/cmd_nvedit.c b/common/cmd_nvedit.c
index 855808c3e4..be792ae746 100644
--- a/common/cmd_nvedit.c
+++ b/common/cmd_nvedit.c
@@ -31,6 +31,7 @@
#include <search.h>
#include <errno.h>
#include <malloc.h>
+#include <mapmem.h>
#include <watchdog.h>
#include <linux/stddef.h>
#include <asm/byteorder.h>
diff --git a/common/cmd_pci.c b/common/cmd_pci.c
index e3a77e3582..dcecef8da8 100644
--- a/common/cmd_pci.c
+++ b/common/cmd_pci.c
@@ -48,6 +48,7 @@ void pciinfo(int BusNum, int ShortPCIListing)
unsigned char HeaderType;
unsigned short VendorID;
pci_dev_t dev;
+ int ret;
if (!hose)
return;
@@ -74,7 +75,10 @@ void pciinfo(int BusNum, int ShortPCIListing)
if (pci_skip_dev(hose, dev))
continue;
- pci_read_config_word(dev, PCI_VENDOR_ID, &VendorID);
+ ret = pci_read_config_word(dev, PCI_VENDOR_ID,
+ &VendorID);
+ if (ret)
+ goto error;
if ((VendorID == 0xFFFF) || (VendorID == 0x0000))
continue;
@@ -91,8 +95,12 @@ void pciinfo(int BusNum, int ShortPCIListing)
BusNum, Device, Function);
pci_header_show(dev);
}
- }
- }
+ }
+ }
+
+ return;
+error:
+ printf("Cannot read bus configuration: %d\n", ret);
}
diff --git a/common/cmd_pxe.c b/common/cmd_pxe.c
index 7e32c95df3..4cbb2b1173 100644
--- a/common/cmd_pxe.c
+++ b/common/cmd_pxe.c
@@ -8,11 +8,13 @@
#include <common.h>
#include <command.h>
#include <malloc.h>
+#include <mapmem.h>
#include <linux/string.h>
#include <linux/ctype.h>
#include <errno.h>
#include <linux/list.h>
#include <fs.h>
+#include <asm/io.h>
#include "menu.h"
#include "cli.h"
@@ -188,11 +190,12 @@ static int do_get_any(cmd_tbl_t *cmdtp, const char *file_path, char *file_addr)
*
* Returns 1 for success, or < 0 on error.
*/
-static int get_relfile(cmd_tbl_t *cmdtp, const char *file_path, void *file_addr)
+static int get_relfile(cmd_tbl_t *cmdtp, const char *file_path,
+ unsigned long file_addr)
{
size_t path_len;
char relfile[MAX_TFTP_PATH_LEN+1];
- char addr_buf[10];
+ char addr_buf[18];
int err;
err = get_bootfile_path(file_path, relfile, sizeof(relfile));
@@ -215,7 +218,7 @@ static int get_relfile(cmd_tbl_t *cmdtp, const char *file_path, void *file_addr)
printf("Retrieving file: %s\n", relfile);
- sprintf(addr_buf, "%p", file_addr);
+ sprintf(addr_buf, "%lx", file_addr);
return do_getfile(cmdtp, relfile, addr_buf);
}
@@ -227,11 +230,13 @@ static int get_relfile(cmd_tbl_t *cmdtp, const char *file_path, void *file_addr)
*
* Returns 1 on success, or < 0 for error.
*/
-static int get_pxe_file(cmd_tbl_t *cmdtp, const char *file_path, void *file_addr)
+static int get_pxe_file(cmd_tbl_t *cmdtp, const char *file_path,
+ unsigned long file_addr)
{
unsigned long config_file_size;
char *tftp_filesize;
int err;
+ char *buf;
err = get_relfile(cmdtp, file_path, file_addr);
@@ -250,7 +255,9 @@ static int get_pxe_file(cmd_tbl_t *cmdtp, const char *file_path, void *file_addr
if (strict_strtoul(tftp_filesize, 16, &config_file_size) < 0)
return -EINVAL;
- *(char *)(file_addr + config_file_size) = '\0';
+ buf = map_sysmem(file_addr + config_file_size, 1);
+ *buf = '\0';
+ unmap_sysmem(buf);
return 1;
}
@@ -266,7 +273,8 @@ static int get_pxe_file(cmd_tbl_t *cmdtp, const char *file_path, void *file_addr
*
* Returns 1 on success or < 0 on error.
*/
-static int get_pxelinux_path(cmd_tbl_t *cmdtp, const char *file, void *pxefile_addr_r)
+static int get_pxelinux_path(cmd_tbl_t *cmdtp, const char *file,
+ unsigned long pxefile_addr_r)
{
size_t base_len = strlen(PXELINUX_DIR);
char path[MAX_TFTP_PATH_LEN+1];
@@ -287,7 +295,7 @@ static int get_pxelinux_path(cmd_tbl_t *cmdtp, const char *file, void *pxefile_a
*
* Returns 1 on success or < 0 on error.
*/
-static int pxe_uuid_path(cmd_tbl_t *cmdtp, void *pxefile_addr_r)
+static int pxe_uuid_path(cmd_tbl_t *cmdtp, unsigned long pxefile_addr_r)
{
char *uuid_str;
@@ -305,7 +313,7 @@ static int pxe_uuid_path(cmd_tbl_t *cmdtp, void *pxefile_addr_r)
*
* Returns 1 on success or < 0 on error.
*/
-static int pxe_mac_path(cmd_tbl_t *cmdtp, void *pxefile_addr_r)
+static int pxe_mac_path(cmd_tbl_t *cmdtp, unsigned long pxefile_addr_r)
{
char mac_str[21];
int err;
@@ -325,12 +333,12 @@ static int pxe_mac_path(cmd_tbl_t *cmdtp, void *pxefile_addr_r)
*
* Returns 1 on success or < 0 on error.
*/
-static int pxe_ipaddr_paths(cmd_tbl_t *cmdtp, void *pxefile_addr_r)
+static int pxe_ipaddr_paths(cmd_tbl_t *cmdtp, unsigned long pxefile_addr_r)
{
char ip_addr[9];
int mask_pos, err;
- sprintf(ip_addr, "%08X", ntohl(NetOurIP));
+ sprintf(ip_addr, "%08X", ntohl(net_ip.s_addr));
for (mask_pos = 7; mask_pos >= 0; mask_pos--) {
err = get_pxelinux_path(cmdtp, ip_addr, pxefile_addr_r);
@@ -384,9 +392,9 @@ do_pxe_get(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
* Keep trying paths until we successfully get a file we're looking
* for.
*/
- if (pxe_uuid_path(cmdtp, (void *)pxefile_addr_r) > 0 ||
- pxe_mac_path(cmdtp, (void *)pxefile_addr_r) > 0 ||
- pxe_ipaddr_paths(cmdtp, (void *)pxefile_addr_r) > 0) {
+ if (pxe_uuid_path(cmdtp, pxefile_addr_r) > 0 ||
+ pxe_mac_path(cmdtp, pxefile_addr_r) > 0 ||
+ pxe_ipaddr_paths(cmdtp, pxefile_addr_r) > 0) {
printf("Config file found\n");
return 0;
@@ -394,7 +402,7 @@ do_pxe_get(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
while (pxe_default_paths[i]) {
if (get_pxelinux_path(cmdtp, pxe_default_paths[i],
- (void *)pxefile_addr_r) > 0) {
+ pxefile_addr_r) > 0) {
printf("Config file found\n");
return 0;
}
@@ -427,7 +435,7 @@ static int get_relfile_envaddr(cmd_tbl_t *cmdtp, const char *file_path, const ch
if (strict_strtoul(envaddr, 16, &file_addr) < 0)
return -EINVAL;
- return get_relfile(cmdtp, file_path, (void *)file_addr);
+ return get_relfile(cmdtp, file_path, file_addr);
}
/*
@@ -790,6 +798,7 @@ static int label_boot(cmd_tbl_t *cmdtp, struct pxe_label *label)
else
do_bootz(cmdtp, 0, bootm_argc, bootm_argv);
#endif
+ unmap_sysmem(buf);
return 1;
}
@@ -1054,7 +1063,8 @@ static int parse_integer(char **c, int *dst)
return 1;
}
-static int parse_pxefile_top(cmd_tbl_t *cmdtp, char *p, struct pxe_menu *cfg, int nest_level);
+static int parse_pxefile_top(cmd_tbl_t *cmdtp, char *p, unsigned long base,
+ struct pxe_menu *cfg, int nest_level);
/*
* Parse an include statement, and retrieve and parse the file it mentions.
@@ -1064,12 +1074,14 @@ static int parse_pxefile_top(cmd_tbl_t *cmdtp, char *p, struct pxe_menu *cfg, in
* include, nest_level has already been incremented and doesn't need to be
* incremented here.
*/
-static int handle_include(cmd_tbl_t *cmdtp, char **c, char *base,
+static int handle_include(cmd_tbl_t *cmdtp, char **c, unsigned long base,
struct pxe_menu *cfg, int nest_level)
{
char *include_path;
char *s = *c;
int err;
+ char *buf;
+ int ret;
err = parse_sliteral(c, &include_path);
@@ -1086,20 +1098,25 @@ static int handle_include(cmd_tbl_t *cmdtp, char **c, char *base,
return err;
}
- return parse_pxefile_top(cmdtp, base, cfg, nest_level);
+ buf = map_sysmem(base, 0);
+ ret = parse_pxefile_top(cmdtp, buf, base, cfg, nest_level);
+ unmap_sysmem(buf);
+
+ return ret;
}
/*
* Parse lines that begin with 'menu'.
*
- * b and nest are provided to handle the 'menu include' case.
+ * base and nest are provided to handle the 'menu include' case.
*
- * b should be the address where the file currently being parsed is stored.
+ * base should point to a location where it's safe to store the included file.
*
* nest_level should be 1 when parsing the top level pxe file, 2 when parsing
* a file it includes, 3 when parsing a file included by that file, and so on.
*/
-static int parse_menu(cmd_tbl_t *cmdtp, char **c, struct pxe_menu *cfg, char *b, int nest_level)
+static int parse_menu(cmd_tbl_t *cmdtp, char **c, struct pxe_menu *cfg,
+ unsigned long base, int nest_level)
{
struct token t;
char *s = *c;
@@ -1114,7 +1131,7 @@ static int parse_menu(cmd_tbl_t *cmdtp, char **c, struct pxe_menu *cfg, char *b,
break;
case T_INCLUDE:
- err = handle_include(cmdtp, c, b + strlen(b) + 1, cfg,
+ err = handle_include(cmdtp, c, base, cfg,
nest_level + 1);
break;
@@ -1281,7 +1298,8 @@ static int parse_label(char **c, struct pxe_menu *cfg)
*
* Returns 1 on success, < 0 on error.
*/
-static int parse_pxefile_top(cmd_tbl_t *cmdtp, char *p, struct pxe_menu *cfg, int nest_level)
+static int parse_pxefile_top(cmd_tbl_t *cmdtp, char *p, unsigned long base,
+ struct pxe_menu *cfg, int nest_level)
{
struct token t;
char *s, *b, *label_name;
@@ -1303,7 +1321,9 @@ static int parse_pxefile_top(cmd_tbl_t *cmdtp, char *p, struct pxe_menu *cfg, in
switch (t.type) {
case T_MENU:
cfg->prompt = 1;
- err = parse_menu(cmdtp, &p, cfg, b, nest_level);
+ err = parse_menu(cmdtp, &p, cfg,
+ base + ALIGN(strlen(b) + 1, 4),
+ nest_level);
break;
case T_TIMEOUT:
@@ -1328,8 +1348,9 @@ static int parse_pxefile_top(cmd_tbl_t *cmdtp, char *p, struct pxe_menu *cfg, in
break;
case T_INCLUDE:
- err = handle_include(cmdtp, &p, b + ALIGN(strlen(b), 4), cfg,
- nest_level + 1);
+ err = handle_include(cmdtp, &p,
+ base + ALIGN(strlen(b), 4), cfg,
+ nest_level + 1);
break;
case T_PROMPT:
@@ -1385,9 +1406,11 @@ static void destroy_pxe_menu(struct pxe_menu *cfg)
* files it includes). The resulting pxe_menu struct can be free()'d by using
* the destroy_pxe_menu() function.
*/
-static struct pxe_menu *parse_pxefile(cmd_tbl_t *cmdtp, char *menucfg)
+static struct pxe_menu *parse_pxefile(cmd_tbl_t *cmdtp, unsigned long menucfg)
{
struct pxe_menu *cfg;
+ char *buf;
+ int r;
cfg = malloc(sizeof(struct pxe_menu));
@@ -1398,7 +1421,11 @@ static struct pxe_menu *parse_pxefile(cmd_tbl_t *cmdtp, char *menucfg)
INIT_LIST_HEAD(&cfg->labels);
- if (parse_pxefile_top(cmdtp, menucfg, cfg, 1) < 0) {
+ buf = map_sysmem(menucfg, 0);
+ r = parse_pxefile_top(cmdtp, buf, menucfg, cfg, 1);
+ unmap_sysmem(buf);
+
+ if (r < 0) {
destroy_pxe_menu(cfg);
return NULL;
}
@@ -1556,7 +1583,7 @@ do_pxe_boot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
return 1;
}
- cfg = parse_pxefile(cmdtp, (char *)(pxefile_addr_r));
+ cfg = parse_pxefile(cmdtp, pxefile_addr_r);
if (cfg == NULL) {
printf("Error parsing config file\n");
@@ -1567,7 +1594,7 @@ do_pxe_boot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
destroy_pxe_menu(cfg);
- copy_filename(BootFile, "", sizeof(BootFile));
+ copy_filename(net_boot_file_name, "", sizeof(net_boot_file_name));
return 0;
}
@@ -1663,12 +1690,12 @@ static int do_sysboot(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
return 1;
}
- if (get_pxe_file(cmdtp, filename, (void *)pxefile_addr_r) < 0) {
+ if (get_pxe_file(cmdtp, filename, pxefile_addr_r) < 0) {
printf("Error reading config file\n");
return 1;
}
- cfg = parse_pxefile(cmdtp, (char *)(pxefile_addr_r));
+ cfg = parse_pxefile(cmdtp, pxefile_addr_r);
if (cfg == NULL) {
printf("Error parsing config file\n");
diff --git a/common/cmd_sandbox.c b/common/cmd_sandbox.c
deleted file mode 100644
index 428696982e..0000000000
--- a/common/cmd_sandbox.c
+++ /dev/null
@@ -1,126 +0,0 @@
-/*
- * Copyright (c) 2012, Google Inc.
- *
- * SPDX-License-Identifier: GPL-2.0+
- */
-
-#include <common.h>
-#include <fs.h>
-#include <part.h>
-#include <sandboxblockdev.h>
-#include <asm/errno.h>
-
-static int do_sandbox_load(cmd_tbl_t *cmdtp, int flag, int argc,
- char * const argv[])
-{
- return do_load(cmdtp, flag, argc, argv, FS_TYPE_SANDBOX);
-}
-
-static int do_sandbox_ls(cmd_tbl_t *cmdtp, int flag, int argc,
- char * const argv[])
-{
- return do_ls(cmdtp, flag, argc, argv, FS_TYPE_SANDBOX);
-}
-
-static int do_sandbox_save(cmd_tbl_t *cmdtp, int flag, int argc,
- char * const argv[])
-{
- return do_save(cmdtp, flag, argc, argv, FS_TYPE_SANDBOX);
-}
-
-static int do_sandbox_bind(cmd_tbl_t *cmdtp, int flag, int argc,
- char * const argv[])
-{
- if (argc < 2 || argc > 3)
- return CMD_RET_USAGE;
- char *ep;
- char *dev_str = argv[1];
- char *file = argc >= 3 ? argv[2] : NULL;
- int dev = simple_strtoul(dev_str, &ep, 16);
- if (*ep) {
- printf("** Bad device specification %s **\n", dev_str);
- return CMD_RET_USAGE;
- }
- return host_dev_bind(dev, file);
-}
-
-static int do_sandbox_info(cmd_tbl_t *cmdtp, int flag, int argc,
- char * const argv[])
-{
- if (argc < 1 || argc > 2)
- return CMD_RET_USAGE;
- int min_dev = 0;
- int max_dev = CONFIG_HOST_MAX_DEVICES - 1;
- if (argc >= 2) {
- char *ep;
- char *dev_str = argv[1];
- int dev = simple_strtoul(dev_str, &ep, 16);
- if (*ep) {
- printf("** Bad device specification %s **\n", dev_str);
- return CMD_RET_USAGE;
- }
- min_dev = dev;
- max_dev = dev;
- }
- int dev;
- printf("%3s %12s %s\n", "dev", "blocks", "path");
- for (dev = min_dev; dev <= max_dev; dev++) {
- block_dev_desc_t *blk_dev;
- int ret;
-
- printf("%3d ", dev);
- ret = host_get_dev_err(dev, &blk_dev);
- if (ret) {
- if (ret == -ENOENT)
- puts("Not bound to a backing file\n");
- else if (ret == -ENODEV)
- puts("Invalid host device number\n");
-
- continue;
- }
- struct host_block_dev *host_dev = blk_dev->priv;
- printf("%12lu %s\n", (unsigned long)blk_dev->lba,
- host_dev->filename);
- }
- return 0;
-}
-
-static cmd_tbl_t cmd_sandbox_sub[] = {
- U_BOOT_CMD_MKENT(load, 7, 0, do_sandbox_load, "", ""),
- U_BOOT_CMD_MKENT(ls, 3, 0, do_sandbox_ls, "", ""),
- U_BOOT_CMD_MKENT(save, 6, 0, do_sandbox_save, "", ""),
- U_BOOT_CMD_MKENT(bind, 3, 0, do_sandbox_bind, "", ""),
- U_BOOT_CMD_MKENT(info, 3, 0, do_sandbox_info, "", ""),
-};
-
-static int do_sandbox(cmd_tbl_t *cmdtp, int flag, int argc,
- char * const argv[])
-{
- cmd_tbl_t *c;
-
- /* Skip past 'sandbox' */
- argc--;
- argv++;
-
- c = find_cmd_tbl(argv[0], cmd_sandbox_sub,
- ARRAY_SIZE(cmd_sandbox_sub));
-
- if (c)
- return c->cmd(cmdtp, flag, argc, argv);
- else
- return CMD_RET_USAGE;
-}
-
-U_BOOT_CMD(
- sb, 8, 1, do_sandbox,
- "Miscellaneous sandbox commands",
- "load hostfs - <addr> <filename> [<bytes> <offset>] - "
- "load a file from host\n"
- "sb ls hostfs - <filename> - list files on host\n"
- "sb save hostfs - <addr> <filename> <bytes> [<offset>] - "
- "save a file to host\n"
- "sb bind <dev> [<filename>] - bind \"host\" device to file\n"
- "sb info [<dev>] - show device binding & info\n"
- "sb commands use the \"hostfs\" device. The \"host\" device is used\n"
- "with standard IO commands such as fatls or ext2load"
-);
diff --git a/common/cmd_sf.c b/common/cmd_sf.c
index 5c788e96bd..6aabf39302 100644
--- a/common/cmd_sf.c
+++ b/common/cmd_sf.c
@@ -10,6 +10,7 @@
#include <div64.h>
#include <dm.h>
#include <malloc.h>
+#include <mapmem.h>
#include <spi.h>
#include <spi_flash.h>
@@ -130,7 +131,7 @@ static int do_spi_flash_probe(int argc, char * const argv[])
return 1;
}
- flash = new->uclass_priv;
+ flash = dev_get_uclass_priv(new);
#else
new = spi_flash_probe(bus, cs, speed, mode);
if (!new) {
diff --git a/common/cmd_source.c b/common/cmd_source.c
index 6881bc9ddd..d2a881ddc7 100644
--- a/common/cmd_source.c
+++ b/common/cmd_source.c
@@ -19,6 +19,7 @@
#include <command.h>
#include <image.h>
#include <malloc.h>
+#include <mapmem.h>
#include <asm/byteorder.h>
#include <asm/io.h>
#if defined(CONFIG_8xx)
diff --git a/common/cmd_trace.c b/common/cmd_trace.c
index 8c630e6a84..1e62a1a199 100644
--- a/common/cmd_trace.c
+++ b/common/cmd_trace.c
@@ -6,6 +6,7 @@
#include <common.h>
#include <command.h>
+#include <mapmem.h>
#include <trace.h>
#include <asm/io.h>
diff --git a/common/cmd_usb.c b/common/cmd_usb.c
index 27813f0d7a..eab55cd674 100644
--- a/common/cmd_usb.c
+++ b/common/cmd_usb.c
@@ -2,6 +2,9 @@
* (C) Copyright 2001
* Denis Peter, MPL AG Switzerland
*
+ * Adapted for U-Boot driver model
+ * (C) Copyright 2015 Google, Inc
+ *
* Most of this source has been derived from the Linux USB
* project.
*
@@ -10,6 +13,7 @@
#include <common.h>
#include <command.h>
+#include <dm.h>
#include <asm/byteorder.h>
#include <asm/unaligned.h>
#include <part.h>
@@ -252,18 +256,57 @@ static void usb_display_config(struct usb_device *dev)
printf("\n");
}
+/*
+ * With driver model this isn't right since we can have multiple controllers
+ * and the device numbering starts at 1 on each bus.
+ * TODO(sjg@chromium.org): Add a way to specify the controller/bus.
+ */
static struct usb_device *usb_find_device(int devnum)
{
- struct usb_device *dev;
+#ifdef CONFIG_DM_USB
+ struct usb_device *udev;
+ struct udevice *hub;
+ struct uclass *uc;
+ int ret;
+
+ /* Device addresses start at 1 */
+ devnum++;
+ ret = uclass_get(UCLASS_USB_HUB, &uc);
+ if (ret)
+ return NULL;
+
+ uclass_foreach_dev(hub, uc) {
+ struct udevice *dev;
+
+ if (!device_active(hub))
+ continue;
+ udev = dev_get_parentdata(hub);
+ if (udev->devnum == devnum)
+ return udev;
+
+ for (device_find_first_child(hub, &dev);
+ dev;
+ device_find_next_child(&dev)) {
+ if (!device_active(hub))
+ continue;
+
+ udev = dev_get_parentdata(dev);
+ if (udev->devnum == devnum)
+ return udev;
+ }
+ }
+#else
+ struct usb_device *udev;
int d;
for (d = 0; d < USB_MAX_DEVICE; d++) {
- dev = usb_get_dev_index(d);
- if (dev == NULL)
+ udev = usb_get_dev_index(d);
+ if (udev == NULL)
return NULL;
- if (dev->devnum == devnum)
- return dev;
+ if (udev->devnum == devnum)
+ return udev;
}
+#endif
return NULL;
}
@@ -293,20 +336,31 @@ static inline char *portspeed(int speed)
/* shows the device tree recursively */
static void usb_show_tree_graph(struct usb_device *dev, char *pre)
{
- int i, index;
+ int index;
int has_child, last_child;
index = strlen(pre);
printf(" %s", pre);
+#ifdef CONFIG_DM_USB
+ has_child = device_has_active_children(dev->dev);
+#else
/* check if the device has connected children */
+ int i;
+
has_child = 0;
for (i = 0; i < dev->maxchild; i++) {
if (dev->children[i] != NULL)
has_child = 1;
}
+#endif
/* check if we are the last one */
- last_child = 1;
- if (dev->parent != NULL) {
+#ifdef CONFIG_DM_USB
+ last_child = device_is_last_sibling(dev->dev);
+#else
+ last_child = (dev->parent != NULL);
+#endif
+ if (last_child) {
+#ifndef CONFIG_DM_USB
for (i = 0; i < dev->parent->maxchild; i++) {
/* search for children */
if (dev->parent->children[i] == dev) {
@@ -322,9 +376,10 @@ static void usb_show_tree_graph(struct usb_device *dev, char *pre)
} /* while */
} /* device found */
} /* for all children of the parent */
+#endif
printf("\b+-");
/* correct last child */
- if (last_child)
+ if (last_child && index)
pre[index-1] = ' ';
} /* if not root hub */
else
@@ -340,6 +395,26 @@ static void usb_show_tree_graph(struct usb_device *dev, char *pre)
if (strlen(dev->mf) || strlen(dev->prod) || strlen(dev->serial))
printf(" %s %s %s %s\n", pre, dev->mf, dev->prod, dev->serial);
printf(" %s\n", pre);
+#ifdef CONFIG_DM_USB
+ struct udevice *child;
+
+ for (device_find_first_child(dev->dev, &child);
+ child;
+ device_find_next_child(&child)) {
+ struct usb_device *udev;
+
+ if (!device_active(child))
+ continue;
+
+ udev = dev_get_parentdata(child);
+
+ /* Ignore emulators, we only want real devices */
+ if (device_get_uclass_id(child) != UCLASS_USB_EMUL) {
+ usb_show_tree_graph(udev, pre);
+ pre[index] = 0;
+ }
+ }
+#else
if (dev->maxchild > 0) {
for (i = 0; i < dev->maxchild; i++) {
if (dev->children[i] != NULL) {
@@ -348,6 +423,7 @@ static void usb_show_tree_graph(struct usb_device *dev, char *pre)
}
}
}
+#endif
}
/* main routine for the tree command */
@@ -355,7 +431,7 @@ static void usb_show_tree(struct usb_device *dev)
{
char preamble[32];
- memset(preamble, 0, 32);
+ memset(preamble, '\0', sizeof(preamble));
usb_show_tree_graph(dev, &preamble[0]);
}
@@ -448,10 +524,13 @@ static void do_usb_start(void)
if (usb_init() < 0)
return;
+ /* Driver model will probe the devices as they are found */
+#ifndef CONFIG_DM_USB
#ifdef CONFIG_USB_STORAGE
/* try to recognize storage devices immediately */
usb_stor_curr_dev = usb_stor_scan(1);
#endif
+#endif
#ifdef CONFIG_USB_HOST_ETHER
/* try to recognize ethernet devices immediately */
usb_ether_curr_dev = usb_host_eth_scan(1);
@@ -461,14 +540,50 @@ static void do_usb_start(void)
#endif
}
+#ifdef CONFIG_DM_USB
+static void show_info(struct udevice *dev)
+{
+ struct udevice *child;
+ struct usb_device *udev;
+
+ udev = dev_get_parentdata(dev);
+ usb_display_desc(udev);
+ usb_display_config(udev);
+ for (device_find_first_child(dev, &child);
+ child;
+ device_find_next_child(&child)) {
+ if (device_active(child))
+ show_info(child);
+ }
+}
+
+static int usb_device_info(void)
+{
+ struct udevice *bus;
+
+ for (uclass_first_device(UCLASS_USB, &bus);
+ bus;
+ uclass_next_device(&bus)) {
+ struct udevice *hub;
+
+ device_find_first_child(bus, &hub);
+ if (device_get_uclass_id(hub) == UCLASS_USB_HUB &&
+ device_active(hub)) {
+ show_info(hub);
+ }
+ }
+
+ return 0;
+}
+#endif
+
/******************************************************************************
* usb command intepreter
*/
static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
-
+ struct usb_device *udev = NULL;
int i;
- struct usb_device *dev = NULL;
extern char usb_started;
#ifdef CONFIG_USB_STORAGE
block_dev_desc_t *stor_dev;
@@ -508,36 +623,63 @@ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
}
if (strncmp(argv[1], "tree", 4) == 0) {
puts("USB device tree:\n");
+#ifdef CONFIG_DM_USB
+ struct udevice *bus;
+
+ for (uclass_first_device(UCLASS_USB, &bus);
+ bus;
+ uclass_next_device(&bus)) {
+ struct usb_device *udev;
+ struct udevice *hub;
+
+ device_find_first_child(bus, &hub);
+ if (device_get_uclass_id(hub) == UCLASS_USB_HUB &&
+ device_active(hub)) {
+ udev = dev_get_parentdata(hub);
+ usb_show_tree(udev);
+ }
+ }
+#else
for (i = 0; i < USB_MAX_DEVICE; i++) {
- dev = usb_get_dev_index(i);
- if (dev == NULL)
+ udev = usb_get_dev_index(i);
+ if (udev == NULL)
break;
- if (dev->parent == NULL)
- usb_show_tree(dev);
+ if (udev->parent == NULL)
+ usb_show_tree(udev);
}
+#endif
return 0;
}
if (strncmp(argv[1], "inf", 3) == 0) {
- int d;
if (argc == 2) {
+#ifdef CONFIG_DM_USB
+ usb_device_info();
+#else
+ int d;
for (d = 0; d < USB_MAX_DEVICE; d++) {
- dev = usb_get_dev_index(d);
- if (dev == NULL)
+ udev = usb_get_dev_index(d);
+ if (udev == NULL)
break;
- usb_display_desc(dev);
- usb_display_config(dev);
+ usb_display_desc(udev);
+ usb_display_config(udev);
}
+#endif
return 0;
} else {
+ /*
+ * With driver model this isn't right since we can
+ * have multiple controllers and the device numbering
+ * starts at 1 on each bus.
+ */
i = simple_strtoul(argv[2], NULL, 10);
printf("config for device %d\n", i);
- dev = usb_find_device(i);
- if (dev == NULL) {
+ udev = usb_find_device(i);
+ if (udev == NULL) {
printf("*** No device available ***\n");
return 0;
} else {
- usb_display_desc(dev);
- usb_display_config(dev);
+ usb_display_desc(udev);
+ usb_display_config(udev);
}
}
return 0;
@@ -546,13 +688,13 @@ static int do_usb(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
if (argc < 5)
return CMD_RET_USAGE;
i = simple_strtoul(argv[2], NULL, 10);
- dev = usb_find_device(i);
- if (dev == NULL) {
+ udev = usb_find_device(i);
+ if (udev == NULL) {
printf("Device %d does not exist.\n", i);
return 1;
}
i = simple_strtoul(argv[3], NULL, 10);
- return usb_test(dev, i, argv[4]);
+ return usb_test(udev, i, argv[4]);
}
#ifdef CONFIG_USB_STORAGE
if (strncmp(argv[1], "stor", 4) == 0)
diff --git a/common/cmd_ximg.c b/common/cmd_ximg.c
index 64b9186d73..8b8645c9e1 100644
--- a/common/cmd_ximg.c
+++ b/common/cmd_ximg.c
@@ -15,6 +15,7 @@
#include <common.h>
#include <command.h>
#include <image.h>
+#include <mapmem.h>
#include <watchdog.h>
#if defined(CONFIG_BZIP2)
#include <bzlib.h>
diff --git a/common/cros_ec.c b/common/cros_ec.c
index bb299bccff..7a4f785bc8 100644
--- a/common/cros_ec.c
+++ b/common/cros_ec.c
@@ -15,18 +15,8 @@
DECLARE_GLOBAL_DATA_PTR;
-#ifndef CONFIG_DM_CROS_EC
-struct local_info {
- struct cros_ec_dev *cros_ec_dev; /* Pointer to cros_ec device */
- int cros_ec_err; /* Error for cros_ec, 0 if ok */
-};
-
-static struct local_info local;
-#endif
-
struct cros_ec_dev *board_get_cros_ec_dev(void)
{
-#ifdef CONFIG_DM_CROS_EC
struct udevice *dev;
int ret;
@@ -35,31 +25,11 @@ struct cros_ec_dev *board_get_cros_ec_dev(void)
debug("%s: Error %d\n", __func__, ret);
return NULL;
}
- return dev->uclass_priv;
-#else
- return local.cros_ec_dev;
-#endif
-}
-
-static int board_init_cros_ec_devices(const void *blob)
-{
-#ifndef CONFIG_DM_CROS_EC
- local.cros_ec_err = cros_ec_init(blob, &local.cros_ec_dev);
- if (local.cros_ec_err)
- return -1; /* Will report in board_late_init() */
-#endif
-
- return 0;
-}
-
-int cros_ec_board_init(void)
-{
- return board_init_cros_ec_devices(gd->fdt_blob);
+ return dev_get_uclass_priv(dev);
}
int cros_ec_get_error(void)
{
-#ifdef CONFIG_DM_CROS_EC
struct udevice *dev;
int ret;
@@ -68,7 +38,4 @@ int cros_ec_get_error(void)
return ret;
return 0;
-#else
- return local.cros_ec_err;
-#endif
}
diff --git a/common/hash.c b/common/hash.c
index 9e9f84b9fb..c94c98be9e 100644
--- a/common/hash.c
+++ b/common/hash.c
@@ -14,6 +14,7 @@
#include <common.h>
#include <command.h>
#include <malloc.h>
+#include <mapmem.h>
#include <hw_sha.h>
#include <asm/io.h>
#include <asm/errno.h>
diff --git a/common/image-fdt.c b/common/image-fdt.c
index d9e47283c7..7e2da7b3b7 100644
--- a/common/image-fdt.c
+++ b/common/image-fdt.c
@@ -14,6 +14,7 @@
#include <errno.h>
#include <image.h>
#include <libfdt.h>
+#include <mapmem.h>
#include <asm/io.h>
#ifndef CONFIG_SYS_FDT_PAD
diff --git a/common/image-fit.c b/common/image-fit.c
index 778d2a148b..4eb4d42655 100644
--- a/common/image-fit.c
+++ b/common/image-fit.c
@@ -16,6 +16,7 @@
#else
#include <common.h>
#include <errno.h>
+#include <mapmem.h>
#include <asm/io.h>
DECLARE_GLOBAL_DATA_PTR;
#endif /* !USE_HOSTCC*/
diff --git a/common/image.c b/common/image.c
index 162b68269d..abc0d890f2 100644
--- a/common/image.c
+++ b/common/image.c
@@ -27,6 +27,7 @@
#include <environment.h>
#include <image.h>
+#include <mapmem.h>
#if defined(CONFIG_FIT) || defined(CONFIG_OF_LIBFDT)
#include <libfdt.h>
diff --git a/common/iotrace.c b/common/iotrace.c
index ced426ea5c..2725563e8f 100644
--- a/common/iotrace.c
+++ b/common/iotrace.c
@@ -7,6 +7,7 @@
#define IOTRACE_IMPL
#include <common.h>
+#include <mapmem.h>
#include <asm/io.h>
DECLARE_GLOBAL_DATA_PTR;
diff --git a/common/lcd.c b/common/lcd.c
index aab73d8a61..055c366b19 100644
--- a/common/lcd.c
+++ b/common/lcd.c
@@ -15,6 +15,7 @@
#include <linux/types.h>
#include <stdio_dev.h>
#include <lcd.h>
+#include <mapmem.h>
#include <watchdog.h>
#include <asm/unaligned.h>
#include <splash.h>
diff --git a/common/malloc_simple.c b/common/malloc_simple.c
index 64ae0365af..d445199c58 100644
--- a/common/malloc_simple.c
+++ b/common/malloc_simple.c
@@ -8,6 +8,7 @@
#include <common.h>
#include <malloc.h>
+#include <mapmem.h>
#include <asm/io.h>
DECLARE_GLOBAL_DATA_PTR;
diff --git a/common/miiphyutil.c b/common/miiphyutil.c
index 74812e6e1b..c88c28adbf 100644
--- a/common/miiphyutil.c
+++ b/common/miiphyutil.c
@@ -11,6 +11,7 @@
*/
#include <common.h>
+#include <dm.h>
#include <miiphy.h>
#include <phy.h>
diff --git a/common/spl/spl_net.c b/common/spl/spl_net.c
index ff53705926..217a435c73 100644
--- a/common/spl/spl_net.c
+++ b/common/spl/spl_net.c
@@ -21,14 +21,14 @@ void spl_net_load_image(const char *device)
env_relocate();
setenv("autoload", "yes");
load_addr = CONFIG_SYS_TEXT_BASE - sizeof(struct image_header);
- rv = eth_initialize(gd->bd);
+ rv = eth_initialize();
if (rv == 0) {
printf("No Ethernet devices found\n");
hang();
}
if (device)
setenv("ethact", device);
- rv = NetLoop(BOOTP);
+ rv = net_loop(BOOTP);
if (rv < 0) {
printf("Problem booting with BOOTP\n");
hang();
diff --git a/common/update.c b/common/update.c
index cc830a7865..1c6aa186d0 100644
--- a/common/update.c
+++ b/common/update.c
@@ -39,8 +39,8 @@
#define CONFIG_UPDATE_TFTP_CNT_MAX 0
#endif
-extern ulong TftpRRQTimeoutMSecs;
-extern int TftpRRQTimeoutCountMax;
+extern ulong tftp_timeout_ms;
+extern int tftp_timeout_count_max;
extern flash_info_t flash_info[];
extern ulong load_addr;
@@ -55,22 +55,22 @@ static int update_load(char *filename, ulong msec_max, int cnt_max, ulong addr)
rv = 0;
/* save used globals and env variable */
- saved_timeout_msecs = TftpRRQTimeoutMSecs;
- saved_timeout_count = TftpRRQTimeoutCountMax;
+ saved_timeout_msecs = tftp_timeout_ms;
+ saved_timeout_count = tftp_timeout_count_max;
saved_netretry = strdup(getenv("netretry"));
- saved_bootfile = strdup(BootFile);
+ saved_bootfile = strdup(net_boot_file_name);
/* set timeouts for auto-update */
- TftpRRQTimeoutMSecs = msec_max;
- TftpRRQTimeoutCountMax = cnt_max;
+ tftp_timeout_ms = msec_max;
+ tftp_timeout_count_max = cnt_max;
/* we don't want to retry the connection if errors occur */
setenv("netretry", "no");
/* download the update file */
load_addr = addr;
- copy_filename(BootFile, filename, sizeof(BootFile));
- size = NetLoop(TFTPGET);
+ copy_filename(net_boot_file_name, filename, sizeof(net_boot_file_name));
+ size = net_loop(TFTPGET);
if (size < 0)
rv = 1;
@@ -78,15 +78,16 @@ static int update_load(char *filename, ulong msec_max, int cnt_max, ulong addr)
flush_cache(addr, size);
/* restore changed globals and env variable */
- TftpRRQTimeoutMSecs = saved_timeout_msecs;
- TftpRRQTimeoutCountMax = saved_timeout_count;
+ tftp_timeout_ms = saved_timeout_msecs;
+ tftp_timeout_count_max = saved_timeout_count;
setenv("netretry", saved_netretry);
if (saved_netretry != NULL)
free(saved_netretry);
if (saved_bootfile != NULL) {
- copy_filename(BootFile, saved_bootfile, sizeof(BootFile));
+ copy_filename(net_boot_file_name, saved_bootfile,
+ sizeof(net_boot_file_name));
free(saved_bootfile);
}
diff --git a/common/usb.c b/common/usb.c
index d94640a99e..a4820d3e94 100644
--- a/common/usb.c
+++ b/common/usb.c
@@ -28,6 +28,7 @@
*/
#include <common.h>
#include <command.h>
+#include <dm.h>
#include <asm/processor.h>
#include <linux/compiler.h>
#include <linux/ctype.h>
@@ -41,12 +42,13 @@
#define USB_BUFSIZ 512
-static struct usb_device usb_dev[USB_MAX_DEVICE];
-static int dev_index;
static int asynch_allowed;
-
char usb_started; /* flag for the started/stopped USB status */
+#ifndef CONFIG_DM_USB
+static struct usb_device usb_dev[USB_MAX_DEVICE];
+static int dev_index;
+
#ifndef CONFIG_USB_MAX_CONTROLLER_COUNT
#define CONFIG_USB_MAX_CONTROLLER_COUNT 1
#endif
@@ -94,8 +96,8 @@ int usb_init(void)
controllers_initialized++;
start_index = dev_index;
printf("scanning bus %d for devices... ", i);
- dev = usb_alloc_new_device(ctrl);
- if (!dev)
+ ret = usb_alloc_new_device(ctrl, &dev);
+ if (ret)
break;
/*
@@ -104,7 +106,7 @@ int usb_init(void)
*/
ret = usb_new_device(dev);
if (ret)
- usb_free_device();
+ usb_free_device(dev->controller);
if (start_index == dev_index) {
puts("No USB Device found\n");
@@ -158,6 +160,7 @@ int usb_disable_asynch(int disable)
asynch_allowed = !disable;
return old_value;
}
+#endif /* !CONFIG_DM_USB */
/*-------------------------------------------------------------------
@@ -821,6 +824,7 @@ int usb_string(struct usb_device *dev, int index, char *buf, size_t size)
* the USB device are static allocated [USB_MAX_DEVICE].
*/
+#ifndef CONFIG_DM_USB
/* returns a pointer to the device with the index [index].
* if the device is not assigned (dev->devnum==-1) returns NULL
@@ -833,16 +837,13 @@ struct usb_device *usb_get_dev_index(int index)
return &usb_dev[index];
}
-/* returns a pointer of a new device structure or NULL, if
- * no device struct is available
- */
-struct usb_device *usb_alloc_new_device(void *controller)
+int usb_alloc_new_device(struct udevice *controller, struct usb_device **devp)
{
int i;
debug("New Device %d\n", dev_index);
if (dev_index == USB_MAX_DEVICE) {
printf("ERROR, too many USB Devices, max=%d\n", USB_MAX_DEVICE);
- return NULL;
+ return -ENOSPC;
}
/* default Address is 0, real addresses start with 1 */
usb_dev[dev_index].devnum = dev_index + 1;
@@ -852,7 +853,9 @@ struct usb_device *usb_alloc_new_device(void *controller)
usb_dev[dev_index].parent = NULL;
usb_dev[dev_index].controller = controller;
dev_index++;
- return &usb_dev[dev_index - 1];
+ *devp = &usb_dev[dev_index - 1];
+
+ return 0;
}
/*
@@ -860,7 +863,7 @@ struct usb_device *usb_alloc_new_device(void *controller)
* Called in error cases where configuring a newly attached
* device fails for some reason.
*/
-void usb_free_device(void)
+void usb_free_device(struct udevice *controller)
{
dev_index--;
debug("Freeing device node: %d\n", dev_index);
@@ -878,123 +881,101 @@ __weak int usb_alloc_device(struct usb_device *udev)
{
return 0;
}
-/*
- * By the time we get here, the device has gotten a new device ID
- * and is in the default state. We need to identify the thing and
- * get the ball rolling..
- *
- * Returns 0 for success, != 0 for error.
- */
-int usb_new_device(struct usb_device *dev)
+#endif /* !CONFIG_DM_USB */
+
+#ifndef CONFIG_DM_USB
+int usb_legacy_port_reset(struct usb_device *hub, int portnr)
{
- int addr, err;
- int tmp;
- ALLOC_CACHE_ALIGN_BUFFER(unsigned char, tmpbuf, USB_BUFSIZ);
+ if (hub) {
+ unsigned short portstatus;
+ int err;
- /*
- * Allocate usb 3.0 device context.
- * USB 3.0 (xHCI) protocol tries to allocate device slot
- * and related data structures first. This call does that.
- * Refer to sec 4.3.2 in xHCI spec rev1.0
- */
- if (usb_alloc_device(dev)) {
- printf("Cannot allocate device context to get SLOT_ID\n");
- return -EINVAL;
+ /* reset the port for the second time */
+ err = legacy_hub_port_reset(hub, portnr - 1, &portstatus);
+ if (err < 0) {
+ printf("\n Couldn't reset port %i\n", portnr);
+ return err;
+ }
+ } else {
+ usb_reset_root_port();
}
- /* We still haven't set the Address yet */
- addr = dev->devnum;
- dev->devnum = 0;
+ return 0;
+}
+#endif
-#ifdef CONFIG_LEGACY_USB_INIT_SEQ
- /* this is the old and known way of initializing devices, it is
- * different than what Windows and Linux are doing. Windows and Linux
- * both retrieve 64 bytes while reading the device descriptor
- * Several USB stick devices report ERR: CTL_TIMEOUT, caused by an
- * invalid header while reading 8 bytes as device descriptor. */
- dev->descriptor.bMaxPacketSize0 = 8; /* Start off at 8 bytes */
- dev->maxpacketsize = PACKET_SIZE_8;
- dev->epmaxpacketin[0] = 8;
- dev->epmaxpacketout[0] = 8;
-
- err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, tmpbuf, 8);
- if (err < 8) {
- printf("\n USB device not responding, " \
- "giving up (status=%lX)\n", dev->status);
- return -EIO;
+static int get_descriptor_len(struct usb_device *dev, int len, int expect_len)
+{
+ __maybe_unused struct usb_device_descriptor *desc;
+ ALLOC_CACHE_ALIGN_BUFFER(unsigned char, tmpbuf, USB_BUFSIZ);
+ int err;
+
+ desc = (struct usb_device_descriptor *)tmpbuf;
+
+ err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc, len);
+ if (err < expect_len) {
+ if (err < 0) {
+ printf("unable to get device descriptor (error=%d)\n",
+ err);
+ return err;
+ } else {
+ printf("USB device descriptor short read (expected %i, got %i)\n",
+ expect_len, err);
+ return -EIO;
+ }
}
- memcpy(&dev->descriptor, tmpbuf, 8);
-#else
- /* This is a Windows scheme of initialization sequence, with double
+ memcpy(&dev->descriptor, tmpbuf, sizeof(dev->descriptor));
+
+ return 0;
+}
+
+static int usb_setup_descriptor(struct usb_device *dev, bool do_read)
+{
+ __maybe_unused struct usb_device_descriptor *desc;
+
+ /*
+ * This is a Windows scheme of initialization sequence, with double
* reset of the device (Linux uses the same sequence)
* Some equipment is said to work only with such init sequence; this
* patch is based on the work by Alan Stern:
* http://sourceforge.net/mailarchive/forum.php?
* thread_id=5729457&forum_id=5398
*/
- __maybe_unused struct usb_device_descriptor *desc;
- struct usb_device *parent = dev->parent;
- unsigned short portstatus;
- /* send 64-byte GET-DEVICE-DESCRIPTOR request. Since the descriptor is
+ /*
+ * send 64-byte GET-DEVICE-DESCRIPTOR request. Since the descriptor is
* only 18 bytes long, this will terminate with a short packet. But if
* the maxpacket size is 8 or 16 the device may be waiting to transmit
* some more, or keeps on retransmitting the 8 byte header. */
- desc = (struct usb_device_descriptor *)tmpbuf;
dev->descriptor.bMaxPacketSize0 = 64; /* Start off at 64 bytes */
/* Default to 64 byte max packet size */
dev->maxpacketsize = PACKET_SIZE_64;
dev->epmaxpacketin[0] = 64;
dev->epmaxpacketout[0] = 64;
- /*
- * XHCI needs to issue a Address device command to setup
- * proper device context structures, before it can interact
- * with the device. So a get_descriptor will fail before any
- * of that is done for XHCI unlike EHCI.
- */
-#ifndef CONFIG_USB_XHCI
- err = usb_get_descriptor(dev, USB_DT_DEVICE, 0, desc, 64);
- /*
- * Validate we've received only at least 8 bytes, not that we've
- * received the entire descriptor. The reasoning is:
- * - The code only uses fields in the first 8 bytes, so that's all we
- * need to have fetched at this stage.
- * - The smallest maxpacket size is 8 bytes. Before we know the actual
- * maxpacket the device uses, the USB controller may only accept a
- * single packet. Consequently we are only guaranteed to receive 1
- * packet (at least 8 bytes) even in a non-error case.
- *
- * At least the DWC2 controller needs to be programmed with the number
- * of packets in addition to the number of bytes. A request for 64
- * bytes of data with the maxpacket guessed as 64 (above) yields a
- * request for 1 packet.
- */
- if (err < 8) {
- debug("usb_new_device: usb_get_descriptor() failed\n");
- return -EIO;
- }
-
- dev->descriptor.bMaxPacketSize0 = desc->bMaxPacketSize0;
- /*
- * Fetch the device class, driver can use this info
- * to differentiate between HUB and DEVICE.
- */
- dev->descriptor.bDeviceClass = desc->bDeviceClass;
-#endif
+ if (do_read) {
+ int err;
- if (parent) {
- /* reset the port for the second time */
- err = hub_port_reset(dev->parent, dev->portnr - 1, &portstatus);
- if (err < 0) {
- printf("\n Couldn't reset port %i\n", dev->portnr);
- return -EIO;
- }
- } else {
- usb_reset_root_port();
+ /*
+ * Validate we've received only at least 8 bytes, not that we've
+ * received the entire descriptor. The reasoning is:
+ * - The code only uses fields in the first 8 bytes, so that's all we
+ * need to have fetched at this stage.
+ * - The smallest maxpacket size is 8 bytes. Before we know the actual
+ * maxpacket the device uses, the USB controller may only accept a
+ * single packet. Consequently we are only guaranteed to receive 1
+ * packet (at least 8 bytes) even in a non-error case.
+ *
+ * At least the DWC2 controller needs to be programmed with the number
+ * of packets in addition to the number of bytes. A request for 64
+ * bytes of data with the maxpacket guessed as 64 (above) yields a
+ * request for 1 packet.
+ */
+ err = get_descriptor_len(dev, 64, 8);
+ if (err)
+ return err;
}
-#endif
dev->epmaxpacketin[0] = dev->descriptor.bMaxPacketSize0;
dev->epmaxpacketout[0] = dev->descriptor.bMaxPacketSize0;
@@ -1015,6 +996,33 @@ int usb_new_device(struct usb_device *dev)
printf("usb_new_device: invalid max packet size\n");
return -EIO;
}
+
+ return 0;
+}
+
+static int usb_prepare_device(struct usb_device *dev, int addr, bool do_read,
+ struct usb_device *parent, int portnr)
+{
+ int err;
+
+ /*
+ * Allocate usb 3.0 device context.
+ * USB 3.0 (xHCI) protocol tries to allocate device slot
+ * and related data structures first. This call does that.
+ * Refer to sec 4.3.2 in xHCI spec rev1.0
+ */
+ err = usb_alloc_device(dev);
+ if (err) {
+ printf("Cannot allocate device context to get SLOT_ID\n");
+ return err;
+ }
+ err = usb_setup_descriptor(dev, do_read);
+ if (err)
+ return err;
+ err = usb_legacy_port_reset(parent, portnr);
+ if (err)
+ return err;
+
dev->devnum = addr;
err = usb_set_address(dev); /* set address */
@@ -1022,45 +1030,49 @@ int usb_new_device(struct usb_device *dev)
if (err < 0) {
printf("\n USB device not accepting new address " \
"(error=%lX)\n", dev->status);
- return -EIO;
+ return err;
}
mdelay(10); /* Let the SET_ADDRESS settle */
- tmp = sizeof(dev->descriptor);
+ return 0;
+}
+
+int usb_select_config(struct usb_device *dev)
+{
+ ALLOC_CACHE_ALIGN_BUFFER(unsigned char, tmpbuf, USB_BUFSIZ);
+ int err;
+
+ err = get_descriptor_len(dev, USB_DT_DEVICE_SIZE, USB_DT_DEVICE_SIZE);
+ if (err)
+ return err;
- err = usb_get_descriptor(dev, USB_DT_DEVICE, 0,
- tmpbuf, sizeof(dev->descriptor));
- if (err < tmp) {
- if (err < 0)
- printf("unable to get device descriptor (error=%d)\n",
- err);
- else
- printf("USB device descriptor short read " \
- "(expected %i, got %i)\n", tmp, err);
- return -EIO;
- }
- memcpy(&dev->descriptor, tmpbuf, sizeof(dev->descriptor));
/* correct le values */
le16_to_cpus(&dev->descriptor.bcdUSB);
le16_to_cpus(&dev->descriptor.idVendor);
le16_to_cpus(&dev->descriptor.idProduct);
le16_to_cpus(&dev->descriptor.bcdDevice);
+
/* only support for one config for now */
err = usb_get_configuration_no(dev, tmpbuf, 0);
if (err < 0) {
printf("usb_new_device: Cannot read configuration, " \
"skipping device %04x:%04x\n",
dev->descriptor.idVendor, dev->descriptor.idProduct);
- return -EIO;
+ return err;
}
usb_parse_config(dev, tmpbuf, 0);
usb_set_maxpacket(dev);
- /* we set the default configuration here */
- if (usb_set_configuration(dev, dev->config.desc.bConfigurationValue)) {
+ /*
+ * we set the default configuration here
+ * This seems premature. If the driver wants a different configuration
+ * it will need to select itself.
+ */
+ err = usb_set_configuration(dev, dev->config.desc.bConfigurationValue);
+ if (err < 0) {
printf("failed to set default configuration " \
"len %d, status %lX\n", dev->act_len, dev->status);
- return -EIO;
+ return err;
}
debug("new device strings: Mfr=%d, Product=%d, SerialNumber=%d\n",
dev->descriptor.iManufacturer, dev->descriptor.iProduct,
@@ -1080,11 +1092,63 @@ int usb_new_device(struct usb_device *dev)
debug("Manufacturer %s\n", dev->mf);
debug("Product %s\n", dev->prod);
debug("SerialNumber %s\n", dev->serial);
- /* now prode if the device is a hub */
- usb_hub_probe(dev, 0);
+
return 0;
}
+int usb_setup_device(struct usb_device *dev, bool do_read,
+ struct usb_device *parent, int portnr)
+{
+ int addr;
+ int ret;
+
+ /* We still haven't set the Address yet */
+ addr = dev->devnum;
+ dev->devnum = 0;
+
+ ret = usb_prepare_device(dev, addr, do_read, parent, portnr);
+ if (ret)
+ return ret;
+ ret = usb_select_config(dev);
+
+ return ret;
+}
+
+#ifndef CONFIG_DM_USB
+/*
+ * By the time we get here, the device has gotten a new device ID
+ * and is in the default state. We need to identify the thing and
+ * get the ball rolling..
+ *
+ * Returns 0 for success, != 0 for error.
+ */
+int usb_new_device(struct usb_device *dev)
+{
+ bool do_read = true;
+ int err;
+
+ /*
+ * XHCI needs to issue a Address device command to setup
+ * proper device context structures, before it can interact
+ * with the device. So a get_descriptor will fail before any
+ * of that is done for XHCI unlike EHCI.
+ */
+#ifdef CONFIG_USB_XHCI
+ do_read = false;
+#endif
+ err = usb_setup_device(dev, do_read, dev->parent, dev->portnr);
+ if (err)
+ return err;
+
+ /* Now probe if the device is a hub */
+ err = usb_hub_probe(dev, 0);
+ if (err < 0)
+ return err;
+
+ return 0;
+}
+#endif
+
__weak
int board_usb_init(int index, enum usb_init_type init)
{
@@ -1096,4 +1160,14 @@ int board_usb_cleanup(int index, enum usb_init_type init)
{
return 0;
}
+
+bool usb_device_has_child_on_port(struct usb_device *parent, int port)
+{
+#ifdef CONFIG_DM_USB
+ return false;
+#else
+ return parent->children[port] != NULL;
+#endif
+}
+
/* EOF */
diff --git a/common/usb_hub.c b/common/usb_hub.c
index f54a404a49..c9be530d0b 100644
--- a/common/usb_hub.c
+++ b/common/usb_hub.c
@@ -24,11 +24,16 @@
#include <common.h>
#include <command.h>
+#include <dm.h>
+#include <errno.h>
#include <asm/processor.h>
#include <asm/unaligned.h>
#include <linux/ctype.h>
#include <asm/byteorder.h>
#include <asm/unaligned.h>
+#include <dm/root.h>
+
+DECLARE_GLOBAL_DATA_PTR;
#include <usb.h>
#ifdef CONFIG_4xx
@@ -37,6 +42,7 @@
#define USB_BUFSIZ 512
+/* TODO(sjg@chromium.org): Remove this when CONFIG_DM_USB is defined */
static struct usb_hub_device hub_dev[USB_MAX_HUB];
static int usb_hub_index;
@@ -148,14 +154,19 @@ static inline char *portspeed(int portstatus)
return speed_str;
}
-int hub_port_reset(struct usb_device *dev, int port,
+int legacy_hub_port_reset(struct usb_device *dev, int port,
unsigned short *portstat)
{
int tries;
ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);
unsigned short portstatus, portchange;
- debug("hub_port_reset: resetting port %d...\n", port);
+#ifdef CONFIG_DM_USB
+ debug("%s: resetting '%s' port %d...\n", __func__, dev->dev->name,
+ port + 1);
+#else
+ debug("%s: resetting port %d...\n", __func__, port + 1);
+#endif
for (tries = 0; tries < MAX_TRIES; tries++) {
usb_set_port_feature(dev, port + 1, USB_PORT_FEAT_RESET);
@@ -213,17 +224,26 @@ int hub_port_reset(struct usb_device *dev, int port,
return 0;
}
+#ifdef CONFIG_DM_USB
+int hub_port_reset(struct udevice *dev, int port, unsigned short *portstat)
+{
+ struct usb_device *udev = dev_get_parentdata(dev);
-void usb_hub_port_connect_change(struct usb_device *dev, int port)
+ return legacy_hub_port_reset(udev, port, portstat);
+}
+#endif
+
+int usb_hub_port_connect_change(struct usb_device *dev, int port)
{
- struct usb_device *usb;
ALLOC_CACHE_ALIGN_BUFFER(struct usb_port_status, portsts, 1);
unsigned short portstatus;
+ int ret, speed;
/* Check status */
- if (usb_get_port_status(dev, port + 1, portsts) < 0) {
+ ret = usb_get_port_status(dev, port + 1, portsts);
+ if (ret < 0) {
debug("get_port_status failed\n");
- return;
+ return ret;
}
portstatus = le16_to_cpu(portsts->wPortStatus);
@@ -237,51 +257,70 @@ void usb_hub_port_connect_change(struct usb_device *dev, int port)
/* Disconnect any existing devices under this port */
if (((!(portstatus & USB_PORT_STAT_CONNECTION)) &&
- (!(portstatus & USB_PORT_STAT_ENABLE))) || (dev->children[port])) {
+ (!(portstatus & USB_PORT_STAT_ENABLE))) ||
+ usb_device_has_child_on_port(dev, port)) {
debug("usb_disconnect(&hub->children[port]);\n");
/* Return now if nothing is connected */
if (!(portstatus & USB_PORT_STAT_CONNECTION))
- return;
+ return -ENOTCONN;
}
mdelay(200);
/* Reset the port */
- if (hub_port_reset(dev, port, &portstatus) < 0) {
+ ret = legacy_hub_port_reset(dev, port, &portstatus);
+ if (ret < 0) {
printf("cannot reset port %i!?\n", port + 1);
- return;
+ return ret;
}
mdelay(200);
- /* Allocate a new device struct for it */
- usb = usb_alloc_new_device(dev->controller);
-
switch (portstatus & USB_PORT_STAT_SPEED_MASK) {
case USB_PORT_STAT_SUPER_SPEED:
- usb->speed = USB_SPEED_SUPER;
+ speed = USB_SPEED_SUPER;
break;
case USB_PORT_STAT_HIGH_SPEED:
- usb->speed = USB_SPEED_HIGH;
+ speed = USB_SPEED_HIGH;
break;
case USB_PORT_STAT_LOW_SPEED:
- usb->speed = USB_SPEED_LOW;
+ speed = USB_SPEED_LOW;
break;
default:
- usb->speed = USB_SPEED_FULL;
+ speed = USB_SPEED_FULL;
break;
}
+#ifdef CONFIG_DM_USB
+ struct udevice *child;
+
+ ret = usb_scan_device(dev->dev, port + 1, speed, &child);
+#else
+ struct usb_device *usb;
+
+ ret = usb_alloc_new_device(dev->controller, &usb);
+ if (ret) {
+ printf("cannot create new device: ret=%d", ret);
+ return ret;
+ }
+
dev->children[port] = usb;
+ usb->speed = speed;
usb->parent = dev;
usb->portnr = port + 1;
/* Run it through the hoops (find a driver, etc) */
- if (usb_new_device(usb)) {
+ ret = usb_new_device(usb);
+ if (ret < 0) {
/* Woops, disable the port */
- usb_free_device();
+ usb_free_device(dev->controller);
dev->children[port] = NULL;
+ }
+#endif
+ if (ret < 0) {
debug("hub: disabling port %d\n", port + 1);
usb_clear_port_feature(dev, port + 1, USB_PORT_FEAT_ENABLE);
}
+
+ return ret;
}
@@ -294,27 +333,30 @@ static int usb_hub_configure(struct usb_device *dev)
struct usb_hub_descriptor *descriptor;
struct usb_hub_device *hub;
__maybe_unused struct usb_hub_status *hubsts;
+ int ret;
/* "allocate" Hub device */
hub = usb_hub_allocate();
if (hub == NULL)
- return -1;
+ return -ENOMEM;
hub->pusb_dev = dev;
/* Get the the hub descriptor */
- if (usb_get_hub_descriptor(dev, buffer, 4) < 0) {
+ ret = usb_get_hub_descriptor(dev, buffer, 4);
+ if (ret < 0) {
debug("usb_hub_configure: failed to get hub " \
"descriptor, giving up %lX\n", dev->status);
- return -1;
+ return ret;
}
descriptor = (struct usb_hub_descriptor *)buffer;
length = min_t(int, descriptor->bLength,
sizeof(struct usb_hub_descriptor));
- if (usb_get_hub_descriptor(dev, buffer, length) < 0) {
+ ret = usb_get_hub_descriptor(dev, buffer, length);
+ if (ret < 0) {
debug("usb_hub_configure: failed to get hub " \
"descriptor 2nd giving up %lX\n", dev->status);
- return -1;
+ return ret;
}
memcpy((unsigned char *)&hub->desc, buffer, length);
/* adjust 16bit values */
@@ -382,13 +424,14 @@ static int usb_hub_configure(struct usb_device *dev)
if (sizeof(struct usb_hub_status) > USB_BUFSIZ) {
debug("usb_hub_configure: failed to get Status - " \
"too long: %d\n", descriptor->bLength);
- return -1;
+ return -EFBIG;
}
- if (usb_get_hub_status(dev, buffer) < 0) {
+ ret = usb_get_hub_status(dev, buffer);
+ if (ret < 0) {
debug("usb_hub_configure: failed to get Status %lX\n",
dev->status);
- return -1;
+ return ret;
}
#ifdef DEBUG
@@ -420,6 +463,11 @@ static int usb_hub_configure(struct usb_device *dev)
int ret;
ulong start = get_timer(0);
+#ifdef CONFIG_DM_USB
+ debug("\n\nScanning '%s' port %d\n", dev->dev->name, i + 1);
+#else
+ debug("\n\nScanning port %d\n", i + 1);
+#endif
/*
* Wait for (whichever finishes first)
* - A maximum of 10 seconds
@@ -469,7 +517,7 @@ static int usb_hub_configure(struct usb_device *dev)
* them again. Works at least with mouse driver */
if (!(portstatus & USB_PORT_STAT_ENABLE) &&
(portstatus & USB_PORT_STAT_CONNECTION) &&
- ((dev->children[i]))) {
+ usb_device_has_child_on_port(dev, i)) {
debug("already running port %i " \
"disabled by hub (EMI?), " \
"re-enabling...\n", i + 1);
@@ -500,33 +548,107 @@ static int usb_hub_configure(struct usb_device *dev)
return 0;
}
-int usb_hub_probe(struct usb_device *dev, int ifnum)
+static int usb_hub_check(struct usb_device *dev, int ifnum)
{
struct usb_interface *iface;
- struct usb_endpoint_descriptor *ep;
- int ret;
+ struct usb_endpoint_descriptor *ep = NULL;
iface = &dev->config.if_desc[ifnum];
/* Is it a hub? */
if (iface->desc.bInterfaceClass != USB_CLASS_HUB)
- return 0;
+ goto err;
/* Some hubs have a subclass of 1, which AFAICT according to the */
/* specs is not defined, but it works */
if ((iface->desc.bInterfaceSubClass != 0) &&
(iface->desc.bInterfaceSubClass != 1))
- return 0;
+ goto err;
/* Multiple endpoints? What kind of mutant ninja-hub is this? */
if (iface->desc.bNumEndpoints != 1)
- return 0;
+ goto err;
ep = &iface->ep_desc[0];
/* Output endpoint? Curiousier and curiousier.. */
if (!(ep->bEndpointAddress & USB_DIR_IN))
- return 0;
+ goto err;
/* If it's not an interrupt endpoint, we'd better punt! */
if ((ep->bmAttributes & 3) != 3)
- return 0;
+ goto err;
/* We found a hub */
debug("USB hub found\n");
+ return 0;
+
+err:
+ debug("USB hub not found: bInterfaceClass=%d, bInterfaceSubClass=%d, bNumEndpoints=%d\n",
+ iface->desc.bInterfaceClass, iface->desc.bInterfaceSubClass,
+ iface->desc.bNumEndpoints);
+ if (ep) {
+ debug(" bEndpointAddress=%#x, bmAttributes=%d",
+ ep->bEndpointAddress, ep->bmAttributes);
+ }
+
+ return -ENOENT;
+}
+
+int usb_hub_probe(struct usb_device *dev, int ifnum)
+{
+ int ret;
+
+ ret = usb_hub_check(dev, ifnum);
+ if (ret)
+ return 0;
ret = usb_hub_configure(dev);
return ret;
}
+
+#ifdef CONFIG_DM_USB
+int usb_hub_scan(struct udevice *hub)
+{
+ struct usb_device *udev = dev_get_parentdata(hub);
+
+ return usb_hub_configure(udev);
+}
+
+static int usb_hub_post_bind(struct udevice *dev)
+{
+ /* Scan the bus for devices */
+ return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false);
+}
+
+static int usb_hub_post_probe(struct udevice *dev)
+{
+ debug("%s\n", __func__);
+ return usb_hub_scan(dev);
+}
+
+static const struct udevice_id usb_hub_ids[] = {
+ { .compatible = "usb-hub" },
+ { }
+};
+
+U_BOOT_DRIVER(usb_generic_hub) = {
+ .name = "usb_hub",
+ .id = UCLASS_USB_HUB,
+ .of_match = usb_hub_ids,
+ .flags = DM_FLAG_ALLOC_PRIV_DMA,
+};
+
+UCLASS_DRIVER(usb_hub) = {
+ .id = UCLASS_USB_HUB,
+ .name = "usb_hub",
+ .post_bind = usb_hub_post_bind,
+ .post_probe = usb_hub_post_probe,
+ .child_pre_probe = usb_child_pre_probe,
+ .per_child_auto_alloc_size = sizeof(struct usb_device),
+ .per_child_platdata_auto_alloc_size = sizeof(struct usb_dev_platdata),
+};
+
+static const struct usb_device_id hub_id_table[] = {
+ {
+ .match_flags = USB_DEVICE_ID_MATCH_DEV_CLASS,
+ .bDeviceClass = USB_CLASS_HUB
+ },
+ { } /* Terminating entry */
+};
+
+USB_DEVICE(usb_generic_hub, hub_id_table);
+
+#endif
diff --git a/common/usb_kbd.c b/common/usb_kbd.c
index ecc3085cc0..24a1a56141 100644
--- a/common/usb_kbd.c
+++ b/common/usb_kbd.c
@@ -8,6 +8,7 @@
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
+#include <dm.h>
#include <errno.h>
#include <malloc.h>
#include <stdio_dev.h>
@@ -471,60 +472,104 @@ static int usb_kbd_probe(struct usb_device *dev, unsigned int ifnum)
return 1;
}
+static int probe_usb_keyboard(struct usb_device *dev)
+{
+ char *stdinname;
+ struct stdio_dev usb_kbd_dev;
+ int error;
+
+ /* Try probing the keyboard */
+ if (usb_kbd_probe(dev, 0) != 1)
+ return -ENOENT;
+
+ /* Register the keyboard */
+ debug("USB KBD: register.\n");
+ memset(&usb_kbd_dev, 0, sizeof(struct stdio_dev));
+ strcpy(usb_kbd_dev.name, DEVNAME);
+ usb_kbd_dev.flags = DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM;
+ usb_kbd_dev.getc = usb_kbd_getc;
+ usb_kbd_dev.tstc = usb_kbd_testc;
+ usb_kbd_dev.priv = (void *)dev;
+ error = stdio_register(&usb_kbd_dev);
+ if (error)
+ return error;
+
+ stdinname = getenv("stdin");
+#ifdef CONFIG_CONSOLE_MUX
+ error = iomux_doenv(stdin, stdinname);
+ if (error)
+ return error;
+#else
+ /* Check if this is the standard input device. */
+ if (strcmp(stdinname, DEVNAME))
+ return 1;
+
+ /* Reassign the console */
+ if (overwrite_console())
+ return 1;
+
+ error = console_assign(stdin, DEVNAME);
+ if (error)
+ return error;
+#endif
+
+ return 0;
+}
+
/* Search for keyboard and register it if found. */
int drv_usb_kbd_init(void)
{
- struct stdio_dev usb_kbd_dev;
- struct usb_device *dev;
- char *stdinname = getenv("stdin");
int error, i;
+ debug("%s: Probing for keyboard\n", __func__);
+#ifdef CONFIG_DM_USB
+ /*
+ * TODO: We should add USB_DEVICE() declarations to each USB ethernet
+ * driver and then most of this file can be removed.
+ */
+ struct udevice *bus;
+ struct uclass *uc;
+ int ret;
+
+ ret = uclass_get(UCLASS_USB, &uc);
+ if (ret)
+ return ret;
+ uclass_foreach_dev(bus, uc) {
+ for (i = 0; i < USB_MAX_DEVICE; i++) {
+ struct usb_device *dev;
+
+ dev = usb_get_dev_index(bus, i); /* get device */
+ debug("i=%d, %p\n", i, dev);
+ if (!dev)
+ break; /* no more devices available */
+
+ error = probe_usb_keyboard(dev);
+ if (!error)
+ return 1;
+ if (error && error != -ENOENT)
+ return error;
+ } /* for */
+ }
+#else
/* Scan all USB Devices */
for (i = 0; i < USB_MAX_DEVICE; i++) {
+ struct usb_device *dev;
+
/* Get USB device. */
dev = usb_get_dev_index(i);
if (!dev)
- return -1;
+ break;
if (dev->devnum == -1)
continue;
- /* Try probing the keyboard */
- if (usb_kbd_probe(dev, 0) != 1)
- continue;
-
- /* Register the keyboard */
- debug("USB KBD: register.\n");
- memset(&usb_kbd_dev, 0, sizeof(struct stdio_dev));
- strcpy(usb_kbd_dev.name, DEVNAME);
- usb_kbd_dev.flags = DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM;
- usb_kbd_dev.getc = usb_kbd_getc;
- usb_kbd_dev.tstc = usb_kbd_testc;
- usb_kbd_dev.priv = (void *)dev;
- error = stdio_register(&usb_kbd_dev);
- if (error)
- return error;
-
-#ifdef CONFIG_CONSOLE_MUX
- error = iomux_doenv(stdin, stdinname);
- if (error)
- return error;
-#else
- /* Check if this is the standard input device. */
- if (strcmp(stdinname, DEVNAME))
- return 1;
-
- /* Reassign the console */
- if (overwrite_console())
+ error = probe_usb_keyboard(dev);
+ if (!error)
return 1;
-
- error = console_assign(stdin, DEVNAME);
- if (error)
+ if (error && error != -ENOENT)
return error;
-#endif
-
- return 1;
}
+#endif
/* No USB Keyboard found */
return -1;
diff --git a/common/usb_storage.c b/common/usb_storage.c
index a4ca7a5957..cc9b3e37a1 100644
--- a/common/usb_storage.c
+++ b/common/usb_storage.c
@@ -9,6 +9,8 @@
*
* Adapted for U-Boot:
* (C) Copyright 2001 Denis Peter, MPL AG Switzerland
+ * Driver model conversion:
+ * (C) Copyright 2015 Google, Inc
*
* For BBB support (C) Copyright 2003
* Gary Jennejohn, DENX Software Engineering <garyj@denx.de>
@@ -33,9 +35,13 @@
#include <common.h>
#include <command.h>
+#include <dm.h>
+#include <errno.h>
#include <inttypes.h>
+#include <mapmem.h>
#include <asm/byteorder.h>
#include <asm/processor.h>
+#include <dm/device-internal.h>
#include <part.h>
#include <usb.h>
@@ -56,49 +62,8 @@ static const unsigned char us_direction[256/8] = {
#define US_DIRECTION(x) ((us_direction[x>>3] >> (x & 7)) & 1)
static ccb usb_ccb __attribute__((aligned(ARCH_DMA_MINALIGN)));
-
-/*
- * CBI style
- */
-
-#define US_CBI_ADSC 0
-
-/*
- * BULK only
- */
-#define US_BBB_RESET 0xff
-#define US_BBB_GET_MAX_LUN 0xfe
-
-/* Command Block Wrapper */
-typedef struct {
- __u32 dCBWSignature;
-# define CBWSIGNATURE 0x43425355
- __u32 dCBWTag;
- __u32 dCBWDataTransferLength;
- __u8 bCBWFlags;
-# define CBWFLAGS_OUT 0x00
-# define CBWFLAGS_IN 0x80
- __u8 bCBWLUN;
- __u8 bCDBLength;
-# define CBWCDBLENGTH 16
- __u8 CBWCDB[CBWCDBLENGTH];
-} umass_bbb_cbw_t;
-#define UMASS_BBB_CBW_SIZE 31
static __u32 CBWTag;
-/* Command Status Wrapper */
-typedef struct {
- __u32 dCSWSignature;
-# define CSWSIGNATURE 0x53425355
- __u32 dCSWTag;
- __u32 dCSWDataResidue;
- __u8 bCSWStatus;
-# define CSWSTATUS_GOOD 0x0
-# define CSWSTATUS_FAILED 0x1
-# define CSWSTATUS_PHASE 0x2
-} umass_bbb_csw_t;
-#define UMASS_BBB_CSW_SIZE 13
-
#define USB_MAX_STOR_DEV 5
static int usb_max_devs; /* number of highest available usb device */
@@ -145,7 +110,6 @@ struct us_data {
static struct us_data usb_stor[USB_MAX_STOR_DEV];
-
#define USB_STOR_TRANSPORT_GOOD 0
#define USB_STOR_TRANSPORT_FAILED -1
#define USB_STOR_TRANSPORT_ERROR -2
@@ -158,7 +122,6 @@ unsigned long usb_stor_read(int device, lbaint_t blknr,
lbaint_t blkcnt, void *buffer);
unsigned long usb_stor_write(int device, lbaint_t blknr,
lbaint_t blkcnt, const void *buffer);
-struct usb_device * usb_get_dev_index(int index);
void uhci_show_temp_int_td(void);
#ifdef CONFIG_PARTITIONS
@@ -208,30 +171,61 @@ static unsigned int usb_get_max_lun(struct us_data *us)
return (len > 0) ? *result : 0;
}
-static int usb_storage_register(struct usb_device *dev, unsigned char iface)
+static int usb_stor_probe_device(struct usb_device *dev)
{
- int lun, max_lun, start = usb_max_devs;
- int nb_dev = 0;
-
- if (!usb_storage_probe(dev, iface, &usb_stor[usb_max_devs]))
- return nb_dev;
-
- /*
- * OK, it's a storage device. Iterate over its LUNs
- * and populate `usb_dev_desc'.
- */
- max_lun = usb_get_max_lun(&usb_stor[usb_max_devs]);
- for (lun = 0; lun <= max_lun && usb_max_devs < USB_MAX_STOR_DEV; lun++) {
- usb_dev_desc[usb_max_devs].lun = lun;
- if (usb_stor_get_info(dev, &usb_stor[start],
- &usb_dev_desc[usb_max_devs]) == 1) {
- nb_dev++;
+ if (dev == NULL)
+ return -ENOENT; /* no more devices available */
+
+ debug("\n\nProbing for storage\n");
+ if (usb_storage_probe(dev, 0, &usb_stor[usb_max_devs])) {
+ /* OK, it's a storage device. Iterate over its LUNs
+ * and populate `usb_dev_desc'.
+ */
+ int lun, max_lun, start = usb_max_devs;
+
+ max_lun = usb_get_max_lun(&usb_stor[usb_max_devs]);
+ for (lun = 0;
+ lun <= max_lun && usb_max_devs < USB_MAX_STOR_DEV;
+ lun++) {
+ struct block_dev_desc *blkdev;
+
+ blkdev = &usb_dev_desc[usb_max_devs];
+ memset(blkdev, '\0', sizeof(block_dev_desc_t));
+ blkdev->if_type = IF_TYPE_USB;
+ blkdev->dev = usb_max_devs;
+ blkdev->part_type = PART_TYPE_UNKNOWN;
+ blkdev->target = 0xff;
+ blkdev->type = DEV_TYPE_UNKNOWN;
+ blkdev->block_read = usb_stor_read;
+ blkdev->block_write = usb_stor_write;
+ blkdev->lun = lun;
+ blkdev->priv = dev;
+
+ if (usb_stor_get_info(dev, &usb_stor[start],
+ &usb_dev_desc[usb_max_devs]) ==
+ 1) {
+ usb_max_devs++;
+ debug("%s: Found device %p\n", __func__, dev);
+ }
}
}
- return nb_dev;
+ /* if storage device */
+ if (usb_max_devs == USB_MAX_STOR_DEV) {
+ printf("max USB Storage Device reached: %d stopping\n",
+ usb_max_devs);
+ return -ENOSPC;
+ }
+
+ return 0;
+}
+
+void usb_stor_reset(void)
+{
+ usb_max_devs = 0;
}
+#ifndef CONFIG_DM_USB
/*******************************************************************************
* scan the usb and reports device info
* to the user if mode = 1
@@ -239,42 +233,21 @@ static int usb_storage_register(struct usb_device *dev, unsigned char iface)
*/
int usb_stor_scan(int mode)
{
- unsigned char i, iface;
- struct usb_device *dev;
+ unsigned char i;
if (mode == 1)
printf(" scanning usb for storage devices... ");
usb_disable_asynch(1); /* asynch transfer not allowed */
- for (i = 0; i < USB_MAX_STOR_DEV; i++) {
- memset(&usb_dev_desc[i], 0, sizeof(block_dev_desc_t));
- usb_dev_desc[i].if_type = IF_TYPE_USB;
- usb_dev_desc[i].dev = i;
- usb_dev_desc[i].part_type = PART_TYPE_UNKNOWN;
- usb_dev_desc[i].target = 0xff;
- usb_dev_desc[i].type = DEV_TYPE_UNKNOWN;
- usb_dev_desc[i].block_read = usb_stor_read;
- usb_dev_desc[i].block_write = usb_stor_write;
- }
-
- usb_max_devs = 0;
+ usb_stor_reset();
for (i = 0; i < USB_MAX_DEVICE; i++) {
+ struct usb_device *dev;
+
dev = usb_get_dev_index(i); /* get device */
debug("i=%d\n", i);
- if (dev == NULL)
- break; /* no more devices available */
-
- for (iface = 0; iface < dev->config.no_of_if; iface++) {
- usb_max_devs += usb_storage_register(dev, iface);
- }
-
- /* if storage device */
- if (usb_max_devs == USB_MAX_STOR_DEV) {
- printf("max USB Storage Device reached: %d stopping\n",
- usb_max_devs);
+ if (usb_stor_probe_device(dev))
break;
- }
} /* for */
usb_disable_asynch(0); /* asynch transfer allowed */
@@ -283,6 +256,7 @@ int usb_stor_scan(int mode)
return 0;
return -1;
}
+#endif
static int usb_stor_irq(struct usb_device *dev)
{
@@ -347,8 +321,9 @@ static int us_one_transfer(struct us_data *us, int pipe, char *buf, int length)
/* set up the transfer loop */
do {
/* transfer the data */
- debug("Bulk xfer %p(%d) try #%d\n",
- buf, this_xfer, 11 - maxtry);
+ debug("Bulk xfer 0x%lx(%d) try #%d\n",
+ (ulong)map_to_sysmem(buf), this_xfer,
+ 11 - maxtry);
result = usb_bulk_msg(us->pusb_dev, pipe, buf,
this_xfer, &partial,
USB_CNTL_TIMEOUT * 5);
@@ -494,7 +469,7 @@ static int usb_stor_BBB_comdat(ccb *srb, struct us_data *us)
int actlen;
int dir_in;
unsigned int pipe;
- ALLOC_CACHE_ALIGN_BUFFER(umass_bbb_cbw_t, cbw, 1);
+ ALLOC_CACHE_ALIGN_BUFFER(struct umass_bbb_cbw, cbw, 1);
dir_in = US_DIRECTION(srb->cmd[0]);
@@ -670,7 +645,7 @@ static int usb_stor_BBB_transport(ccb *srb, struct us_data *us)
int dir_in;
int actlen, data_actlen;
unsigned int pipe, pipein, pipeout;
- ALLOC_CACHE_ALIGN_BUFFER(umass_bbb_csw_t, csw, 1);
+ ALLOC_CACHE_ALIGN_BUFFER(struct umass_bbb_csw, csw, 1);
#ifdef BBB_XPORT_TRACE
unsigned char *ptr;
int index;
@@ -1059,7 +1034,7 @@ unsigned long usb_stor_read(int device, lbaint_t blknr,
unsigned short smallblks;
struct usb_device *dev;
struct us_data *ss;
- int retry, i;
+ int retry;
ccb *srb = &usb_ccb;
if (blkcnt == 0)
@@ -1067,14 +1042,11 @@ unsigned long usb_stor_read(int device, lbaint_t blknr,
device &= 0xff;
/* Setup device */
- debug("\nusb_read: dev %d \n", device);
- dev = NULL;
- for (i = 0; i < USB_MAX_DEVICE; i++) {
- dev = usb_get_dev_index(i);
- if (dev == NULL)
- return 0;
- if (dev->devnum == usb_dev_desc[device].target)
- break;
+ debug("\nusb_read: dev %d\n", device);
+ dev = usb_dev_desc[device].priv;
+ if (!dev) {
+ debug("%s: No device\n", __func__);
+ return 0;
}
ss = (struct us_data *)dev->privptr;
@@ -1132,7 +1104,7 @@ unsigned long usb_stor_write(int device, lbaint_t blknr,
unsigned short smallblks;
struct usb_device *dev;
struct us_data *ss;
- int retry, i;
+ int retry;
ccb *srb = &usb_ccb;
if (blkcnt == 0)
@@ -1140,15 +1112,10 @@ unsigned long usb_stor_write(int device, lbaint_t blknr,
device &= 0xff;
/* Setup device */
- debug("\nusb_write: dev %d \n", device);
- dev = NULL;
- for (i = 0; i < USB_MAX_DEVICE; i++) {
- dev = usb_get_dev_index(i);
- if (dev == NULL)
- return 0;
- if (dev->devnum == usb_dev_desc[device].target)
- break;
- }
+ debug("\nusb_write: dev %d\n", device);
+ dev = usb_dev_desc[device].priv;
+ if (!dev)
+ return 0;
ss = (struct us_data *)dev->privptr;
usb_disable_asynch(1); /* asynch transfer not allowed */
@@ -1232,6 +1199,7 @@ int usb_storage_probe(struct usb_device *dev, unsigned int ifnum,
iface->desc.bInterfaceClass != USB_CLASS_MASS_STORAGE ||
iface->desc.bInterfaceSubClass < US_SC_MIN ||
iface->desc.bInterfaceSubClass > US_SC_MAX) {
+ debug("Not mass storage\n");
/* if it's not a mass storage, we go no further */
return 0;
}
@@ -1358,8 +1326,10 @@ int usb_stor_get_info(struct usb_device *dev, struct us_data *ss,
pccb->lun = dev_desc->lun;
debug(" address %d\n", dev_desc->target);
- if (usb_inquiry(pccb, ss))
+ if (usb_inquiry(pccb, ss)) {
+ debug("%s: usb_inquiry() failed\n", __func__);
return -1;
+ }
perq = usb_stor_buf[0];
modi = usb_stor_buf[1];
@@ -1369,6 +1339,7 @@ int usb_stor_get_info(struct usb_device *dev, struct us_data *ss,
* they would not respond to test_unit_ready .
*/
if (((perq & 0x1f) == 0x1f) || ((perq & 0x1f) == 0x0d)) {
+ debug("%s: unknown/unsupported device\n", __func__);
return 0;
}
if ((modi&0x80) == 0x80) {
@@ -1431,3 +1402,46 @@ int usb_stor_get_info(struct usb_device *dev, struct us_data *ss,
debug("partype: %d\n", dev_desc->part_type);
return 1;
}
+
+#ifdef CONFIG_DM_USB
+
+static int usb_mass_storage_probe(struct udevice *dev)
+{
+ struct usb_device *udev = dev_get_parentdata(dev);
+ int ret;
+
+ usb_disable_asynch(1); /* asynch transfer not allowed */
+ ret = usb_stor_probe_device(udev);
+ usb_disable_asynch(0); /* asynch transfer allowed */
+
+ return ret;
+}
+
+static const struct udevice_id usb_mass_storage_ids[] = {
+ { .compatible = "usb-mass-storage" },
+ { }
+};
+
+U_BOOT_DRIVER(usb_mass_storage) = {
+ .name = "usb_mass_storage",
+ .id = UCLASS_MASS_STORAGE,
+ .of_match = usb_mass_storage_ids,
+ .probe = usb_mass_storage_probe,
+};
+
+UCLASS_DRIVER(usb_mass_storage) = {
+ .id = UCLASS_MASS_STORAGE,
+ .name = "usb_mass_storage",
+};
+
+static const struct usb_device_id mass_storage_id_table[] = {
+ {
+ .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
+ .bInterfaceClass = USB_CLASS_MASS_STORAGE
+ },
+ { } /* Terminating entry */
+};
+
+USB_DEVICE(usb_mass_storage, mass_storage_id_table);
+
+#endif
diff --git a/configs/A20-OLinuXino-Lime2_defconfig b/configs/A20-OLinuXino-Lime2_defconfig
index 4fcff923ba..f7231c612d 100644
--- a/configs/A20-OLinuXino-Lime2_defconfig
+++ b/configs/A20-OLinuXino-Lime2_defconfig
@@ -10,3 +10,6 @@ CONFIG_MACH_SUN7I=y
CONFIG_DRAM_CLK=480
CONFIG_DRAM_ZQ=127
CONFIG_DRAM_EMR1=4
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET=y
diff --git a/configs/A20-OLinuXino-Lime_defconfig b/configs/A20-OLinuXino-Lime_defconfig
index 8d71d5f018..7868d6edcc 100644
--- a/configs/A20-OLinuXino-Lime_defconfig
+++ b/configs/A20-OLinuXino-Lime_defconfig
@@ -7,3 +7,6 @@ CONFIG_MACH_SUN7I=y
CONFIG_DRAM_CLK=480
CONFIG_DRAM_ZQ=127
CONFIG_DRAM_EMR1=4
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET=y
diff --git a/configs/A20-OLinuXino_MICRO_defconfig b/configs/A20-OLinuXino_MICRO_defconfig
index 377bd4692a..11fb76096f 100644
--- a/configs/A20-OLinuXino_MICRO_defconfig
+++ b/configs/A20-OLinuXino_MICRO_defconfig
@@ -11,3 +11,6 @@ CONFIG_MACH_SUN7I=y
CONFIG_DRAM_CLK=384
CONFIG_DRAM_ZQ=127
CONFIG_DRAM_EMR1=4
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET=y
diff --git a/configs/Bananapi_defconfig b/configs/Bananapi_defconfig
index bad6081fe4..36a867114e 100644
--- a/configs/Bananapi_defconfig
+++ b/configs/Bananapi_defconfig
@@ -8,3 +8,6 @@ CONFIG_MACH_SUN7I=y
CONFIG_DRAM_CLK=432
CONFIG_DRAM_ZQ=127
CONFIG_DRAM_EMR1=4
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET=y
diff --git a/configs/Bananapro_defconfig b/configs/Bananapro_defconfig
index 2274c80b01..236a99240f 100644
--- a/configs/Bananapro_defconfig
+++ b/configs/Bananapro_defconfig
@@ -10,3 +10,6 @@ CONFIG_MACH_SUN7I=y
CONFIG_DRAM_CLK=432
CONFIG_DRAM_ZQ=127
CONFIG_DRAM_EMR1=4
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET=y
diff --git a/configs/CSQ_CS908_defconfig b/configs/CSQ_CS908_defconfig
index ec84acb028..776636ef43 100644
--- a/configs/CSQ_CS908_defconfig
+++ b/configs/CSQ_CS908_defconfig
@@ -13,3 +13,6 @@ CONFIG_AXP221_ALDO1_VOLT=3300
# No Vbus gpio for either usb
CONFIG_USB1_VBUS_PIN=""
CONFIG_USB2_VBUS_PIN=""
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET=y
diff --git a/configs/Colombus_defconfig b/configs/Colombus_defconfig
index d6aad5e674..810c88f230 100644
--- a/configs/Colombus_defconfig
+++ b/configs/Colombus_defconfig
@@ -10,3 +10,6 @@ CONFIG_DRAM_ZQ=251
CONFIG_AXP221_ALDO1_VOLT=3300
# No Vbus gpio for usb1
CONFIG_USB1_VBUS_PIN=""
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET=y
diff --git a/configs/Cubieboard2_defconfig b/configs/Cubieboard2_defconfig
index d866ad1e77..7f65c1d472 100644
--- a/configs/Cubieboard2_defconfig
+++ b/configs/Cubieboard2_defconfig
@@ -8,3 +8,6 @@ CONFIG_MACH_SUN7I=y
CONFIG_DRAM_CLK=480
CONFIG_DRAM_ZQ=127
CONFIG_DRAM_EMR1=4
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET=y
diff --git a/configs/Cubietruck_defconfig b/configs/Cubietruck_defconfig
index fa48331fc5..b8418f7eba 100644
--- a/configs/Cubietruck_defconfig
+++ b/configs/Cubietruck_defconfig
@@ -9,3 +9,6 @@ CONFIG_MACH_SUN7I=y
CONFIG_DRAM_CLK=432
CONFIG_DRAM_ZQ=127
CONFIG_DRAM_EMR1=4
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET=y
diff --git a/configs/Hummingbird_A31_defconfig b/configs/Hummingbird_A31_defconfig
index 7fd5a2a681..8a11e09d87 100644
--- a/configs/Hummingbird_A31_defconfig
+++ b/configs/Hummingbird_A31_defconfig
@@ -14,3 +14,6 @@ CONFIG_AXP221_ALDO1_VOLT=3300
CONFIG_USB1_VBUS_PIN="PH24"
# No Vbus gpio for usb2
CONFIG_USB2_VBUS_PIN=""
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET=y
diff --git a/configs/Linksprite_pcDuino3_Nano_defconfig b/configs/Linksprite_pcDuino3_Nano_defconfig
index 15a883aa15..9d171bd4ff 100644
--- a/configs/Linksprite_pcDuino3_Nano_defconfig
+++ b/configs/Linksprite_pcDuino3_Nano_defconfig
@@ -9,3 +9,6 @@ CONFIG_MACH_SUN7I=y
CONFIG_DRAM_CLK=408
CONFIG_DRAM_ZQ=122
CONFIG_DRAM_EMR1=4
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET=y
diff --git a/configs/Linksprite_pcDuino3_defconfig b/configs/Linksprite_pcDuino3_defconfig
index e6420695f5..e5aabdb888 100644
--- a/configs/Linksprite_pcDuino3_defconfig
+++ b/configs/Linksprite_pcDuino3_defconfig
@@ -7,3 +7,14 @@ CONFIG_MACH_SUN7I=y
CONFIG_DRAM_CLK=480
CONFIG_DRAM_ZQ=122
CONFIG_DRAM_EMR1=4
+CONFIG_DM=y
+CONFIG_DM_GPIO=y
+CONFIG_DM_SERIAL=y
+CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-pcduino3"
+CONFIG_OF_CONTROL=y
+CONFIG_SPL_DISABLE_OF_CONTROL=y
+CONFIG_OF_SEPARATE=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET=y
+CONFIG_DM_ETH=y
diff --git a/configs/Linksprite_pcDuino3_fdt_defconfig b/configs/Linksprite_pcDuino3_fdt_defconfig
deleted file mode 100644
index 7690d1e722..0000000000
--- a/configs/Linksprite_pcDuino3_fdt_defconfig
+++ /dev/null
@@ -1,15 +0,0 @@
-CONFIG_SPL=y
-CONFIG_SYS_EXTRA_OPTIONS="AXP209_POWER,SUNXI_GMAC,AHCI,SATAPWR=SUNXI_GPH(2),USB_EHCI"
-CONFIG_FDTFILE="sun7i-a20-pcduino3.dtb"
-CONFIG_DM=y
-CONFIG_DM_GPIO=y
-CONFIG_DM_SERIAL=y
-CONFIG_DEFAULT_DEVICE_TREE="sun7i-a20-pcduino3"
-CONFIG_OF_CONTROL=y
-CONFIG_OF_SEPARATE=y
-CONFIG_ARM=y
-CONFIG_ARCH_SUNXI=y
-CONFIG_MACH_SUN7I=y
-CONFIG_DRAM_CLK=480
-CONFIG_DRAM_ZQ=122
-CONFIG_DRAM_EMR1=4
diff --git a/configs/Mele_I7_defconfig b/configs/Mele_I7_defconfig
index 0e9a9500f2..e91d507f4d 100644
--- a/configs/Mele_I7_defconfig
+++ b/configs/Mele_I7_defconfig
@@ -24,3 +24,6 @@ CONFIG_AXP221_ALDO1_VOLT=3300
CONFIG_USB1_VBUS_PIN="PC27"
# No Vbus gpio for usb2
CONFIG_USB2_VBUS_PIN=""
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET=y
diff --git a/configs/Mele_M3_defconfig b/configs/Mele_M3_defconfig
index a28e0a0a45..a74dd2df25 100644
--- a/configs/Mele_M3_defconfig
+++ b/configs/Mele_M3_defconfig
@@ -10,3 +10,6 @@ CONFIG_MACH_SUN7I=y
CONFIG_DRAM_CLK=384
CONFIG_DRAM_ZQ=127
CONFIG_DRAM_EMR1=4
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET=y
diff --git a/configs/Mele_M5_defconfig b/configs/Mele_M5_defconfig
index 14423182ae..d0f0425a92 100644
--- a/configs/Mele_M5_defconfig
+++ b/configs/Mele_M5_defconfig
@@ -11,3 +11,6 @@ CONFIG_MACH_SUN7I=y
CONFIG_DRAM_CLK=432
CONFIG_DRAM_ZQ=122
CONFIG_DRAM_EMR1=4
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET=y
diff --git a/configs/Mele_M9_defconfig b/configs/Mele_M9_defconfig
index f9d4ccc415..592322d41f 100644
--- a/configs/Mele_M9_defconfig
+++ b/configs/Mele_M9_defconfig
@@ -18,3 +18,6 @@ CONFIG_AXP221_ALDO1_VOLT=3300
CONFIG_USB1_VBUS_PIN="PC27"
# No Vbus gpio for usb2
CONFIG_USB2_VBUS_PIN=""
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET=y
diff --git a/configs/Orangepi_defconfig b/configs/Orangepi_defconfig
index 0c39f70203..5bf9cacc4c 100644
--- a/configs/Orangepi_defconfig
+++ b/configs/Orangepi_defconfig
@@ -18,3 +18,6 @@ CONFIG_MACH_SUN7I=y
CONFIG_DRAM_CLK=432
CONFIG_DRAM_ZQ=127
CONFIG_DRAM_EMR1=4
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET=y
diff --git a/configs/Orangepi_mini_defconfig b/configs/Orangepi_mini_defconfig
index 733e07fa96..fce05555dd 100644
--- a/configs/Orangepi_mini_defconfig
+++ b/configs/Orangepi_mini_defconfig
@@ -21,3 +21,6 @@ CONFIG_MACH_SUN7I=y
CONFIG_DRAM_CLK=432
CONFIG_DRAM_ZQ=127
CONFIG_DRAM_EMR1=4
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET=y
diff --git a/configs/Wits_Pro_A20_DKT_defconfig b/configs/Wits_Pro_A20_DKT_defconfig
index 9147ead6b4..92c33b3995 100644
--- a/configs/Wits_Pro_A20_DKT_defconfig
+++ b/configs/Wits_Pro_A20_DKT_defconfig
@@ -13,3 +13,6 @@ CONFIG_MACH_SUN7I=y
CONFIG_DRAM_CLK=384
CONFIG_DRAM_ZQ=127
CONFIG_DRAM_EMR1=4
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET=y
diff --git a/configs/alt_defconfig b/configs/alt_defconfig
index ff872302b4..0a18409bf2 100644
--- a/configs/alt_defconfig
+++ b/configs/alt_defconfig
@@ -1,6 +1,4 @@
CONFIG_ARM=y
CONFIG_RMOBILE=y
CONFIG_TARGET_ALT=y
-CONFIG_DM=y
-CONFIG_DM_SERIAL=y
CONFIG_SH_SDHI=y
diff --git a/configs/am335x_boneblack_vboot_defconfig b/configs/am335x_boneblack_vboot_defconfig
index 0e39c7dd1a..e4ffe5f37a 100644
--- a/configs/am335x_boneblack_vboot_defconfig
+++ b/configs/am335x_boneblack_vboot_defconfig
@@ -9,4 +9,3 @@ CONFIG_DEFAULT_DEVICE_TREE="am335x-boneblack"
CONFIG_FIT=y
CONFIG_FIT_VERBOSE=y
CONFIG_FIT_SIGNATURE=y
-CONFIG_DM=y
diff --git a/configs/am3517_crane_defconfig b/configs/am3517_crane_defconfig
index 72cc2d75f0..cd16724a72 100644
--- a/configs/am3517_crane_defconfig
+++ b/configs/am3517_crane_defconfig
@@ -2,6 +2,3 @@ CONFIG_SPL=y
CONFIG_ARM=y
CONFIG_OMAP34XX=y
CONFIG_TARGET_AM3517_CRANE=y
-CONFIG_DM=n
-CONFIG_DM_SERIAL=n
-CONFIG_DM_GPIO=n
diff --git a/configs/am3517_evm_defconfig b/configs/am3517_evm_defconfig
index 6d6b0d2a8a..daf1ae4f9c 100644
--- a/configs/am3517_evm_defconfig
+++ b/configs/am3517_evm_defconfig
@@ -2,6 +2,3 @@ CONFIG_SPL=y
CONFIG_ARM=y
CONFIG_OMAP34XX=y
CONFIG_TARGET_AM3517_EVM=y
-CONFIG_DM=n
-CONFIG_DM_SERIAL=n
-CONFIG_DM_GPIO=n
diff --git a/configs/arndale_defconfig b/configs/arndale_defconfig
index 4aa14af057..21d5f4a976 100644
--- a/configs/arndale_defconfig
+++ b/configs/arndale_defconfig
@@ -3,3 +3,9 @@ CONFIG_ARM=y
CONFIG_ARCH_EXYNOS=y
CONFIG_TARGET_ARNDALE=y
CONFIG_DEFAULT_DEVICE_TREE="exynos5250-arndale"
+CONFIG_SOUND=y
+CONFIG_CMD_SOUND=y
+CONFIG_I2S=y
+CONFIG_I2S_SAMSUNG=y
+CONFIG_SOUND_MAX98095=y
+CONFIG_SOUND_WM8994=y
diff --git a/configs/axs101_defconfig b/configs/axs101_defconfig
index e5e1d8769a..c97628d606 100644
--- a/configs/axs101_defconfig
+++ b/configs/axs101_defconfig
@@ -4,3 +4,6 @@ CONFIG_ARC_CACHE_LINE_SHIFT=5
CONFIG_TARGET_AXS101=y
CONFIG_SYS_TEXT_BASE=0x81000000
CONFIG_SYS_CLK_FREQ=750000000
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET=y
diff --git a/configs/axs103_defconfig b/configs/axs103_defconfig
index 7d662add41..e92fd7c4a0 100644
--- a/configs/axs103_defconfig
+++ b/configs/axs103_defconfig
@@ -3,3 +3,6 @@ CONFIG_ISA_ARCV2=y
CONFIG_TARGET_AXS101=y
CONFIG_SYS_TEXT_BASE=0x81000000
CONFIG_SYS_CLK_FREQ=50000000
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET=y
diff --git a/configs/bf609-ezkit_defconfig b/configs/bf609-ezkit_defconfig
index 2bfb6a54bc..96f746ed5c 100644
--- a/configs/bf609-ezkit_defconfig
+++ b/configs/bf609-ezkit_defconfig
@@ -1,2 +1,5 @@
CONFIG_BLACKFIN=y
CONFIG_TARGET_BF609_EZKIT=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET=y
diff --git a/configs/birdland_bav335a_defconfig b/configs/birdland_bav335a_defconfig
index 54ac4d1024..43a4206457 100644
--- a/configs/birdland_bav335a_defconfig
+++ b/configs/birdland_bav335a_defconfig
@@ -1,8 +1,5 @@
CONFIG_ARM=y
CONFIG_TARGET_BAV335X=y
-CONFIG_DM=y
-CONFIG_DM_SERIAL=y
-CONFIG_SYS_MALLOC_F=y
CONFIG_BAV_VERSION=1
CONFIG_SPL=y
CONFIG_SYS_EXTRA_OPTIONS="SERIAL1,CONS_INDEX=1"
diff --git a/configs/birdland_bav335b_defconfig b/configs/birdland_bav335b_defconfig
index 9046553878..7206e8ee68 100644
--- a/configs/birdland_bav335b_defconfig
+++ b/configs/birdland_bav335b_defconfig
@@ -1,8 +1,5 @@
CONFIG_ARM=y
CONFIG_TARGET_BAV335X=y
-CONFIG_DM=y
-CONFIG_DM_SERIAL=y
-CONFIG_SYS_MALLOC_F=y
CONFIG_BAV_VERSION=2
CONFIG_SPL=y
CONFIG_SYS_EXTRA_OPTIONS="SERIAL1,CONS_INDEX=1"
diff --git a/configs/chromebook_link_defconfig b/configs/chromebook_link_defconfig
index 2f0c714e59..fe2610a351 100644
--- a/configs/chromebook_link_defconfig
+++ b/configs/chromebook_link_defconfig
@@ -9,3 +9,5 @@ CONFIG_SMM_TSEG_SIZE=0x800000
CONFIG_VIDEO_VESA=y
CONFIG_FRAMEBUFFER_SET_VESA_MODE=y
CONFIG_FRAMEBUFFER_VESA_MODE_11A=y
+CONFIG_DM_PCI=y
+CONFIG_CROS_EC_LPC=y
diff --git a/configs/chromebox_panther_defconfig b/configs/chromebox_panther_defconfig
new file mode 100644
index 0000000000..0613cd64a9
--- /dev/null
+++ b/configs/chromebox_panther_defconfig
@@ -0,0 +1,12 @@
+CONFIG_SYS_EXTRA_OPTIONS="SYS_TEXT_BASE=0xfff00000"
+CONFIG_X86=y
+CONFIG_TARGET_CHROMEBOX_PANTHER=y
+CONFIG_OF_CONTROL=y
+CONFIG_OF_SEPARATE=y
+CONFIG_DEFAULT_DEVICE_TREE="chromebox_panther"
+CONFIG_HAVE_MRC=y
+CONFIG_SMM_TSEG_SIZE=0x800000
+CONFIG_VIDEO_VESA=y
+CONFIG_FRAMEBUFFER_SET_VESA_MODE=y
+CONFIG_FRAMEBUFFER_VESA_MODE_11A=y
+CONFIG_DM_PCI=y
diff --git a/configs/cm_fx6_defconfig b/configs/cm_fx6_defconfig
index f10a5c2c90..c83a0e8dac 100644
--- a/configs/cm_fx6_defconfig
+++ b/configs/cm_fx6_defconfig
@@ -2,6 +2,3 @@ CONFIG_SPL=y
CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/imx-common/spl_sd.cfg,MX6QDL,SPL"
CONFIG_ARM=y
CONFIG_TARGET_CM_FX6=y
-CONFIG_DM=y
-CONFIG_DM_GPIO=y
-CONFIG_DM_SERIAL=y
diff --git a/configs/cm_t3517_defconfig b/configs/cm_t3517_defconfig
index 5c40b900c7..2d05ffb30f 100644
--- a/configs/cm_t3517_defconfig
+++ b/configs/cm_t3517_defconfig
@@ -2,6 +2,3 @@ CONFIG_SPL=n
CONFIG_ARM=y
CONFIG_OMAP34XX=y
CONFIG_TARGET_CM_T3517=y
-CONFIG_DM=n
-CONFIG_DM_SERIAL=n
-CONFIG_DM_GPIO=n
diff --git a/configs/cm_t35_defconfig b/configs/cm_t35_defconfig
index 4a99263d9b..63a85b4a22 100644
--- a/configs/cm_t35_defconfig
+++ b/configs/cm_t35_defconfig
@@ -2,6 +2,3 @@ CONFIG_SPL=y
CONFIG_ARM=y
CONFIG_OMAP34XX=y
CONFIG_TARGET_CM_T35=y
-CONFIG_DM=n
-CONFIG_DM_SERIAL=n
-CONFIG_DM_GPIO=n
diff --git a/configs/coreboot-x86_defconfig b/configs/coreboot-x86_defconfig
index 3cc034a98b..0249172feb 100644
--- a/configs/coreboot-x86_defconfig
+++ b/configs/coreboot-x86_defconfig
@@ -2,3 +2,4 @@ CONFIG_SYS_EXTRA_OPTIONS="SYS_TEXT_BASE=0x01110000"
CONFIG_X86=y
CONFIG_TARGET_COREBOOT=y
CONFIG_OF_CONTROL=y
+CONFIG_DM_PCI=y
diff --git a/configs/devkit8000_defconfig b/configs/devkit8000_defconfig
index 97564617c2..84a1a258ea 100644
--- a/configs/devkit8000_defconfig
+++ b/configs/devkit8000_defconfig
@@ -2,6 +2,3 @@ CONFIG_SPL=y
CONFIG_ARM=y
CONFIG_OMAP34XX=y
CONFIG_TARGET_DEVKIT8000=y
-CONFIG_DM=y
-CONFIG_DM_SERIAL=y
-CONFIG_DM_GPIO=y
diff --git a/configs/dig297_defconfig b/configs/dig297_defconfig
index 0d182900f9..95bc353926 100644
--- a/configs/dig297_defconfig
+++ b/configs/dig297_defconfig
@@ -1,6 +1,3 @@
CONFIG_ARM=y
CONFIG_OMAP34XX=y
CONFIG_TARGET_DIG297=y
-CONFIG_DM=n
-CONFIG_DM_SERIAL=n
-CONFIG_DM_GPIO=n
diff --git a/configs/eco5pk_defconfig b/configs/eco5pk_defconfig
index fbe6335a88..8587c51911 100644
--- a/configs/eco5pk_defconfig
+++ b/configs/eco5pk_defconfig
@@ -2,6 +2,3 @@ CONFIG_SPL=y
CONFIG_ARM=y
CONFIG_OMAP34XX=y
CONFIG_TARGET_ECO5PK=y
-CONFIG_DM=n
-CONFIG_DM_SERIAL=n
-CONFIG_DM_GPIO=n
diff --git a/configs/galileo_defconfig b/configs/galileo_defconfig
index f2086514be..9b0f969c53 100644
--- a/configs/galileo_defconfig
+++ b/configs/galileo_defconfig
@@ -4,3 +4,6 @@ CONFIG_TARGET_GALILEO=y
CONFIG_OF_CONTROL=y
CONFIG_OF_SEPARATE=y
CONFIG_DEFAULT_DEVICE_TREE="galileo"
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET=y
diff --git a/configs/gose_defconfig b/configs/gose_defconfig
index 353f854a40..b6054f711a 100644
--- a/configs/gose_defconfig
+++ b/configs/gose_defconfig
@@ -1,6 +1,4 @@
CONFIG_ARM=y
CONFIG_RMOBILE=y
CONFIG_TARGET_GOSE=y
-CONFIG_DM=y
-CONFIG_DM_SERIAL=y
CONFIG_SH_SDHI=y
diff --git a/configs/i12-tvbox_defconfig b/configs/i12-tvbox_defconfig
index 157997f001..b10f4d0e76 100644
--- a/configs/i12-tvbox_defconfig
+++ b/configs/i12-tvbox_defconfig
@@ -7,3 +7,6 @@ CONFIG_MACH_SUN7I=y
CONFIG_DRAM_CLK=384
CONFIG_DRAM_ZQ=127
CONFIG_DRAM_EMR1=4
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET=y
diff --git a/configs/ids8313_defconfig b/configs/ids8313_defconfig
index 0950ec8b77..8479cd42f7 100644
--- a/configs/ids8313_defconfig
+++ b/configs/ids8313_defconfig
@@ -4,4 +4,3 @@ CONFIG_MPC83xx=y
CONFIG_FIT=y
CONFIG_FIT_SIGNATURE=y
CONFIG_TARGET_IDS8313=y
-CONFIG_DM=y
diff --git a/configs/koelsch_defconfig b/configs/koelsch_defconfig
index b1e35299f5..7ab2bfd213 100644
--- a/configs/koelsch_defconfig
+++ b/configs/koelsch_defconfig
@@ -1,6 +1,4 @@
CONFIG_ARM=y
CONFIG_RMOBILE=y
CONFIG_TARGET_KOELSCH=y
-CONFIG_DM=y
-CONFIG_DM_SERIAL=y
CONFIG_SH_SDHI=y
diff --git a/configs/lager_defconfig b/configs/lager_defconfig
index 950b037eb8..08adfe3654 100644
--- a/configs/lager_defconfig
+++ b/configs/lager_defconfig
@@ -1,6 +1,4 @@
CONFIG_ARM=y
CONFIG_RMOBILE=y
CONFIG_TARGET_LAGER=y
-CONFIG_DM=y
-CONFIG_DM_SERIAL=y
CONFIG_SH_SDHI=y
diff --git a/configs/mcx_defconfig b/configs/mcx_defconfig
index 2f6185879b..4abf34d3c5 100644
--- a/configs/mcx_defconfig
+++ b/configs/mcx_defconfig
@@ -2,6 +2,3 @@ CONFIG_SPL=y
CONFIG_ARM=y
CONFIG_OMAP34XX=y
CONFIG_TARGET_MCX=y
-CONFIG_DM=n
-CONFIG_DM_SERIAL=n
-CONFIG_DM_GPIO=n
diff --git a/configs/mixtile_loftq_defconfig b/configs/mixtile_loftq_defconfig
index 47453cd362..8275df8462 100644
--- a/configs/mixtile_loftq_defconfig
+++ b/configs/mixtile_loftq_defconfig
@@ -19,3 +19,6 @@ CONFIG_AXP221_ALDO1_VOLT=3300
CONFIG_USB1_VBUS_PIN="PH24"
# No Vbus gpio for usb2
CONFIG_USB2_VBUS_PIN=""
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET=y
diff --git a/configs/mt_ventoux_defconfig b/configs/mt_ventoux_defconfig
index 5b1da8c30d..fd4f649c9a 100644
--- a/configs/mt_ventoux_defconfig
+++ b/configs/mt_ventoux_defconfig
@@ -2,6 +2,3 @@ CONFIG_SPL=y
CONFIG_ARM=y
CONFIG_OMAP34XX=y
CONFIG_TARGET_MT_VENTOUX=y
-CONFIG_DM=n
-CONFIG_DM_SERIAL=n
-CONFIG_DM_GPIO=n
diff --git a/configs/mx6dlsabreauto_defconfig b/configs/mx6dlsabreauto_defconfig
index 8bc5e8be8b..b649935912 100644
--- a/configs/mx6dlsabreauto_defconfig
+++ b/configs/mx6dlsabreauto_defconfig
@@ -1,5 +1,3 @@
CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/freescale/mx6qsabreauto/mx6dl.cfg,MX6DL"
CONFIG_ARM=y
CONFIG_TARGET_MX6QSABREAUTO=y
-CONFIG_DM=y
-CONFIG_DM_THERMAL=y
diff --git a/configs/mx6dlsabresd_defconfig b/configs/mx6dlsabresd_defconfig
index cde0d705a5..b333e59ba5 100644
--- a/configs/mx6dlsabresd_defconfig
+++ b/configs/mx6dlsabresd_defconfig
@@ -3,5 +3,3 @@ CONFIG_ARM=y
CONFIG_TARGET_MX6SABRESD=y
CONFIG_SYS_MALLOC_F=y
CONFIG_SYS_MALLOC_F_LEN=0x400
-CONFIG_DM=y
-CONFIG_DM_THERMAL=y
diff --git a/configs/mx6qsabreauto_defconfig b/configs/mx6qsabreauto_defconfig
index ba9e512b4e..7d86700b30 100644
--- a/configs/mx6qsabreauto_defconfig
+++ b/configs/mx6qsabreauto_defconfig
@@ -1,5 +1,3 @@
CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/freescale/mx6qsabreauto/imximage.cfg,MX6Q"
CONFIG_ARM=y
CONFIG_TARGET_MX6QSABREAUTO=y
-CONFIG_DM=y
-CONFIG_DM_THERMAL=y
diff --git a/configs/mx6qsabresd_defconfig b/configs/mx6qsabresd_defconfig
index 1764b39207..67c1b77e05 100644
--- a/configs/mx6qsabresd_defconfig
+++ b/configs/mx6qsabresd_defconfig
@@ -1,5 +1,3 @@
CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/freescale/mx6sabresd/mx6q_4x_mt41j128.cfg,MX6Q"
CONFIG_ARM=y
CONFIG_TARGET_MX6SABRESD=y
-CONFIG_DM=y
-CONFIG_DM_THERMAL=y
diff --git a/configs/mx6sabresd_spl_defconfig b/configs/mx6sabresd_spl_defconfig
index 16a947e843..7f563cd58f 100644
--- a/configs/mx6sabresd_spl_defconfig
+++ b/configs/mx6sabresd_spl_defconfig
@@ -2,5 +2,3 @@ CONFIG_SPL=y
CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/imx-common/spl_sd.cfg,SPL,MX6Q"
CONFIG_ARM=y
CONFIG_TARGET_MX6SABRESD=y
-CONFIG_DM=y
-CONFIG_DM_THERMAL=y
diff --git a/configs/mx6sxsabresd_defconfig b/configs/mx6sxsabresd_defconfig
index 5c862cf11e..f23d48f361 100644
--- a/configs/mx6sxsabresd_defconfig
+++ b/configs/mx6sxsabresd_defconfig
@@ -1,5 +1,3 @@
CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=board/freescale/mx6sxsabresd/imximage.cfg,MX6SX"
CONFIG_ARM=y
CONFIG_TARGET_MX6SXSABRESD=y
-CONFIG_DM=y
-CONFIG_DM_THERMAL=y
diff --git a/configs/mx6sxsabresd_spl_defconfig b/configs/mx6sxsabresd_spl_defconfig
index de3d98fc89..b5e0635920 100644
--- a/configs/mx6sxsabresd_spl_defconfig
+++ b/configs/mx6sxsabresd_spl_defconfig
@@ -2,5 +2,3 @@ CONFIG_SPL=y
CONFIG_SYS_EXTRA_OPTIONS="IMX_CONFIG=arch/arm/imx-common/spl_sd.cfg,MX6SX"
CONFIG_ARM=y
CONFIG_TARGET_MX6SXSABRESD=y
-CONFIG_DM=y
-CONFIG_DM_THERMAL=y
diff --git a/configs/nokia_rx51_defconfig b/configs/nokia_rx51_defconfig
index 20a51e1d2f..e03f586880 100644
--- a/configs/nokia_rx51_defconfig
+++ b/configs/nokia_rx51_defconfig
@@ -1,6 +1,3 @@
CONFIG_ARM=y
CONFIG_OMAP34XX=y
CONFIG_TARGET_NOKIA_RX51=y
-CONFIG_DM=n
-CONFIG_DM_SERIAL=n
-CONFIG_DM_GPIO=n
diff --git a/configs/omap3_beagle_defconfig b/configs/omap3_beagle_defconfig
index 51068210d6..2a3cc66166 100644
--- a/configs/omap3_beagle_defconfig
+++ b/configs/omap3_beagle_defconfig
@@ -3,6 +3,3 @@ CONFIG_SYS_EXTRA_OPTIONS="NAND"
CONFIG_ARM=y
CONFIG_OMAP34XX=y
CONFIG_TARGET_OMAP3_BEAGLE=y
-CONFIG_DM=y
-CONFIG_DM_GPIO=y
-CONFIG_DM_SERIAL=y
diff --git a/configs/omap3_evm_defconfig b/configs/omap3_evm_defconfig
index fb4a80092a..91c290b17b 100644
--- a/configs/omap3_evm_defconfig
+++ b/configs/omap3_evm_defconfig
@@ -2,6 +2,3 @@ CONFIG_SPL=y
CONFIG_ARM=y
CONFIG_OMAP34XX=y
CONFIG_TARGET_OMAP3_EVM=y
-CONFIG_DM=n
-CONFIG_DM_SERIAL=n
-CONFIG_DM_GPIO=n
diff --git a/configs/omap3_evm_quick_mmc_defconfig b/configs/omap3_evm_quick_mmc_defconfig
index d4594cb2c0..12005bf620 100644
--- a/configs/omap3_evm_quick_mmc_defconfig
+++ b/configs/omap3_evm_quick_mmc_defconfig
@@ -2,6 +2,3 @@ CONFIG_SPL=y
CONFIG_ARM=y
CONFIG_OMAP34XX=y
CONFIG_TARGET_OMAP3_EVM_QUICK_MMC=y
-CONFIG_DM=n
-CONFIG_DM_SERIAL=n
-CONFIG_DM_GPIO=n
diff --git a/configs/omap3_evm_quick_nand_defconfig b/configs/omap3_evm_quick_nand_defconfig
index 1a78a6e491..5cc9512a77 100644
--- a/configs/omap3_evm_quick_nand_defconfig
+++ b/configs/omap3_evm_quick_nand_defconfig
@@ -2,6 +2,3 @@ CONFIG_SPL=y
CONFIG_ARM=y
CONFIG_OMAP34XX=y
CONFIG_TARGET_OMAP3_EVM_QUICK_NAND=y
-CONFIG_DM=n
-CONFIG_DM_SERIAL=n
-CONFIG_DM_GPIO=n
diff --git a/configs/omap3_ha_defconfig b/configs/omap3_ha_defconfig
index 344eca5db8..250890b005 100644
--- a/configs/omap3_ha_defconfig
+++ b/configs/omap3_ha_defconfig
@@ -3,6 +3,3 @@ CONFIG_SYS_EXTRA_OPTIONS="SYS_BOARD_OMAP3_HA"
CONFIG_ARM=y
CONFIG_OMAP34XX=y
CONFIG_TARGET_TAO3530=y
-CONFIG_DM=n
-CONFIG_DM_SERIAL=n
-CONFIG_DM_GPIO=n
diff --git a/configs/omap3_logic_defconfig b/configs/omap3_logic_defconfig
index 790ccbaa34..5f2c063b6e 100644
--- a/configs/omap3_logic_defconfig
+++ b/configs/omap3_logic_defconfig
@@ -1,6 +1,3 @@
CONFIG_ARM=y
CONFIG_OMAP34XX=y
CONFIG_TARGET_OMAP3_LOGIC=y
-CONFIG_DM=n
-CONFIG_DM_SERIAL=n
-CONFIG_DM_GPIO=n
diff --git a/configs/omap3_mvblx_defconfig b/configs/omap3_mvblx_defconfig
index b75f51323e..fb6edc252a 100644
--- a/configs/omap3_mvblx_defconfig
+++ b/configs/omap3_mvblx_defconfig
@@ -1,6 +1,3 @@
CONFIG_ARM=y
CONFIG_OMAP34XX=y
CONFIG_TARGET_OMAP3_MVBLX=y
-CONFIG_DM=n
-CONFIG_DM_SERIAL=n
-CONFIG_DM_GPIO=n
diff --git a/configs/omap3_pandora_defconfig b/configs/omap3_pandora_defconfig
index dd0f17c20c..bf285378a3 100644
--- a/configs/omap3_pandora_defconfig
+++ b/configs/omap3_pandora_defconfig
@@ -1,6 +1,3 @@
CONFIG_ARM=y
CONFIG_OMAP34XX=y
CONFIG_TARGET_OMAP3_PANDORA=y
-CONFIG_DM=n
-CONFIG_DM_SERIAL=n
-CONFIG_DM_GPIO=n
diff --git a/configs/omap3_sdp3430_defconfig b/configs/omap3_sdp3430_defconfig
index b3a8745a02..1172c2adc5 100644
--- a/configs/omap3_sdp3430_defconfig
+++ b/configs/omap3_sdp3430_defconfig
@@ -1,6 +1,3 @@
CONFIG_ARM=y
CONFIG_OMAP34XX=y
CONFIG_TARGET_OMAP3_SDP3430=y
-CONFIG_DM=n
-CONFIG_DM_SERIAL=n
-CONFIG_DM_GPIO=n
diff --git a/configs/ph1_ld4_defconfig b/configs/ph1_ld4_defconfig
index aa1805b665..036e2d1c69 100644
--- a/configs/ph1_ld4_defconfig
+++ b/configs/ph1_ld4_defconfig
@@ -1,9 +1,6 @@
CONFIG_ARM=y
CONFIG_ARCH_UNIPHIER=y
-CONFIG_DM=y
-CONFIG_DM_SERIAL=y
CONFIG_SPL_DM=y
-CONFIG_DM_I2C=y
CONFIG_MACH_PH1_LD4=y
CONFIG_PFC_MICRO_SUPPORT_CARD=y
CONFIG_DEFAULT_DEVICE_TREE="uniphier-ph1-ld4-ref"
diff --git a/configs/ph1_pro4_defconfig b/configs/ph1_pro4_defconfig
index 194f7a5c58..9a010ee913 100644
--- a/configs/ph1_pro4_defconfig
+++ b/configs/ph1_pro4_defconfig
@@ -1,9 +1,6 @@
CONFIG_ARM=y
CONFIG_ARCH_UNIPHIER=y
-CONFIG_DM=y
-CONFIG_DM_SERIAL=y
CONFIG_SPL_DM=y
-CONFIG_DM_I2C=y
CONFIG_MACH_PH1_PRO4=y
CONFIG_PFC_MICRO_SUPPORT_CARD=y
CONFIG_DEFAULT_DEVICE_TREE="uniphier-ph1-pro4-ref"
diff --git a/configs/ph1_sld8_defconfig b/configs/ph1_sld8_defconfig
index e7e7ffff0b..29fe0e8063 100644
--- a/configs/ph1_sld8_defconfig
+++ b/configs/ph1_sld8_defconfig
@@ -1,9 +1,6 @@
CONFIG_ARM=y
CONFIG_ARCH_UNIPHIER=y
-CONFIG_DM=y
-CONFIG_DM_SERIAL=y
CONFIG_SPL_DM=y
-CONFIG_DM_I2C=y
CONFIG_MACH_PH1_SLD8=y
CONFIG_PFC_MICRO_SUPPORT_CARD=y
CONFIG_DEFAULT_DEVICE_TREE="uniphier-ph1-sld8-ref"
diff --git a/configs/porter_defconfig b/configs/porter_defconfig
index 8d594d97df..a7b044e452 100644
--- a/configs/porter_defconfig
+++ b/configs/porter_defconfig
@@ -1,6 +1,4 @@
CONFIG_ARM=y
CONFIG_RMOBILE=y
CONFIG_TARGET_PORTER=y
-CONFIG_DM=y
-CONFIG_DM_SERIAL=y
CONFIG_SH_SDHI=y
diff --git a/configs/sandbox_defconfig b/configs/sandbox_defconfig
index a216039ab2..5de7fbedb4 100644
--- a/configs/sandbox_defconfig
+++ b/configs/sandbox_defconfig
@@ -3,10 +3,26 @@ CONFIG_OF_HOSTFILE=y
CONFIG_FIT=y
CONFIG_FIT_VERBOSE=y
CONFIG_FIT_SIGNATURE=y
-CONFIG_DM=y
CONFIG_DEFAULT_DEVICE_TREE="sandbox"
CONFIG_CROS_EC=y
-CONFIG_DM_CROS_EC=y
CONFIG_CROS_EC_SANDBOX=y
CONFIG_CROS_EC_KEYB=y
CONFIG_CMD_CROS_EC=y
+CONFIG_PCI=y
+CONFIG_DM_PCI=y
+CONFIG_PCI_SANDBOX=y
+CONFIG_USB=y
+CONFIG_DM_USB=y
+CONFIG_USB_EMUL=y
+CONFIG_USB_STORAGE=y
+CONFIG_BOOTSTAGE=y
+CONFIG_BOOTSTAGE_REPORT=y
+CONFIG_SANDBOX_GPIO=y
+CONFIG_SYS_VSNPRINTF=y
+CONFIG_SYS_I2C_SANDBOX=y
+CONFIG_SANDBOX_SPI=y
+CONFIG_SPI_FLASH_SANDBOX=y
+CONFIG_TPM_TIS_SANDBOX=y
+CONFIG_SOUND=y
+CONFIG_CMD_SOUND=y
+CONFIG_SOUND_SANDBOX=y
diff --git a/configs/silk_defconfig b/configs/silk_defconfig
index 23d4f5849c..3c6f16ec00 100644
--- a/configs/silk_defconfig
+++ b/configs/silk_defconfig
@@ -1,6 +1,4 @@
CONFIG_ARM=y
CONFIG_RMOBILE=y
CONFIG_TARGET_SILK=y
-CONFIG_DM=y
-CONFIG_DM_SERIAL=y
CONFIG_SH_SDHI=y
diff --git a/configs/smdk5250_defconfig b/configs/smdk5250_defconfig
index efc738bfeb..0e7b868496 100644
--- a/configs/smdk5250_defconfig
+++ b/configs/smdk5250_defconfig
@@ -3,3 +3,9 @@ CONFIG_ARM=y
CONFIG_ARCH_EXYNOS=y
CONFIG_TARGET_SMDK5250=y
CONFIG_DEFAULT_DEVICE_TREE="exynos5250-smdk5250"
+CONFIG_SOUND=y
+CONFIG_CMD_SOUND=y
+CONFIG_I2S=y
+CONFIG_I2S_SAMSUNG=y
+CONFIG_SOUND_MAX98095=y
+CONFIG_SOUND_WM8994=y
diff --git a/configs/snapper9260_defconfig b/configs/snapper9260_defconfig
index 576d9c51aa..5c8850af95 100644
--- a/configs/snapper9260_defconfig
+++ b/configs/snapper9260_defconfig
@@ -2,6 +2,3 @@ CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9260"
CONFIG_ARM=y
CONFIG_ARCH_AT91=y
CONFIG_TARGET_SNAPPER9260=y
-CONFIG_DM=y
-CONFIG_DM_GPIO=y
-CONFIG_DM_SERIAL=y
diff --git a/configs/snapper9g20_defconfig b/configs/snapper9g20_defconfig
index 07a26434dc..9270b8df01 100644
--- a/configs/snapper9g20_defconfig
+++ b/configs/snapper9g20_defconfig
@@ -2,6 +2,3 @@ CONFIG_SYS_EXTRA_OPTIONS="AT91SAM9G20"
CONFIG_ARM=y
CONFIG_ARCH_AT91=y
CONFIG_TARGET_SNAPPER9260=y
-CONFIG_DM=y
-CONFIG_DM_GPIO=y
-CONFIG_DM_SERIAL=y
diff --git a/configs/snow_defconfig b/configs/snow_defconfig
index 2b0d6faf98..6c76f4d4bf 100644
--- a/configs/snow_defconfig
+++ b/configs/snow_defconfig
@@ -4,7 +4,12 @@ CONFIG_ARCH_EXYNOS=y
CONFIG_TARGET_SNOW=y
CONFIG_DEFAULT_DEVICE_TREE="exynos5250-snow"
CONFIG_CROS_EC=y
-CONFIG_DM_CROS_EC=y
CONFIG_CROS_EC_I2C=y
CONFIG_CROS_EC_KEYB=y
CONFIG_CMD_CROS_EC=y
+CONFIG_SOUND=y
+CONFIG_CMD_SOUND=y
+CONFIG_I2S=y
+CONFIG_I2S_SAMSUNG=y
+CONFIG_SOUND_MAX98095=y
+CONFIG_SOUND_WM8994=y
diff --git a/configs/socfpga_arria5_defconfig b/configs/socfpga_arria5_defconfig
index 87d6007f0d..52032e523e 100644
--- a/configs/socfpga_arria5_defconfig
+++ b/configs/socfpga_arria5_defconfig
@@ -3,6 +3,3 @@ CONFIG_ARM=y
CONFIG_TARGET_SOCFPGA_ARRIA5=y
CONFIG_OF_CONTROL=y
CONFIG_DEFAULT_DEVICE_TREE="socfpga_arria5_socdk"
-CONFIG_DM=y
-CONFIG_DM_SPI=y
-CONFIG_DM_SPI_FLASH=y
diff --git a/configs/socfpga_cyclone5_defconfig b/configs/socfpga_cyclone5_defconfig
index 0ebfbfcece..6c982abb03 100644
--- a/configs/socfpga_cyclone5_defconfig
+++ b/configs/socfpga_cyclone5_defconfig
@@ -3,6 +3,6 @@ CONFIG_ARM=y
CONFIG_TARGET_SOCFPGA_CYCLONE5=y
CONFIG_OF_CONTROL=y
CONFIG_DEFAULT_DEVICE_TREE="socfpga_cyclone5_socdk"
-CONFIG_DM=y
-CONFIG_DM_SPI=y
-CONFIG_DM_SPI_FLASH=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET=y
diff --git a/configs/socfpga_socrates_defconfig b/configs/socfpga_socrates_defconfig
index 873b721ead..c81ab0fa8d 100644
--- a/configs/socfpga_socrates_defconfig
+++ b/configs/socfpga_socrates_defconfig
@@ -3,6 +3,6 @@ CONFIG_ARM=y
CONFIG_TARGET_SOCFPGA_CYCLONE5=y
CONFIG_OF_CONTROL=y
CONFIG_DEFAULT_DEVICE_TREE="socfpga_cyclone5_socrates"
-CONFIG_DM=y
-CONFIG_DM_SPI=y
-CONFIG_DM_SPI_FLASH=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET=y
diff --git a/configs/spear300_defconfig b/configs/spear300_defconfig
index 25a08df34e..df0b1907f8 100644
--- a/configs/spear300_defconfig
+++ b/configs/spear300_defconfig
@@ -1,3 +1,6 @@
CONFIG_SYS_EXTRA_OPTIONS="spear300"
CONFIG_ARM=y
CONFIG_TARGET_SPEAR300=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET=y
diff --git a/configs/spear300_nand_defconfig b/configs/spear300_nand_defconfig
index a4b70e8090..a49492c783 100644
--- a/configs/spear300_nand_defconfig
+++ b/configs/spear300_nand_defconfig
@@ -1,3 +1,6 @@
CONFIG_SYS_EXTRA_OPTIONS="spear300,nand"
CONFIG_ARM=y
CONFIG_TARGET_SPEAR300=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET=y
diff --git a/configs/spear300_usbtty_defconfig b/configs/spear300_usbtty_defconfig
index d750cf49d7..3d60d7f36f 100644
--- a/configs/spear300_usbtty_defconfig
+++ b/configs/spear300_usbtty_defconfig
@@ -1,3 +1,6 @@
CONFIG_SYS_EXTRA_OPTIONS="spear300,usbtty"
CONFIG_ARM=y
CONFIG_TARGET_SPEAR300=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET=y
diff --git a/configs/spear300_usbtty_nand_defconfig b/configs/spear300_usbtty_nand_defconfig
index 8bafdb5396..ffe4f5951b 100644
--- a/configs/spear300_usbtty_nand_defconfig
+++ b/configs/spear300_usbtty_nand_defconfig
@@ -1,3 +1,6 @@
CONFIG_SYS_EXTRA_OPTIONS="spear300,usbtty,nand"
CONFIG_ARM=y
CONFIG_TARGET_SPEAR300=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET=y
diff --git a/configs/spear310_defconfig b/configs/spear310_defconfig
index 8a9ec859a0..16a6bc3a57 100644
--- a/configs/spear310_defconfig
+++ b/configs/spear310_defconfig
@@ -1,3 +1,6 @@
CONFIG_SYS_EXTRA_OPTIONS="spear310"
CONFIG_ARM=y
CONFIG_TARGET_SPEAR310=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET=y
diff --git a/configs/spear310_nand_defconfig b/configs/spear310_nand_defconfig
index 1439ac53d2..05e3c966d1 100644
--- a/configs/spear310_nand_defconfig
+++ b/configs/spear310_nand_defconfig
@@ -1,3 +1,6 @@
CONFIG_SYS_EXTRA_OPTIONS="spear310,nand"
CONFIG_ARM=y
CONFIG_TARGET_SPEAR310=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET=y
diff --git a/configs/spear310_pnor_defconfig b/configs/spear310_pnor_defconfig
index 19604b3fed..384cb541c0 100644
--- a/configs/spear310_pnor_defconfig
+++ b/configs/spear310_pnor_defconfig
@@ -1,3 +1,6 @@
CONFIG_SYS_EXTRA_OPTIONS="spear310,FLASH_PNOR"
CONFIG_ARM=y
CONFIG_TARGET_SPEAR310=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET=y
diff --git a/configs/spear310_usbtty_defconfig b/configs/spear310_usbtty_defconfig
index 6342a56512..0115f2cabe 100644
--- a/configs/spear310_usbtty_defconfig
+++ b/configs/spear310_usbtty_defconfig
@@ -1,3 +1,6 @@
CONFIG_SYS_EXTRA_OPTIONS="spear310,usbtty"
CONFIG_ARM=y
CONFIG_TARGET_SPEAR310=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET=y
diff --git a/configs/spear310_usbtty_nand_defconfig b/configs/spear310_usbtty_nand_defconfig
index 5b9f1f6d70..2d82b66c06 100644
--- a/configs/spear310_usbtty_nand_defconfig
+++ b/configs/spear310_usbtty_nand_defconfig
@@ -1,3 +1,6 @@
CONFIG_SYS_EXTRA_OPTIONS="spear310,usbtty,nand"
CONFIG_ARM=y
CONFIG_TARGET_SPEAR310=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET=y
diff --git a/configs/spear310_usbtty_pnor_defconfig b/configs/spear310_usbtty_pnor_defconfig
index 0567936ac6..579df36631 100644
--- a/configs/spear310_usbtty_pnor_defconfig
+++ b/configs/spear310_usbtty_pnor_defconfig
@@ -1,3 +1,6 @@
CONFIG_SYS_EXTRA_OPTIONS="spear310,usbtty,FLASH_PNOR"
CONFIG_ARM=y
CONFIG_TARGET_SPEAR310=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET=y
diff --git a/configs/spear320_defconfig b/configs/spear320_defconfig
index 3d91bb186e..7bd51a8d05 100644
--- a/configs/spear320_defconfig
+++ b/configs/spear320_defconfig
@@ -1,3 +1,6 @@
CONFIG_SYS_EXTRA_OPTIONS="spear320"
CONFIG_ARM=y
CONFIG_TARGET_SPEAR320=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET=y
diff --git a/configs/spear320_nand_defconfig b/configs/spear320_nand_defconfig
index fd0f908d3a..d7c995c2df 100644
--- a/configs/spear320_nand_defconfig
+++ b/configs/spear320_nand_defconfig
@@ -1,3 +1,6 @@
CONFIG_SYS_EXTRA_OPTIONS="spear320,nand"
CONFIG_ARM=y
CONFIG_TARGET_SPEAR320=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET=y
diff --git a/configs/spear320_pnor_defconfig b/configs/spear320_pnor_defconfig
index 6cce316460..a56a4e079b 100644
--- a/configs/spear320_pnor_defconfig
+++ b/configs/spear320_pnor_defconfig
@@ -1,3 +1,6 @@
CONFIG_SYS_EXTRA_OPTIONS="spear320,FLASH_PNOR"
CONFIG_ARM=y
CONFIG_TARGET_SPEAR320=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET=y
diff --git a/configs/spear320_usbtty_defconfig b/configs/spear320_usbtty_defconfig
index 7ad3d8413e..c2fb481819 100644
--- a/configs/spear320_usbtty_defconfig
+++ b/configs/spear320_usbtty_defconfig
@@ -1,3 +1,6 @@
CONFIG_SYS_EXTRA_OPTIONS="spear320,usbtty"
CONFIG_ARM=y
CONFIG_TARGET_SPEAR320=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET=y
diff --git a/configs/spear320_usbtty_nand_defconfig b/configs/spear320_usbtty_nand_defconfig
index a5ad90bb05..98368ed190 100644
--- a/configs/spear320_usbtty_nand_defconfig
+++ b/configs/spear320_usbtty_nand_defconfig
@@ -1,3 +1,6 @@
CONFIG_SYS_EXTRA_OPTIONS="spear320,usbtty,nand"
CONFIG_ARM=y
CONFIG_TARGET_SPEAR320=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET=y
diff --git a/configs/spear320_usbtty_pnor_defconfig b/configs/spear320_usbtty_pnor_defconfig
index 6b110ef97a..e428d25441 100644
--- a/configs/spear320_usbtty_pnor_defconfig
+++ b/configs/spear320_usbtty_pnor_defconfig
@@ -1,3 +1,6 @@
CONFIG_SYS_EXTRA_OPTIONS="spear320,usbtty,FLASH_PNOR"
CONFIG_ARM=y
CONFIG_TARGET_SPEAR320=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET=y
diff --git a/configs/spear600_defconfig b/configs/spear600_defconfig
index f1cb0aa17a..dae0d59581 100644
--- a/configs/spear600_defconfig
+++ b/configs/spear600_defconfig
@@ -1,3 +1,6 @@
CONFIG_SYS_EXTRA_OPTIONS="spear600"
CONFIG_ARM=y
CONFIG_TARGET_SPEAR600=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET=y
diff --git a/configs/spear600_nand_defconfig b/configs/spear600_nand_defconfig
index 172c187f07..cdd98fc50d 100644
--- a/configs/spear600_nand_defconfig
+++ b/configs/spear600_nand_defconfig
@@ -1,3 +1,6 @@
CONFIG_SYS_EXTRA_OPTIONS="spear600,nand"
CONFIG_ARM=y
CONFIG_TARGET_SPEAR600=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET=y
diff --git a/configs/spear600_usbtty_defconfig b/configs/spear600_usbtty_defconfig
index cf8b0ec847..1e28edfc2e 100644
--- a/configs/spear600_usbtty_defconfig
+++ b/configs/spear600_usbtty_defconfig
@@ -1,3 +1,6 @@
CONFIG_SYS_EXTRA_OPTIONS="spear600,usbtty"
CONFIG_ARM=y
CONFIG_TARGET_SPEAR600=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET=y
diff --git a/configs/spear600_usbtty_nand_defconfig b/configs/spear600_usbtty_nand_defconfig
index 8bd2f0776f..2f8fd5ead3 100644
--- a/configs/spear600_usbtty_nand_defconfig
+++ b/configs/spear600_usbtty_nand_defconfig
@@ -1,3 +1,6 @@
CONFIG_SYS_EXTRA_OPTIONS="spear600,usbtty,nand"
CONFIG_ARM=y
CONFIG_TARGET_SPEAR600=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET=y
diff --git a/configs/stv0991_defconfig b/configs/stv0991_defconfig
index e8cf311eb5..76ba41bf5f 100644
--- a/configs/stv0991_defconfig
+++ b/configs/stv0991_defconfig
@@ -2,5 +2,6 @@ CONFIG_SYS_EXTRA_OPTIONS="stv0991"
CONFIG_ARM=y
CONFIG_TARGET_STV0991=y
CONFIG_SYS_MALLOC_F_LEN=0x2000
-CONFIG_DM=y
-CONFIG_DM_SERIAL=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET=y
diff --git a/configs/tao3530_defconfig b/configs/tao3530_defconfig
index 077dc892d6..86ba4cd37a 100644
--- a/configs/tao3530_defconfig
+++ b/configs/tao3530_defconfig
@@ -2,6 +2,3 @@ CONFIG_SPL=y
CONFIG_ARM=y
CONFIG_OMAP34XX=y
CONFIG_TARGET_TAO3530=y
-CONFIG_DM=n
-CONFIG_DM_SERIAL=n
-CONFIG_DM_GPIO=n
diff --git a/configs/tb100_defconfig b/configs/tb100_defconfig
index 59f09d9f64..aed9210eff 100644
--- a/configs/tb100_defconfig
+++ b/configs/tb100_defconfig
@@ -8,3 +8,6 @@ CONFIG_SYS_TEXT_BASE=0x84000000
CONFIG_SYS_CLK_FREQ=500000000
CONFIG_OF_CONTROL=y
CONFIG_OF_EMBED=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET=y
diff --git a/configs/tricorder_defconfig b/configs/tricorder_defconfig
index 745ebc83a5..e307c65d66 100644
--- a/configs/tricorder_defconfig
+++ b/configs/tricorder_defconfig
@@ -2,6 +2,3 @@ CONFIG_SPL=y
CONFIG_ARM=y
CONFIG_OMAP34XX=y
CONFIG_TARGET_TRICORDER=y
-CONFIG_DM=n
-CONFIG_DM_SERIAL=n
-CONFIG_DM_GPIO=n
diff --git a/configs/tricorder_flash_defconfig b/configs/tricorder_flash_defconfig
index cc935669e8..de6c16e725 100644
--- a/configs/tricorder_flash_defconfig
+++ b/configs/tricorder_flash_defconfig
@@ -3,6 +3,3 @@ CONFIG_SYS_EXTRA_OPTIONS="FLASHCARD"
CONFIG_ARM=y
CONFIG_OMAP34XX=y
CONFIG_TARGET_TRICORDER=y
-CONFIG_DM=n
-CONFIG_DM_SERIAL=n
-CONFIG_DM_GPIO=n
diff --git a/configs/twister_defconfig b/configs/twister_defconfig
index 5e7250ab99..344369d34a 100644
--- a/configs/twister_defconfig
+++ b/configs/twister_defconfig
@@ -2,6 +2,3 @@ CONFIG_SPL=y
CONFIG_ARM=y
CONFIG_OMAP34XX=y
CONFIG_TARGET_TWISTER=y
-CONFIG_DM=n
-CONFIG_DM_SERIAL=n
-CONFIG_DM_GPIO=n
diff --git a/configs/x600_defconfig b/configs/x600_defconfig
index c8bec6791e..7cd239b785 100644
--- a/configs/x600_defconfig
+++ b/configs/x600_defconfig
@@ -1,3 +1,6 @@
CONFIG_SPL=y
CONFIG_ARM=y
CONFIG_TARGET_X600=y
+CONFIG_ETH_DESIGNWARE=y
+CONFIG_NETDEVICES=y
+CONFIG_NET=y
diff --git a/configs/zynq_microzed_defconfig b/configs/zynq_microzed_defconfig
index b6bca82db0..95cfe8938d 100644
--- a/configs/zynq_microzed_defconfig
+++ b/configs/zynq_microzed_defconfig
@@ -7,5 +7,4 @@ CONFIG_OF_CONTROL=y
CONFIG_FIT=y
CONFIG_FIT_VERBOSE=y
CONFIG_FIT_SIGNATURE=y
-CONFIG_DM=y
CONFIG_DEFAULT_DEVICE_TREE="zynq-microzed"
diff --git a/configs/zynq_zc70x_defconfig b/configs/zynq_zc70x_defconfig
index 44f3ae0ad1..81fb4af4f9 100644
--- a/configs/zynq_zc70x_defconfig
+++ b/configs/zynq_zc70x_defconfig
@@ -8,4 +8,3 @@ CONFIG_DEFAULT_DEVICE_TREE="zynq-zc702"
CONFIG_FIT=y
CONFIG_FIT_VERBOSE=y
CONFIG_FIT_SIGNATURE=y
-CONFIG_DM=y
diff --git a/configs/zynq_zc770_xm010_defconfig b/configs/zynq_zc770_xm010_defconfig
index d689857f17..fc39cca1b8 100644
--- a/configs/zynq_zc770_xm010_defconfig
+++ b/configs/zynq_zc770_xm010_defconfig
@@ -9,4 +9,3 @@ CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm010"
CONFIG_FIT=y
CONFIG_FIT_VERBOSE=y
CONFIG_FIT_SIGNATURE=y
-CONFIG_DM=y
diff --git a/configs/zynq_zc770_xm012_defconfig b/configs/zynq_zc770_xm012_defconfig
index 9745d21703..21e52fbf1f 100644
--- a/configs/zynq_zc770_xm012_defconfig
+++ b/configs/zynq_zc770_xm012_defconfig
@@ -9,4 +9,3 @@ CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm012"
CONFIG_FIT=y
CONFIG_FIT_VERBOSE=y
CONFIG_FIT_SIGNATURE=y
-CONFIG_DM=y
diff --git a/configs/zynq_zc770_xm013_defconfig b/configs/zynq_zc770_xm013_defconfig
index 924efb4262..2c38012643 100644
--- a/configs/zynq_zc770_xm013_defconfig
+++ b/configs/zynq_zc770_xm013_defconfig
@@ -9,4 +9,3 @@ CONFIG_DEFAULT_DEVICE_TREE="zynq-zc770-xm013"
CONFIG_FIT=y
CONFIG_FIT_VERBOSE=y
CONFIG_FIT_SIGNATURE=y
-CONFIG_DM=y
diff --git a/configs/zynq_zed_defconfig b/configs/zynq_zed_defconfig
index 01fa7235f9..d4dc5bb83b 100644
--- a/configs/zynq_zed_defconfig
+++ b/configs/zynq_zed_defconfig
@@ -8,4 +8,3 @@ CONFIG_DEFAULT_DEVICE_TREE="zynq-zed"
CONFIG_FIT=y
CONFIG_FIT_VERBOSE=y
CONFIG_FIT_SIGNATURE=y
-CONFIG_DM=y
diff --git a/configs/zynq_zybo_defconfig b/configs/zynq_zybo_defconfig
index f1001f1162..7d06073cad 100644
--- a/configs/zynq_zybo_defconfig
+++ b/configs/zynq_zybo_defconfig
@@ -8,4 +8,3 @@ CONFIG_DEFAULT_DEVICE_TREE="zynq-zybo"
CONFIG_FIT=y
CONFIG_FIT_VERBOSE=y
CONFIG_FIT_SIGNATURE=y
-CONFIG_DM=y
diff --git a/doc/README.drivers.eth b/doc/README.drivers.eth
index 42af442ea1..1a9a23b51b 100644
--- a/doc/README.drivers.eth
+++ b/doc/README.drivers.eth
@@ -1,3 +1,9 @@
+!!! WARNING !!!
+
+This guide describes to the old way of doing things. No new Ethernet drivers
+should be implemented this way. All new drivers should be written against the
+U-Boot core driver model. See doc/driver-model/README.txt
+
-----------------------
Ethernet Driver Guide
-----------------------
@@ -135,11 +141,11 @@ function can be called multiple times in a row.
The recv function should process packets as long as the hardware has them
readily available before returning. i.e. you should drain the hardware fifo.
-For each packet you receive, you should call the NetReceive() function on it
+For each packet you receive, you should call the net_process_received_packet() function on it
along with the packet length. The common code sets up packet buffers for you
-already in the .bss (NetRxPackets), so there should be no need to allocate your
-own. This doesn't mean you must use the NetRxPackets array however; you're
-free to call the NetReceive() function with any buffer you wish. So the pseudo
+already in the .bss (net_rx_packets), so there should be no need to allocate your
+own. This doesn't mean you must use the net_rx_packets array however; you're
+free to call the net_process_received_packet() function with any buffer you wish. So the pseudo
code here would look something like:
int ape_recv(struct eth_device *dev)
{
@@ -147,9 +153,9 @@ int ape_recv(struct eth_device *dev)
...
while (packets_are_available()) {
...
- length = ape_get_packet(&NetRxPackets[i]);
+ length = ape_get_packet(&net_rx_packets[i]);
...
- NetReceive(&NetRxPackets[i], length);
+ net_process_received_packet(&net_rx_packets[i], length);
...
if (++i >= PKTBUFSRX)
i = 0;
diff --git a/doc/README.enetaddr b/doc/README.enetaddr
index 1eaeaf9416..0fafd2cdcd 100644
--- a/doc/README.enetaddr
+++ b/doc/README.enetaddr
@@ -87,7 +87,7 @@ eth_parse_enetaddr(addr, enetaddr);
Look up an environment variable and convert the stored address. If the address
is valid, then the function returns 1. Otherwise, the function returns 0. In
all cases, the enetaddr memory is initialized. If the env var is not found,
-then it is set to all zeros. The common function is_valid_ether_addr() is used
+then it is set to all zeros. The common function is_valid_ethaddr() is used
to determine address validity.
uchar enetaddr[6];
if (!eth_getenv_enetaddr("ethaddr", enetaddr)) {
diff --git a/doc/README.fdt-control b/doc/README.fdt-control
index d8fe4a826f..e6d5ed0bb6 100644
--- a/doc/README.fdt-control
+++ b/doc/README.fdt-control
@@ -171,6 +171,22 @@ After board configuration is done, fdt supported u-boot can be build in two ways
$ make DEVICE_TREE=<dts-file-name>
+Configuration Options
+---------------------
+
+A number of run-time configuration options are provided in the /config node
+of the control device tree. You can access these using fdtdec_get_config_int(),
+fdtdec_get_config_bool() and fdtdec_get_config_string().
+
+Available options are:
+
+silent-console
+ If present and non-zero, the console is silenced by default on boot.
+
+no-keyboard
+ Tells U-Boot not to expect an attached keyboard with a VGA console
+
+
Limitations
-----------
diff --git a/doc/README.link-local b/doc/README.link-local
index 9586eca269..148b4987f2 100644
--- a/doc/README.link-local
+++ b/doc/README.link-local
@@ -32,11 +32,11 @@ after successful negotiation to enable network access.
-------------
RFC3927 requires that addresses are continuously checked to
-avoid conflicts, however this can only happen when the NetLoop
+avoid conflicts, however this can only happen when the net_loop
is getting called. It is possible for a conflict to go undetected
until a command that accesses the network is executed.
-Using NetConsole is one way to ensure that NetLoop is always
+Using NetConsole is one way to ensure that net_loop is always
processing packets and monitoring for conflicts.
This is also not a concern if the feature is use to connect
diff --git a/doc/device-tree-bindings/i2c/i2c-gpio.txt b/doc/device-tree-bindings/i2c/i2c-gpio.txt
new file mode 100644
index 0000000000..ba56ed5dea
--- /dev/null
+++ b/doc/device-tree-bindings/i2c/i2c-gpio.txt
@@ -0,0 +1,37 @@
+I2C gpio device binding
+=======================
+
+Driver:
+- drivers/i2c/i2c-gpio.c
+
+Software i2c device-tree node properties:
+Required:
+* #address-cells = <1>;
+* #size-cells = <0>;
+* compatible = "i2c-gpio";
+* gpios = <sda ...>, <scl ...>;
+
+Optional:
+* i2c-gpio,delay-us = <5>;
+ The resulting transfer speed can be adjusted by setting the delay[us]
+ between gpio-toggle operations. Speed [Hz] = 1000000 / 4 * udelay[us],
+ It not defined, then default is 5us (~50KHz).
+
+Example:
+
+i2c-gpio@1 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+
+ compatible = "i2c-gpio";
+ gpios = <&gpd1 0 GPIO_ACTIVE_HIGH>, /* SDA */
+ <&gpd1 1 GPIO_ACTIVE_HIGH>; /* CLK */
+
+ i2c-gpio,delay-us = <5>;
+
+ some_device@5 {
+ compatible = "some_device";
+ reg = <0x5>;
+ ...
+ };
+};
diff --git a/doc/device-tree-bindings/net/allwinner,sun4i-emac.txt b/doc/device-tree-bindings/net/allwinner,sun4i-emac.txt
new file mode 100644
index 0000000000..10640b17c8
--- /dev/null
+++ b/doc/device-tree-bindings/net/allwinner,sun4i-emac.txt
@@ -0,0 +1,19 @@
+* Allwinner EMAC ethernet controller
+
+Required properties:
+- compatible: should be "allwinner,sun4i-a10-emac" (Deprecated:
+ "allwinner,sun4i-emac")
+- reg: address and length of the register set for the device.
+- interrupts: interrupt for the device
+- phy: see ethernet.txt file in the same directory.
+- clocks: A phandle to the reference clock for this device
+
+Example:
+
+emac: ethernet@01c0b000 {
+ compatible = "allwinner,sun4i-a10-emac";
+ reg = <0x01c0b000 0x1000>;
+ interrupts = <55>;
+ clocks = <&ahb_gates 17>;
+ phy = <&phy0>;
+};
diff --git a/doc/device-tree-bindings/net/allwinner,sun4i-mdio.txt b/doc/device-tree-bindings/net/allwinner,sun4i-mdio.txt
new file mode 100644
index 0000000000..4ec5641377
--- /dev/null
+++ b/doc/device-tree-bindings/net/allwinner,sun4i-mdio.txt
@@ -0,0 +1,27 @@
+* Allwinner A10 MDIO Ethernet Controller interface
+
+Required properties:
+- compatible: should be "allwinner,sun4i-a10-mdio"
+ (Deprecated: "allwinner,sun4i-mdio").
+- reg: address and length of the register set for the device.
+
+Optional properties:
+- phy-supply: phandle to a regulator if the PHY needs one
+
+Example at the SoC level:
+mdio@01c0b080 {
+ compatible = "allwinner,sun4i-a10-mdio";
+ reg = <0x01c0b080 0x14>;
+ #address-cells = <1>;
+ #size-cells = <0>;
+};
+
+And at the board level:
+
+mdio@01c0b080 {
+ phy-supply = <&reg_emac_3v3>;
+
+ phy0: ethernet-phy@0 {
+ reg = <0>;
+ };
+};
diff --git a/doc/device-tree-bindings/net/allwinner,sun7i-a20-gmac.txt b/doc/device-tree-bindings/net/allwinner,sun7i-a20-gmac.txt
new file mode 100644
index 0000000000..ea4d752389
--- /dev/null
+++ b/doc/device-tree-bindings/net/allwinner,sun7i-a20-gmac.txt
@@ -0,0 +1,27 @@
+* Allwinner GMAC ethernet controller
+
+This device is a platform glue layer for stmmac.
+Please see stmmac.txt for the other unchanged properties.
+
+Required properties:
+ - compatible: Should be "allwinner,sun7i-a20-gmac"
+ - clocks: Should contain the GMAC main clock, and tx clock
+ The tx clock type should be "allwinner,sun7i-a20-gmac-clk"
+ - clock-names: Should contain the clock names "stmmaceth",
+ and "allwinner_gmac_tx"
+
+Optional properties:
+- phy-supply: phandle to a regulator if the PHY needs one
+
+Examples:
+
+ gmac: ethernet@01c50000 {
+ compatible = "allwinner,sun7i-a20-gmac";
+ reg = <0x01c50000 0x10000>,
+ <0x01c20164 0x4>;
+ interrupts = <0 85 1>;
+ interrupt-names = "macirq";
+ clocks = <&ahb_gates 49>, <&gmac_tx>;
+ clock-names = "stmmaceth", "allwinner_gmac_tx";
+ phy-mode = "mii";
+ };
diff --git a/doc/device-tree-bindings/net/ethernet.txt b/doc/device-tree-bindings/net/ethernet.txt
new file mode 100644
index 0000000000..3fc360523b
--- /dev/null
+++ b/doc/device-tree-bindings/net/ethernet.txt
@@ -0,0 +1,25 @@
+The following properties are common to the Ethernet controllers:
+
+- local-mac-address: array of 6 bytes, specifies the MAC address that was
+ assigned to the network device;
+- mac-address: array of 6 bytes, specifies the MAC address that was last used by
+ the boot program; should be used in cases where the MAC address assigned to
+ the device by the boot program is different from the "local-mac-address"
+ property;
+- max-speed: number, specifies maximum speed in Mbit/s supported by the device;
+- max-frame-size: number, maximum transfer unit (IEEE defined MTU), rather than
+ the maximum frame size (there's contradiction in ePAPR).
+- phy-mode: string, operation mode of the PHY interface; supported values are
+ "mii", "gmii", "sgmii", "qsgmii", "tbi", "rev-mii", "rmii", "rgmii", "rgmii-id",
+ "rgmii-rxid", "rgmii-txid", "rtbi", "smii", "xgmii"; this is now a de-facto
+ standard property;
+- phy-connection-type: the same as "phy-mode" property but described in ePAPR;
+- phy-handle: phandle, specifies a reference to a node representing a PHY
+ device; this property is described in ePAPR and so preferred;
+- phy: the same as "phy-handle" property, not recommended for new bindings.
+- phy-device: the same as "phy-handle" property, not recommended for new
+ bindings.
+
+Child nodes of the Ethernet controller are typically the individual PHY devices
+connected via the MDIO bus (sometimes the MDIO bus controller is separate).
+They are described in the phy.txt file in this same directory.
diff --git a/doc/device-tree-bindings/net/stmmac.txt b/doc/device-tree-bindings/net/stmmac.txt
new file mode 100644
index 0000000000..5f025174cf
--- /dev/null
+++ b/doc/device-tree-bindings/net/stmmac.txt
@@ -0,0 +1,63 @@
+* STMicroelectronics 10/100/1000 Ethernet driver (GMAC)
+
+Required properties:
+- compatible: Should be "snps,dwmac-<ip_version>" "snps,dwmac"
+ For backwards compatibility: "st,spear600-gmac" is also supported.
+- reg: Address and length of the register set for the device
+- interrupt-parent: Should be the phandle for the interrupt controller
+ that services interrupts for this device
+- interrupts: Should contain the STMMAC interrupts
+- interrupt-names: Should contain the interrupt names "macirq"
+ "eth_wake_irq" if this interrupt is supported in the "interrupts"
+ property
+- phy-mode: See ethernet.txt file in the same directory.
+- snps,reset-gpio gpio number for phy reset.
+- snps,reset-active-low boolean flag to indicate if phy reset is active low.
+- snps,reset-delays-us is triplet of delays
+ The 1st cell is reset pre-delay in micro seconds.
+ The 2nd cell is reset pulse in micro seconds.
+ The 3rd cell is reset post-delay in micro seconds.
+- snps,pbl Programmable Burst Length
+- snps,fixed-burst Program the DMA to use the fixed burst mode
+- snps,mixed-burst Program the DMA to use the mixed burst mode
+- snps,force_thresh_dma_mode Force DMA to use the threshold mode for
+ both tx and rx
+- snps,force_sf_dma_mode Force DMA to use the Store and Forward
+ mode for both tx and rx. This flag is
+ ignored if force_thresh_dma_mode is set.
+- snps,multicast-filter-bins: Number of multicast filter hash bins
+ supported by this device instance
+- snps,perfect-filter-entries: Number of perfect filter entries supported
+ by this device instance
+
+Optional properties:
+- resets: Should contain a phandle to the STMMAC reset signal, if any
+- reset-names: Should contain the reset signal name "stmmaceth", if a
+ reset phandle is given
+- max-frame-size: See ethernet.txt file in the same directory
+- clocks: If present, the first clock should be the GMAC main clock,
+ further clocks may be specified in derived bindings.
+- clock-names: One name for each entry in the clocks property, the
+ first one should be "stmmaceth".
+- clk_ptp_ref: this is the PTP reference clock; in case of the PTP is
+ available this clock is used for programming the Timestamp Addend Register.
+ If not passed then the system clock will be used and this is fine on some
+ platforms.
+- snps,burst_len: The AXI burst lenth value of the AXI BUS MODE register.
+
+Examples:
+
+ gmac0: ethernet@e0800000 {
+ compatible = "st,spear600-gmac";
+ reg = <0xe0800000 0x8000>;
+ interrupt-parent = <&vic1>;
+ interrupts = <24 23>;
+ interrupt-names = "macirq", "eth_wake_irq";
+ mac-address = [000000000000]; /* Filled in by U-Boot */
+ max-frame-size = <3800>;
+ phy-mode = "gmii";
+ snps,multicast-filter-bins = <256>;
+ snps,perfect-filter-entries = <128>;
+ clocks = <&clock>;
+ clock-names = "stmmaceth";
+ };
diff --git a/doc/driver-model/pci-info.txt b/doc/driver-model/pci-info.txt
new file mode 100644
index 0000000000..63efcb7b92
--- /dev/null
+++ b/doc/driver-model/pci-info.txt
@@ -0,0 +1,70 @@
+PCI with Driver Model
+=====================
+
+How busses are scanned
+----------------------
+
+Any config read will end up at pci_read_config(). This uses
+uclass_get_device_by_seq() to get the PCI bus for a particular bus number.
+Bus number 0 will need to be requested first, and the alias in the device
+tree file will point to the correct device:
+
+
+ aliases {
+ pci0 = &pci;
+ };
+
+ pci: pci-controller {
+ compatible = "sandbox,pci";
+ ...
+ };
+
+
+If there is no alias the devices will be numbered sequentially in the device
+tree.
+
+The call to uclass_get_device by seq() will cause the PCI bus to be probed.
+This does a scan of the bus to locate available devices. These devices are
+bound to their appropriate driver if available. If there is no driver, then
+they are bound to a generic PCI driver which does nothing.
+
+After probing a bus, the available devices will appear in the device tree
+under that bus.
+
+Note that this is all done on a lazy basis, as needed, so until something is
+touched on PCI it will not be probed.
+
+PCI devices can appear in the device tree. If they do this serves to specify
+the driver to use for the device. In this case they will be bound at
+start-up.
+
+
+Sandbox
+-------
+
+With sandbox we need a device emulator for each device on the bus since there
+is no real PCI bus. This works by looking in the device tree node for a
+driver. For example:
+
+
+ pci@1f,0 {
+ compatible = "pci-generic";
+ reg = <0xf800 0 0 0 0>;
+ emul@1f,0 {
+ compatible = "sandbox,swap-case";
+ };
+ };
+
+This means that there is a 'sandbox,swap-case' driver at that bus position.
+Note that the first cell in the 'reg' value is the bus/device/function. See
+PCI_BDF() for the encoding (it is also specified in the IEEE Std 1275-1994
+PCI bus binding document, v2.1)
+
+When this bus is scanned we will end up with something like this:
+
+`- * pci-controller @ 05c660c8, 0
+ `- pci@1f,0 @ 05c661c8, 63488
+ `- emul@1f,0 @ 05c662c8
+
+When accesses go to the pci@1f,0 device they are forwarded to its child, the
+emulator.
diff --git a/doc/driver-model/usb-info.txt b/doc/driver-model/usb-info.txt
new file mode 100644
index 0000000000..66f2daec7c
--- /dev/null
+++ b/doc/driver-model/usb-info.txt
@@ -0,0 +1,415 @@
+How USB works with driver model
+===============================
+
+Introduction
+------------
+
+Driver model USB support makes use of existing features but changes how
+drivers are found. This document provides some information intended to help
+understand how things work with USB in U-Boot when driver model is enabled.
+
+
+Enabling driver model for USB
+-----------------------------
+
+A new CONFIG_DM_USB option is provided to enable driver model for USB. This
+causes the USB uclass to be included, and drops the equivalent code in
+usb.c. In particular the usb_init() function is then implemented by the
+uclass.
+
+
+Support for EHCI and XHCI
+-------------------------
+
+So far OHCI is not supported. Both EHCI and XHCI drivers should be declared
+as drivers in the USB uclass. For example:
+
+static const struct udevice_id ehci_usb_ids[] = {
+ { .compatible = "nvidia,tegra20-ehci", .data = USB_CTLR_T20 },
+ { .compatible = "nvidia,tegra30-ehci", .data = USB_CTLR_T30 },
+ { .compatible = "nvidia,tegra114-ehci", .data = USB_CTLR_T114 },
+ { }
+};
+
+U_BOOT_DRIVER(usb_ehci) = {
+ .name = "ehci_tegra",
+ .id = UCLASS_USB,
+ .of_match = ehci_usb_ids,
+ .ofdata_to_platdata = ehci_usb_ofdata_to_platdata,
+ .probe = tegra_ehci_usb_probe,
+ .remove = tegra_ehci_usb_remove,
+ .ops = &ehci_usb_ops,
+ .platdata_auto_alloc_size = sizeof(struct usb_platdata),
+ .priv_auto_alloc_size = sizeof(struct fdt_usb),
+ .flags = DM_FLAG_ALLOC_PRIV_DMA,
+};
+
+Here ehci_usb_ids is used to list the controllers that the driver supports.
+Each has its own data value. Controllers must be in the UCLASS_USB uclass.
+
+The ofdata_to_platdata() method allows the controller driver to grab any
+necessary settings from the device tree.
+
+The ops here are ehci_usb_ops. All EHCI drivers will use these same ops in
+most cases, since they are all EHCI-compatible. For EHCI there are also some
+special operations that can be overridden when calling ehci_register().
+
+The driver can use priv_auto_alloc_size to set the size of its private data.
+This can hold run-time information needed by the driver for operation. It
+exists when the device is probed (not when it is bound) and is removed when
+the driver is removed.
+
+Note that usb_platdata is currently only used to deal with setting up a bus
+in USB device mode (OTG operation). It can be omitted if that is not
+supported.
+
+The driver's probe() method should do the basic controller init and then
+call ehci_register() to register itself as an EHCI device. It should call
+ehci_deregister() in the remove() method. Registering a new EHCI device
+does not by itself cause the bus to be scanned.
+
+The old ehci_hcd_init() function is no-longer used. Nor is it necessary to
+set up the USB controllers from board init code. When 'usb start' is used,
+each controller will be probed and its bus scanned.
+
+XHCI works in a similar way.
+
+
+Data structures
+---------------
+
+The following primary data structures are in use:
+
+- struct usb_device
+ This holds information about a device on the bus. All devices have
+ this structure, even the root hub. The controller itself does not
+ have this structure. You can access it for a device 'dev' with
+ dev_get_parentdata(dev). It matches the old structure except that the
+ parent and child information is not present (since driver model
+ handles that). Once the device is set up, you can find the device
+ descriptor and current configuration descriptor in this structure.
+
+- struct usb_platdata
+ This holds platform data for a controller. So far this is only used
+ as a work-around for controllers which can act as USB devices in OTG
+ mode, since the gadget framework does not use driver model.
+
+- struct usb_dev_platdata
+ This holds platform data for a device. You can access it for a
+ device 'dev' with dev_get_parent_platdata(dev). It holds the device
+ address and speed - anything that can be determined before the device
+ driver is actually set up. When probing the bus this structure is
+ used to provide essential information to the device driver.
+
+- struct usb_bus_priv
+ This is private information for each controller, maintained by the
+ controller uclass. It is mostly used to keep track of the next
+ device address to use.
+
+Of these, only struct usb_device was used prior to driver model.
+
+
+USB buses
+---------
+
+Given a controller, you know the bus - it is the one attached to the
+controller. Each controller handles exactly one bus. Every controller has a
+root hub attached to it. This hub, which is itself a USB device, can provide
+one or more 'ports' to which additional devices can be attached. It is
+possible to power up a hub and find out which of its ports have devices
+attached.
+
+Devices are given addresses starting at 1. The root hub is always address 1,
+and from there the devices are numbered in sequence. The USB uclass takes
+care of this numbering automatically during enumeration.
+
+USB devices are enumerated by finding a device on a particular hub, and
+setting its address to the next available address. The USB bus stretches out
+in a tree structure, potentially with multiple hubs each with several ports
+and perhaps other hubs. Some hubs will have their own power since otherwise
+the 5V 500mA power supplied by the controller will not be sufficient to run
+very many devices.
+
+Enumeration in U-Boot takes a long time since devices are probed one at a
+time, and each is given sufficient time to wake up and announce itself. The
+timeouts are set for the slowest device.
+
+Up to 127 devices can be on each bus. USB has four bus speeds: low
+(1.5Mbps), full (12Mbps), high (480Mbps) which is only available with USB2
+and newer (EHCI), and super (5Gbps) which is only available with USB3 and
+newer (XHCI). If you connect a super-speed device to a high-speed hub, you
+will only get high-speed.
+
+
+USB operations
+--------------
+
+As before driver model, messages can be sent using submit_bulk_msg() and the
+like. These are now implemented by the USB uclass and route through the
+controller drivers. Note that messages are not sent to the driver of the
+device itself - i.e. they don't pass down the stack to the controller.
+U-Boot simply finds the controller to which the device is attached, and sends
+the message there with an appropriate 'pipe' value so it can be addressed
+properly. Having said that, the USB device which should receive the message
+is passed in to the driver methods, for use by sandbox. This design decision
+is open for review and the code impact of changing it is small since the
+methods are typically implemented by the EHCI and XHCI stacks.
+
+Controller drivers (in UCLASS_USB) themselves provide methods for sending
+each message type. For XHCI an additional alloc_device() method is provided
+since XHCI needs to allocate a device context before it can even read the
+device's descriptor.
+
+These methods use a 'pipe' which is a collection of bit fields used to
+describe the type of message, direction of transfer and the intended
+recipient (device number).
+
+
+USB Devices
+-----------
+
+USB devices are found using a simple algorithm which works through the
+available hubs in a depth-first search. Devices can be in any uclass, but
+are attached to a parent hub (or controller in the case of the root hub) and
+so have parent data attached to them (this is struct usb_device).
+
+By the time the device's probe() method is called, it is enumerated and is
+ready to talk to the host.
+
+The enumeration process needs to work out which driver to attach to each USB
+device. It does this by examining the device class, interface class, vendor
+ID, product ID, etc. See struct usb_driver_entry for how drivers are matched
+with USB devices - you can use the USB_DEVICE() macro to declare a USB
+driver. For example, usb_storage.c defines a USB_DEVICE() to handle storage
+devices, and it will be used for all USB devices which match.
+
+
+
+Technical details on enumeration flow
+-------------------------------------
+
+It is useful to understand precisely how a USB bus is enumerating to avoid
+confusion when dealing with USB devices.
+
+Device initialisation happens roughly like this:
+
+- At some point the 'usb start' command is run
+- This calls usb_init() which works through each controller in turn
+- The controller is probed(). This does no enumeration.
+- Then usb_scan_bus() is called. This calls usb_scan_device() to scan the
+(only) device that is attached to the controller - a root hub
+- usb_scan_device() sets up a fake struct usb_device and calls
+usb_setup_device(), passing the port number to be scanned, in this case port
+0
+- usb_setup_device() first calls usb_prepare_device() to set the device
+address, then usb_select_config() to select the first configuration
+- at this point the device is enumerated but we do not have a real struct
+udevice for it. But we do have the descriptor in struct usb_device so we can
+use this to figure out what driver to use
+- back in usb_scan_device(), we call usb_find_child() to try to find an
+existing device which matches the one we just found on the bus. This can
+happen if the device is mentioned in the device tree, or if we previously
+scanned the bus and so the device was created before
+- if usb_find_child() does not find an existing device, we call
+usb_find_and_bind_driver() which tries to bind one
+- usb_find_and_bind_driver() searches all available USB drivers (declared
+with USB_DEVICE()). If it finds a match it binds that driver to create a new
+device.
+- If it does not, it binds a generic driver. A generic driver is good enough
+to allow access to the device (sending it packets, etc.) but all
+functionality will need to be implemented outside the driver model.
+- in any case, when usb_find_child() and/or usb_find_and_bind_driver() are
+done, we have a device with the correct uclass. At this point we want to
+probe the device
+- first we store basic information about the new device (address, port,
+speed) in its parent platform data. We cannot store it its private data
+since that will not exist until the device is probed.
+- then we call device_probe() which probes the device
+- the first probe step is actually the USB controller's (or USB hubs's)
+child_pre_probe() method. This gets called before anything else and is
+intended to set up a child device ready to be used with its parent bus. For
+USB this calls usb_child_pre_probe() which grabs the information that was
+stored in the parent platform data and stores it in the parent private data
+(which is struct usb_device, a real one this time). It then calls
+usb_select_config() again to make sure that everything about the device is
+set up
+- note that we have called usb_select_config() twice. This is inefficient
+but the alternative is to store additional information in the platform data.
+The time taken is minimal and this way is simpler
+- at this point the device is set up and ready for use so far as the USB
+subsystem is concerned
+- the device's probe() method is then called. It can send messages and do
+whatever else it wants to make the device work.
+
+Note that the first device is always a root hub, and this must be scanned to
+find any devices. The above steps will have created a hub (UCLASS_USB_HUB),
+given it address 1 and set the configuration.
+
+For hubs, the hub uclass has a post_probe() method. This means that after
+any hub is probed, the uclass gets to do some processing. In this case
+usb_hub_post_probe() is called, and the following steps take place:
+
+- usb_hub_post_probe() calls usb_hub_scan() to scan the hub, which in turn
+calls usb_hub_configure()
+- hub power is enabled
+- we loop through each port on the hub, performing the same steps for each
+- first, check if there is a device present. This happens in
+usb_hub_port_connect_change(). If so, then usb_scan_device() is called to
+scan the device, passing the appropriate port number.
+- you will recognise usb_scan_device() from the steps above. It sets up the
+device ready for use. If it is a hub, it will scan that hub before it
+continues here (recursively, depth-first)
+- once all hub ports are scanned in this way, the hub is ready for use and
+all of its downstream devices also
+- additional controllers are scanned in the same way
+
+The above method has some nice properties:
+
+- the bus enumeration happens by virtue of driver model's natural device flow
+- most logic is in the USB controller and hub uclasses; the actual device
+drivers do not need to know they are on a USB bus, at least so far as
+enumeration goes
+- hub scanning happens automatically after a hub is probed
+
+
+Hubs
+----
+
+USB hubs are scanned as in the section above. While hubs have their own
+uclass, they share some common elements with controllers:
+
+- they both attach private data to their children (struct usb_device,
+accessible for a child with dev_get_parentdata(child))
+- they both use usb_child_pre_probe() to set up their children as proper USB
+devices
+
+
+Example - Mass Storage
+----------------------
+
+As an example of a USB device driver, see usb_storage.c. It uses its own
+uclass and declares itself as follows:
+
+U_BOOT_DRIVER(usb_mass_storage) = {
+ .name = "usb_mass_storage",
+ .id = UCLASS_MASS_STORAGE,
+ .of_match = usb_mass_storage_ids,
+ .probe = usb_mass_storage_probe,
+};
+
+static const struct usb_device_id mass_storage_id_table[] = {
+ { .match_flags = USB_DEVICE_ID_MATCH_INT_CLASS,
+ .bInterfaceClass = USB_CLASS_MASS_STORAGE},
+ { } /* Terminating entry */
+};
+
+USB_DEVICE(usb_mass_storage, mass_storage_id_table);
+
+The USB_DEVICE() macro attaches the given table of matching information to
+the given driver. Note that the driver is declared in U_BOOT_DRIVER() as
+'usb_mass_storage' and this must match the first parameter of USB_DEVICE.
+
+When usb_find_and_bind_driver() is called on a USB device with the
+bInterfaceClass value of USB_CLASS_MASS_STORAGE, it will automatically find
+this driver and use it.
+
+
+Counter-example: USB Ethernet
+-----------------------------
+
+As an example of the old way of doing things, see usb_ether.c. When the bus
+is scanned, all Ethernet devices will be created as generic USB devices (in
+uclass UCLASS_USB_DEV_GENERIC). Then, when the scan is completed,
+usb_host_eth_scan() will be called. This looks through all the devices on
+each bus and manually figures out which are Ethernet devices in the ways of
+yore.
+
+In fact, usb_ether should be moved to driver model. Each USB Ethernet driver
+(e.g drivers/usb/eth/asix.c) should include a USB_DEVICE() declaration, so
+that it will be found as part of normal USB enumeration. Then, instead of a
+generic USB driver, a real (driver-model-aware) driver will be used. Since
+Ethernet now supports driver model, this should be fairly easy to achieve,
+and then usb_ether.c and the usb_host_eth_scan() will melt away.
+
+
+Sandbox
+-------
+
+All driver model uclasses must have tests and USB is no exception. To
+achieve this, a sandbox USB controller is provided. This can make use of
+emulation drivers which pretend to be USB devices. Emulations are provided
+for a hub and a flash stick. These are enough to create a pretend USB bus
+(defined by the sandbox device tree sandbox.dts) which can be scanned and
+used.
+
+Tests in test/dm/usb.c make use of this feature. It allows much of the USB
+stack to be tested without real hardware being needed.
+
+Here is an example device tree fragment:
+
+ usb@1 {
+ compatible = "sandbox,usb";
+ hub {
+ compatible = "usb-hub";
+ usb,device-class = <USB_CLASS_HUB>;
+ hub-emul {
+ compatible = "sandbox,usb-hub";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ flash-stick {
+ reg = <0>;
+ compatible = "sandbox,usb-flash";
+ sandbox,filepath = "flash.bin";
+ };
+ };
+ };
+ };
+
+This defines a single controller, containing a root hub (which is required).
+The hub is emulated by a hub emulator, and the emulated hub has a single
+flash stick to emulate on one of its ports.
+
+When 'usb start' is used, the following 'dm tree' output will be available:
+
+ usb [ + ] `-- usb@1
+ usb_hub [ + ] `-- hub
+ usb_emul [ + ] |-- hub-emul
+ usb_emul [ + ] | `-- flash-stick
+ usb_mass_st [ + ] `-- usb_mass_storage
+
+
+This may look confusing. Most of it mirrors the device tree, but the
+'usb_mass_storage' device is not in the device tree. This is created by
+usb_find_and_bind_driver() based on the USB_DRIVER in usb_storage.c. While
+'flash-stick' is the emulation device, 'usb_mass_storage' is the real U-Boot
+USB device driver that talks to it.
+
+
+Future work
+-----------
+
+It is pretty uncommon to have a large USB bus with lots of hubs on an
+embedded system. In fact anything other than a root hub is uncommon. Still
+it would be possible to speed up enumeration in two ways:
+
+- breadth-first search would allow devices to be reset and probed in
+parallel to some extent
+- enumeration could be lazy, in the sense that we could enumerate just the
+root hub at first, then only progress to the next 'level' when a device is
+used that we cannot find. This could be made easier if the devices were
+statically declared in the device tree (which is acceptable for production
+boards where the same, known, things are on each bus).
+
+But in common cases the current algorithm is sufficient.
+
+Other things that need doing:
+- Convert usb_ether to use driver model as described above
+- Test that keyboards work (and convert to driver model)
+- Move the USB gadget framework to driver model
+- Implement OHCI in driver model
+- Implement USB PHYs in driver model
+- Work out a clever way to provide lazy init for USB devices
+
+--
+Simon Glass <sjg@chromium.org>
+23-Mar-15
diff --git a/drivers/block/ahci.c b/drivers/block/ahci.c
index 88b90e0203..65086484ee 100644
--- a/drivers/block/ahci.c
+++ b/drivers/block/ahci.c
@@ -137,10 +137,10 @@ static void sunxi_dma_init(volatile u8 *port_mmio)
}
#endif
-int ahci_reset(u32 base)
+int ahci_reset(void __iomem *base)
{
int i = 1000;
- u32 host_ctl_reg = base + HOST_CTL;
+ u32 __iomem *host_ctl_reg = base + HOST_CTL;
u32 tmp = readl(host_ctl_reg); /* global controller reset */
if ((tmp & HOST_RESET) == 0)
@@ -419,8 +419,9 @@ static int ahci_init_one(pci_dev_t pdev)
probe_ent->pio_mask = 0x1f;
probe_ent->udma_mask = 0x7f; /*Fixme,assume to support UDMA6 */
- pci_read_config_dword(pdev, PCI_BASE_ADDRESS_5, &probe_ent->mmio_base);
- debug("ahci mmio_base=0x%08x\n", probe_ent->mmio_base);
+ probe_ent->mmio_base = pci_map_bar(pdev, PCI_BASE_ADDRESS_5,
+ PCI_REGION_MEM);
+ debug("ahci mmio_base=0x%p\n", probe_ent->mmio_base);
/* Take from kernel:
* JMicron-specific fixup:
@@ -939,7 +940,7 @@ void scsi_low_level_init(int busdevfunc)
}
#ifdef CONFIG_SCSI_AHCI_PLAT
-int ahci_init(u32 base)
+int ahci_init(void __iomem *base)
{
int i, rc = 0;
u32 linkmap;
diff --git a/drivers/block/dwc_ahsata.c b/drivers/block/dwc_ahsata.c
index 01a4148a52..cf3ef6be62 100644
--- a/drivers/block/dwc_ahsata.c
+++ b/drivers/block/dwc_ahsata.c
@@ -343,7 +343,7 @@ static int ahci_init_one(int pdev)
| ATA_FLAG_PIO_DMA
| ATA_FLAG_NO_ATAPI;
- probe_ent->mmio_base = CONFIG_DWC_AHSATA_BASE_ADDR;
+ probe_ent->mmio_base = (void __iomem *)CONFIG_DWC_AHSATA_BASE_ADDR;
/* initialize adapter */
rc = ahci_host_init(probe_ent);
diff --git a/drivers/core/device-remove.c b/drivers/core/device-remove.c
index 3a5f48df7a..7fee1c001e 100644
--- a/drivers/core/device-remove.c
+++ b/drivers/core/device-remove.c
@@ -66,7 +66,7 @@ static int device_chld_remove(struct udevice *dev)
int device_unbind(struct udevice *dev)
{
- struct driver *drv;
+ const struct driver *drv;
int ret;
if (!dev)
@@ -139,7 +139,7 @@ void device_free(struct udevice *dev)
int device_remove(struct udevice *dev)
{
- struct driver *drv;
+ const struct driver *drv;
int ret;
if (!dev)
diff --git a/drivers/core/device.c b/drivers/core/device.c
index 73c3e07c28..ccaa99ca63 100644
--- a/drivers/core/device.c
+++ b/drivers/core/device.c
@@ -24,8 +24,9 @@
DECLARE_GLOBAL_DATA_PTR;
-int device_bind(struct udevice *parent, struct driver *drv, const char *name,
- void *platdata, int of_offset, struct udevice **devp)
+int device_bind(struct udevice *parent, const struct driver *drv,
+ const char *name, void *platdata, int of_offset,
+ struct udevice **devp)
{
struct udevice *dev;
struct uclass *uc;
@@ -164,9 +165,24 @@ int device_bind_by_name(struct udevice *parent, bool pre_reloc_only,
-1, devp);
}
+static void *alloc_priv(int size, uint flags)
+{
+ void *priv;
+
+ if (flags & DM_FLAG_ALLOC_PRIV_DMA) {
+ priv = memalign(ARCH_DMA_MINALIGN, size);
+ if (priv)
+ memset(priv, '\0', size);
+ } else {
+ priv = calloc(1, size);
+ }
+
+ return priv;
+}
+
int device_probe_child(struct udevice *dev, void *parent_priv)
{
- struct driver *drv;
+ const struct driver *drv;
int size = 0;
int ret;
int seq;
@@ -182,7 +198,7 @@ int device_probe_child(struct udevice *dev, void *parent_priv)
/* Allocate private data if requested */
if (drv->priv_auto_alloc_size) {
- dev->priv = calloc(1, drv->priv_auto_alloc_size);
+ dev->priv = alloc_priv(drv->priv_auto_alloc_size, drv->flags);
if (!dev->priv) {
ret = -ENOMEM;
goto fail;
@@ -206,7 +222,7 @@ int device_probe_child(struct udevice *dev, void *parent_priv)
per_child_auto_alloc_size;
}
if (size) {
- dev->parent_priv = calloc(1, size);
+ dev->parent_priv = alloc_priv(size, drv->flags);
if (!dev->parent_priv) {
ret = -ENOMEM;
goto fail;
@@ -227,7 +243,9 @@ int device_probe_child(struct udevice *dev, void *parent_priv)
}
dev->seq = seq;
- ret = uclass_pre_probe_child(dev);
+ dev->flags |= DM_FLAG_ACTIVATED;
+
+ ret = uclass_pre_probe_device(dev);
if (ret)
goto fail;
@@ -243,19 +261,18 @@ int device_probe_child(struct udevice *dev, void *parent_priv)
goto fail;
}
+ dev->flags |= DM_FLAG_ACTIVATED;
if (drv->probe) {
ret = drv->probe(dev);
- if (ret)
+ if (ret) {
+ dev->flags &= ~DM_FLAG_ACTIVATED;
goto fail;
+ }
}
- dev->flags |= DM_FLAG_ACTIVATED;
-
ret = uclass_post_probe_device(dev);
- if (ret) {
- dev->flags &= ~DM_FLAG_ACTIVATED;
+ if (ret)
goto fail_uclass;
- }
return 0;
fail_uclass:
@@ -264,6 +281,8 @@ fail_uclass:
__func__, dev->name);
}
fail:
+ dev->flags &= ~DM_FLAG_ACTIVATED;
+
dev->seq = -1;
device_free(dev);
@@ -305,6 +324,16 @@ void *dev_get_priv(struct udevice *dev)
return dev->priv;
}
+void *dev_get_uclass_priv(struct udevice *dev)
+{
+ if (!dev) {
+ dm_warn("%s: null device\n", __func__);
+ return NULL;
+ }
+
+ return dev->uclass_priv;
+}
+
void *dev_get_parentdata(struct udevice *dev)
{
if (!dev) {
@@ -440,9 +469,9 @@ struct udevice *dev_get_parent(struct udevice *child)
return child->parent;
}
-ulong dev_get_of_data(struct udevice *dev)
+ulong dev_get_driver_data(struct udevice *dev)
{
- return dev->of_id->data;
+ return dev->driver_data;
}
enum uclass_id device_get_uclass_id(struct udevice *dev)
@@ -461,3 +490,31 @@ fdt_addr_t dev_get_addr(struct udevice *dev)
return FDT_ADDR_T_NONE;
}
#endif
+
+bool device_has_children(struct udevice *dev)
+{
+ return !list_empty(&dev->child_head);
+}
+
+bool device_has_active_children(struct udevice *dev)
+{
+ struct udevice *child;
+
+ for (device_find_first_child(dev, &child);
+ child;
+ device_find_next_child(&child)) {
+ if (device_active(child))
+ return true;
+ }
+
+ return false;
+}
+
+bool device_is_last_sibling(struct udevice *dev)
+{
+ struct udevice *parent = dev->parent;
+
+ if (!parent)
+ return false;
+ return list_is_last(&dev->sibling_node, &parent->child_head);
+}
diff --git a/drivers/core/lists.c b/drivers/core/lists.c
index ff115c4723..647e390bfe 100644
--- a/drivers/core/lists.c
+++ b/drivers/core/lists.c
@@ -168,7 +168,7 @@ int lists_bind_fdt(struct udevice *parent, const void *blob, int offset,
dm_warn("Error binding driver '%s'\n", entry->name);
return ret;
} else {
- dev->of_id = id;
+ dev->driver_data = id->data;
found = true;
if (devp)
*devp = dev;
diff --git a/drivers/core/uclass.c b/drivers/core/uclass.c
index 289a5d2d53..98c15e585d 100644
--- a/drivers/core/uclass.c
+++ b/drivers/core/uclass.c
@@ -391,9 +391,17 @@ int uclass_resolve_seq(struct udevice *dev)
return seq;
}
-int uclass_pre_probe_child(struct udevice *dev)
+int uclass_pre_probe_device(struct udevice *dev)
{
struct uclass_driver *uc_drv;
+ int ret;
+
+ uc_drv = dev->uclass->uc_drv;
+ if (uc_drv->pre_probe) {
+ ret = uc_drv->pre_probe(dev);
+ if (ret)
+ return ret;
+ }
if (!dev->parent)
return 0;
diff --git a/drivers/demo/demo-simple.c b/drivers/demo/demo-simple.c
index 2bcb7dfb47..f069748e05 100644
--- a/drivers/demo/demo-simple.c
+++ b/drivers/demo/demo-simple.c
@@ -10,6 +10,7 @@
#include <common.h>
#include <dm.h>
#include <dm-demo.h>
+#include <mapmem.h>
#include <asm/io.h>
static int simple_hello(struct udevice *dev, int ch)
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 7b5178a23a..0840a30fba 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -14,3 +14,24 @@ config LPC32XX_GPIO
default n
help
Support for the LPC32XX GPIO driver.
+
+config SANDBOX_GPIO
+ bool "Enable sandbox GPIO driver"
+ depends on SANDBOX && DM && DM_GPIO
+ help
+ This driver supports some simulated GPIOs which can be adjusted
+ using 'back door' functions like sandbox_gpio_set_value(). Then the
+ GPIOs can be inspected through the normal get_get_value()
+ interface. The purpose of this is to allow GPIOs to be used as
+ normal in sandbox, perhaps with test code actually driving the
+ behaviour of those GPIOs.
+
+config SANDBOX_GPIO_COUNT
+ int "Number of sandbox GPIOs"
+ depends on SANDBOX_GPIO
+ default 128
+ help
+ The sandbox driver can support any number of GPIOs. Generally these
+ are specified using the device tree. But you can also have a number
+ of 'anonymous' GPIOs that do not belong to any device or bank.
+ Select a suitable value depending on your needs.
diff --git a/drivers/gpio/at91_gpio.c b/drivers/gpio/at91_gpio.c
index 22fbd63098..75a32ee815 100644
--- a/drivers/gpio/at91_gpio.c
+++ b/drivers/gpio/at91_gpio.c
@@ -511,7 +511,7 @@ static int at91_gpio_probe(struct udevice *dev)
{
struct at91_port_priv *port = dev_get_priv(dev);
struct at91_port_platdata *plat = dev_get_platdata(dev);
- struct gpio_dev_priv *uc_priv = dev->uclass_priv;
+ struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
uc_priv->bank_name = plat->bank_name;
uc_priv->gpio_count = GPIO_PER_BANK;
diff --git a/drivers/gpio/bcm2835_gpio.c b/drivers/gpio/bcm2835_gpio.c
index 0244c01882..fbc641d662 100644
--- a/drivers/gpio/bcm2835_gpio.c
+++ b/drivers/gpio/bcm2835_gpio.c
@@ -105,7 +105,7 @@ static int bcm2835_gpio_probe(struct udevice *dev)
{
struct bcm2835_gpios *gpios = dev_get_priv(dev);
struct bcm2835_gpio_platdata *plat = dev_get_platdata(dev);
- struct gpio_dev_priv *uc_priv = dev->uclass_priv;
+ struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
uc_priv->bank_name = "GPIO";
uc_priv->gpio_count = BCM2835_GPIO_COUNT;
diff --git a/drivers/gpio/gpio-uclass.c b/drivers/gpio/gpio-uclass.c
index a69bbd2002..381868bfb1 100644
--- a/drivers/gpio/gpio-uclass.c
+++ b/drivers/gpio/gpio-uclass.c
@@ -34,7 +34,7 @@ static int gpio_to_device(unsigned int gpio, struct gpio_desc *desc)
for (ret = uclass_first_device(UCLASS_GPIO, &dev);
dev;
ret = uclass_next_device(&dev)) {
- uc_priv = dev->uclass_priv;
+ uc_priv = dev_get_uclass_priv(dev);
if (gpio >= uc_priv->gpio_base &&
gpio < uc_priv->gpio_base + uc_priv->gpio_count) {
desc->dev = dev;
@@ -65,7 +65,7 @@ int gpio_lookup_name(const char *name, struct udevice **devp,
ret = uclass_next_device(&dev)) {
int len;
- uc_priv = dev->uclass_priv;
+ uc_priv = dev_get_uclass_priv(dev);
if (numeric != -1) {
offset = numeric - uc_priv->gpio_base;
/* Allow GPIOs to be numbered from 0 */
@@ -116,7 +116,7 @@ static int dm_gpio_request(struct gpio_desc *desc, const char *label)
char *str;
int ret;
- uc_priv = dev->uclass_priv;
+ uc_priv = dev_get_uclass_priv(dev);
if (uc_priv->name[desc->offset])
return -EBUSY;
str = strdup(label);
@@ -195,7 +195,7 @@ int _dm_gpio_free(struct udevice *dev, uint offset)
struct gpio_dev_priv *uc_priv;
int ret;
- uc_priv = dev->uclass_priv;
+ uc_priv = dev_get_uclass_priv(dev);
if (!uc_priv->name[offset])
return -ENXIO;
if (gpio_get_ops(dev)->free) {
@@ -232,7 +232,7 @@ int gpio_free(unsigned gpio)
static int check_reserved(struct gpio_desc *desc, const char *func)
{
- struct gpio_dev_priv *uc_priv = desc->dev->uclass_priv;
+ struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(desc->dev);
if (!uc_priv->name[desc->offset]) {
printf("%s: %s: error: gpio %s%d not reserved\n",
@@ -402,7 +402,7 @@ const char *gpio_get_bank_info(struct udevice *dev, int *bit_count)
struct gpio_dev_priv *priv;
/* Must be called on an active device */
- priv = dev->uclass_priv;
+ priv = dev_get_uclass_priv(dev);
assert(priv);
*bit_count = priv->gpio_count;
@@ -420,7 +420,7 @@ static const char * const gpio_function[GPIOF_COUNT] = {
int get_function(struct udevice *dev, int offset, bool skip_unused,
const char **namep)
{
- struct gpio_dev_priv *uc_priv = dev->uclass_priv;
+ struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
struct dm_gpio_ops *ops = gpio_get_ops(dev);
BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function));
@@ -468,7 +468,7 @@ int gpio_get_status(struct udevice *dev, int offset, char *buf, int buffsize)
BUILD_BUG_ON(GPIOF_COUNT != ARRAY_SIZE(gpio_function));
*buf = 0;
- priv = dev->uclass_priv;
+ priv = dev_get_uclass_priv(dev);
ret = gpio_get_raw_function(dev, offset, NULL);
if (ret < 0)
return ret;
@@ -590,11 +590,7 @@ int gpio_request_list_by_name_nodev(const void *blob, int node,
int count;
int ret;
- for (count = 0; ; count++) {
- if (count >= max_count) {
- ret = -ENOSPC;
- goto err;
- }
+ for (count = 0; count < max_count; count++) {
ret = _gpio_request_by_name_nodev(blob, node, list_name, count,
&desc[count], flags, true);
if (ret == -ENOENT)
@@ -680,7 +676,7 @@ static int gpio_renumber(struct udevice *removed_dev)
base = 0;
uclass_foreach_dev(dev, uc) {
if (device_active(dev) && dev != removed_dev) {
- uc_priv = dev->uclass_priv;
+ uc_priv = dev_get_uclass_priv(dev);
uc_priv->gpio_base = base;
base += uc_priv->gpio_count;
}
@@ -689,9 +685,21 @@ static int gpio_renumber(struct udevice *removed_dev)
return 0;
}
+int gpio_get_number(struct gpio_desc *desc)
+{
+ struct udevice *dev = desc->dev;
+ struct gpio_dev_priv *uc_priv;
+
+ if (!dev)
+ return -1;
+ uc_priv = dev->uclass_priv;
+
+ return uc_priv->gpio_base + desc->offset;
+}
+
static int gpio_post_probe(struct udevice *dev)
{
- struct gpio_dev_priv *uc_priv = dev->uclass_priv;
+ struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
uc_priv->name = calloc(uc_priv->gpio_count, sizeof(char *));
if (!uc_priv->name)
@@ -702,7 +710,7 @@ static int gpio_post_probe(struct udevice *dev)
static int gpio_pre_remove(struct udevice *dev)
{
- struct gpio_dev_priv *uc_priv = dev->uclass_priv;
+ struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
int i;
for (i = 0; i < uc_priv->gpio_count; i++) {
diff --git a/drivers/gpio/intel_ich6_gpio.c b/drivers/gpio/intel_ich6_gpio.c
index 7720cc3dad..7e679a086e 100644
--- a/drivers/gpio/intel_ich6_gpio.c
+++ b/drivers/gpio/intel_ich6_gpio.c
@@ -64,13 +64,13 @@ static int gpio_ich6_ofdata_to_platdata(struct udevice *dev)
pci_dev = PCI_BDF(0, 0x1f, 0);
/* Is the device present? */
- tmpword = pci_read_config16(pci_dev, PCI_VENDOR_ID);
+ tmpword = x86_pci_read_config16(pci_dev, PCI_VENDOR_ID);
if (tmpword != PCI_VENDOR_ID_INTEL) {
debug("%s: wrong VendorID\n", __func__);
return -ENODEV;
}
- tmpword = pci_read_config16(pci_dev, PCI_DEVICE_ID);
+ tmpword = x86_pci_read_config16(pci_dev, PCI_DEVICE_ID);
debug("Found %04x:%04x\n", PCI_VENDOR_ID_INTEL, tmpword);
/*
* We'd like to validate the Device ID too, but pretty much any
@@ -80,34 +80,34 @@ static int gpio_ich6_ofdata_to_platdata(struct udevice *dev)
*/
/* I/O should already be enabled (it's a RO bit). */
- tmpword = pci_read_config16(pci_dev, PCI_COMMAND);
+ tmpword = x86_pci_read_config16(pci_dev, PCI_COMMAND);
if (!(tmpword & PCI_COMMAND_IO)) {
debug("%s: device IO not enabled\n", __func__);
return -ENODEV;
}
/* Header Type must be normal (bits 6-0 only; see spec.) */
- tmpbyte = pci_read_config8(pci_dev, PCI_HEADER_TYPE);
+ tmpbyte = x86_pci_read_config8(pci_dev, PCI_HEADER_TYPE);
if ((tmpbyte & 0x7f) != PCI_HEADER_TYPE_NORMAL) {
debug("%s: invalid Header type\n", __func__);
return -ENODEV;
}
/* Base Class must be a bridge device */
- tmpbyte = pci_read_config8(pci_dev, PCI_CLASS_CODE);
+ tmpbyte = x86_pci_read_config8(pci_dev, PCI_CLASS_CODE);
if (tmpbyte != PCI_CLASS_CODE_BRIDGE) {
debug("%s: invalid class\n", __func__);
return -ENODEV;
}
/* Sub Class must be ISA */
- tmpbyte = pci_read_config8(pci_dev, PCI_CLASS_SUB_CODE);
+ tmpbyte = x86_pci_read_config8(pci_dev, PCI_CLASS_SUB_CODE);
if (tmpbyte != PCI_CLASS_SUB_CODE_BRIDGE_ISA) {
debug("%s: invalid subclass\n", __func__);
return -ENODEV;
}
/* Programming Interface must be 0x00 (no others exist) */
- tmpbyte = pci_read_config8(pci_dev, PCI_CLASS_PROG);
+ tmpbyte = x86_pci_read_config8(pci_dev, PCI_CLASS_PROG);
if (tmpbyte != 0x00) {
debug("%s: invalid interface type\n", __func__);
return -ENODEV;
@@ -123,7 +123,7 @@ static int gpio_ich6_ofdata_to_platdata(struct udevice *dev)
* while on the Ivybridge the bit0 is used to indicate it is an
* I/O space.
*/
- tmplong = pci_read_config32(pci_dev, PCI_CFG_GPIOBASE);
+ tmplong = x86_pci_read_config32(pci_dev, PCI_CFG_GPIOBASE);
if (tmplong == 0x00000000 || tmplong == 0xffffffff) {
debug("%s: unexpected GPIOBASE value\n", __func__);
return -ENODEV;
@@ -151,7 +151,7 @@ static int gpio_ich6_ofdata_to_platdata(struct udevice *dev)
static int ich6_gpio_probe(struct udevice *dev)
{
struct ich6_bank_platdata *plat = dev_get_platdata(dev);
- struct gpio_dev_priv *uc_priv = dev->uclass_priv;
+ struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
struct ich6_bank_priv *bank = dev_get_priv(dev);
if (gd->arch.gpio_map) {
diff --git a/drivers/gpio/mxc_gpio.c b/drivers/gpio/mxc_gpio.c
index 815407bb03..2012f994c8 100644
--- a/drivers/gpio/mxc_gpio.c
+++ b/drivers/gpio/mxc_gpio.c
@@ -266,7 +266,7 @@ static int mxc_gpio_probe(struct udevice *dev)
{
struct mxc_bank_info *bank = dev_get_priv(dev);
struct mxc_gpio_plat *plat = dev_get_platdata(dev);
- struct gpio_dev_priv *uc_priv = dev->uclass_priv;
+ struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
int banknum;
char name[18], *str;
diff --git a/drivers/gpio/omap_gpio.c b/drivers/gpio/omap_gpio.c
index 19fc451079..0a1e12419b 100644
--- a/drivers/gpio/omap_gpio.c
+++ b/drivers/gpio/omap_gpio.c
@@ -309,7 +309,7 @@ static int omap_gpio_probe(struct udevice *dev)
{
struct gpio_bank *bank = dev_get_priv(dev);
struct omap_gpio_platdata *plat = dev_get_platdata(dev);
- struct gpio_dev_priv *uc_priv = dev->uclass_priv;
+ struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
char name[18], *str;
sprintf(name, "GPIO%d_", plat->bank_index);
diff --git a/drivers/gpio/s5p_gpio.c b/drivers/gpio/s5p_gpio.c
index 0a245ba18a..49b1054660 100644
--- a/drivers/gpio/s5p_gpio.c
+++ b/drivers/gpio/s5p_gpio.c
@@ -296,7 +296,7 @@ static const struct dm_gpio_ops gpio_exynos_ops = {
static int gpio_exynos_probe(struct udevice *dev)
{
- struct gpio_dev_priv *uc_priv = dev->uclass_priv;
+ struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
struct exynos_bank_info *priv = dev->priv;
struct exynos_gpio_platdata *plat = dev->platdata;
diff --git a/drivers/gpio/sandbox.c b/drivers/gpio/sandbox.c
index d564c252c7..a9b1efcd06 100644
--- a/drivers/gpio/sandbox.c
+++ b/drivers/gpio/sandbox.c
@@ -24,7 +24,7 @@ struct gpio_state {
/* Access routines for GPIO state */
static u8 *get_gpio_flags(struct udevice *dev, unsigned offset)
{
- struct gpio_dev_priv *uc_priv = dev->uclass_priv;
+ struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
struct gpio_state *state = dev_get_priv(dev);
if (offset >= uc_priv->gpio_count) {
@@ -160,7 +160,7 @@ static const struct dm_gpio_ops gpio_sandbox_ops = {
static int sandbox_gpio_ofdata_to_platdata(struct udevice *dev)
{
- struct gpio_dev_priv *uc_priv = dev->uclass_priv;
+ struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
uc_priv->gpio_count = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
"num-gpios", 0);
@@ -172,7 +172,7 @@ static int sandbox_gpio_ofdata_to_platdata(struct udevice *dev)
static int gpio_sandbox_probe(struct udevice *dev)
{
- struct gpio_dev_priv *uc_priv = dev->uclass_priv;
+ struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
if (dev->of_offset == -1) {
/* Tell the uclass how many GPIOs we have */
diff --git a/drivers/gpio/sunxi_gpio.c b/drivers/gpio/sunxi_gpio.c
index 510123fdf8..cf5c62463e 100644
--- a/drivers/gpio/sunxi_gpio.c
+++ b/drivers/gpio/sunxi_gpio.c
@@ -261,7 +261,7 @@ static char *gpio_bank_name(int bank)
static int gpio_sunxi_probe(struct udevice *dev)
{
struct sunxi_gpio_platdata *plat = dev_get_platdata(dev);
- struct gpio_dev_priv *uc_priv = dev->uclass_priv;
+ struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
/* Tell the uclass how many GPIOs we have */
if (plat) {
diff --git a/drivers/gpio/tegra_gpio.c b/drivers/gpio/tegra_gpio.c
index f870cdbddf..8017e359f5 100644
--- a/drivers/gpio/tegra_gpio.c
+++ b/drivers/gpio/tegra_gpio.c
@@ -295,7 +295,7 @@ static const struct udevice_id tegra_gpio_ids[] = {
static int gpio_tegra_probe(struct udevice *dev)
{
- struct gpio_dev_priv *uc_priv = dev->uclass_priv;
+ struct gpio_dev_priv *uc_priv = dev_get_uclass_priv(dev);
struct tegra_port_info *priv = dev->priv;
struct tegra_gpio_platdata *plat = dev->platdata;
diff --git a/drivers/i2c/Kconfig b/drivers/i2c/Kconfig
index 692810d057..ba43019ab9 100644
--- a/drivers/i2c/Kconfig
+++ b/drivers/i2c/Kconfig
@@ -2,16 +2,13 @@ config DM_I2C
bool "Enable Driver Model for I2C drivers"
depends on DM
help
- Enable driver model for I2C. This SPI flash interface
- (spi_flash_probe(), spi_flash_write(), etc.) is then
- implemented by the SPI flash uclass. There is one standard
- SPI flash driver which knows how to probe most chips
- supported by U-Boot. The uclass interface is defined in
- include/spi_flash.h, but is currently fully compatible
- with the old interface to avoid confusion and duplication
- during the transition parent. SPI and SPI flash must be
- enabled together (it is not possible to use driver model
- for one and not the other).
+ Enable driver model for I2C. The I2C uclass interface: probe, read,
+ write and speed, is implemented with the bus drivers operations,
+ which provide methods for bus setting and data transfer. Each chip
+ device (bus child) info is kept as parent platdata. The interface
+ is defined in include/i2c.h. When i2c bus driver supports the i2c
+ uclass, but the device drivers not, then DM_I2C_COMPAT config can
+ be used as compatibility layer.
config DM_I2C_COMPAT
bool "Enable I2C compatibility layer"
@@ -22,6 +19,45 @@ config DM_I2C_COMPAT
to convert all code for a board in a single commit. It should not
be enabled for any board in an official release.
+config DM_I2C_GPIO
+ bool "Enable Driver Model for software emulated I2C bus driver"
+ depends on DM_I2C && DM_GPIO
+ help
+ Enable the i2c bus driver emulation by using the GPIOs. The bus GPIO
+ configuration is given by the device tree. Kernel-style device tree
+ bindings are supported.
+ Binding info: doc/device-tree-bindings/i2c/i2c-gpio.txt
+
+config SYS_I2C_SANDBOX
+ bool "Sandbox I2C driver"
+ depends on SANDBOX && DM_I2C
+ help
+ Enable I2C support for sandbox. This is an emulation of a real I2C
+ bus. Devices can be attached to the bus using the device tree
+ which specifies the driver to use. As an example, see this device
+ tree fragment from sandbox.dts. It shows that the I2C bus has a
+ single EEPROM at address 0x2c (7-bit address) which is emulated by
+ the driver for "sandbox,i2c-eeprom", which is in
+ drivers/misc/i2c_eeprom_emul.c.
+
+ i2c@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ compatible = "sandbox,i2c";
+ clock-frequency = <400000>;
+ eeprom@2c {
+ reg = <0x2c>;
+ compatible = "i2c-eeprom";
+ emul {
+ compatible = "sandbox,i2c-eeprom";
+ sandbox,filename = "i2c.bin";
+ sandbox,size = <128>;
+ };
+ };
+ };
+
+
config SYS_I2C_UNIPHIER
bool "UniPhier I2C driver"
depends on ARCH_UNIPHIER && DM_I2C
diff --git a/drivers/i2c/Makefile b/drivers/i2c/Makefile
index 26ea854ec8..d9e912f786 100644
--- a/drivers/i2c/Makefile
+++ b/drivers/i2c/Makefile
@@ -6,6 +6,7 @@
#
obj-$(CONFIG_DM_I2C) += i2c-uclass.o
obj-$(CONFIG_DM_I2C_COMPAT) += i2c-uclass-compat.o
+obj-$(CONFIG_DM_I2C_GPIO) += i2c-gpio.o
obj-$(CONFIG_SYS_I2C_ADI) += adi_i2c.o
obj-$(CONFIG_I2C_MV) += mv_i2c.o
diff --git a/drivers/i2c/i2c-gpio.c b/drivers/i2c/i2c-gpio.c
new file mode 100644
index 0000000000..ed899d4777
--- /dev/null
+++ b/drivers/i2c/i2c-gpio.c
@@ -0,0 +1,346 @@
+/*
+ * (C) Copyright 2015, Samsung Electronics
+ * Przemyslaw Marczak <p.marczak@samsung.com>
+ *
+ * This file is based on: drivers/i2c/soft-i2c.c,
+ * with added driver-model support and code cleanup.
+ */
+#include <common.h>
+#include <errno.h>
+#include <dm.h>
+#include <i2c.h>
+#include <asm/gpio.h>
+
+#define DEFAULT_UDELAY 5
+#define RETRIES 0
+#define I2C_ACK 0
+#define I2C_NOACK 1
+
+DECLARE_GLOBAL_DATA_PTR;
+
+enum {
+ PIN_SDA = 0,
+ PIN_SCL,
+ PIN_COUNT,
+};
+
+struct i2c_gpio_bus {
+ /**
+ * udelay - delay [us] between GPIO toggle operations,
+ * which is 1/4 of I2C speed clock period.
+ */
+ int udelay;
+ /* sda, scl */
+ struct gpio_desc gpios[PIN_COUNT];
+};
+
+static int i2c_gpio_sda_get(struct gpio_desc *sda)
+{
+ return dm_gpio_get_value(sda);
+}
+
+static void i2c_gpio_sda_set(struct gpio_desc *sda, int bit)
+{
+ if (bit) {
+ dm_gpio_set_dir_flags(sda, GPIOD_IS_IN);
+ } else {
+ dm_gpio_set_dir_flags(sda, GPIOD_IS_OUT);
+ dm_gpio_set_value(sda, 0);
+ }
+}
+
+static void i2c_gpio_scl_set(struct gpio_desc *scl, int bit)
+{
+ dm_gpio_set_dir_flags(scl, GPIOD_IS_OUT);
+ dm_gpio_set_value(scl, bit);
+}
+
+static void i2c_gpio_write_bit(struct gpio_desc *scl, struct gpio_desc *sda,
+ int delay, uchar bit)
+{
+ i2c_gpio_scl_set(scl, 0);
+ udelay(delay);
+ i2c_gpio_sda_set(sda, bit);
+ udelay(delay);
+ i2c_gpio_scl_set(scl, 1);
+ udelay(2 * delay);
+}
+
+static int i2c_gpio_read_bit(struct gpio_desc *scl, struct gpio_desc *sda,
+ int delay)
+{
+ int value;
+
+ i2c_gpio_scl_set(scl, 1);
+ udelay(delay);
+ value = i2c_gpio_sda_get(sda);
+ udelay(delay);
+ i2c_gpio_scl_set(scl, 0);
+ udelay(2 * delay);
+
+ return value;
+}
+
+/* START: High -> Low on SDA while SCL is High */
+static void i2c_gpio_send_start(struct gpio_desc *scl, struct gpio_desc *sda,
+ int delay)
+{
+ udelay(delay);
+ i2c_gpio_sda_set(sda, 1);
+ udelay(delay);
+ i2c_gpio_scl_set(scl, 1);
+ udelay(delay);
+ i2c_gpio_sda_set(sda, 0);
+ udelay(delay);
+}
+
+/* STOP: Low -> High on SDA while SCL is High */
+static void i2c_gpio_send_stop(struct gpio_desc *scl, struct gpio_desc *sda,
+ int delay)
+{
+ i2c_gpio_scl_set(scl, 0);
+ udelay(delay);
+ i2c_gpio_sda_set(sda, 0);
+ udelay(delay);
+ i2c_gpio_scl_set(scl, 1);
+ udelay(delay);
+ i2c_gpio_sda_set(sda, 1);
+ udelay(delay);
+}
+
+/* ack should be I2C_ACK or I2C_NOACK */
+static void i2c_gpio_send_ack(struct gpio_desc *scl, struct gpio_desc *sda,
+ int delay, int ack)
+{
+ i2c_gpio_write_bit(scl, sda, delay, ack);
+ i2c_gpio_scl_set(scl, 0);
+ udelay(delay);
+}
+
+/**
+ * Send a reset sequence consisting of 9 clocks with the data signal high
+ * to clock any confused device back into an idle state. Also send a
+ * <stop> at the end of the sequence for belts & suspenders.
+ */
+static void i2c_gpio_send_reset(struct gpio_desc *scl, struct gpio_desc *sda,
+ int delay)
+{
+ int j;
+
+ for (j = 0; j < 9; j++)
+ i2c_gpio_write_bit(scl, sda, delay, 1);
+
+ i2c_gpio_send_stop(scl, sda, delay);
+}
+
+/* Set sda high with low clock, before reading slave data */
+static void i2c_gpio_sda_high(struct gpio_desc *scl, struct gpio_desc *sda,
+ int delay)
+{
+ i2c_gpio_scl_set(scl, 0);
+ udelay(delay);
+ i2c_gpio_sda_set(sda, 1);
+ udelay(delay);
+}
+
+/* Send 8 bits and look for an acknowledgement */
+static int i2c_gpio_write_byte(struct gpio_desc *scl, struct gpio_desc *sda,
+ int delay, uchar data)
+{
+ int j;
+ int nack;
+
+ for (j = 0; j < 8; j++) {
+ i2c_gpio_write_bit(scl, sda, delay, data & 0x80);
+ data <<= 1;
+ }
+
+ udelay(delay);
+
+ /* Look for an <ACK>(negative logic) and return it */
+ i2c_gpio_sda_high(scl, sda, delay);
+ nack = i2c_gpio_read_bit(scl, sda, delay);
+
+ return nack; /* not a nack is an ack */
+}
+
+/**
+ * if ack == I2C_ACK, ACK the byte so can continue reading, else
+ * send I2C_NOACK to end the read.
+ */
+static uchar i2c_gpio_read_byte(struct gpio_desc *scl, struct gpio_desc *sda,
+ int delay, int ack)
+{
+ int data;
+ int j;
+
+ i2c_gpio_sda_high(scl, sda, delay);
+ data = 0;
+ for (j = 0; j < 8; j++) {
+ data <<= 1;
+ data |= i2c_gpio_read_bit(scl, sda, delay);
+ }
+ i2c_gpio_send_ack(scl, sda, delay, ack);
+
+ return data;
+}
+
+/* send start and the slave chip address */
+int i2c_send_slave_addr(struct gpio_desc *scl, struct gpio_desc *sda, int delay,
+ uchar chip)
+{
+ i2c_gpio_send_start(scl, sda, delay);
+
+ if (i2c_gpio_write_byte(scl, sda, delay, chip)) {
+ i2c_gpio_send_stop(scl, sda, delay);
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int i2c_gpio_write_data(struct i2c_gpio_bus *bus, uchar chip,
+ uchar *buffer, int len,
+ bool end_with_repeated_start)
+{
+ struct gpio_desc *scl = &bus->gpios[PIN_SCL];
+ struct gpio_desc *sda = &bus->gpios[PIN_SDA];
+ unsigned int delay = bus->udelay;
+ int failures = 0;
+
+ debug("%s: chip %x buffer %p len %d\n", __func__, chip, buffer, len);
+
+ if (i2c_send_slave_addr(scl, sda, delay, chip << 1)) {
+ debug("i2c_write, no chip responded %02X\n", chip);
+ return -EIO;
+ }
+
+ while (len-- > 0) {
+ if (i2c_gpio_write_byte(scl, sda, delay, *buffer++))
+ failures++;
+ }
+
+ if (!end_with_repeated_start) {
+ i2c_gpio_send_stop(scl, sda, delay);
+ return failures;
+ }
+
+ if (i2c_send_slave_addr(scl, sda, delay, (chip << 1) | 0x1)) {
+ debug("i2c_write, no chip responded %02X\n", chip);
+ return -EIO;
+ }
+
+ return failures;
+}
+
+static int i2c_gpio_read_data(struct i2c_gpio_bus *bus, uchar chip,
+ uchar *buffer, int len)
+{
+ struct gpio_desc *scl = &bus->gpios[PIN_SCL];
+ struct gpio_desc *sda = &bus->gpios[PIN_SDA];
+ unsigned int delay = bus->udelay;
+
+ debug("%s: chip %x buffer: %p len %d\n", __func__, chip, buffer, len);
+
+ while (len-- > 0)
+ *buffer++ = i2c_gpio_read_byte(scl, sda, delay, len == 0);
+
+ i2c_gpio_send_stop(scl, sda, delay);
+
+ return 0;
+}
+
+static int i2c_gpio_xfer(struct udevice *dev, struct i2c_msg *msg, int nmsgs)
+{
+ struct i2c_gpio_bus *bus = dev_get_priv(dev);
+ int ret;
+
+ for (; nmsgs > 0; nmsgs--, msg++) {
+ bool next_is_read = nmsgs > 1 && (msg[1].flags & I2C_M_RD);
+
+ if (msg->flags & I2C_M_RD) {
+ ret = i2c_gpio_read_data(bus, msg->addr, msg->buf,
+ msg->len);
+ } else {
+ ret = i2c_gpio_write_data(bus, msg->addr, msg->buf,
+ msg->len, next_is_read);
+ }
+
+ if (ret)
+ return -EREMOTEIO;
+ }
+
+ return 0;
+}
+
+static int i2c_gpio_probe(struct udevice *dev, uint chip, uint chip_flags)
+{
+ struct i2c_gpio_bus *bus = dev_get_priv(dev);
+ struct gpio_desc *scl = &bus->gpios[PIN_SCL];
+ struct gpio_desc *sda = &bus->gpios[PIN_SDA];
+ unsigned int delay = bus->udelay;
+ int ret;
+
+ i2c_gpio_send_start(scl, sda, delay);
+ ret = i2c_gpio_write_byte(scl, sda, delay, (chip << 1) | 0);
+ i2c_gpio_send_stop(scl, sda, delay);
+
+ debug("%s: bus: %d (%s) chip: %x flags: %x ret: %d\n",
+ __func__, dev->seq, dev->name, chip, chip_flags, ret);
+
+ return ret;
+}
+
+static int i2c_gpio_set_bus_speed(struct udevice *dev, unsigned int speed_hz)
+{
+ struct i2c_gpio_bus *bus = dev_get_priv(dev);
+ struct gpio_desc *scl = &bus->gpios[PIN_SCL];
+ struct gpio_desc *sda = &bus->gpios[PIN_SDA];
+
+ bus->udelay = 1000000 / (speed_hz << 2);
+
+ i2c_gpio_send_reset(scl, sda, bus->udelay);
+
+ return 0;
+}
+
+static int i2c_gpio_ofdata_to_platdata(struct udevice *dev)
+{
+ struct i2c_gpio_bus *bus = dev_get_priv(dev);
+ const void *blob = gd->fdt_blob;
+ int node = dev->of_offset;
+ int ret;
+
+ ret = gpio_request_list_by_name(dev, "gpios", bus->gpios,
+ ARRAY_SIZE(bus->gpios), 0);
+ if (ret < 0)
+ goto error;
+
+ bus->udelay = fdtdec_get_int(blob, node, "i2c-gpio,delay-us",
+ DEFAULT_UDELAY);
+
+ return 0;
+error:
+ error("Can't get %s gpios! Error: %d", dev->name, ret);
+ return ret;
+}
+
+static const struct dm_i2c_ops i2c_gpio_ops = {
+ .xfer = i2c_gpio_xfer,
+ .probe_chip = i2c_gpio_probe,
+ .set_bus_speed = i2c_gpio_set_bus_speed,
+};
+
+static const struct udevice_id i2c_gpio_ids[] = {
+ { .compatible = "i2c-gpio" },
+ { }
+};
+
+U_BOOT_DRIVER(i2c_gpio) = {
+ .name = "i2c-gpio",
+ .id = UCLASS_I2C,
+ .of_match = i2c_gpio_ids,
+ .ofdata_to_platdata = i2c_gpio_ofdata_to_platdata,
+ .priv_auto_alloc_size = sizeof(struct i2c_gpio_bus),
+ .ops = &i2c_gpio_ops,
+};
diff --git a/drivers/i2c/i2c-uclass.c b/drivers/i2c/i2c-uclass.c
index b890806a44..f2e95c0881 100644
--- a/drivers/i2c/i2c-uclass.c
+++ b/drivers/i2c/i2c-uclass.c
@@ -330,7 +330,7 @@ int dm_i2c_probe(struct udevice *bus, uint chip_addr, uint chip_flags,
int dm_i2c_set_bus_speed(struct udevice *bus, unsigned int speed)
{
struct dm_i2c_ops *ops = i2c_get_ops(bus);
- struct dm_i2c_bus *i2c = bus->uclass_priv;
+ struct dm_i2c_bus *i2c = dev_get_uclass_priv(bus);
int ret;
/*
@@ -351,7 +351,7 @@ int dm_i2c_set_bus_speed(struct udevice *bus, unsigned int speed)
int dm_i2c_get_bus_speed(struct udevice *bus)
{
struct dm_i2c_ops *ops = i2c_get_ops(bus);
- struct dm_i2c_bus *i2c = bus->uclass_priv;
+ struct dm_i2c_bus *i2c = dev_get_uclass_priv(bus);
if (!ops->get_bus_speed)
return i2c->speed_hz;
@@ -432,7 +432,7 @@ int i2c_chip_ofdata_to_platdata(const void *blob, int node,
static int i2c_post_probe(struct udevice *dev)
{
- struct dm_i2c_bus *i2c = dev->uclass_priv;
+ struct dm_i2c_bus *i2c = dev_get_uclass_priv(dev);
i2c->speed_hz = fdtdec_get_int(gd->fdt_blob, dev->of_offset,
"clock-frequency", 100000);
diff --git a/drivers/i2c/i2c-uniphier-f.c b/drivers/i2c/i2c-uniphier-f.c
index fd28c17399..d29dd4565d 100644
--- a/drivers/i2c/i2c-uniphier-f.c
+++ b/drivers/i2c/i2c-uniphier-f.c
@@ -14,6 +14,7 @@
#include <dm/root.h>
#include <i2c.h>
#include <fdtdec.h>
+#include <mapmem.h>
DECLARE_GLOBAL_DATA_PTR;
diff --git a/drivers/i2c/i2c-uniphier.c b/drivers/i2c/i2c-uniphier.c
index 666272dd0d..c4972ff501 100644
--- a/drivers/i2c/i2c-uniphier.c
+++ b/drivers/i2c/i2c-uniphier.c
@@ -14,6 +14,7 @@
#include <dm/root.h>
#include <i2c.h>
#include <fdtdec.h>
+#include <mapmem.h>
DECLARE_GLOBAL_DATA_PTR;
diff --git a/drivers/i2c/s3c24x0_i2c.c b/drivers/i2c/s3c24x0_i2c.c
index b4ee33f7da..27ff587440 100644
--- a/drivers/i2c/s3c24x0_i2c.c
+++ b/drivers/i2c/s3c24x0_i2c.c
@@ -1348,7 +1348,7 @@ static int s3c_i2c_ofdata_to_platdata(struct udevice *dev)
struct s3c24x0_i2c_bus *i2c_bus = dev_get_priv(dev);
int node, flags;
- i2c_bus->is_highspeed = dev->of_id->data;
+ i2c_bus->is_highspeed = dev_get_driver_data(dev);
node = dev->of_offset;
if (i2c_bus->is_highspeed) {
diff --git a/drivers/i2c/sandbox_i2c.c b/drivers/i2c/sandbox_i2c.c
index a943aa6382..d6adc0f721 100644
--- a/drivers/i2c/sandbox_i2c.c
+++ b/drivers/i2c/sandbox_i2c.c
@@ -50,7 +50,7 @@ static int get_emul(struct udevice *dev, struct udevice **devp,
static int sandbox_i2c_xfer(struct udevice *bus, struct i2c_msg *msg,
int nmsgs)
{
- struct dm_i2c_bus *i2c = bus->uclass_priv;
+ struct dm_i2c_bus *i2c = dev_get_uclass_priv(bus);
struct dm_i2c_ops *ops;
struct udevice *emul, *dev;
bool is_read;
diff --git a/drivers/i2c/tegra_i2c.c b/drivers/i2c/tegra_i2c.c
index f4142870b3..fc95646994 100644
--- a/drivers/i2c/tegra_i2c.c
+++ b/drivers/i2c/tegra_i2c.c
@@ -338,7 +338,7 @@ static int tegra_i2c_probe(struct udevice *dev)
bool is_dvc;
i2c_bus->id = dev->seq;
- i2c_bus->type = dev_get_of_data(dev);
+ i2c_bus->type = dev_get_driver_data(dev);
i2c_bus->regs = (struct i2c_ctlr *)fdtdec_get_addr(blob, node, "reg");
/*
@@ -360,7 +360,7 @@ static int tegra_i2c_probe(struct udevice *dev)
if (i2c_bus->periph_id == -1)
return -EINVAL;
- is_dvc = dev_get_of_data(dev) == TYPE_DVC;
+ is_dvc = dev_get_driver_data(dev) == TYPE_DVC;
if (is_dvc) {
i2c_bus->control =
&((struct dvc_ctlr *)i2c_bus->regs)->control;
@@ -469,7 +469,7 @@ int tegra_i2c_get_dvc_bus(struct udevice **busp)
for (uclass_first_device(UCLASS_I2C, &bus);
bus;
uclass_next_device(&bus)) {
- if (dev_get_of_data(bus) == TYPE_DVC) {
+ if (dev_get_driver_data(bus) == TYPE_DVC) {
*busp = bus;
return 0;
}
diff --git a/drivers/input/cros_ec_keyb.c b/drivers/input/cros_ec_keyb.c
index 49ee7b2c9b..a31aa77102 100644
--- a/drivers/input/cros_ec_keyb.c
+++ b/drivers/input/cros_ec_keyb.c
@@ -198,7 +198,7 @@ static int cros_ec_keyb_decode_fdt(const void *blob, int node,
return -1;
}
config->ghost_filter = fdtdec_get_bool(blob, node,
- "google,ghost-filter");
+ "google,needs-ghost-filter");
return 0;
}
diff --git a/drivers/input/i8042.c b/drivers/input/i8042.c
index ca1604c540..1769c5e80b 100644
--- a/drivers/input/i8042.c
+++ b/drivers/input/i8042.c
@@ -698,7 +698,14 @@ static int kbd_reset(void)
/* Enable Keyboard */
out8(I8042_COMMAND_REG, 0xae);
+ if (kbd_input_empty() == 0)
+ return -1;
+
+ out8(I8042_COMMAND_REG, 0x60);
+ if (kbd_input_empty() == 0)
+ return -1;
+ out8(I8042_DATA_REG, 0xf4);
if (kbd_input_empty() == 0)
return -1;
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 36a8f0d098..0e571d91ea 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -35,6 +35,15 @@ config CROS_EC_LPC
through a legacy port interface, so on x86 machines the main
function of the EC is power and thermal management.
+config CROS_EC_SANDBOX
+ bool "Enable Chrome OS EC sandbox driver"
+ depends on CROS_EC && SANDBOX
+ help
+ Enable a sandbox emulation of the Chrome OS EC. This supports
+ keyboard (use the -l flag to enable the LCD), verified boot context,
+ EC flash read/write/erase support and a few other things. It is
+ enough to perform a Chrome OS verified boot on sandbox.
+
config CROS_EC_SPI
bool "Enable Chrome OS EC SPI driver"
depends on CROS_EC
@@ -44,16 +53,6 @@ config CROS_EC_SPI
provides a faster and more robust interface than I2C but the bugs
are less interesting.
-config DM_CROS_EC
- bool "Enable Driver Model for Chrome OS EC"
- depends on DM
- help
- Enable driver model for the Chrome OS EC interface. This
- allows the cros_ec SPI driver to operate with CONFIG_DM_SPI
- but otherwise makes few changes. Since cros_ec also supports
- LPC (which doesn't support driver model yet), a full
- conversion is not yet possible.
-
config CONFIG_FSL_SEC_MON
bool "Enable FSL SEC_MON Driver"
help
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 6028cd43fb..842209a2ec 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -26,6 +26,7 @@ obj-$(CONFIG_SANDBOX) += i2c_eeprom_emul.o
endif
obj-$(CONFIG_SMSC_LPC47M) += smsc_lpc47m.o
obj-$(CONFIG_STATUS_LED) += status_led.o
+obj-$(CONFIG_SANDBOX) += swap_case.o
obj-$(CONFIG_TWL4030_LED) += twl4030_led.o
obj-$(CONFIG_FSL_IFC) += fsl_ifc.o
obj-$(CONFIG_FSL_SEC_MON) += fsl_sec_mon.o
diff --git a/drivers/misc/cros_ec.c b/drivers/misc/cros_ec.c
index 5846e76c49..982bac788d 100644
--- a/drivers/misc/cros_ec.c
+++ b/drivers/misc/cros_ec.c
@@ -41,10 +41,6 @@ enum {
CROS_EC_CMD_HASH_TIMEOUT_MS = 2000,
};
-#ifndef CONFIG_DM_CROS_EC
-static struct cros_ec_dev static_dev, *last_dev;
-#endif
-
DECLARE_GLOBAL_DATA_PTR;
/* Note: depends on enum ec_current_image */
@@ -211,9 +207,7 @@ static int send_command_proto3(struct cros_ec_dev *dev,
const void *dout, int dout_len,
uint8_t **dinp, int din_len)
{
-#ifdef CONFIG_DM_CROS_EC
struct dm_cros_ec_ops *ops;
-#endif
int out_bytes, in_bytes;
int rv;
@@ -228,28 +222,8 @@ static int send_command_proto3(struct cros_ec_dev *dev,
if (in_bytes < 0)
return in_bytes;
-#ifdef CONFIG_DM_CROS_EC
ops = dm_cros_ec_get_ops(dev->dev);
rv = ops->packet ? ops->packet(dev->dev, out_bytes, in_bytes) : -ENOSYS;
-#else
- switch (dev->interface) {
-#ifdef CONFIG_CROS_EC_SPI
- case CROS_EC_IF_SPI:
- rv = cros_ec_spi_packet(dev, out_bytes, in_bytes);
- break;
-#endif
-#ifdef CONFIG_CROS_EC_SANDBOX
- case CROS_EC_IF_SANDBOX:
- rv = cros_ec_sandbox_packet(dev, out_bytes, in_bytes);
- break;
-#endif
- case CROS_EC_IF_NONE:
- /* TODO: support protocol 3 for LPC, I2C; for now fall through */
- default:
- debug("%s: Unsupported interface\n", __func__);
- rv = -1;
- }
-#endif
if (rv < 0)
return rv;
@@ -261,9 +235,7 @@ static int send_command(struct cros_ec_dev *dev, uint8_t cmd, int cmd_version,
const void *dout, int dout_len,
uint8_t **dinp, int din_len)
{
-#ifdef CONFIG_DM_CROS_EC
struct dm_cros_ec_ops *ops;
-#endif
int ret = -1;
/* Handle protocol version 3 support */
@@ -272,38 +244,9 @@ static int send_command(struct cros_ec_dev *dev, uint8_t cmd, int cmd_version,
dout, dout_len, dinp, din_len);
}
-#ifdef CONFIG_DM_CROS_EC
ops = dm_cros_ec_get_ops(dev->dev);
ret = ops->command(dev->dev, cmd, cmd_version,
(const uint8_t *)dout, dout_len, dinp, din_len);
-#else
- switch (dev->interface) {
-#ifdef CONFIG_CROS_EC_SPI
- case CROS_EC_IF_SPI:
- ret = cros_ec_spi_command(dev, cmd, cmd_version,
- (const uint8_t *)dout, dout_len,
- dinp, din_len);
- break;
-#endif
-#ifdef CONFIG_CROS_EC_I2C
- case CROS_EC_IF_I2C:
- ret = cros_ec_i2c_command(dev, cmd, cmd_version,
- (const uint8_t *)dout, dout_len,
- dinp, din_len);
- break;
-#endif
-#ifdef CONFIG_CROS_EC_LPC
- case CROS_EC_IF_LPC:
- ret = cros_ec_lpc_command(dev, cmd, cmd_version,
- (const uint8_t *)dout, dout_len,
- dinp, din_len);
- break;
-#endif
- case CROS_EC_IF_NONE:
- default:
- ret = -1;
- }
-#endif
return ret;
}
@@ -681,11 +624,15 @@ static int cros_ec_check_version(struct cros_ec_dev *dev)
struct ec_params_hello req;
struct ec_response_hello *resp;
-#ifdef CONFIG_CROS_EC_LPC
- /* LPC has its own way of doing this */
- if (dev->interface == CROS_EC_IF_LPC)
- return cros_ec_lpc_check_version(dev);
-#endif
+ struct dm_cros_ec_ops *ops;
+ int ret;
+
+ ops = dm_cros_ec_get_ops(dev->dev);
+ if (ops->check_version) {
+ ret = ops->check_version(dev->dev);
+ if (ret)
+ return ret;
+ }
/*
* TODO(sjg@chromium.org).
@@ -1015,79 +962,9 @@ int cros_ec_get_ldo(struct cros_ec_dev *dev, uint8_t index, uint8_t *state)
return 0;
}
-#ifndef CONFIG_DM_CROS_EC
-/**
- * Decode EC interface details from the device tree and allocate a suitable
- * device.
- *
- * @param blob Device tree blob
- * @param node Node to decode from
- * @param devp Returns a pointer to the new allocated device
- * @return 0 if ok, -1 on error
- */
-static int cros_ec_decode_fdt(const void *blob, int node,
- struct cros_ec_dev **devp)
-{
- enum fdt_compat_id compat;
- struct cros_ec_dev *dev;
- int parent;
-
- /* See what type of parent we are inside (this is expensive) */
- parent = fdt_parent_offset(blob, node);
- if (parent < 0) {
- debug("%s: Cannot find node parent\n", __func__);
- return -1;
- }
-
- dev = &static_dev;
- dev->node = node;
- dev->parent_node = parent;
-
- compat = fdtdec_lookup(blob, parent);
- switch (compat) {
-#ifdef CONFIG_CROS_EC_SPI
- case COMPAT_SAMSUNG_EXYNOS_SPI:
- dev->interface = CROS_EC_IF_SPI;
- if (cros_ec_spi_decode_fdt(dev, blob))
- return -1;
- break;
-#endif
-#ifdef CONFIG_CROS_EC_I2C
- case COMPAT_SAMSUNG_S3C2440_I2C:
- dev->interface = CROS_EC_IF_I2C;
- if (cros_ec_i2c_decode_fdt(dev, blob))
- return -1;
- break;
-#endif
-#ifdef CONFIG_CROS_EC_LPC
- case COMPAT_INTEL_LPC:
- dev->interface = CROS_EC_IF_LPC;
- break;
-#endif
-#ifdef CONFIG_CROS_EC_SANDBOX
- case COMPAT_SANDBOX_HOST_EMULATION:
- dev->interface = CROS_EC_IF_SANDBOX;
- break;
-#endif
- default:
- debug("%s: Unknown compat id %d\n", __func__, compat);
- return -1;
- }
-
- gpio_request_by_name_nodev(blob, node, "ec-interrupt", 0, &dev->ec_int,
- GPIOD_IS_IN);
- dev->optimise_flash_write = fdtdec_get_bool(blob, node,
- "optimise-flash-write");
- *devp = dev;
-
- return 0;
-}
-#endif
-
-#ifdef CONFIG_DM_CROS_EC
int cros_ec_register(struct udevice *dev)
{
- struct cros_ec_dev *cdev = dev->uclass_priv;
+ struct cros_ec_dev *cdev = dev_get_uclass_priv(dev);
const void *blob = gd->fdt_blob;
int node = dev->of_offset;
char id[MSG_BYTES];
@@ -1113,94 +990,6 @@ int cros_ec_register(struct udevice *dev)
return 0;
}
-#else
-int cros_ec_init(const void *blob, struct cros_ec_dev **cros_ecp)
-{
- struct cros_ec_dev *dev;
- char id[MSG_BYTES];
-#ifdef CONFIG_DM_CROS_EC
- struct udevice *udev;
- int ret;
-
- ret = uclass_find_device(UCLASS_CROS_EC, 0, &udev);
- if (!ret)
- device_remove(udev);
- ret = uclass_get_device(UCLASS_CROS_EC, 0, &udev);
- if (ret)
- return ret;
- dev = udev->uclass_priv;
- return 0;
-#else
- int node = 0;
-
- *cros_ecp = NULL;
- do {
- node = fdtdec_next_compatible(blob, node,
- COMPAT_GOOGLE_CROS_EC);
- if (node < 0) {
- debug("%s: Node not found\n", __func__);
- return 0;
- }
- } while (!fdtdec_get_is_enabled(blob, node));
-
- if (cros_ec_decode_fdt(blob, node, &dev)) {
- debug("%s: Failed to decode device.\n", __func__);
- return -CROS_EC_ERR_FDT_DECODE;
- }
-
- switch (dev->interface) {
-#ifdef CONFIG_CROS_EC_SPI
- case CROS_EC_IF_SPI:
- if (cros_ec_spi_init(dev, blob)) {
- debug("%s: Could not setup SPI interface\n", __func__);
- return -CROS_EC_ERR_DEV_INIT;
- }
- break;
-#endif
-#ifdef CONFIG_CROS_EC_I2C
- case CROS_EC_IF_I2C:
- if (cros_ec_i2c_init(dev, blob))
- return -CROS_EC_ERR_DEV_INIT;
- break;
-#endif
-#ifdef CONFIG_CROS_EC_LPC
- case CROS_EC_IF_LPC:
- if (cros_ec_lpc_init(dev, blob))
- return -CROS_EC_ERR_DEV_INIT;
- break;
-#endif
-#ifdef CONFIG_CROS_EC_SANDBOX
- case CROS_EC_IF_SANDBOX:
- if (cros_ec_sandbox_init(dev, blob))
- return -CROS_EC_ERR_DEV_INIT;
- break;
-#endif
- case CROS_EC_IF_NONE:
- default:
- return 0;
- }
-#endif
-
- if (cros_ec_check_version(dev)) {
- debug("%s: Could not detect CROS-EC version\n", __func__);
- return -CROS_EC_ERR_CHECK_VERSION;
- }
-
- if (cros_ec_read_id(dev, id, sizeof(id))) {
- debug("%s: Could not read KBC ID\n", __func__);
- return -CROS_EC_ERR_READ_ID;
- }
-
- /* Remember this device for use by the cros_ec command */
- *cros_ecp = dev;
-#ifndef CONFIG_DM_CROS_EC
- last_dev = dev;
-#endif
- debug("Google Chrome EC CROS-EC driver ready, id '%s'\n", id);
-
- return 0;
-}
-#endif
int cros_ec_decode_region(int argc, char * const argv[])
{
@@ -1583,9 +1372,7 @@ static int cros_ec_i2c_passthrough(struct cros_ec_dev *dev, int flag,
static int do_cros_ec(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
{
struct cros_ec_dev *dev;
-#ifdef CONFIG_DM_CROS_EC
struct udevice *udev;
-#endif
const char *cmd;
int ret = 0;
@@ -1594,31 +1381,24 @@ static int do_cros_ec(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
cmd = argv[1];
if (0 == strcmp("init", cmd)) {
-#ifndef CONFIG_DM_CROS_EC
- ret = cros_ec_init(gd->fdt_blob, &dev);
+ /* Remove any existing device */
+ ret = uclass_find_device(UCLASS_CROS_EC, 0, &udev);
+ if (!ret)
+ device_remove(udev);
+ ret = uclass_get_device(UCLASS_CROS_EC, 0, &udev);
if (ret) {
printf("Could not init cros_ec device (err %d)\n", ret);
return 1;
}
-#endif
return 0;
}
-#ifdef CONFIG_DM_CROS_EC
ret = uclass_get_device(UCLASS_CROS_EC, 0, &udev);
if (ret) {
printf("Cannot get cros-ec device (err=%d)\n", ret);
return 1;
}
- dev = udev->uclass_priv;
-#else
- /* Just use the last allocated device; there should be only one */
- if (!last_dev) {
- printf("No CROS-EC device available\n");
- return 1;
- }
- dev = last_dev;
-#endif
+ dev = dev_get_uclass_priv(udev);
if (0 == strcmp("id", cmd)) {
char id[MSG_BYTES];
@@ -1876,10 +1656,8 @@ U_BOOT_CMD(
);
#endif
-#ifdef CONFIG_DM_CROS_EC
UCLASS_DRIVER(cros_ec) = {
.id = UCLASS_CROS_EC,
.name = "cros_ec",
.per_device_auto_alloc_size = sizeof(struct cros_ec_dev),
};
-#endif
diff --git a/drivers/misc/cros_ec_i2c.c b/drivers/misc/cros_ec_i2c.c
index f9bc9750d4..3de18b2d2a 100644
--- a/drivers/misc/cros_ec_i2c.c
+++ b/drivers/misc/cros_ec_i2c.c
@@ -28,7 +28,7 @@ static int cros_ec_i2c_command(struct udevice *udev, uint8_t cmd,
int cmd_version, const uint8_t *dout,
int dout_len, uint8_t **dinp, int din_len)
{
- struct cros_ec_dev *dev = udev->uclass_priv;
+ struct cros_ec_dev *dev = dev_get_uclass_priv(udev);
/* version8, cmd8, arglen8, out8[dout_len], csum8 */
int out_bytes = dout_len + 4;
/* response8, arglen8, in8[din_len], checksum8 */
@@ -139,12 +139,12 @@ static struct dm_cros_ec_ops cros_ec_ops = {
};
static const struct udevice_id cros_ec_ids[] = {
- { .compatible = "google,cros-ec" },
+ { .compatible = "google,cros-ec-i2c" },
{ }
};
U_BOOT_DRIVER(cros_ec_i2c) = {
- .name = "cros_ec",
+ .name = "cros_ec_i2c",
.id = UCLASS_CROS_EC,
.of_match = cros_ec_ids,
.probe = cros_ec_probe,
diff --git a/drivers/misc/cros_ec_lpc.c b/drivers/misc/cros_ec_lpc.c
index 07624a136f..78378410f4 100644
--- a/drivers/misc/cros_ec_lpc.c
+++ b/drivers/misc/cros_ec_lpc.c
@@ -14,6 +14,7 @@
*/
#include <common.h>
+#include <dm.h>
#include <command.h>
#include <cros_ec.h>
#include <asm/io.h>
@@ -40,10 +41,11 @@ static int wait_for_sync(struct cros_ec_dev *dev)
return 0;
}
-int cros_ec_lpc_command(struct cros_ec_dev *dev, uint8_t cmd, int cmd_version,
+int cros_ec_lpc_command(struct udevice *udev, uint8_t cmd, int cmd_version,
const uint8_t *dout, int dout_len,
uint8_t **dinp, int din_len)
{
+ struct cros_ec_dev *dev = dev_get_uclass_priv(udev);
const int cmd_addr = EC_LPC_ADDR_HOST_CMD;
const int data_addr = EC_LPC_ADDR_HOST_DATA;
const int args_addr = EC_LPC_ADDR_HOST_ARGS;
@@ -178,7 +180,7 @@ int cros_ec_lpc_init(struct cros_ec_dev *dev, const void *blob)
* seeing whether the EC sets the EC_HOST_ARGS_FLAG_FROM_HOST flag
* in args when it responds.
*/
-int cros_ec_lpc_check_version(struct cros_ec_dev *dev)
+static int cros_ec_lpc_check_version(struct udevice *dev)
{
if (inb(EC_LPC_ADDR_MEMMAP + EC_MEMMAP_ID) == 'E' &&
inb(EC_LPC_ADDR_MEMMAP + EC_MEMMAP_ID + 1)
@@ -192,3 +194,26 @@ int cros_ec_lpc_check_version(struct cros_ec_dev *dev)
printf("%s: ERROR: old EC interface not supported\n", __func__);
return -1;
}
+
+static int cros_ec_probe(struct udevice *dev)
+{
+ return cros_ec_register(dev);
+}
+
+static struct dm_cros_ec_ops cros_ec_ops = {
+ .command = cros_ec_lpc_command,
+ .check_version = cros_ec_lpc_check_version,
+};
+
+static const struct udevice_id cros_ec_ids[] = {
+ { .compatible = "google,cros-ec-lpc" },
+ { }
+};
+
+U_BOOT_DRIVER(cros_ec_lpc) = {
+ .name = "cros_ec_lpc",
+ .id = UCLASS_CROS_EC,
+ .of_match = cros_ec_ids,
+ .probe = cros_ec_probe,
+ .ops = &cros_ec_ops,
+};
diff --git a/drivers/misc/cros_ec_sandbox.c b/drivers/misc/cros_ec_sandbox.c
index 99cc5297cf..df41e82bc9 100644
--- a/drivers/misc/cros_ec_sandbox.c
+++ b/drivers/misc/cros_ec_sandbox.c
@@ -467,17 +467,10 @@ static int process_cmd(struct ec_state *ec,
return len;
}
-#ifdef CONFIG_DM_CROS_EC
int cros_ec_sandbox_packet(struct udevice *udev, int out_bytes, int in_bytes)
{
- struct cros_ec_dev *dev = udev->uclass_priv;
+ struct cros_ec_dev *dev = dev_get_uclass_priv(udev);
struct ec_state *ec = dev_get_priv(dev->dev);
-#else
-int cros_ec_sandbox_packet(struct cros_ec_dev *dev, int out_bytes,
- int in_bytes)
-{
- struct ec_state *ec = &s_state;
-#endif
struct ec_host_request *req_hdr = (struct ec_host_request *)dev->dout;
const void *req_data = req_hdr + 1;
struct ec_host_response *resp_hdr = (struct ec_host_response *)dev->din;
@@ -500,18 +493,9 @@ int cros_ec_sandbox_packet(struct cros_ec_dev *dev, int out_bytes,
return in_bytes;
}
-int cros_ec_sandbox_decode_fdt(struct cros_ec_dev *dev, const void *blob)
-{
- return 0;
-}
-
void cros_ec_check_keyboard(struct cros_ec_dev *dev)
{
-#ifdef CONFIG_DM_CROS_EC
struct ec_state *ec = dev_get_priv(dev->dev);
-#else
- struct ec_state *ec = &s_state;
-#endif
ulong start;
printf("Press keys for EC to detect on reset (ESC=recovery)...");
@@ -525,7 +509,6 @@ void cros_ec_check_keyboard(struct cros_ec_dev *dev)
}
}
-#ifdef CONFIG_DM_CROS_EC
int cros_ec_probe(struct udevice *dev)
{
struct ec_state *ec = dev->priv;
@@ -569,76 +552,20 @@ int cros_ec_probe(struct udevice *dev)
return cros_ec_register(dev);
}
-#else
-
-/**
- * Initialize sandbox EC emulation.
- *
- * @param dev CROS_EC device
- * @param blob Device tree blob
- * @return 0 if ok, -1 on error
- */
-int cros_ec_sandbox_init(struct cros_ec_dev *dev, const void *blob)
-{
- struct ec_state *ec = &s_state;
- int node;
- int err;
-
- node = fdtdec_next_compatible(blob, 0, COMPAT_GOOGLE_CROS_EC);
- if (node < 0) {
- debug("Failed to find chrome-ec node'\n");
- return -1;
- }
-
- err = cros_ec_decode_ec_flash(blob, node, &ec->ec_config);
- if (err)
- return err;
-
- node = fdtdec_next_compatible(blob, 0, COMPAT_GOOGLE_CROS_EC_KEYB);
- if (node < 0) {
- debug("%s: No cros_ec keyboard found\n", __func__);
- } else if (keyscan_read_fdt_matrix(ec, blob, node)) {
- debug("%s: Could not read key matrix\n", __func__);
- return -1;
- }
-
- /* If we loaded EC data, check that the length matches */
- if (ec->flash_data &&
- ec->flash_data_len != ec->ec_config.flash.length) {
- printf("EC data length is %x, expected %x, discarding data\n",
- ec->flash_data_len, ec->ec_config.flash.length);
- os_free(ec->flash_data);
- ec->flash_data = NULL;
- }
-
- /* Otherwise allocate the memory */
- if (!ec->flash_data) {
- ec->flash_data_len = ec->ec_config.flash.length;
- ec->flash_data = os_malloc(ec->flash_data_len);
- if (!ec->flash_data)
- return -ENOMEM;
- }
-
- return 0;
-}
-#endif
-
-#ifdef CONFIG_DM_CROS_EC
struct dm_cros_ec_ops cros_ec_ops = {
.packet = cros_ec_sandbox_packet,
};
static const struct udevice_id cros_ec_ids[] = {
- { .compatible = "google,cros-ec" },
+ { .compatible = "google,cros-ec-sandbox" },
{ }
};
U_BOOT_DRIVER(cros_ec_sandbox) = {
- .name = "cros_ec",
+ .name = "cros_ec_sandbox",
.id = UCLASS_CROS_EC,
.of_match = cros_ec_ids,
.probe = cros_ec_probe,
.priv_auto_alloc_size = sizeof(struct ec_state),
.ops = &cros_ec_ops,
};
-#endif
diff --git a/drivers/misc/cros_ec_spi.c b/drivers/misc/cros_ec_spi.c
index 9359c56e87..ac2ee86eda 100644
--- a/drivers/misc/cros_ec_spi.c
+++ b/drivers/misc/cros_ec_spi.c
@@ -23,7 +23,7 @@ DECLARE_GLOBAL_DATA_PTR;
int cros_ec_spi_packet(struct udevice *udev, int out_bytes, int in_bytes)
{
- struct cros_ec_dev *dev = udev->uclass_priv;
+ struct cros_ec_dev *dev = dev_get_uclass_priv(udev);
struct spi_slave *slave = dev_get_parentdata(dev->dev);
int rv;
@@ -66,7 +66,7 @@ int cros_ec_spi_command(struct udevice *udev, uint8_t cmd, int cmd_version,
const uint8_t *dout, int dout_len,
uint8_t **dinp, int din_len)
{
- struct cros_ec_dev *dev = udev->uclass_priv;
+ struct cros_ec_dev *dev = dev_get_uclass_priv(udev);
struct spi_slave *slave = dev_get_parentdata(dev->dev);
int in_bytes = din_len + 4; /* status, length, checksum, trailer */
uint8_t *out;
@@ -165,12 +165,12 @@ static struct dm_cros_ec_ops cros_ec_ops = {
};
static const struct udevice_id cros_ec_ids[] = {
- { .compatible = "google,cros-ec" },
+ { .compatible = "google,cros-ec-spi" },
{ }
};
U_BOOT_DRIVER(cros_ec_spi) = {
- .name = "cros_ec",
+ .name = "cros_ec_spi",
.id = UCLASS_CROS_EC,
.of_match = cros_ec_ids,
.probe = cros_ec_probe,
diff --git a/drivers/misc/swap_case.c b/drivers/misc/swap_case.c
new file mode 100644
index 0000000000..f6028ba332
--- /dev/null
+++ b/drivers/misc/swap_case.c
@@ -0,0 +1,285 @@
+/*
+ * PCI emulation device which swaps the case of text
+ *
+ * Copyright (c) 2014 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <pci.h>
+#include <asm/test.h>
+#include <linux/ctype.h>
+
+/**
+ * struct swap_case_platdata - platform data for this device
+ *
+ * @command: Current PCI command value
+ * @bar: Current base address values
+ */
+struct swap_case_platdata {
+ u16 command;
+ u32 bar[2];
+};
+
+#define offset_to_barnum(offset) \
+ (((offset) - PCI_BASE_ADDRESS_0) / sizeof(u32))
+
+enum {
+ MEM_TEXT_SIZE = 0x100,
+};
+
+enum swap_case_op {
+ OP_TO_LOWER,
+ OP_TO_UPPER,
+ OP_SWAP,
+};
+
+static struct pci_bar {
+ int type;
+ u32 size;
+} barinfo[] = {
+ { PCI_BASE_ADDRESS_SPACE_IO, 1 },
+ { PCI_BASE_ADDRESS_MEM_TYPE_32, MEM_TEXT_SIZE },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+ { 0, 0 },
+};
+
+struct swap_case_priv {
+ enum swap_case_op op;
+ char mem_text[MEM_TEXT_SIZE];
+};
+
+static int sandbox_swap_case_get_devfn(struct udevice *dev)
+{
+ struct pci_child_platdata *plat = dev_get_parent_platdata(dev);
+
+ return plat->devfn;
+}
+
+static int sandbox_swap_case_read_config(struct udevice *emul, uint offset,
+ ulong *valuep, enum pci_size_t size)
+{
+ struct swap_case_platdata *plat = dev_get_platdata(emul);
+
+ switch (offset) {
+ case PCI_COMMAND:
+ *valuep = plat->command;
+ break;
+ case PCI_HEADER_TYPE:
+ *valuep = 0;
+ break;
+ case PCI_VENDOR_ID:
+ *valuep = SANDBOX_PCI_VENDOR_ID;
+ break;
+ case PCI_DEVICE_ID:
+ *valuep = SANDBOX_PCI_DEVICE_ID;
+ break;
+ case PCI_CLASS_DEVICE:
+ if (size == PCI_SIZE_8) {
+ *valuep = SANDBOX_PCI_CLASS_SUB_CODE;
+ } else {
+ *valuep = (SANDBOX_PCI_CLASS_CODE << 8) |
+ SANDBOX_PCI_CLASS_SUB_CODE;
+ }
+ break;
+ case PCI_CLASS_CODE:
+ *valuep = SANDBOX_PCI_CLASS_CODE;
+ break;
+ case PCI_BASE_ADDRESS_0:
+ case PCI_BASE_ADDRESS_1:
+ case PCI_BASE_ADDRESS_2:
+ case PCI_BASE_ADDRESS_3:
+ case PCI_BASE_ADDRESS_4:
+ case PCI_BASE_ADDRESS_5: {
+ int barnum;
+ u32 *bar, result;
+
+ barnum = offset_to_barnum(offset);
+ bar = &plat->bar[barnum];
+
+ result = *bar;
+ if (*bar == 0xffffffff) {
+ if (barinfo[barnum].type) {
+ result = (~(barinfo[barnum].size - 1) &
+ PCI_BASE_ADDRESS_IO_MASK) |
+ PCI_BASE_ADDRESS_SPACE_IO;
+ } else {
+ result = (~(barinfo[barnum].size - 1) &
+ PCI_BASE_ADDRESS_MEM_MASK) |
+ PCI_BASE_ADDRESS_MEM_TYPE_32;
+ }
+ }
+ debug("r bar %d=%x\n", barnum, result);
+ *valuep = result;
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static int sandbox_swap_case_write_config(struct udevice *emul, uint offset,
+ ulong value, enum pci_size_t size)
+{
+ struct swap_case_platdata *plat = dev_get_platdata(emul);
+
+ switch (offset) {
+ case PCI_COMMAND:
+ plat->command = value;
+ break;
+ case PCI_BASE_ADDRESS_0:
+ case PCI_BASE_ADDRESS_1: {
+ int barnum;
+ u32 *bar;
+
+ barnum = offset_to_barnum(offset);
+ bar = &plat->bar[barnum];
+
+ debug("w bar %d=%lx\n", barnum, value);
+ *bar = value;
+ break;
+ }
+ }
+
+ return 0;
+}
+
+static int sandbox_swap_case_find_bar(struct udevice *emul, unsigned int addr,
+ int *barnump, unsigned int *offsetp)
+{
+ struct swap_case_platdata *plat = dev_get_platdata(emul);
+ int barnum;
+
+ for (barnum = 0; barnum < ARRAY_SIZE(barinfo); barnum++) {
+ unsigned int size = barinfo[barnum].size;
+
+ if (addr >= plat->bar[barnum] &&
+ addr < plat->bar[barnum] + size) {
+ *barnump = barnum;
+ *offsetp = addr - plat->bar[barnum];
+ return 0;
+ }
+ }
+ *barnump = -1;
+
+ return -ENOENT;
+}
+
+static void sandbox_swap_case_do_op(enum swap_case_op op, char *str, int len)
+{
+ for (; len > 0; len--, str++) {
+ switch (op) {
+ case OP_TO_UPPER:
+ *str = toupper(*str);
+ break;
+ case OP_TO_LOWER:
+ *str = tolower(*str);
+ break;
+ case OP_SWAP:
+ if (isupper(*str))
+ *str = tolower(*str);
+ else
+ *str = toupper(*str);
+ break;
+ }
+ }
+}
+
+int sandbox_swap_case_read_io(struct udevice *dev, unsigned int addr,
+ ulong *valuep, enum pci_size_t size)
+{
+ struct swap_case_priv *priv = dev_get_priv(dev);
+ unsigned int offset;
+ int barnum;
+ int ret;
+
+ ret = sandbox_swap_case_find_bar(dev, addr, &barnum, &offset);
+ if (ret)
+ return ret;
+
+ if (barnum == 0 && offset == 0)
+ *valuep = (*valuep & ~0xff) | priv->op;
+
+ return 0;
+}
+
+int sandbox_swap_case_write_io(struct udevice *dev, unsigned int addr,
+ ulong value, enum pci_size_t size)
+{
+ struct swap_case_priv *priv = dev_get_priv(dev);
+ unsigned int offset;
+ int barnum;
+ int ret;
+
+ ret = sandbox_swap_case_find_bar(dev, addr, &barnum, &offset);
+ if (ret)
+ return ret;
+ if (barnum == 0 && offset == 0)
+ priv->op = value;
+
+ return 0;
+}
+
+static int sandbox_swap_case_map_physmem(struct udevice *dev,
+ phys_addr_t addr, unsigned long *lenp, void **ptrp)
+{
+ struct swap_case_priv *priv = dev_get_priv(dev);
+ unsigned int offset, avail;
+ int barnum;
+ int ret;
+
+ ret = sandbox_swap_case_find_bar(dev, addr, &barnum, &offset);
+ if (ret)
+ return ret;
+ if (barnum == 1) {
+ *ptrp = priv->mem_text + offset;
+ avail = barinfo[1].size - offset;
+ if (avail > barinfo[1].size)
+ *lenp = 0;
+ else
+ *lenp = min(*lenp, (ulong)avail);
+
+ return 0;
+ }
+
+ return -ENOENT;
+}
+
+static int sandbox_swap_case_unmap_physmem(struct udevice *dev,
+ const void *vaddr, unsigned long len)
+{
+ struct swap_case_priv *priv = dev_get_priv(dev);
+
+ sandbox_swap_case_do_op(priv->op, (void *)vaddr, len);
+
+ return 0;
+}
+
+struct dm_pci_emul_ops sandbox_swap_case_emul_ops = {
+ .get_devfn = sandbox_swap_case_get_devfn,
+ .read_config = sandbox_swap_case_read_config,
+ .write_config = sandbox_swap_case_write_config,
+ .read_io = sandbox_swap_case_read_io,
+ .write_io = sandbox_swap_case_write_io,
+ .map_physmem = sandbox_swap_case_map_physmem,
+ .unmap_physmem = sandbox_swap_case_unmap_physmem,
+};
+
+static const struct udevice_id sandbox_swap_case_ids[] = {
+ { .compatible = "sandbox,swap-case" },
+ { }
+};
+
+U_BOOT_DRIVER(sandbox_swap_case_emul) = {
+ .name = "sandbox_swap_case_emul",
+ .id = UCLASS_PCI_EMUL,
+ .of_match = sandbox_swap_case_ids,
+ .ops = &sandbox_swap_case_emul_ops,
+ .priv_auto_alloc_size = sizeof(struct swap_case_priv),
+ .platdata_auto_alloc_size = sizeof(struct swap_case_platdata),
+};
diff --git a/drivers/mtd/spi/Kconfig b/drivers/mtd/spi/Kconfig
index 2dc46b4b34..ac6d09f928 100644
--- a/drivers/mtd/spi/Kconfig
+++ b/drivers/mtd/spi/Kconfig
@@ -1,6 +1,6 @@
config DM_SPI_FLASH
bool "Enable Driver Model for SPI flash"
- depends on DM && SPI
+ depends on DM && DM_SPI
help
Enable driver model for SPI flash. This SPI flash interface
(spi_flash_probe(), spi_flash_write(), etc.) is then
@@ -12,3 +12,13 @@ config DM_SPI_FLASH
during the transition parent. SPI and SPI flash must be
enabled together (it is not possible to use driver model
for one and not the other).
+
+config SPI_FLASH_SANDBOX
+ bool "Support sandbox SPI flash device"
+ depends on SANDBOX && DM_SPI_FLASH
+ help
+ Since sandbox cannot access real devices, an emulation mechanism is
+ provided instead. Drivers can be connected up to the sandbox SPI
+ bus (see CONFIG_SANDBOX_SPI) and SPI traffic will be routed to this
+ device. Typically the contents of the emulated SPI flash device is
+ stored in a file on the host filesystem.
diff --git a/drivers/mtd/spi/sf-uclass.c b/drivers/mtd/spi/sf-uclass.c
index 376d815026..4b25902b8d 100644
--- a/drivers/mtd/spi/sf-uclass.c
+++ b/drivers/mtd/spi/sf-uclass.c
@@ -11,6 +11,22 @@
#include <dm/device-internal.h>
#include "sf_internal.h"
+int spi_flash_read_dm(struct udevice *dev, u32 offset, size_t len, void *buf)
+{
+ return sf_get_ops(dev)->read(dev, offset, len, buf);
+}
+
+int spi_flash_write_dm(struct udevice *dev, u32 offset, size_t len,
+ const void *buf)
+{
+ return sf_get_ops(dev)->write(dev, offset, len, buf);
+}
+
+int spi_flash_erase_dm(struct udevice *dev, u32 offset, size_t len)
+{
+ return sf_get_ops(dev)->erase(dev, offset, len);
+}
+
/*
* TODO(sjg@chromium.org): This is an old-style function. We should remove
* it when all SPI flash drivers use dm
@@ -23,7 +39,7 @@ struct spi_flash *spi_flash_probe(unsigned int bus, unsigned int cs,
if (spi_flash_probe_bus_cs(bus, cs, max_hz, spi_mode, &dev))
return NULL;
- return dev->uclass_priv;
+ return dev_get_uclass_priv(dev);
}
void spi_flash_free(struct spi_flash *flash)
diff --git a/drivers/mtd/spi/sf_probe.c b/drivers/mtd/spi/sf_probe.c
index 4103723859..d19138d907 100644
--- a/drivers/mtd/spi/sf_probe.c
+++ b/drivers/mtd/spi/sf_probe.c
@@ -13,6 +13,7 @@
#include <errno.h>
#include <fdtdec.h>
#include <malloc.h>
+#include <mapmem.h>
#include <spi.h>
#include <spi_flash.h>
#include <asm/io.h>
@@ -458,7 +459,7 @@ void spi_flash_free(struct spi_flash *flash)
static int spi_flash_std_read(struct udevice *dev, u32 offset, size_t len,
void *buf)
{
- struct spi_flash *flash = dev->uclass_priv;
+ struct spi_flash *flash = dev_get_uclass_priv(dev);
return spi_flash_cmd_read_ops(flash, offset, len, buf);
}
@@ -466,14 +467,14 @@ static int spi_flash_std_read(struct udevice *dev, u32 offset, size_t len,
int spi_flash_std_write(struct udevice *dev, u32 offset, size_t len,
const void *buf)
{
- struct spi_flash *flash = dev->uclass_priv;
+ struct spi_flash *flash = dev_get_uclass_priv(dev);
return spi_flash_cmd_write_ops(flash, offset, len, buf);
}
int spi_flash_std_erase(struct udevice *dev, u32 offset, size_t len)
{
- struct spi_flash *flash = dev->uclass_priv;
+ struct spi_flash *flash = dev_get_uclass_priv(dev);
return spi_flash_cmd_erase_ops(flash, offset, len);
}
@@ -484,7 +485,7 @@ int spi_flash_std_probe(struct udevice *dev)
struct dm_spi_slave_platdata *plat = dev_get_parent_platdata(dev);
struct spi_flash *flash;
- flash = dev->uclass_priv;
+ flash = dev_get_uclass_priv(dev);
flash->dev = dev;
debug("%s: slave=%p, cs=%d\n", __func__, slave, plat->cs);
return spi_flash_probe_slave(slave, flash);
diff --git a/drivers/net/4xx_enet.c b/drivers/net/4xx_enet.c
index 381ec42864..3c30f42b42 100644
--- a/drivers/net/4xx_enet.c
+++ b/drivers/net/4xx_enet.c
@@ -1350,7 +1350,7 @@ get_speed:
for (i = 0; i < NUM_RX_BUFF; i++) {
hw_p->rx[i].ctrl = 0;
hw_p->rx[i].data_len = 0;
- hw_p->rx[i].data_ptr = (char *)NetRxPackets[i];
+ hw_p->rx[i].data_ptr = (char *)net_rx_packets[i];
if ((NUM_RX_BUFF - 1) == i)
hw_p->rx[i].ctrl |= MAL_RX_CTRL_WRAP;
hw_p->rx[i].ctrl |= MAL_RX_CTRL_EMPTY | MAL_RX_CTRL_INTR;
@@ -1719,8 +1719,6 @@ static void mal_err (struct eth_device *dev, unsigned long isr,
unsigned long uic, unsigned long maldef,
unsigned long mal_errr)
{
- EMAC_4XX_HW_PST hw_p = dev->priv;
-
mtdcr (MAL0_ESR, isr); /* clear interrupt */
/* clear DE interrupt */
@@ -1728,10 +1726,11 @@ static void mal_err (struct eth_device *dev, unsigned long isr,
mtdcr (MAL0_RXDEIR, 0x80000000);
#ifdef INFO_4XX_ENET
- printf ("\nMAL error occured.... ISR = %lx UIC = = %lx MAL_DEF = %lx MAL_ERR= %lx \n", isr, uic, maldef, mal_errr);
+ printf("\nMAL error occured.... ISR = %lx UIC = = %lx MAL_DEF = %lx MAL_ERR= %lx\n",
+ isr, uic, maldef, mal_errr);
#endif
- eth_init (hw_p->bis); /* start again... */
+ eth_init(); /* start again... */
}
/*-----------------------------------------------------------------------------+
@@ -1859,13 +1858,17 @@ static int ppc_4xx_eth_rx (struct eth_device *dev)
length = hw_p->rx[user_index].data_len & 0x0fff;
- /* Pass the packet up to the protocol layers. */
- /* NetReceive(NetRxPackets[rxIdx], length - 4); */
- /* NetReceive(NetRxPackets[i], length); */
+ /*
+ * Pass the packet up to the protocol layers.
+ * net_process_received_packet(net_rx_packets[rxIdx],
+ * length - 4);
+ * net_process_received_packet(net_rx_packets[i], length);
+ */
invalidate_dcache_range((u32)hw_p->rx[user_index].data_ptr,
(u32)hw_p->rx[user_index].data_ptr +
length - 4);
- NetReceive (NetRxPackets[user_index], length - 4);
+ net_process_received_packet(net_rx_packets[user_index],
+ length - 4);
/* Free Recv Buffer */
hw_p->rx[user_index].ctrl |= MAL_RX_CTRL_EMPTY;
/* Free rx buffer descriptor queue */
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index e69de29bb2..973258a80c 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -0,0 +1,49 @@
+config DM_ETH
+ bool "Enable Driver Model for Ethernet drivers"
+ depends on DM
+ help
+ Enable driver model for Ethernet.
+
+ The eth_*() interface will be implemented by the UC_ETH class
+ This is currently implemented in net/eth.c
+ Look in include/net.h for details.
+
+menuconfig NETDEVICES
+ bool "Network device support"
+ depends on NET
+ help
+ You must select Y to enable any network device support
+ Generally if you have any networking support this is a given
+
+ If unsure, say Y
+
+if NETDEVICES
+
+config ETH_SANDBOX
+ depends on DM_ETH && SANDBOX
+ default y
+ bool "Sandbox: Mocked Ethernet driver"
+ help
+ This driver simply responds with fake ARP replies and ping
+ replies that are used to verify network stack functionality
+
+ This driver is particularly useful in the test/dm/eth.c tests
+
+config ETH_SANDBOX_RAW
+ depends on DM_ETH && SANDBOX
+ default y
+ bool "Sandbox: Bridge to Linux Raw Sockets"
+ help
+ This driver is a bridge from the bottom of the network stack
+ in U-Boot to the RAW AF_PACKET API in Linux. This allows real
+ network traffic to be tested from within sandbox. See
+ board/sandbox/README.sandbox for more details.
+
+config ETH_DESIGNWARE
+ bool "Synopsys Designware Ethernet MAC"
+ help
+ This MAC is present in SoCs from various vendors. It supports
+ 100Mbit and 1 Gbit operation. You must enable CONFIG_PHYLIB to
+ provide the PHY (physical media interface).
+
+endif # NETDEVICES
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index 5a5269aa06..f24443df71 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -16,7 +16,7 @@ obj-$(CONFIG_BFIN_MAC) += bfin_mac.o
obj-$(CONFIG_CALXEDA_XGMAC) += calxedaxgmac.o
obj-$(CONFIG_CS8900) += cs8900.o
obj-$(CONFIG_TULIP) += dc2114x.o
-obj-$(CONFIG_DESIGNWARE_ETH) += designware.o
+obj-$(CONFIG_ETH_DESIGNWARE) += designware.o
obj-$(CONFIG_DRIVER_DM9000) += dm9000x.o
obj-$(CONFIG_DNET) += dnet.o
obj-$(CONFIG_E1000) += e1000.o
@@ -51,6 +51,8 @@ obj-$(CONFIG_PCH_GBE) += pch_gbe.o
obj-$(CONFIG_PCNET) += pcnet.o
obj-$(CONFIG_RTL8139) += rtl8139.o
obj-$(CONFIG_RTL8169) += rtl8169.o
+obj-$(CONFIG_ETH_SANDBOX) += sandbox.o
+obj-$(CONFIG_ETH_SANDBOX_RAW) += sandbox-raw.o
obj-$(CONFIG_SH_ETHER) += sh_eth.o
obj-$(CONFIG_SMC91111) += smc91111.o
obj-$(CONFIG_SMC911X) += smc911x.o
diff --git a/drivers/net/altera_tse.c b/drivers/net/altera_tse.c
index de517f8dab..c4fd6ec2e9 100644
--- a/drivers/net/altera_tse.c
+++ b/drivers/net/altera_tse.c
@@ -303,16 +303,17 @@ static int tse_eth_rx(struct eth_device *dev)
ALT_SGDMA_DESCRIPTOR_STATUS_TERMINATED_BY_EOP_MSK) {
debug("got packet\n");
packet_length = rx_desc->actual_bytes_transferred;
- NetReceive(NetRxPackets[0], packet_length);
+ net_process_received_packet(net_rx_packets[0], packet_length);
/* start descriptor again */
- flush_dcache_range((unsigned long)(NetRxPackets[0]),
- (unsigned long)(NetRxPackets[0]) + PKTSIZE_ALIGN);
+ flush_dcache_range((unsigned long)(net_rx_packets[0]),
+ (unsigned long)(net_rx_packets[0] +
+ PKTSIZE_ALIGN));
alt_sgdma_construct_descriptor_burst(
(volatile struct alt_sgdma_descriptor *)&rx_desc[0],
(volatile struct alt_sgdma_descriptor *)&rx_desc[1],
(unsigned int)0x0, /* read addr */
- (unsigned int *)NetRxPackets[0],
+ (unsigned int *)net_rx_packets[0],
0x0, /* length or EOP */
0x0, /* gen eop */
0x0, /* read fixed */
@@ -835,13 +836,13 @@ static int tse_eth_init(struct eth_device *dev, bd_t * bd)
0x0 /* channel */
);
debug("Configuring rx desc\n");
- flush_dcache_range((unsigned long)(NetRxPackets[0]),
- (unsigned long)(NetRxPackets[0]) + PKTSIZE_ALIGN);
+ flush_dcache_range((unsigned long)(net_rx_packets[0]),
+ (unsigned long)(net_rx_packets[0]) + PKTSIZE_ALIGN);
alt_sgdma_construct_descriptor_burst(
(volatile struct alt_sgdma_descriptor *)&rx_desc[0],
(volatile struct alt_sgdma_descriptor *)&rx_desc[1],
(unsigned int)0x0, /* read addr */
- (unsigned int *)NetRxPackets[0],
+ (unsigned int *)net_rx_packets[0],
0x0, /* length or EOP */
0x0, /* gen eop */
0x0, /* read fixed */
diff --git a/drivers/net/armada100_fec.c b/drivers/net/armada100_fec.c
index a8da6b17d0..e6a62525be 100644
--- a/drivers/net/armada100_fec.c
+++ b/drivers/net/armada100_fec.c
@@ -639,15 +639,16 @@ static int armdfec_recv(struct eth_device *dev)
} else {
/* !!! call higher layer processing */
debug("ARMD100 FEC: (%s) Sending Received packet to"
- " upper layer (NetReceive)\n", __func__);
+ " upper layer (net_process_received_packet)\n", __func__);
/*
* let the upper layer handle the packet, subtract offset
* as two dummy bytes are added in received buffer see
* PORT_CONFIG_EXT register bit TWO_Byte_Stuff_Mode bit.
*/
- NetReceive((p_rxdesc_curr->buf_ptr + RX_BUF_OFFSET),
- (int)(p_rxdesc_curr->byte_cnt - RX_BUF_OFFSET));
+ net_process_received_packet(
+ p_rxdesc_curr->buf_ptr + RX_BUF_OFFSET,
+ (int)(p_rxdesc_curr->byte_cnt - RX_BUF_OFFSET));
}
/*
* free these descriptors and point next in the ring
diff --git a/drivers/net/at91_emac.c b/drivers/net/at91_emac.c
index 64d4c56ac5..d51e098c56 100644
--- a/drivers/net/at91_emac.c
+++ b/drivers/net/at91_emac.c
@@ -352,7 +352,7 @@ static int at91emac_init(struct eth_device *netdev, bd_t *bd)
/* Init Ethernet buffers */
for (i = 0; i < RBF_FRAMEMAX; i++) {
- dev->rbfdt[i].addr = (unsigned long) NetRxPackets[i];
+ dev->rbfdt[i].addr = (unsigned long) net_rx_packets[i];
dev->rbfdt[i].size = 0;
}
dev->rbfdt[RBF_FRAMEMAX - 1].addr |= RBF_WRAP;
@@ -420,7 +420,7 @@ static int at91emac_recv(struct eth_device *netdev)
rbfp = &dev->rbfdt[dev->rbindex];
while (rbfp->addr & RBF_OWNER) {
size = rbfp->size & RBF_SIZE;
- NetReceive(NetRxPackets[dev->rbindex], size);
+ net_process_received_packet(net_rx_packets[dev->rbindex], size);
debug_cond(DEBUG_AT91EMAC, "Recv[%ld]: %d bytes @ %lx\n",
dev->rbindex, size, rbfp->addr);
diff --git a/drivers/net/ax88180.c b/drivers/net/ax88180.c
index 7f0cfe5940..ded9e064e5 100644
--- a/drivers/net/ax88180.c
+++ b/drivers/net/ax88180.c
@@ -192,9 +192,9 @@ static void ax88180_rx_handler (struct eth_device *dev)
unsigned short rxcurt_ptr, rxbound_ptr, next_ptr;
int i;
#if defined (CONFIG_DRIVER_AX88180_16BIT)
- unsigned short *rxdata = (unsigned short *)NetRxPackets[0];
+ unsigned short *rxdata = (unsigned short *)net_rx_packets[0];
#else
- unsigned long *rxdata = (unsigned long *)NetRxPackets[0];
+ unsigned long *rxdata = (unsigned long *)net_rx_packets[0];
#endif
unsigned short count;
@@ -237,7 +237,7 @@ static void ax88180_rx_handler (struct eth_device *dev)
OUTW (dev, RX_STOP_READ, RXINDICATOR);
/* Pass the packet up to the protocol layers. */
- NetReceive (NetRxPackets[0], data_size);
+ net_process_received_packet(net_rx_packets[0], data_size);
OUTW (dev, rxbound_ptr, RXBOUND);
diff --git a/drivers/net/bcm-sf2-eth.c b/drivers/net/bcm-sf2-eth.c
index 5252d49de9..51d5146363 100644
--- a/drivers/net/bcm-sf2-eth.c
+++ b/drivers/net/bcm-sf2-eth.c
@@ -103,7 +103,7 @@ static int bcm_sf2_eth_send(struct eth_device *dev, void *packet, int length)
static int bcm_sf2_eth_receive(struct eth_device *dev)
{
struct eth_dma *dma = &(((struct eth_info *)(dev->priv))->dma);
- uint8_t *buf = (uint8_t *)NetRxPackets[0];
+ uint8_t *buf = (uint8_t *)net_rx_packets[0];
int rcvlen;
int rc = 0;
int i = 0;
@@ -124,11 +124,11 @@ static int bcm_sf2_eth_receive(struct eth_device *dev)
debug("recieved\n");
/* Forward received packet to uboot network handler */
- NetReceive(buf, rcvlen);
+ net_process_received_packet(buf, rcvlen);
if (++i >= PKTBUFSRX)
i = 0;
- buf = NetRxPackets[i];
+ buf = net_rx_packets[i];
}
}
diff --git a/drivers/net/bfin_mac.c b/drivers/net/bfin_mac.c
index 0c2d2ef1a9..61cb1b0cda 100644
--- a/drivers/net/bfin_mac.c
+++ b/drivers/net/bfin_mac.c
@@ -189,8 +189,8 @@ static int bfin_EMAC_recv(struct eth_device *dev)
debug("%s: len = %d\n", __func__, length - 4);
- NetRxPackets[rxIdx] = rxbuf[rxIdx]->FrmData->Dest;
- NetReceive(NetRxPackets[rxIdx], length - 4);
+ net_rx_packets[rxIdx] = rxbuf[rxIdx]->FrmData->Dest;
+ net_process_received_packet(net_rx_packets[rxIdx], length - 4);
bfin_write_DMA1_IRQ_STATUS(DMA_DONE | DMA_ERR);
rxbuf[rxIdx]->StatusWord = 0x00000000;
if ((rxIdx + 1) >= PKTBUFSRX)
diff --git a/drivers/net/calxedaxgmac.c b/drivers/net/calxedaxgmac.c
index ff94865c5d..c02b397fa1 100644
--- a/drivers/net/calxedaxgmac.c
+++ b/drivers/net/calxedaxgmac.c
@@ -466,7 +466,7 @@ static int xgmac_rx(struct eth_device *dev)
length = desc_get_rx_frame_len(rxdesc);
- NetReceive(desc_get_buf_addr(rxdesc), length);
+ net_process_received_packet(desc_get_buf_addr(rxdesc), length);
/* set descriptor back to owned by XGMAC */
desc_set_rx_owner(rxdesc);
diff --git a/drivers/net/cpsw.c b/drivers/net/cpsw.c
index 52f8da67e1..fb4d621a88 100644
--- a/drivers/net/cpsw.c
+++ b/drivers/net/cpsw.c
@@ -289,7 +289,7 @@ static inline void cpsw_ale_get_addr(u32 *ale_entry, u8 *addr)
addr[i] = cpsw_ale_get_field(ale_entry, 40 - 8*i, 8);
}
-static inline void cpsw_ale_set_addr(u32 *ale_entry, u8 *addr)
+static inline void cpsw_ale_set_addr(u32 *ale_entry, const u8 *addr)
{
int i;
@@ -321,7 +321,7 @@ static int cpsw_ale_write(struct cpsw_priv *priv, int idx, u32 *ale_entry)
return idx;
}
-static int cpsw_ale_match_addr(struct cpsw_priv *priv, u8* addr)
+static int cpsw_ale_match_addr(struct cpsw_priv *priv, const u8 *addr)
{
u32 ale_entry[ALE_ENTRY_WORDS];
int type, idx;
@@ -374,7 +374,7 @@ static int cpsw_ale_find_ageable(struct cpsw_priv *priv)
return -ENOENT;
}
-static int cpsw_ale_add_ucast(struct cpsw_priv *priv, u8 *addr,
+static int cpsw_ale_add_ucast(struct cpsw_priv *priv, const u8 *addr,
int port, int flags)
{
u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
@@ -399,7 +399,8 @@ static int cpsw_ale_add_ucast(struct cpsw_priv *priv, u8 *addr,
return 0;
}
-static int cpsw_ale_add_mcast(struct cpsw_priv *priv, u8 *addr, int port_mask)
+static int cpsw_ale_add_mcast(struct cpsw_priv *priv, const u8 *addr,
+ int port_mask)
{
u32 ale_entry[ALE_ENTRY_WORDS] = {0, 0, 0};
int idx, mask;
@@ -644,7 +645,7 @@ static void cpsw_slave_init(struct cpsw_slave *slave, struct cpsw_priv *priv)
slave_port = cpsw_get_slave_port(priv, slave->slave_num);
cpsw_ale_port_state(priv, slave_port, ALE_PORT_STATE_FORWARD);
- cpsw_ale_add_mcast(priv, NetBcastAddr, 1 << slave_port);
+ cpsw_ale_add_mcast(priv, net_bcast_ethaddr, 1 << slave_port);
priv->phy_mask |= 1 << slave->data->phy_addr;
}
@@ -773,7 +774,7 @@ static int cpsw_init(struct eth_device *dev, bd_t *bis)
cpsw_ale_add_ucast(priv, priv->dev->enetaddr, priv->host_port,
ALE_SECURE);
- cpsw_ale_add_mcast(priv, NetBcastAddr, 1 << priv->host_port);
+ cpsw_ale_add_mcast(priv, net_bcast_ethaddr, 1 << priv->host_port);
for_active_slave(slave, priv)
cpsw_slave_init(slave, priv);
@@ -845,7 +846,7 @@ static int cpsw_init(struct eth_device *dev, bd_t *bis)
/* submit rx descs */
for (i = 0; i < PKTBUFSRX; i++) {
- ret = cpdma_submit(priv, &priv->rx_chan, NetRxPackets[i],
+ ret = cpdma_submit(priv, &priv->rx_chan, net_rx_packets[i],
PKTSIZE);
if (ret < 0) {
printf("error %d submitting rx desc\n", ret);
@@ -904,7 +905,7 @@ static int cpsw_recv(struct eth_device *dev)
while (cpdma_process(priv, &priv->rx_chan, &buffer, &len) >= 0) {
invalidate_dcache_range((unsigned long)buffer,
(unsigned long)buffer + PKTSIZE_ALIGN);
- NetReceive(buffer, len);
+ net_process_received_packet(buffer, len);
cpdma_submit(priv, &priv->rx_chan, buffer, PKTSIZE);
}
diff --git a/drivers/net/cs8900.c b/drivers/net/cs8900.c
index 84963c1f22..0713464c77 100644
--- a/drivers/net/cs8900.c
+++ b/drivers/net/cs8900.c
@@ -188,14 +188,13 @@ static int cs8900_recv(struct eth_device *dev)
if (rxlen > PKTSIZE_ALIGN + PKTALIGN)
debug("packet too big!\n");
- for (addr = (u16 *) NetRxPackets[0], i = rxlen >> 1; i > 0;
- i--)
+ for (addr = (u16 *)net_rx_packets[0], i = rxlen >> 1; i > 0; i--)
*addr++ = REG_READ(&priv->regs->rtdata);
if (rxlen & 1)
*addr++ = REG_READ(&priv->regs->rtdata);
/* Pass the packet up to the protocol layers. */
- NetReceive (NetRxPackets[0], rxlen);
+ net_process_received_packet(net_rx_packets[0], rxlen);
return rxlen;
}
diff --git a/drivers/net/davinci_emac.c b/drivers/net/davinci_emac.c
index 08bc1afcf6..427ad3e6fa 100644
--- a/drivers/net/davinci_emac.c
+++ b/drivers/net/davinci_emac.c
@@ -700,8 +700,9 @@ static int davinci_eth_rcv_packet (struct eth_device *dev)
unsigned long tmp = (unsigned long)rx_curr_desc->buffer;
invalidate_dcache_range(tmp, tmp + EMAC_RXBUF_SIZE);
- NetReceive (rx_curr_desc->buffer,
- (rx_curr_desc->buff_off_len & 0xffff));
+ net_process_received_packet(
+ rx_curr_desc->buffer,
+ rx_curr_desc->buff_off_len & 0xffff);
ret = rx_curr_desc->buff_off_len & 0xffff;
}
diff --git a/drivers/net/dc2114x.c b/drivers/net/dc2114x.c
index 799839c4f1..8245cf51cc 100644
--- a/drivers/net/dc2114x.c
+++ b/drivers/net/dc2114x.c
@@ -333,9 +333,11 @@ static int dc21x4x_init(struct eth_device* dev, bd_t* bis)
for (i = 0; i < NUM_RX_DESC; i++) {
rx_ring[i].status = cpu_to_le32(R_OWN);
rx_ring[i].des1 = cpu_to_le32(RX_BUFF_SZ);
- rx_ring[i].buf = cpu_to_le32(phys_to_bus((u32) NetRxPackets[i]));
+ rx_ring[i].buf = cpu_to_le32(
+ phys_to_bus((u32)net_rx_packets[i]));
#ifdef CONFIG_TULIP_FIX_DAVICOM
- rx_ring[i].next = cpu_to_le32(phys_to_bus((u32) &rx_ring[(i+1) % NUM_RX_DESC]));
+ rx_ring[i].next = cpu_to_le32(
+ phys_to_bus((u32)&rx_ring[(i + 1) % NUM_RX_DESC]));
#else
rx_ring[i].next = 0;
#endif
@@ -448,7 +450,8 @@ static int dc21x4x_recv(struct eth_device* dev)
/* Pass the packet up to the protocol
* layers.
*/
- NetReceive(NetRxPackets[rx_new], length - 4);
+ net_process_received_packet(
+ net_rx_packets[rx_new], length - 4);
}
/* Change buffer ownership for this frame, back
diff --git a/drivers/net/designware.c b/drivers/net/designware.c
index cc01604e60..07281a6ce9 100644
--- a/drivers/net/designware.c
+++ b/drivers/net/designware.c
@@ -6,10 +6,12 @@
*/
/*
- * Designware ethernet IP driver for u-boot
+ * Designware ethernet IP driver for U-Boot
*/
#include <common.h>
+#include <dm.h>
+#include <errno.h>
#include <miiphy.h>
#include <malloc.h>
#include <linux/compiler.h>
@@ -17,6 +19,8 @@
#include <asm/io.h>
#include "designware.h"
+DECLARE_GLOBAL_DATA_PTR;
+
#if !defined(CONFIG_PHYLIB)
# error "DesignWare Ether MAC requires PHYLIB - missing CONFIG_PHYLIB"
#endif
@@ -40,7 +44,7 @@ static int dw_mdio_read(struct mii_dev *bus, int addr, int devad, int reg)
udelay(10);
};
- return -1;
+ return -ETIMEDOUT;
}
static int dw_mdio_write(struct mii_dev *bus, int addr, int devad, int reg,
@@ -49,7 +53,7 @@ static int dw_mdio_write(struct mii_dev *bus, int addr, int devad, int reg,
struct eth_mac_regs *mac_p = bus->priv;
ulong start;
u16 miiaddr;
- int ret = -1, timeout = CONFIG_MDIO_TIMEOUT;
+ int ret = -ETIMEDOUT, timeout = CONFIG_MDIO_TIMEOUT;
writel(val, &mac_p->miidata);
miiaddr = ((addr << MIIADDRSHIFT) & MII_ADDRMSK) |
@@ -69,27 +73,26 @@ static int dw_mdio_write(struct mii_dev *bus, int addr, int devad, int reg,
return ret;
}
-static int dw_mdio_init(char *name, struct eth_mac_regs *mac_regs_p)
+static int dw_mdio_init(const char *name, struct eth_mac_regs *mac_regs_p)
{
struct mii_dev *bus = mdio_alloc();
if (!bus) {
printf("Failed to allocate MDIO bus\n");
- return -1;
+ return -ENOMEM;
}
bus->read = dw_mdio_read;
bus->write = dw_mdio_write;
- sprintf(bus->name, name);
+ snprintf(bus->name, sizeof(bus->name), name);
bus->priv = (void *)mac_regs_p;
return mdio_register(bus);
}
-static void tx_descs_init(struct eth_device *dev)
+static void tx_descs_init(struct dw_eth_dev *priv)
{
- struct dw_eth_dev *priv = dev->priv;
struct eth_dma_regs *dma_p = priv->dma_regs_p;
struct dmamacdescr *desc_table_p = &priv->tx_mac_descrtable[0];
char *txbuffs = &priv->txbuffs[0];
@@ -128,9 +131,8 @@ static void tx_descs_init(struct eth_device *dev)
priv->tx_currdescnum = 0;
}
-static void rx_descs_init(struct eth_device *dev)
+static void rx_descs_init(struct dw_eth_dev *priv)
{
- struct dw_eth_dev *priv = dev->priv;
struct eth_dma_regs *dma_p = priv->dma_regs_p;
struct dmamacdescr *desc_table_p = &priv->rx_mac_descrtable[0];
char *rxbuffs = &priv->rxbuffs[0];
@@ -170,12 +172,10 @@ static void rx_descs_init(struct eth_device *dev)
priv->rx_currdescnum = 0;
}
-static int dw_write_hwaddr(struct eth_device *dev)
+static int _dw_write_hwaddr(struct dw_eth_dev *priv, u8 *mac_id)
{
- struct dw_eth_dev *priv = dev->priv;
struct eth_mac_regs *mac_p = priv->mac_regs_p;
u32 macid_lo, macid_hi;
- u8 *mac_id = &dev->enetaddr[0];
macid_lo = mac_id[0] + (mac_id[1] << 8) + (mac_id[2] << 16) +
(mac_id[3] << 24);
@@ -213,9 +213,8 @@ static void dw_adjust_link(struct eth_mac_regs *mac_p,
(phydev->port == PORT_FIBRE) ? ", fiber mode" : "");
}
-static void dw_eth_halt(struct eth_device *dev)
+static void _dw_eth_halt(struct dw_eth_dev *priv)
{
- struct dw_eth_dev *priv = dev->priv;
struct eth_mac_regs *mac_p = priv->mac_regs_p;
struct eth_dma_regs *dma_p = priv->dma_regs_p;
@@ -225,12 +224,12 @@ static void dw_eth_halt(struct eth_device *dev)
phy_shutdown(priv->phydev);
}
-static int dw_eth_init(struct eth_device *dev, bd_t *bis)
+static int _dw_eth_init(struct dw_eth_dev *priv, u8 *enetaddr)
{
- struct dw_eth_dev *priv = dev->priv;
struct eth_mac_regs *mac_p = priv->mac_regs_p;
struct eth_dma_regs *dma_p = priv->dma_regs_p;
unsigned int start;
+ int ret;
writel(readl(&dma_p->busmode) | DMAMAC_SRST, &dma_p->busmode);
@@ -238,7 +237,7 @@ static int dw_eth_init(struct eth_device *dev, bd_t *bis)
while (readl(&dma_p->busmode) & DMAMAC_SRST) {
if (get_timer(start) >= CONFIG_MACRESET_TIMEOUT) {
printf("DMA reset timeout\n");
- return -1;
+ return -ETIMEDOUT;
}
mdelay(100);
@@ -246,10 +245,10 @@ static int dw_eth_init(struct eth_device *dev, bd_t *bis)
/* Soft reset above clears HW address registers.
* So we have to set it here once again */
- dw_write_hwaddr(dev);
+ _dw_write_hwaddr(priv, enetaddr);
- rx_descs_init(dev);
- tx_descs_init(dev);
+ rx_descs_init(priv);
+ tx_descs_init(priv);
writel(FIXEDBURST | PRIORXTX_41 | DMA_PBL, &dma_p->busmode);
@@ -268,25 +267,25 @@ static int dw_eth_init(struct eth_device *dev, bd_t *bis)
#endif
/* Start up the PHY */
- if (phy_startup(priv->phydev)) {
+ ret = phy_startup(priv->phydev);
+ if (ret) {
printf("Could not initialize PHY %s\n",
priv->phydev->dev->name);
- return -1;
+ return ret;
}
dw_adjust_link(mac_p, priv->phydev);
if (!priv->phydev->link)
- return -1;
+ return -EIO;
writel(readl(&mac_p->conf) | RXENABLE | TXENABLE, &mac_p->conf);
return 0;
}
-static int dw_eth_send(struct eth_device *dev, void *packet, int length)
+static int _dw_eth_send(struct dw_eth_dev *priv, void *packet, int length)
{
- struct dw_eth_dev *priv = dev->priv;
struct eth_dma_regs *dma_p = priv->dma_regs_p;
u32 desc_num = priv->tx_currdescnum;
struct dmamacdescr *desc_p = &priv->tx_mac_descrtable[desc_num];
@@ -309,7 +308,7 @@ static int dw_eth_send(struct eth_device *dev, void *packet, int length)
/* Check if the descriptor is owned by CPU */
if (desc_p->txrx_status & DESC_TXSTS_OWNBYDMA) {
printf("CPU not owner of tx frame\n");
- return -1;
+ return -EPERM;
}
memcpy(desc_p->dmamac_addr, packet, length);
@@ -347,12 +346,11 @@ static int dw_eth_send(struct eth_device *dev, void *packet, int length)
return 0;
}
-static int dw_eth_recv(struct eth_device *dev)
+static int _dw_eth_recv(struct dw_eth_dev *priv, uchar **packetp)
{
- struct dw_eth_dev *priv = dev->priv;
u32 status, desc_num = priv->rx_currdescnum;
struct dmamacdescr *desc_p = &priv->rx_mac_descrtable[desc_num];
- int length = 0;
+ int length = -EAGAIN;
uint32_t desc_start = (uint32_t)desc_p;
uint32_t desc_end = desc_start +
roundup(sizeof(*desc_p), ARCH_DMA_MINALIGN);
@@ -373,31 +371,39 @@ static int dw_eth_recv(struct eth_device *dev)
/* Invalidate received data */
data_end = data_start + roundup(length, ARCH_DMA_MINALIGN);
invalidate_dcache_range(data_start, data_end);
+ *packetp = desc_p->dmamac_addr;
+ }
- NetReceive(desc_p->dmamac_addr, length);
+ return length;
+}
- /*
- * Make the current descriptor valid again and go to
- * the next one
- */
- desc_p->txrx_status |= DESC_RXSTS_OWNBYDMA;
+static int _dw_free_pkt(struct dw_eth_dev *priv)
+{
+ u32 desc_num = priv->rx_currdescnum;
+ struct dmamacdescr *desc_p = &priv->rx_mac_descrtable[desc_num];
+ uint32_t desc_start = (uint32_t)desc_p;
+ uint32_t desc_end = desc_start +
+ roundup(sizeof(*desc_p), ARCH_DMA_MINALIGN);
- /* Flush only status field - others weren't changed */
- flush_dcache_range(desc_start, desc_end);
+ /*
+ * Make the current descriptor valid again and go to
+ * the next one
+ */
+ desc_p->txrx_status |= DESC_RXSTS_OWNBYDMA;
- /* Test the wrap-around condition. */
- if (++desc_num >= CONFIG_RX_DESCR_NUM)
- desc_num = 0;
- }
+ /* Flush only status field - others weren't changed */
+ flush_dcache_range(desc_start, desc_end);
+ /* Test the wrap-around condition. */
+ if (++desc_num >= CONFIG_RX_DESCR_NUM)
+ desc_num = 0;
priv->rx_currdescnum = desc_num;
- return length;
+ return 0;
}
-static int dw_phy_init(struct eth_device *dev)
+static int dw_phy_init(struct dw_eth_dev *priv, void *dev)
{
- struct dw_eth_dev *priv = dev->priv;
struct phy_device *phydev;
int mask = 0xffffffff;
@@ -407,7 +413,7 @@ static int dw_phy_init(struct eth_device *dev)
phydev = phy_find_by_mask(priv->bus, mask, priv->interface);
if (!phydev)
- return -1;
+ return -ENODEV;
phy_connect_dev(phydev, dev);
@@ -417,7 +423,43 @@ static int dw_phy_init(struct eth_device *dev)
priv->phydev = phydev;
phy_config(phydev);
- return 1;
+ return 0;
+}
+
+#ifndef CONFIG_DM_ETH
+static int dw_eth_init(struct eth_device *dev, bd_t *bis)
+{
+ return _dw_eth_init(dev->priv, dev->enetaddr);
+}
+
+static int dw_eth_send(struct eth_device *dev, void *packet, int length)
+{
+ return _dw_eth_send(dev->priv, packet, length);
+}
+
+static int dw_eth_recv(struct eth_device *dev)
+{
+ uchar *packet;
+ int length;
+
+ length = _dw_eth_recv(dev->priv, &packet);
+ if (length == -EAGAIN)
+ return 0;
+ net_process_received_packet(packet, length);
+
+ _dw_free_pkt(dev->priv);
+
+ return 0;
+}
+
+static void dw_eth_halt(struct eth_device *dev)
+{
+ return _dw_eth_halt(dev->priv);
+}
+
+static int dw_write_hwaddr(struct eth_device *dev)
+{
+ return _dw_write_hwaddr(dev->priv, dev->enetaddr);
}
int designware_initialize(ulong base_addr, u32 interface)
@@ -465,5 +507,117 @@ int designware_initialize(ulong base_addr, u32 interface)
dw_mdio_init(dev->name, priv->mac_regs_p);
priv->bus = miiphy_get_dev_by_name(dev->name);
- return dw_phy_init(dev);
+ return dw_phy_init(priv, dev);
+}
+#endif
+
+#ifdef CONFIG_DM_ETH
+static int designware_eth_start(struct udevice *dev)
+{
+ struct eth_pdata *pdata = dev_get_platdata(dev);
+
+ return _dw_eth_init(dev->priv, pdata->enetaddr);
+}
+
+static int designware_eth_send(struct udevice *dev, void *packet, int length)
+{
+ struct dw_eth_dev *priv = dev_get_priv(dev);
+
+ return _dw_eth_send(priv, packet, length);
+}
+
+static int designware_eth_recv(struct udevice *dev, uchar **packetp)
+{
+ struct dw_eth_dev *priv = dev_get_priv(dev);
+
+ return _dw_eth_recv(priv, packetp);
+}
+
+static int designware_eth_free_pkt(struct udevice *dev, uchar *packet,
+ int length)
+{
+ struct dw_eth_dev *priv = dev_get_priv(dev);
+
+ return _dw_free_pkt(priv);
+}
+
+static void designware_eth_stop(struct udevice *dev)
+{
+ struct dw_eth_dev *priv = dev_get_priv(dev);
+
+ return _dw_eth_halt(priv);
+}
+
+static int designware_eth_write_hwaddr(struct udevice *dev)
+{
+ struct eth_pdata *pdata = dev_get_platdata(dev);
+ struct dw_eth_dev *priv = dev_get_priv(dev);
+
+ return _dw_write_hwaddr(priv, pdata->enetaddr);
+}
+
+static int designware_eth_probe(struct udevice *dev)
+{
+ struct eth_pdata *pdata = dev_get_platdata(dev);
+ struct dw_eth_dev *priv = dev_get_priv(dev);
+ int ret;
+
+ debug("%s, iobase=%lx, priv=%p\n", __func__, pdata->iobase, priv);
+ priv->mac_regs_p = (struct eth_mac_regs *)pdata->iobase;
+ priv->dma_regs_p = (struct eth_dma_regs *)(pdata->iobase +
+ DW_DMA_BASE_OFFSET);
+ priv->interface = pdata->phy_interface;
+
+ dw_mdio_init(dev->name, priv->mac_regs_p);
+ priv->bus = miiphy_get_dev_by_name(dev->name);
+
+ ret = dw_phy_init(priv, dev);
+ debug("%s, ret=%d\n", __func__, ret);
+
+ return ret;
}
+
+static const struct eth_ops designware_eth_ops = {
+ .start = designware_eth_start,
+ .send = designware_eth_send,
+ .recv = designware_eth_recv,
+ .free_pkt = designware_eth_free_pkt,
+ .stop = designware_eth_stop,
+ .write_hwaddr = designware_eth_write_hwaddr,
+};
+
+static int designware_eth_ofdata_to_platdata(struct udevice *dev)
+{
+ struct eth_pdata *pdata = dev_get_platdata(dev);
+ const char *phy_mode;
+
+ pdata->iobase = dev_get_addr(dev);
+ pdata->phy_interface = -1;
+ phy_mode = fdt_getprop(gd->fdt_blob, dev->of_offset, "phy-mode", NULL);
+ if (phy_mode)
+ pdata->phy_interface = phy_get_interface_by_name(phy_mode);
+ if (pdata->phy_interface == -1) {
+ debug("%s: Invalid PHY interface '%s'\n", __func__, phy_mode);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static const struct udevice_id designware_eth_ids[] = {
+ { .compatible = "allwinner,sun7i-a20-gmac" },
+ { }
+};
+
+U_BOOT_DRIVER(eth_sandbox) = {
+ .name = "eth_designware",
+ .id = UCLASS_ETH,
+ .of_match = designware_eth_ids,
+ .ofdata_to_platdata = designware_eth_ofdata_to_platdata,
+ .probe = designware_eth_probe,
+ .ops = &designware_eth_ops,
+ .priv_auto_alloc_size = sizeof(struct dw_eth_dev),
+ .platdata_auto_alloc_size = sizeof(struct eth_pdata),
+ .flags = DM_FLAG_ALLOC_PRIV_DMA,
+};
+#endif
diff --git a/drivers/net/designware.h b/drivers/net/designware.h
index 49d900cb3f..4b9ec39cc8 100644
--- a/drivers/net/designware.h
+++ b/drivers/net/designware.h
@@ -228,8 +228,9 @@ struct dw_eth_dev {
struct eth_mac_regs *mac_regs_p;
struct eth_dma_regs *dma_regs_p;
-
+#ifndef CONFIG_DM_ETH
struct eth_device *dev;
+#endif
struct phy_device *phydev;
struct mii_dev *bus;
};
diff --git a/drivers/net/dm9000x.c b/drivers/net/dm9000x.c
index 4de9d41642..ccd2131f88 100644
--- a/drivers/net/dm9000x.c
+++ b/drivers/net/dm9000x.c
@@ -342,10 +342,10 @@ static int dm9000_init(struct eth_device *dev, bd_t *bd)
DM9000_iow(DM9000_ISR, ISR_ROOS | ISR_ROS | ISR_PTS | ISR_PRS);
printf("MAC: %pM\n", dev->enetaddr);
- if (!is_valid_ether_addr(dev->enetaddr)) {
+ if (!is_valid_ethaddr(dev->enetaddr)) {
#ifdef CONFIG_RANDOM_MACADDR
printf("Bad MAC address (uninitialized EEPROM?), randomizing\n");
- eth_random_addr(dev->enetaddr);
+ net_random_ethaddr(dev->enetaddr);
printf("MAC: %pM\n", dev->enetaddr);
#else
printf("WARNING: Bad MAC address (uninitialized EEPROM?)\n");
@@ -464,7 +464,8 @@ static void dm9000_halt(struct eth_device *netdev)
*/
static int dm9000_rx(struct eth_device *netdev)
{
- u8 rxbyte, *rdptr = (u8 *) NetRxPackets[0];
+ u8 rxbyte;
+ u8 *rdptr = (u8 *)net_rx_packets[0];
u16 RxStatus, RxLen = 0;
struct board_info *db = &dm9000_info;
@@ -525,7 +526,7 @@ static int dm9000_rx(struct eth_device *netdev)
DM9000_DMP_PACKET(__func__ , rdptr, RxLen);
DM9000_DBG("passing packet to upper layer\n");
- NetReceive(NetRxPackets[0], RxLen);
+ net_process_received_packet(net_rx_packets[0], RxLen);
}
}
return 0;
diff --git a/drivers/net/dnet.c b/drivers/net/dnet.c
index 944a0c046f..933d1fc2f1 100644
--- a/drivers/net/dnet.c
+++ b/drivers/net/dnet.c
@@ -188,12 +188,13 @@ static int dnet_recv(struct eth_device *netdev)
if (cmd_word & 0xDF180000)
printf("%s packet receive error %x\n", __func__, cmd_word);
- data_ptr = (unsigned int *) NetRxPackets[0];
+ data_ptr = (unsigned int *)net_rx_packets[0];
for (i = 0; i < (pkt_len + 3) >> 2; i++)
*data_ptr++ = readl(&dnet->regs->RX_DATA_FIFO);
- NetReceive(NetRxPackets[0], pkt_len + 5); /* ok + 5 ?? */
+ /* ok + 5 ?? */
+ net_process_received_packet(net_rx_packets[0], pkt_len + 5);
return 0;
}
diff --git a/drivers/net/e1000.c b/drivers/net/e1000.c
index cd4422215f..2d66690226 100644
--- a/drivers/net/e1000.c
+++ b/drivers/net/e1000.c
@@ -1197,7 +1197,7 @@ e1000_read_mac_addr(struct eth_device *nic)
nic->enetaddr[5] ^= 1;
#ifdef CONFIG_E1000_FALLBACK_MAC
- if (!is_valid_ether_addr(nic->enetaddr)) {
+ if (!is_valid_ethaddr(nic->enetaddr)) {
unsigned char fb_mac[NODE_ADDRESS_SIZE] = CONFIG_E1000_FALLBACK_MAC;
memcpy (nic->enetaddr, fb_mac, NODE_ADDRESS_SIZE);
@@ -5158,7 +5158,7 @@ e1000_poll(struct eth_device *nic)
invalidate_dcache_range((unsigned long)packet,
(unsigned long)packet +
roundup(len, ARCH_DMA_MINALIGN));
- NetReceive((uchar *)packet, len);
+ net_process_received_packet((uchar *)packet, len);
fill_rx(hw);
return 1;
}
diff --git a/drivers/net/eepro100.c b/drivers/net/eepro100.c
index a23a5852ee..f2cd32c548 100644
--- a/drivers/net/eepro100.c
+++ b/drivers/net/eepro100.c
@@ -674,7 +674,8 @@ static int eepro100_recv (struct eth_device *dev)
/* Pass the packet up to the protocol
* layers.
*/
- NetReceive((u8 *)rx_ring[rx_next].data, length);
+ net_process_received_packet((u8 *)rx_ring[rx_next].data,
+ length);
} else {
/* There was an error.
*/
diff --git a/drivers/net/enc28j60.c b/drivers/net/enc28j60.c
index ec33764f5e..59ea11cd6a 100644
--- a/drivers/net/enc28j60.c
+++ b/drivers/net/enc28j60.c
@@ -21,8 +21,8 @@
* enc_miiphy_read(), enc_miiphy_write(), enc_write_hwaddr(),
* enc_init(), enc_recv(), enc_send(), enc_halt()
* ALL other functions assume that the bus has already been claimed!
- * Since NetReceive() might call enc_send() in return, the bus must be
- * released, NetReceive() called and claimed again.
+ * Since net_process_received_packet() might call enc_send() in return, the bus
+ * must be released, net_process_received_packet() called and claimed again.
*/
/*
@@ -415,7 +415,7 @@ static void enc_reset_rx_call(enc_dev_t *enc)
*/
static void enc_receive(enc_dev_t *enc)
{
- u8 *packet = (u8 *)NetRxPackets[0];
+ u8 *packet = (u8 *)net_rx_packets[0];
u16 pkt_len;
u16 copy_len;
u16 status;
@@ -468,11 +468,12 @@ static void enc_receive(enc_dev_t *enc)
continue;
}
/*
- * Because NetReceive() might call enc_send(), we need to
- * release the SPI bus, call NetReceive(), reclaim the bus
+ * Because net_process_received_packet() might call enc_send(),
+ * we need to release the SPI bus, call
+ * net_process_received_packet(), reclaim the bus.
*/
enc_release_bus(enc);
- NetReceive(packet, pkt_len);
+ net_process_received_packet(packet, pkt_len);
if (enc_claim_bus(enc))
return;
(void)enc_r8(enc, CTL_REG_EIR);
diff --git a/drivers/net/ep93xx_eth.c b/drivers/net/ep93xx_eth.c
index 1c09f1004a..a3721c5513 100644
--- a/drivers/net/ep93xx_eth.c
+++ b/drivers/net/ep93xx_eth.c
@@ -53,7 +53,7 @@ static void dump_dev(struct eth_device *dev)
printf(" rx_sq.end %p\n", priv->rx_sq.end);
for (i = 0; i < NUMRXDESC; i++)
- printf(" rx_buffer[%2.d] %p\n", i, NetRxPackets[i]);
+ printf(" rx_buffer[%2.d] %p\n", i, net_rx_packets[i]);
printf(" tx_dq.base %p\n", priv->tx_dq.base);
printf(" tx_dq.current %p\n", priv->tx_dq.current);
@@ -237,7 +237,7 @@ static int ep93xx_eth_open(struct eth_device *dev, bd_t *bd)
*/
for (i = 0; i < NUMRXDESC; i++) {
/* set buffer address */
- (priv->rx_dq.base + i)->word1 = (uint32_t)NetRxPackets[i];
+ (priv->rx_dq.base + i)->word1 = (uint32_t)net_rx_packets[i];
/* set buffer length, clear buffer index and NSOF */
(priv->rx_dq.base + i)->word2 = PKTSIZE_ALIGN;
@@ -310,15 +310,16 @@ static int ep93xx_eth_rcv_packet(struct eth_device *dev)
/*
* We have a good frame. Extract the frame's length
* from the current rx_status_queue entry, and copy
- * the frame's data into NetRxPackets[] of the
+ * the frame's data into net_rx_packets[] of the
* protocol stack. We track the total number of
* bytes in the frame (nbytes_frame) which will be
* used when we pass the data off to the protocol
- * layer via NetReceive().
+ * layer via net_process_received_packet().
*/
len = RX_STATUS_FRAME_LEN(priv->rx_sq.current);
- NetReceive((uchar *)priv->rx_dq.current->word1, len);
+ net_process_received_packet(
+ (uchar *)priv->rx_dq.current->word1, len);
debug("reporting %d bytes...\n", len);
} else {
diff --git a/drivers/net/ethoc.c b/drivers/net/ethoc.c
index 46c82bbb40..edb3c808fa 100644
--- a/drivers/net/ethoc.c
+++ b/drivers/net/ethoc.c
@@ -267,7 +267,7 @@ static int ethoc_init_ring(struct eth_device *dev)
bd.stat = RX_BD_EMPTY | RX_BD_IRQ;
for (i = 0; i < priv->num_rx; i++) {
- bd.addr = (u32)NetRxPackets[i];
+ bd.addr = (u32)net_rx_packets[i];
if (i == priv->num_rx - 1)
bd.stat |= RX_BD_WRAP;
@@ -372,7 +372,7 @@ static int ethoc_rx(struct eth_device *dev, int limit)
if (ethoc_update_rx_stats(&bd) == 0) {
int size = bd.stat >> 16;
size -= 4; /* strip the CRC */
- NetReceive((void *)bd.addr, size);
+ net_process_received_packet((void *)bd.addr, size);
}
/* clear the buffer descriptor so it can be reused */
diff --git a/drivers/net/fec_mxc.c b/drivers/net/fec_mxc.c
index b57247032f..9225d37285 100644
--- a/drivers/net/fec_mxc.c
+++ b/drivers/net/fec_mxc.c
@@ -357,7 +357,7 @@ static int fec_get_hwaddr(struct eth_device *dev, int dev_id,
unsigned char *mac)
{
imx_get_mac_from_fuse(dev_id, mac);
- return !is_valid_ether_addr(mac);
+ return !is_valid_ethaddr(mac);
}
static int fec_set_hwaddr(struct eth_device *dev)
@@ -852,7 +852,7 @@ static int fec_recv(struct eth_device *dev)
swap_packet((uint32_t *)frame->data, frame_length);
#endif
memcpy(buff, frame->data, frame_length);
- NetReceive(buff, frame_length);
+ net_process_received_packet(buff, frame_length);
len = frame_length;
} else {
if (bd_status & FEC_RBD_ERR)
diff --git a/drivers/net/fm/eth.c b/drivers/net/fm/eth.c
index 1d1089d017..55e76a7d88 100644
--- a/drivers/net/fm/eth.c
+++ b/drivers/net/fm/eth.c
@@ -530,7 +530,7 @@ static int fm_eth_recv(struct eth_device *dev)
if (!(status & RxBD_ERROR)) {
data = (u8 *)rxbd->buf_ptr_lo;
len = rxbd->len;
- NetReceive(data, len);
+ net_process_received_packet(data, len);
} else {
printf("%s: Rx error\n", dev->name);
return 0;
diff --git a/drivers/net/fsl_mcdmafec.c b/drivers/net/fsl_mcdmafec.c
index 6391f9b32f..792534b139 100644
--- a/drivers/net/fsl_mcdmafec.c
+++ b/drivers/net/fsl_mcdmafec.c
@@ -244,7 +244,7 @@ static int fec_recv(struct eth_device *dev)
struct fec_info_dma *info = dev->priv;
volatile fecdma_t *fecp = (fecdma_t *) (info->iobase);
- cbd_t *pRbd = &info->rxbd[info->rxIdx];
+ cbd_t *prbd = &info->rxbd[info->rxIdx];
u32 ievent;
int frame_length, len = 0;
@@ -276,26 +276,27 @@ static int fec_recv(struct eth_device *dev)
}
}
- if (!(pRbd->cbd_sc & BD_ENET_RX_EMPTY)) {
- if ((pRbd->cbd_sc & BD_ENET_RX_LAST)
- && !(pRbd->cbd_sc & BD_ENET_RX_ERR)
- && ((pRbd->cbd_datlen - 4) > 14)) {
+ if (!(prbd->cbd_sc & BD_ENET_RX_EMPTY)) {
+ if ((prbd->cbd_sc & BD_ENET_RX_LAST) &&
+ !(prbd->cbd_sc & BD_ENET_RX_ERR) &&
+ ((prbd->cbd_datlen - 4) > 14)) {
/* Get buffer address and size */
- frame_length = pRbd->cbd_datlen - 4;
+ frame_length = prbd->cbd_datlen - 4;
/* Fill the buffer and pass it to upper layers */
- NetReceive((uchar *)pRbd->cbd_bufaddr, frame_length);
+ net_process_received_packet((uchar *)prbd->cbd_bufaddr,
+ frame_length);
len = frame_length;
}
/* Reset buffer descriptor as empty */
if ((info->rxIdx) == (PKTBUFSRX - 1))
- pRbd->cbd_sc = (BD_ENET_RX_WRAP | BD_ENET_RX_EMPTY);
+ prbd->cbd_sc = (BD_ENET_RX_WRAP | BD_ENET_RX_EMPTY);
else
- pRbd->cbd_sc = BD_ENET_RX_EMPTY;
+ prbd->cbd_sc = BD_ENET_RX_EMPTY;
- pRbd->cbd_datlen = PKTSIZE_ALIGN;
+ prbd->cbd_datlen = PKTSIZE_ALIGN;
/* Now, we have an empty RxBD, restart the DMA receive task */
MCD_continDma(info->rxTask);
@@ -399,7 +400,7 @@ static int fec_init(struct eth_device *dev, bd_t * bd)
for (i = 0; i < PKTBUFSRX; i++) {
info->rxbd[i].cbd_sc = BD_ENET_RX_EMPTY;
info->rxbd[i].cbd_datlen = PKTSIZE_ALIGN;
- info->rxbd[i].cbd_bufaddr = (uint) NetRxPackets[i];
+ info->rxbd[i].cbd_bufaddr = (uint) net_rx_packets[i];
}
info->rxbd[PKTBUFSRX - 1].cbd_sc |= BD_ENET_RX_WRAP;
diff --git a/drivers/net/ftgmac100.c b/drivers/net/ftgmac100.c
index 85193140af..515f0b2746 100644
--- a/drivers/net/ftgmac100.c
+++ b/drivers/net/ftgmac100.c
@@ -423,7 +423,7 @@ static int ftgmac100_init(struct eth_device *dev, bd_t *bd)
for (i = 0; i < PKTBUFSRX; i++) {
/* RXBUF_BADR */
if (!rxdes[i].rxdes2) {
- buf = NetRxPackets[i];
+ buf = net_rx_packets[i];
rxdes[i].rxdes3 = virt_to_phys(buf);
rxdes[i].rxdes2 = (uint)buf;
}
@@ -493,7 +493,7 @@ static int ftgmac100_recv(struct eth_device *dev)
dma_map_single((void *)curr_des->rxdes2, rxlen, DMA_FROM_DEVICE);
/* pass the packet up to the protocol layers. */
- NetReceive((void *)curr_des->rxdes2, rxlen);
+ net_process_received_packet((void *)curr_des->rxdes2, rxlen);
/* release buffer to DMA */
curr_des->rxdes0 &= ~FTGMAC100_RXDES0_RXPKT_RDY;
diff --git a/drivers/net/ftmac100.c b/drivers/net/ftmac100.c
index 3e148db5cd..bd94f83f04 100644
--- a/drivers/net/ftmac100.c
+++ b/drivers/net/ftmac100.c
@@ -102,7 +102,7 @@ static int ftmac100_init (struct eth_device *dev, bd_t *bd)
for (i = 0; i < PKTBUFSRX; i++) {
/* RXBUF_BADR */
- rxdes[i].rxdes2 = (unsigned int)NetRxPackets[i];
+ rxdes[i].rxdes2 = (unsigned int)net_rx_packets[i];
rxdes[i].rxdes1 |= FTMAC100_RXDES1_RXBUF_SIZE (PKTSIZE_ALIGN);
rxdes[i].rxdes0 = FTMAC100_RXDES0_RXDMA_OWN;
}
@@ -164,7 +164,7 @@ static int ftmac100_recv (struct eth_device *dev)
/* pass the packet up to the protocol layers. */
- NetReceive ((void *)curr_des->rxdes2, rxlen);
+ net_process_received_packet((void *)curr_des->rxdes2, rxlen);
/* release buffer to DMA */
diff --git a/drivers/net/ftmac110.c b/drivers/net/ftmac110.c
index 98c4f09629..4bae9ad977 100644
--- a/drivers/net/ftmac110.c
+++ b/drivers/net/ftmac110.c
@@ -347,7 +347,7 @@ static int ftmac110_recv(struct eth_device *dev)
printf("ftmac110: rx error\n");
} else {
dma_map_single(buf, len, DMA_FROM_DEVICE);
- NetReceive(buf, len);
+ net_process_received_packet(buf, len);
rlen += len;
}
@@ -425,7 +425,7 @@ int ftmac110_initialize(bd_t *bis)
dev->recv = ftmac110_recv;
if (!eth_getenv_enetaddr_by_index("eth", card_nr, dev->enetaddr))
- eth_random_addr(dev->enetaddr);
+ net_random_ethaddr(dev->enetaddr);
/* allocate tx descriptors (it must be 16 bytes aligned) */
chip->txd = dma_alloc_coherent(
diff --git a/drivers/net/greth.c b/drivers/net/greth.c
index c817af4dac..a93b37a5d7 100644
--- a/drivers/net/greth.c
+++ b/drivers/net/greth.c
@@ -533,7 +533,7 @@ int greth_recv(struct eth_device *dev)
sparc_dcache_flush_all();
/* pass packet on to network subsystem */
- NetReceive((void *)d, len);
+ net_process_received_packet((void *)d, len);
/* bump stats counters */
greth->stats.rx_packets++;
diff --git a/drivers/net/keystone_net.c b/drivers/net/keystone_net.c
index 35f1a57331..0c5fdeefd7 100644
--- a/drivers/net/keystone_net.c
+++ b/drivers/net/keystone_net.c
@@ -505,7 +505,7 @@ static int keystone2_eth_rcv_packet(struct eth_device *dev)
if (hd == NULL)
return 0;
- NetReceive((uchar *)pkt, pkt_size);
+ net_process_received_packet((uchar *)pkt, pkt_size);
ksnav_release_rxhd(&netcp_pktdma, hd);
diff --git a/drivers/net/ks8851_mll.c b/drivers/net/ks8851_mll.c
index 05e5b14d29..5b4c5b0df6 100644
--- a/drivers/net/ks8851_mll.c
+++ b/drivers/net/ks8851_mll.c
@@ -321,8 +321,8 @@ static void ks_rcv(struct eth_device *dev, uchar **pv_data)
/* read data block including CRC 4 bytes */
ks_read_qmu(dev, (u16 *)(*pv_data), frame_hdr->len);
- /* NetRxPackets buffer size is ok (*pv_data pointer) */
- NetReceive(*pv_data, frame_hdr->len);
+ /* net_rx_packets buffer size is ok (*pv_data) */
+ net_process_received_packet(*pv_data, frame_hdr->len);
pv_data++;
} else {
ks_wrreg16(dev, KS_RXQCR, (ks->rc_rxqcr | RXQCR_RRXEF));
@@ -573,7 +573,7 @@ static int ks8851_mll_recv(struct eth_device *dev)
ks_wrreg16(dev, KS_ISR, status);
if ((status & IRQ_RXI))
- ks_rcv(dev, (uchar **)NetRxPackets);
+ ks_rcv(dev, (uchar **)net_rx_packets);
if ((status & IRQ_LDI)) {
u16 pmecr = ks_rdreg16(dev, KS_PMECR);
diff --git a/drivers/net/lan91c96.c b/drivers/net/lan91c96.c
index 229658abc8..495c0886fa 100644
--- a/drivers/net/lan91c96.c
+++ b/drivers/net/lan91c96.c
@@ -568,29 +568,30 @@ static int smc_rcv(struct eth_device *dev)
to send the DWORDs or the bytes first, or some
mixture. A mixture might improve already slow PIO
performance */
- SMC_insl(dev, LAN91C96_DATA_HIGH, NetRxPackets[0],
- packet_length >> 2);
+ SMC_insl(dev, LAN91C96_DATA_HIGH, net_rx_packets[0],
+ packet_length >> 2);
/* read the left over bytes */
if (packet_length & 3) {
int i;
- byte *tail = (byte *) (NetRxPackets[0] + (packet_length & ~3));
+ byte *tail = (byte *)(net_rx_packets[0] +
+ (packet_length & ~3));
dword leftover = SMC_inl(dev, LAN91C96_DATA_HIGH);
for (i = 0; i < (packet_length & 3); i++)
*tail++ = (byte) (leftover >> (8 * i)) & 0xff;
}
#else
- PRINTK3 (" Reading %d words and %d byte(s) \n",
- (packet_length >> 1), packet_length & 1);
- SMC_insw(dev, LAN91C96_DATA_HIGH, NetRxPackets[0],
- packet_length >> 1);
+ PRINTK3(" Reading %d words and %d byte(s)\n",
+ (packet_length >> 1), packet_length & 1);
+ SMC_insw(dev, LAN91C96_DATA_HIGH, net_rx_packets[0],
+ packet_length >> 1);
#endif /* USE_32_BIT */
#if SMC_DEBUG > 2
printf ("Receiving Packet\n");
- print_packet((byte *)NetRxPackets[0], packet_length);
+ print_packet((byte *)net_rx_packets[0], packet_length);
#endif
} else {
/* error ... */
@@ -609,7 +610,7 @@ static int smc_rcv(struct eth_device *dev)
if (!is_error) {
/* Pass the packet up to the protocol layers. */
- NetReceive (NetRxPackets[0], packet_length);
+ net_process_received_packet(net_rx_packets[0], packet_length);
return packet_length;
} else {
return 0;
diff --git a/drivers/net/lpc32xx_eth.c b/drivers/net/lpc32xx_eth.c
index fcadf0c77f..8dcbb4a04a 100644
--- a/drivers/net/lpc32xx_eth.c
+++ b/drivers/net/lpc32xx_eth.c
@@ -419,10 +419,12 @@ static int lpc32xx_eth_recv(struct eth_device *dev)
rx_index = readl(&regs->rxconsumeindex);
/* if data was valid, pass it on */
- if (!(bufs->rx_stat[rx_index].statusinfo & RX_STAT_ERRORS))
- NetReceive(&(bufs->rx_buf[rx_index*PKTSIZE_ALIGN]),
- (bufs->rx_stat[rx_index].statusinfo
- & RX_STAT_RXSIZE) + 1);
+ if (!(bufs->rx_stat[rx_index].statusinfo & RX_STAT_ERRORS)) {
+ net_process_received_packet(
+ &(bufs->rx_buf[rx_index * PKTSIZE_ALIGN]),
+ (bufs->rx_stat[rx_index].statusinfo
+ & RX_STAT_RXSIZE) + 1);
+ }
/* pass receive slot back to DMA engine */
rx_index = (rx_index + 1) % RX_BUF_COUNT;
diff --git a/drivers/net/macb.c b/drivers/net/macb.c
index 170ff0646f..4e1a7fe583 100644
--- a/drivers/net/macb.c
+++ b/drivers/net/macb.c
@@ -347,14 +347,14 @@ static int macb_recv(struct eth_device *netdev)
headlen = 128 * (MACB_RX_RING_SIZE
- macb->rx_tail);
taillen = length - headlen;
- memcpy((void *)NetRxPackets[0],
+ memcpy((void *)net_rx_packets[0],
buffer, headlen);
- memcpy((void *)NetRxPackets[0] + headlen,
+ memcpy((void *)net_rx_packets[0] + headlen,
macb->rx_buffer, taillen);
- buffer = (void *)NetRxPackets[0];
+ buffer = (void *)net_rx_packets[0];
}
- NetReceive(buffer, length);
+ net_process_received_packet(buffer, length);
if (++rx_tail >= MACB_RX_RING_SIZE)
rx_tail = 0;
reclaim_rx_buffers(macb, rx_tail);
@@ -595,7 +595,7 @@ static int macb_init(struct eth_device *netdev, bd_t *bd)
}
/* update the ethaddr */
- if (is_valid_ether_addr(netdev->enetaddr)) {
+ if (is_valid_ethaddr(netdev->enetaddr)) {
macb_write_hwaddr(netdev);
} else {
printf("%s: mac address is not valid\n", netdev->name);
diff --git a/drivers/net/mcffec.c b/drivers/net/mcffec.c
index 7c4b210b00..fd73099371 100644
--- a/drivers/net/mcffec.c
+++ b/drivers/net/mcffec.c
@@ -219,7 +219,8 @@ int fec_recv(struct eth_device *dev)
length -= 4;
/* Pass the packet up to the protocol layers. */
- NetReceive(NetRxPackets[info->rxIdx], length);
+ net_process_received_packet(net_rx_packets[info->rxIdx],
+ length);
fecp->eir |= FEC_EIR_RXF;
}
@@ -477,7 +478,7 @@ int fec_init(struct eth_device *dev, bd_t * bd)
for (i = 0; i < PKTBUFSRX; i++) {
info->rxbd[i].cbd_sc = BD_ENET_RX_EMPTY;
info->rxbd[i].cbd_datlen = 0; /* Reset */
- info->rxbd[i].cbd_bufaddr = (uint) NetRxPackets[i];
+ info->rxbd[i].cbd_bufaddr = (uint) net_rx_packets[i];
}
info->rxbd[PKTBUFSRX - 1].cbd_sc |= BD_ENET_RX_WRAP;
diff --git a/drivers/net/mpc512x_fec.c b/drivers/net/mpc512x_fec.c
index 427e0b8b46..22ea114f01 100644
--- a/drivers/net/mpc512x_fec.c
+++ b/drivers/net/mpc512x_fec.c
@@ -591,7 +591,8 @@ static int mpc512x_fec_recv (struct eth_device *dev)
rx_buff_idx = frame_length;
if (pRbd->status & FEC_RBD_LAST) {
- NetReceive ((uchar*)rx_buff, frame_length);
+ net_process_received_packet((uchar *)rx_buff,
+ frame_length);
rx_buff_idx = 0;
}
}
diff --git a/drivers/net/mpc5xxx_fec.c b/drivers/net/mpc5xxx_fec.c
index d2a8ae0868..2ebd1761c3 100644
--- a/drivers/net/mpc5xxx_fec.c
+++ b/drivers/net/mpc5xxx_fec.c
@@ -859,7 +859,7 @@ static int mpc5xxx_fec_recv(struct eth_device *dev)
*/
memcpy(buff, frame->head, 14);
memcpy(buff + 14, frame->data, frame_length);
- NetReceive(buff, frame_length);
+ net_process_received_packet(buff, frame_length);
len = frame_length;
}
/*
diff --git a/drivers/net/mvgbe.c b/drivers/net/mvgbe.c
index 6b31a82ec4..ab5aa68fc8 100644
--- a/drivers/net/mvgbe.c
+++ b/drivers/net/mvgbe.c
@@ -66,12 +66,12 @@ static int smi_reg_read(const char *devname, u8 phy_adr, u8 reg_ofs, u16 * data)
/* check parameters */
if (phy_adr > PHYADR_MASK) {
printf("Err..(%s) Invalid PHY address %d\n",
- __FUNCTION__, phy_adr);
+ __func__, phy_adr);
return -EFAULT;
}
if (reg_ofs > PHYREG_MASK) {
printf("Err..(%s) Invalid register offset %d\n",
- __FUNCTION__, reg_ofs);
+ __func__, reg_ofs);
return -EFAULT;
}
@@ -81,7 +81,7 @@ static int smi_reg_read(const char *devname, u8 phy_adr, u8 reg_ofs, u16 * data)
/* read smi register */
smi_reg = MVGBE_REG_RD(MVGBE_SMI_REG);
if (timeout-- == 0) {
- printf("Err..(%s) SMI busy timeout\n", __FUNCTION__);
+ printf("Err..(%s) SMI busy timeout\n", __func__);
return -EFAULT;
}
} while (smi_reg & MVGBE_PHY_SMI_BUSY_MASK);
@@ -102,7 +102,7 @@ static int smi_reg_read(const char *devname, u8 phy_adr, u8 reg_ofs, u16 * data)
smi_reg = MVGBE_REG_RD(MVGBE_SMI_REG);
if (timeout-- == 0) {
printf("Err..(%s) SMI read ready timeout\n",
- __FUNCTION__);
+ __func__);
return -EFAULT;
}
} while (!(smi_reg & MVGBE_PHY_SMI_READ_VALID_MASK));
@@ -113,8 +113,8 @@ static int smi_reg_read(const char *devname, u8 phy_adr, u8 reg_ofs, u16 * data)
*data = (u16) (MVGBE_REG_RD(MVGBE_SMI_REG) & MVGBE_PHY_SMI_DATA_MASK);
- debug("%s:(adr %d, off %d) value= %04x\n", __FUNCTION__, phy_adr,
- reg_ofs, *data);
+ debug("%s:(adr %d, off %d) value= %04x\n", __func__, phy_adr, reg_ofs,
+ *data);
return 0;
}
@@ -142,11 +142,11 @@ static int smi_reg_write(const char *devname, u8 phy_adr, u8 reg_ofs, u16 data)
/* check parameters */
if (phy_adr > PHYADR_MASK) {
- printf("Err..(%s) Invalid phy address\n", __FUNCTION__);
+ printf("Err..(%s) Invalid phy address\n", __func__);
return -EINVAL;
}
if (reg_ofs > PHYREG_MASK) {
- printf("Err..(%s) Invalid register offset\n", __FUNCTION__);
+ printf("Err..(%s) Invalid register offset\n", __func__);
return -EINVAL;
}
@@ -156,7 +156,7 @@ static int smi_reg_write(const char *devname, u8 phy_adr, u8 reg_ofs, u16 data)
/* read smi register */
smi_reg = MVGBE_REG_RD(MVGBE_SMI_REG);
if (timeout-- == 0) {
- printf("Err..(%s) SMI busy timeout\n", __FUNCTION__);
+ printf("Err..(%s) SMI busy timeout\n", __func__);
return -ETIME;
}
} while (smi_reg & MVGBE_PHY_SMI_BUSY_MASK);
@@ -583,7 +583,7 @@ static int mvgbe_send(struct eth_device *dev, void *dataptr, int datasize)
if ((cmd_sts & (MVGBE_ERROR_SUMMARY | MVGBE_TX_LAST_FRAME)) ==
(MVGBE_ERROR_SUMMARY | MVGBE_TX_LAST_FRAME) &&
cmd_sts & (MVGBE_UR_ERROR | MVGBE_RL_ERROR)) {
- printf("Err..(%s) in xmit packet\n", __FUNCTION__);
+ printf("Err..(%s) in xmit packet\n", __func__);
return -1;
}
cmd_sts = readl(&p_txdesc->cmd_sts);
@@ -604,14 +604,14 @@ static int mvgbe_recv(struct eth_device *dev)
if (timeout < MVGBE_PHY_SMI_TIMEOUT)
timeout++;
else {
- debug("%s time out...\n", __FUNCTION__);
+ debug("%s time out...\n", __func__);
return -1;
}
} while (readl(&p_rxdesc_curr->cmd_sts) & MVGBE_BUFFER_OWNED_BY_DMA);
if (p_rxdesc_curr->byte_cnt != 0) {
debug("%s: Received %d byte Packet @ 0x%x (cmd_sts= %08x)\n",
- __FUNCTION__, (u32) p_rxdesc_curr->byte_cnt,
+ __func__, (u32) p_rxdesc_curr->byte_cnt,
(u32) p_rxdesc_curr->buf_ptr,
(u32) p_rxdesc_curr->cmd_sts);
}
@@ -628,21 +628,24 @@ static int mvgbe_recv(struct eth_device *dev)
!= (MVGBE_RX_FIRST_DESC | MVGBE_RX_LAST_DESC)) {
printf("Err..(%s) Dropping packet spread on"
- " multiple descriptors\n", __FUNCTION__);
+ " multiple descriptors\n", __func__);
} else if (cmd_sts & MVGBE_ERROR_SUMMARY) {
printf("Err..(%s) Dropping packet with errors\n",
- __FUNCTION__);
+ __func__);
} else {
/* !!! call higher layer processing */
debug("%s: Sending Received packet to"
- " upper layer (NetReceive)\n", __FUNCTION__);
+ " upper layer (net_process_received_packet)\n",
+ __func__);
/* let the upper layer handle the packet */
- NetReceive((p_rxdesc_curr->buf_ptr + RX_BUF_OFFSET),
- (int)(p_rxdesc_curr->byte_cnt - RX_BUF_OFFSET));
+ net_process_received_packet((p_rxdesc_curr->buf_ptr +
+ RX_BUF_OFFSET),
+ (int)(p_rxdesc_curr->byte_cnt -
+ RX_BUF_OFFSET));
}
/*
* free these descriptors and point next in the ring
@@ -747,7 +750,7 @@ error2:
free(dmvgbe);
error1:
printf("Err.. %s Failed to allocate memory\n",
- __FUNCTION__);
+ __func__);
return -1;
}
@@ -767,7 +770,7 @@ error1:
#endif
default: /* this should never happen */
printf("Err..(%s) Invalid device number %d\n",
- __FUNCTION__, devnum);
+ __func__, devnum);
return -1;
}
diff --git a/drivers/net/mvneta.c b/drivers/net/mvneta.c
index a2a69b4219..efaae167fe 100644
--- a/drivers/net/mvneta.c
+++ b/drivers/net/mvneta.c
@@ -1572,7 +1572,7 @@ static int mvneta_recv(struct eth_device *dev)
* No cache invalidation needed here, since the rx_buffer's are
* located in a uncached memory region
*/
- NetReceive(data, rx_bytes);
+ net_process_received_packet(data, rx_bytes);
}
/* Update rxq management counters */
diff --git a/drivers/net/natsemi.c b/drivers/net/natsemi.c
index 04743bd2b3..0ed9bb5765 100644
--- a/drivers/net/natsemi.c
+++ b/drivers/net/natsemi.c
@@ -841,7 +841,8 @@ natsemi_poll(struct eth_device *dev)
rx_status);
retstat = 0;
} else { /* give packet to higher level routine */
- NetReceive((rxb + cur_rx * RX_BUF_SIZE), length);
+ net_process_received_packet((rxb + cur_rx * RX_BUF_SIZE),
+ length);
retstat = 1;
}
diff --git a/drivers/net/ne2000_base.c b/drivers/net/ne2000_base.c
index ef35922042..07a7cec2a8 100644
--- a/drivers/net/ne2000_base.c
+++ b/drivers/net/ne2000_base.c
@@ -665,7 +665,7 @@ void uboot_push_packet_len(int len) {
dp83902a_recv(&pbuf[0], len);
/*Just pass it to the upper layer*/
- NetReceive(&pbuf[0], len);
+ net_process_received_packet(&pbuf[0], len);
}
void uboot_push_tx_done(int key, int val) {
diff --git a/drivers/net/netconsole.c b/drivers/net/netconsole.c
index 677c89f048..31042a6b6b 100644
--- a/drivers/net/netconsole.c
+++ b/drivers/net/netconsole.c
@@ -23,7 +23,7 @@ static int input_recursion;
static int output_recursion;
static int net_timeout;
static uchar nc_ether[6]; /* server enet address */
-static IPaddr_t nc_ip; /* server ip */
+static struct in_addr nc_ip; /* server ip */
static short nc_out_port; /* target output port */
static short nc_in_port; /* source input port */
static const char *output_packet; /* used by first send udp */
@@ -35,42 +35,43 @@ static int output_packet_len;
enum proto_t net_loop_last_protocol = BOOTP;
static void nc_wait_arp_handler(uchar *pkt, unsigned dest,
- IPaddr_t sip, unsigned src,
+ struct in_addr sip, unsigned src,
unsigned len)
{
net_set_state(NETLOOP_SUCCESS); /* got arp reply - quit net loop */
}
-static void nc_handler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src,
- unsigned len)
+static void nc_handler(uchar *pkt, unsigned dest, struct in_addr sip,
+ unsigned src, unsigned len)
{
if (input_size)
net_set_state(NETLOOP_SUCCESS); /* got input - quit net loop */
}
-static void nc_timeout(void)
+static void nc_timeout_handler(void)
{
net_set_state(NETLOOP_SUCCESS);
}
-static int is_broadcast(IPaddr_t ip)
+static int is_broadcast(struct in_addr ip)
{
- static IPaddr_t netmask;
- static IPaddr_t our_ip;
+ static struct in_addr netmask;
+ static struct in_addr our_ip;
static int env_changed_id;
int env_id = get_env_id();
/* update only when the environment has changed */
if (env_changed_id != env_id) {
- netmask = getenv_IPaddr("netmask");
- our_ip = getenv_IPaddr("ipaddr");
+ netmask = getenv_ip("netmask");
+ our_ip = getenv_ip("ipaddr");
env_changed_id = env_id;
}
- return (ip == ~0 || /* 255.255.255.255 */
- ((netmask & our_ip) == (netmask & ip) && /* on the same net */
- (netmask | ip) == ~0)); /* broadcast to our net */
+ return (ip.s_addr == ~0 || /* 255.255.255.255 (global bcast) */
+ ((netmask.s_addr & our_ip.s_addr) ==
+ (netmask.s_addr & ip.s_addr) && /* on the same net and */
+ (netmask.s_addr | ip.s_addr) == ~0)); /* bcast to our net */
}
static int refresh_settings_from_env(void)
@@ -82,16 +83,17 @@ static int refresh_settings_from_env(void)
/* update only when the environment has changed */
if (env_changed_id != env_id) {
if (getenv("ncip")) {
- nc_ip = getenv_IPaddr("ncip");
- if (!nc_ip)
+ nc_ip = getenv_ip("ncip");
+ if (!nc_ip.s_addr)
return -1; /* ncip is 0.0.0.0 */
p = strchr(getenv("ncip"), ':');
if (p != NULL) {
nc_out_port = simple_strtoul(p + 1, NULL, 10);
nc_in_port = nc_out_port;
}
- } else
- nc_ip = ~0; /* ncip is not set, so broadcast */
+ } else {
+ nc_ip.s_addr = ~0; /* ncip is not set, so broadcast */
+ }
p = getenv("ncoutport");
if (p != NULL)
@@ -111,27 +113,28 @@ static int refresh_settings_from_env(void)
}
/**
- * Called from NetLoop in net/net.c before each packet
+ * Called from net_loop in net/net.c before each packet
*/
-void NcStart(void)
+void nc_start(void)
{
refresh_settings_from_env();
- if (!output_packet_len || memcmp(nc_ether, NetEtherNullAddr, 6)) {
+ if (!output_packet_len || memcmp(nc_ether, net_null_ethaddr, 6)) {
/* going to check for input packet */
net_set_udp_handler(nc_handler);
- NetSetTimeout(net_timeout, nc_timeout);
+ net_set_timeout_handler(net_timeout, nc_timeout_handler);
} else {
/* send arp request */
uchar *pkt;
net_set_arp_handler(nc_wait_arp_handler);
- pkt = (uchar *)NetTxPacket + NetEthHdrSize() + IP_UDP_HDR_SIZE;
+ pkt = (uchar *)net_tx_packet + net_eth_hdr_size() +
+ IP_UDP_HDR_SIZE;
memcpy(pkt, output_packet, output_packet_len);
- NetSendUDPPacket(nc_ether, nc_ip, nc_out_port, nc_in_port,
- output_packet_len);
+ net_send_udp_packet(nc_ether, nc_ip, nc_out_port, nc_in_port,
+ output_packet_len);
}
}
-int nc_input_packet(uchar *pkt, IPaddr_t src_ip, unsigned dest_port,
+int nc_input_packet(uchar *pkt, struct in_addr src_ip, unsigned dest_port,
unsigned src_port, unsigned len)
{
int end, chunk;
@@ -139,7 +142,7 @@ int nc_input_packet(uchar *pkt, IPaddr_t src_ip, unsigned dest_port,
if (dest_port != nc_in_port || !len)
return 0; /* not for us */
- if (src_ip != nc_ip && !is_broadcast(nc_ip))
+ if (src_ip.s_addr != nc_ip.s_addr && !is_broadcast(nc_ip))
return 0; /* not from our client */
debug_cond(DEBUG_DEV_PKT, "input: \"%*.*s\"\n", len, len, pkt);
@@ -171,7 +174,7 @@ static void nc_send_packet(const char *buf, int len)
int inited = 0;
uchar *pkt;
uchar *ether;
- IPaddr_t ip;
+ struct in_addr ip;
debug_cond(DEBUG_DEV_PKT, "output: \"%*.*s\"\n", len, len, buf);
@@ -179,13 +182,13 @@ static void nc_send_packet(const char *buf, int len)
if (eth == NULL)
return;
- if (!memcmp(nc_ether, NetEtherNullAddr, 6)) {
+ if (!memcmp(nc_ether, net_null_ethaddr, 6)) {
if (eth->state == ETH_STATE_ACTIVE)
return; /* inside net loop */
output_packet = buf;
output_packet_len = len;
input_recursion = 1;
- NetLoop(NETCONS); /* wait for arp reply and send packet */
+ net_loop(NETCONS); /* wait for arp reply and send packet */
input_recursion = 0;
output_packet_len = 0;
return;
@@ -193,19 +196,20 @@ static void nc_send_packet(const char *buf, int len)
if (eth->state != ETH_STATE_ACTIVE) {
if (eth_is_on_demand_init()) {
- if (eth_init(gd->bd) < 0)
+ if (eth_init() < 0)
return;
eth_set_last_protocol(NETCONS);
- } else
- eth_init_state_only(gd->bd);
+ } else {
+ eth_init_state_only();
+ }
inited = 1;
}
- pkt = (uchar *)NetTxPacket + NetEthHdrSize() + IP_UDP_HDR_SIZE;
+ pkt = (uchar *)net_tx_packet + net_eth_hdr_size() + IP_UDP_HDR_SIZE;
memcpy(pkt, buf, len);
ether = nc_ether;
ip = nc_ip;
- NetSendUDPPacket(ether, ip, nc_out_port, nc_in_port, len);
+ net_send_udp_packet(ether, ip, nc_out_port, nc_in_port, len);
if (inited) {
if (eth_is_on_demand_init())
@@ -215,7 +219,7 @@ static void nc_send_packet(const char *buf, int len)
}
}
-static int nc_start(struct stdio_dev *dev)
+static int nc_stdio_start(struct stdio_dev *dev)
{
int retval;
@@ -228,14 +232,14 @@ static int nc_start(struct stdio_dev *dev)
/*
* Initialize the static IP settings and buffer pointers
- * incase we call NetSendUDPPacket before NetLoop
+ * incase we call net_send_udp_packet before net_loop
*/
net_init();
return 0;
}
-static void nc_putc(struct stdio_dev *dev, char c)
+static void nc_stdio_putc(struct stdio_dev *dev, char c)
{
if (output_recursion)
return;
@@ -246,7 +250,7 @@ static void nc_putc(struct stdio_dev *dev, char c)
output_recursion = 0;
}
-static void nc_puts(struct stdio_dev *dev, const char *s)
+static void nc_stdio_puts(struct stdio_dev *dev, const char *s)
{
int len;
@@ -265,7 +269,7 @@ static void nc_puts(struct stdio_dev *dev, const char *s)
output_recursion = 0;
}
-static int nc_getc(struct stdio_dev *dev)
+static int nc_stdio_getc(struct stdio_dev *dev)
{
uchar c;
@@ -273,7 +277,7 @@ static int nc_getc(struct stdio_dev *dev)
net_timeout = 0; /* no timeout */
while (!input_size)
- NetLoop(NETCONS);
+ net_loop(NETCONS);
input_recursion = 0;
@@ -286,7 +290,7 @@ static int nc_getc(struct stdio_dev *dev)
return c;
}
-static int nc_tstc(struct stdio_dev *dev)
+static int nc_stdio_tstc(struct stdio_dev *dev)
{
struct eth_device *eth;
@@ -303,7 +307,7 @@ static int nc_tstc(struct stdio_dev *dev)
input_recursion = 1;
net_timeout = 1;
- NetLoop(NETCONS); /* kind of poll */
+ net_loop(NETCONS); /* kind of poll */
input_recursion = 0;
@@ -319,11 +323,11 @@ int drv_nc_init(void)
strcpy(dev.name, "nc");
dev.flags = DEV_FLAGS_OUTPUT | DEV_FLAGS_INPUT | DEV_FLAGS_SYSTEM;
- dev.start = nc_start;
- dev.putc = nc_putc;
- dev.puts = nc_puts;
- dev.getc = nc_getc;
- dev.tstc = nc_tstc;
+ dev.start = nc_stdio_start;
+ dev.putc = nc_stdio_putc;
+ dev.puts = nc_stdio_puts;
+ dev.getc = nc_stdio_getc;
+ dev.tstc = nc_stdio_tstc;
rc = stdio_register(&dev);
diff --git a/drivers/net/ns8382x.c b/drivers/net/ns8382x.c
index cfe1f349db..f941c15b27 100644
--- a/drivers/net/ns8382x.c
+++ b/drivers/net/ns8382x.c
@@ -809,11 +809,13 @@ ns8382x_poll(struct eth_device *dev)
if ((rx_status & (DescMore | DescPktOK | DescRxLong)) != DescPktOK) {
/* corrupted packet received */
- printf("ns8382x_poll: Corrupted packet, status:%lx\n", rx_status);
+ printf("ns8382x_poll: Corrupted packet, status:%lx\n",
+ rx_status);
retstat = 0;
} else {
/* give packet to higher level routine */
- NetReceive((rxb + cur_rx * RX_BUF_SIZE), length);
+ net_process_received_packet((rxb + cur_rx * RX_BUF_SIZE),
+ length);
retstat = 1;
}
diff --git a/drivers/net/pch_gbe.c b/drivers/net/pch_gbe.c
index 976848df4d..15c9cdcc3a 100644
--- a/drivers/net/pch_gbe.c
+++ b/drivers/net/pch_gbe.c
@@ -297,7 +297,7 @@ static int pch_gbe_recv(struct eth_device *dev)
buffer_addr = pci_mem_to_phys(priv->bdf, rx_desc->buffer_addr);
length = rx_desc->rx_words_eob - 3 - ETH_FCS_LEN;
- NetReceive((uchar *)buffer_addr, length);
+ net_process_received_packet((uchar *)buffer_addr, length);
/* Test the wrap-around condition */
if (++priv->rx_idx >= PCH_GBE_DESC_NUM)
diff --git a/drivers/net/pcnet.c b/drivers/net/pcnet.c
index 237fbba513..cfcb1b4e23 100644
--- a/drivers/net/pcnet.c
+++ b/drivers/net/pcnet.c
@@ -507,7 +507,7 @@ static int pcnet_recv (struct eth_device *dev)
buf = (*lp->rx_buf)[lp->cur_rx];
invalidate_dcache_range((unsigned long)buf,
(unsigned long)buf + pkt_len);
- NetReceive(buf, pkt_len);
+ net_process_received_packet(buf, pkt_len);
PCNET_DEBUG2("Rx%d: %d bytes from 0x%p\n",
lp->cur_rx, pkt_len, buf);
}
diff --git a/drivers/net/phy/phy.c b/drivers/net/phy/phy.c
index df7e9450c2..9d88afe8fc 100644
--- a/drivers/net/phy/phy.c
+++ b/drivers/net/phy/phy.c
@@ -11,6 +11,7 @@
#include <config.h>
#include <common.h>
+#include <dm.h>
#include <malloc.h>
#include <net.h>
#include <command.h>
@@ -754,7 +755,11 @@ struct phy_device *phy_find_by_mask(struct mii_dev *bus, unsigned phy_mask,
return get_phy_device_by_mask(bus, phy_mask, interface);
}
+#ifdef CONFIG_DM_ETH
+void phy_connect_dev(struct phy_device *phydev, struct udevice *dev)
+#else
void phy_connect_dev(struct phy_device *phydev, struct eth_device *dev)
+#endif
{
/* Soft Reset the PHY */
phy_reset(phydev);
@@ -767,8 +772,13 @@ void phy_connect_dev(struct phy_device *phydev, struct eth_device *dev)
debug("%s connected to %s\n", dev->name, phydev->drv->name);
}
+#ifdef CONFIG_DM_ETH
+struct phy_device *phy_connect(struct mii_dev *bus, int addr,
+ struct udevice *dev, phy_interface_t interface)
+#else
struct phy_device *phy_connect(struct mii_dev *bus, int addr,
struct eth_device *dev, phy_interface_t interface)
+#endif
{
struct phy_device *phydev;
@@ -813,3 +823,15 @@ int phy_shutdown(struct phy_device *phydev)
return 0;
}
+
+int phy_get_interface_by_name(const char *str)
+{
+ int i;
+
+ for (i = 0; i < PHY_INTERFACE_MODE_COUNT; i++) {
+ if (!strcmp(str, phy_interface_strings[i]))
+ return i;
+ }
+
+ return -1;
+}
diff --git a/drivers/net/rtl8139.c b/drivers/net/rtl8139.c
index 208ce5ccc4..ea523435f0 100644
--- a/drivers/net/rtl8139.c
+++ b/drivers/net/rtl8139.c
@@ -504,11 +504,11 @@ static int rtl_poll(struct eth_device *dev)
memcpy(rxdata, rx_ring + ring_offs + 4, semi_count);
memcpy(&(rxdata[semi_count]), rx_ring, rx_size-4-semi_count);
- NetReceive(rxdata, length);
+ net_process_received_packet(rxdata, length);
debug_cond(DEBUG_RX, "rx packet %d+%d bytes",
semi_count, rx_size-4-semi_count);
} else {
- NetReceive(rx_ring + ring_offs + 4, length);
+ net_process_received_packet(rx_ring + ring_offs + 4, length);
debug_cond(DEBUG_RX, "rx packet %d bytes", rx_size-4);
}
flush_cache((unsigned long)rx_ring, RX_BUF_LEN);
diff --git a/drivers/net/rtl8169.c b/drivers/net/rtl8169.c
index cea6701203..4a5371051b 100644
--- a/drivers/net/rtl8169.c
+++ b/drivers/net/rtl8169.c
@@ -538,7 +538,7 @@ static int rtl_recv(struct eth_device *dev)
cpu_to_le32(bus_to_phys(tpc->RxBufferRing[cur_rx]));
rtl_flush_rx_desc(&tpc->RxDescArray[cur_rx]);
- NetReceive(rxdata, length);
+ net_process_received_packet(rxdata, length);
} else {
puts("Error Rx");
}
diff --git a/drivers/net/sandbox-raw.c b/drivers/net/sandbox-raw.c
new file mode 100644
index 0000000000..45c3b18bdf
--- /dev/null
+++ b/drivers/net/sandbox-raw.c
@@ -0,0 +1,165 @@
+/*
+ * Copyright (c) 2015 National Instruments
+ *
+ * (C) Copyright 2015
+ * Joe Hershberger <joe.hershberger@ni.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <asm/eth-raw-os.h>
+#include <common.h>
+#include <dm.h>
+#include <malloc.h>
+#include <net.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static int reply_arp;
+static struct in_addr arp_ip;
+
+static int sb_eth_raw_start(struct udevice *dev)
+{
+ struct eth_sandbox_raw_priv *priv = dev_get_priv(dev);
+ struct eth_pdata *pdata = dev_get_platdata(dev);
+ const char *interface;
+
+ debug("eth_sandbox_raw: Start\n");
+
+ interface = fdt_getprop(gd->fdt_blob, dev->of_offset,
+ "host-raw-interface", NULL);
+ if (interface == NULL)
+ return -EINVAL;
+
+ if (strcmp(interface, "lo") == 0) {
+ priv->local = 1;
+ setenv("ipaddr", "127.0.0.1");
+ setenv("serverip", "127.0.0.1");
+ }
+ return sandbox_eth_raw_os_start(interface, pdata->enetaddr, priv);
+}
+
+static int sb_eth_raw_send(struct udevice *dev, void *packet, int length)
+{
+ struct eth_sandbox_raw_priv *priv = dev_get_priv(dev);
+
+ debug("eth_sandbox_raw: Send packet %d\n", length);
+
+ if (priv->local) {
+ struct ethernet_hdr *eth = packet;
+
+ if (ntohs(eth->et_protlen) == PROT_ARP) {
+ struct arp_hdr *arp = packet + ETHER_HDR_SIZE;
+
+ /**
+ * localhost works on a higher-level API in Linux than
+ * ARP packets, so fake it
+ */
+ arp_ip = net_read_ip(&arp->ar_tpa);
+ reply_arp = 1;
+ return 0;
+ }
+ packet += ETHER_HDR_SIZE;
+ length -= ETHER_HDR_SIZE;
+ }
+ return sandbox_eth_raw_os_send(packet, length, priv);
+}
+
+static int sb_eth_raw_recv(struct udevice *dev, uchar **packetp)
+{
+ struct eth_pdata *pdata = dev_get_platdata(dev);
+ struct eth_sandbox_raw_priv *priv = dev_get_priv(dev);
+ int retval = 0;
+ int length;
+
+ if (reply_arp) {
+ struct arp_hdr *arp = (void *)net_rx_packets[0] +
+ ETHER_HDR_SIZE;
+
+ /*
+ * Fake an ARP response. The u-boot network stack is sending an
+ * ARP request (to find the MAC address to address the actual
+ * packet to) and requires an ARP response to continue. Since
+ * this is the localhost interface, there is no Etherent level
+ * traffic at all, so there is no way to send an ARP request or
+ * to get a response. For this reason we fake the response to
+ * make the u-boot network stack happy.
+ */
+ arp->ar_hrd = htons(ARP_ETHER);
+ arp->ar_pro = htons(PROT_IP);
+ arp->ar_hln = ARP_HLEN;
+ arp->ar_pln = ARP_PLEN;
+ arp->ar_op = htons(ARPOP_REPLY);
+ /* Any non-zero MAC address will work */
+ memset(&arp->ar_sha, 0x01, ARP_HLEN);
+ /* Use whatever IP we were looking for (always 127.0.0.1?) */
+ net_write_ip(&arp->ar_spa, arp_ip);
+ memcpy(&arp->ar_tha, pdata->enetaddr, ARP_HLEN);
+ net_write_ip(&arp->ar_tpa, net_ip);
+ length = ARP_HDR_SIZE;
+ } else {
+ /* If local, the Ethernet header won't be included; skip it */
+ uchar *pktptr = priv->local ?
+ net_rx_packets[0] + ETHER_HDR_SIZE : net_rx_packets[0];
+
+ retval = sandbox_eth_raw_os_recv(pktptr, &length, priv);
+ }
+
+ if (!retval && length) {
+ if (priv->local) {
+ struct ethernet_hdr *eth = (void *)net_rx_packets[0];
+
+ /* Fill in enough of the missing Ethernet header */
+ memcpy(eth->et_dest, pdata->enetaddr, ARP_HLEN);
+ memset(eth->et_src, 0x01, ARP_HLEN);
+ eth->et_protlen = htons(reply_arp ? PROT_ARP : PROT_IP);
+ reply_arp = 0;
+ length += ETHER_HDR_SIZE;
+ }
+
+ debug("eth_sandbox_raw: received packet %d\n",
+ length);
+ *packetp = net_rx_packets[0];
+ return length;
+ }
+ return retval;
+}
+
+static void sb_eth_raw_stop(struct udevice *dev)
+{
+ struct eth_sandbox_raw_priv *priv = dev_get_priv(dev);
+
+ debug("eth_sandbox_raw: Stop\n");
+
+ sandbox_eth_raw_os_stop(priv);
+}
+
+static const struct eth_ops sb_eth_raw_ops = {
+ .start = sb_eth_raw_start,
+ .send = sb_eth_raw_send,
+ .recv = sb_eth_raw_recv,
+ .stop = sb_eth_raw_stop,
+};
+
+static int sb_eth_raw_ofdata_to_platdata(struct udevice *dev)
+{
+ struct eth_pdata *pdata = dev_get_platdata(dev);
+
+ pdata->iobase = dev_get_addr(dev);
+ return 0;
+}
+
+static const struct udevice_id sb_eth_raw_ids[] = {
+ { .compatible = "sandbox,eth-raw" },
+ { }
+};
+
+U_BOOT_DRIVER(eth_sandbox_raw) = {
+ .name = "eth_sandbox_raw",
+ .id = UCLASS_ETH,
+ .of_match = sb_eth_raw_ids,
+ .ofdata_to_platdata = sb_eth_raw_ofdata_to_platdata,
+ .ops = &sb_eth_raw_ops,
+ .priv_auto_alloc_size = sizeof(struct eth_sandbox_raw_priv),
+ .platdata_auto_alloc_size = sizeof(struct eth_pdata),
+};
diff --git a/drivers/net/sandbox.c b/drivers/net/sandbox.c
new file mode 100644
index 0000000000..e239ff4447
--- /dev/null
+++ b/drivers/net/sandbox.c
@@ -0,0 +1,208 @@
+/*
+ * Copyright (c) 2015 National Instruments
+ *
+ * (C) Copyright 2015
+ * Joe Hershberger <joe.hershberger@ni.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <malloc.h>
+#include <net.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/**
+ * struct eth_sandbox_priv - memory for sandbox mock driver
+ *
+ * fake_host_hwaddr: MAC address of mocked machine
+ * fake_host_ipaddr: IP address of mocked machine
+ * recv_packet_buffer: buffer of the packet returned as received
+ * recv_packet_length: length of the packet returned as received
+ */
+struct eth_sandbox_priv {
+ uchar fake_host_hwaddr[ARP_HLEN];
+ struct in_addr fake_host_ipaddr;
+ uchar *recv_packet_buffer;
+ int recv_packet_length;
+};
+
+static bool disabled[8] = {false};
+
+/*
+ * sandbox_eth_disable_response()
+ *
+ * index - The alias index (also DM seq number)
+ * disable - If non-zero, ignore sent packets and don't send mock response
+ */
+void sandbox_eth_disable_response(int index, bool disable)
+{
+ disabled[index] = disable;
+}
+
+static int sb_eth_start(struct udevice *dev)
+{
+ struct eth_sandbox_priv *priv = dev_get_priv(dev);
+
+ debug("eth_sandbox: Start\n");
+
+ fdtdec_get_byte_array(gd->fdt_blob, dev->of_offset, "fake-host-hwaddr",
+ priv->fake_host_hwaddr, ARP_HLEN);
+ priv->recv_packet_buffer = net_rx_packets[0];
+ return 0;
+}
+
+static int sb_eth_send(struct udevice *dev, void *packet, int length)
+{
+ struct eth_sandbox_priv *priv = dev_get_priv(dev);
+ struct ethernet_hdr *eth = packet;
+
+ debug("eth_sandbox: Send packet %d\n", length);
+
+ if (dev->seq >= 0 && dev->seq < ARRAY_SIZE(disabled) &&
+ disabled[dev->seq])
+ return 0;
+
+ if (ntohs(eth->et_protlen) == PROT_ARP) {
+ struct arp_hdr *arp = packet + ETHER_HDR_SIZE;
+
+ if (ntohs(arp->ar_op) == ARPOP_REQUEST) {
+ struct ethernet_hdr *eth_recv;
+ struct arp_hdr *arp_recv;
+
+ /* store this as the assumed IP of the fake host */
+ priv->fake_host_ipaddr = net_read_ip(&arp->ar_tpa);
+ /* Formulate a fake response */
+ eth_recv = (void *)priv->recv_packet_buffer;
+ memcpy(eth_recv->et_dest, eth->et_src, ARP_HLEN);
+ memcpy(eth_recv->et_src, priv->fake_host_hwaddr,
+ ARP_HLEN);
+ eth_recv->et_protlen = htons(PROT_ARP);
+
+ arp_recv = (void *)priv->recv_packet_buffer +
+ ETHER_HDR_SIZE;
+ arp_recv->ar_hrd = htons(ARP_ETHER);
+ arp_recv->ar_pro = htons(PROT_IP);
+ arp_recv->ar_hln = ARP_HLEN;
+ arp_recv->ar_pln = ARP_PLEN;
+ arp_recv->ar_op = htons(ARPOP_REPLY);
+ memcpy(&arp_recv->ar_sha, priv->fake_host_hwaddr,
+ ARP_HLEN);
+ net_write_ip(&arp_recv->ar_spa, priv->fake_host_ipaddr);
+ memcpy(&arp_recv->ar_tha, &arp->ar_sha, ARP_HLEN);
+ net_copy_ip(&arp_recv->ar_tpa, &arp->ar_spa);
+
+ priv->recv_packet_length = ETHER_HDR_SIZE +
+ ARP_HDR_SIZE;
+ }
+ } else if (ntohs(eth->et_protlen) == PROT_IP) {
+ struct ip_udp_hdr *ip = packet + ETHER_HDR_SIZE;
+
+ if (ip->ip_p == IPPROTO_ICMP) {
+ struct icmp_hdr *icmp = (struct icmp_hdr *)&ip->udp_src;
+
+ if (icmp->type == ICMP_ECHO_REQUEST) {
+ struct ethernet_hdr *eth_recv;
+ struct ip_udp_hdr *ipr;
+ struct icmp_hdr *icmpr;
+
+ /* reply to the ping */
+ memcpy(priv->recv_packet_buffer, packet,
+ length);
+ eth_recv = (void *)priv->recv_packet_buffer;
+ ipr = (void *)priv->recv_packet_buffer +
+ ETHER_HDR_SIZE;
+ icmpr = (struct icmp_hdr *)&ipr->udp_src;
+ memcpy(eth_recv->et_dest, eth->et_src,
+ ARP_HLEN);
+ memcpy(eth_recv->et_src, priv->fake_host_hwaddr,
+ ARP_HLEN);
+ ipr->ip_sum = 0;
+ ipr->ip_off = 0;
+ net_copy_ip((void *)&ipr->ip_dst, &ip->ip_src);
+ net_write_ip((void *)&ipr->ip_src,
+ priv->fake_host_ipaddr);
+ ipr->ip_sum = compute_ip_checksum(ipr,
+ IP_HDR_SIZE);
+
+ icmpr->type = ICMP_ECHO_REPLY;
+ icmpr->checksum = 0;
+ icmpr->checksum = compute_ip_checksum(icmpr,
+ ICMP_HDR_SIZE);
+
+ priv->recv_packet_length = length;
+ }
+ }
+ }
+
+ return 0;
+}
+
+static int sb_eth_recv(struct udevice *dev, uchar **packetp)
+{
+ struct eth_sandbox_priv *priv = dev_get_priv(dev);
+
+ if (priv->recv_packet_length) {
+ int lcl_recv_packet_length = priv->recv_packet_length;
+
+ debug("eth_sandbox: received packet %d\n",
+ priv->recv_packet_length);
+ priv->recv_packet_length = 0;
+ *packetp = priv->recv_packet_buffer;
+ return lcl_recv_packet_length;
+ }
+ return 0;
+}
+
+static void sb_eth_stop(struct udevice *dev)
+{
+ debug("eth_sandbox: Stop\n");
+}
+
+static int sb_eth_write_hwaddr(struct udevice *dev)
+{
+ struct eth_pdata *pdata = dev_get_platdata(dev);
+
+ debug("eth_sandbox %s: Write HW ADDR - %pM\n", dev->name,
+ pdata->enetaddr);
+ return 0;
+}
+
+static const struct eth_ops sb_eth_ops = {
+ .start = sb_eth_start,
+ .send = sb_eth_send,
+ .recv = sb_eth_recv,
+ .stop = sb_eth_stop,
+ .write_hwaddr = sb_eth_write_hwaddr,
+};
+
+static int sb_eth_remove(struct udevice *dev)
+{
+ return 0;
+}
+
+static int sb_eth_ofdata_to_platdata(struct udevice *dev)
+{
+ struct eth_pdata *pdata = dev_get_platdata(dev);
+
+ pdata->iobase = dev_get_addr(dev);
+ return 0;
+}
+
+static const struct udevice_id sb_eth_ids[] = {
+ { .compatible = "sandbox,eth" },
+ { }
+};
+
+U_BOOT_DRIVER(eth_sandbox) = {
+ .name = "eth_sandbox",
+ .id = UCLASS_ETH,
+ .of_match = sb_eth_ids,
+ .ofdata_to_platdata = sb_eth_ofdata_to_platdata,
+ .remove = sb_eth_remove,
+ .ops = &sb_eth_ops,
+ .priv_auto_alloc_size = sizeof(struct eth_sandbox_priv),
+ .platdata_auto_alloc_size = sizeof(struct eth_pdata),
+};
diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c
index 4bf493ed45..a320b4d75b 100644
--- a/drivers/net/sh_eth.c
+++ b/drivers/net/sh_eth.c
@@ -127,7 +127,7 @@ int sh_eth_recv(struct eth_device *dev)
packet = (uchar *)
ADDR_TO_P2(port_info->rx_desc_cur->rd2);
invalidate_cache(packet, len);
- NetReceive(packet, len);
+ net_process_received_packet(packet, len);
}
/* Make current descriptor available again */
diff --git a/drivers/net/smc91111.c b/drivers/net/smc91111.c
index 57c667a58a..ade14cd475 100644
--- a/drivers/net/smc91111.c
+++ b/drivers/net/smc91111.c
@@ -756,35 +756,35 @@ static int smc_rcv(struct eth_device *dev)
#ifdef USE_32_BIT
- PRINTK3(" Reading %d dwords (and %d bytes) \n",
+ PRINTK3(" Reading %d dwords (and %d bytes)\n",
packet_length >> 2, packet_length & 3 );
/* QUESTION: Like in the TX routine, do I want
to send the DWORDs or the bytes first, or some
mixture. A mixture might improve already slow PIO
performance */
- SMC_insl( dev, SMC91111_DATA_REG, NetRxPackets[0],
- packet_length >> 2 );
+ SMC_insl(dev, SMC91111_DATA_REG, net_rx_packets[0],
+ packet_length >> 2);
/* read the left over bytes */
if (packet_length & 3) {
int i;
- byte *tail = (byte *)(NetRxPackets[0] +
+ byte *tail = (byte *)(net_rx_packets[0] +
(packet_length & ~3));
dword leftover = SMC_inl(dev, SMC91111_DATA_REG);
for (i=0; i<(packet_length & 3); i++)
*tail++ = (byte) (leftover >> (8*i)) & 0xff;
}
#else
- PRINTK3(" Reading %d words and %d byte(s) \n",
+ PRINTK3(" Reading %d words and %d byte(s)\n",
(packet_length >> 1 ), packet_length & 1 );
- SMC_insw(dev, SMC91111_DATA_REG , NetRxPackets[0],
- packet_length >> 1);
+ SMC_insw(dev, SMC91111_DATA_REG , net_rx_packets[0],
+ packet_length >> 1);
#endif /* USE_32_BIT */
#if SMC_DEBUG > 2
printf("Receiving Packet\n");
- print_packet( NetRxPackets[0], packet_length );
+ print_packet(net_rx_packets[0], packet_length);
#endif
} else {
/* error ... */
@@ -815,7 +815,7 @@ static int smc_rcv(struct eth_device *dev)
if (!is_error) {
/* Pass the packet up to the protocol layers. */
- NetReceive(NetRxPackets[0], packet_length);
+ net_process_received_packet(net_rx_packets[0], packet_length);
return packet_length;
} else {
return 0;
diff --git a/drivers/net/smc911x.c b/drivers/net/smc911x.c
index 5959672370..c85a178cd8 100644
--- a/drivers/net/smc911x.c
+++ b/drivers/net/smc911x.c
@@ -192,7 +192,7 @@ static void smc911x_halt(struct eth_device *dev)
static int smc911x_rx(struct eth_device *dev)
{
- u32 *data = (u32 *)NetRxPackets[0];
+ u32 *data = (u32 *)net_rx_packets[0];
u32 pktlen, tmplen;
u32 status;
@@ -211,7 +211,7 @@ static int smc911x_rx(struct eth_device *dev)
": dropped bad packet. Status: 0x%08x\n",
status);
else
- NetReceive(NetRxPackets[0], pktlen);
+ net_process_received_packet(net_rx_packets[0], pktlen);
}
return 0;
diff --git a/drivers/net/sunxi_emac.c b/drivers/net/sunxi_emac.c
index 2a9fd56c95..7b31f8c1da 100644
--- a/drivers/net/sunxi_emac.c
+++ b/drivers/net/sunxi_emac.c
@@ -437,10 +437,10 @@ static int sunxi_emac_eth_recv(struct eth_device *dev)
printf("Received packet is too big (len=%d)\n", rx_len);
} else {
emac_inblk_32bit((void *)&regs->rx_io_data,
- NetRxPackets[0], rx_len);
+ net_rx_packets[0], rx_len);
/* Pass to upper layer */
- NetReceive(NetRxPackets[0], rx_len);
+ net_process_received_packet(net_rx_packets[0], rx_len);
return rx_len;
}
}
diff --git a/drivers/net/tsec.c b/drivers/net/tsec.c
index dcdba4ea82..42d037471f 100644
--- a/drivers/net/tsec.c
+++ b/drivers/net/tsec.c
@@ -287,7 +287,7 @@ void redundant_init(struct eth_device *dev)
}
}
- if (!memcmp(pkt, (void *)NetRxPackets[rx_idx], sizeof(pkt)))
+ if (!memcmp(pkt, (void *)net_rx_packets[rx_idx], sizeof(pkt)))
fail = 0;
out_be16(&rxbd[rx_idx].length, 0);
@@ -343,7 +343,7 @@ static void startup_tsec(struct eth_device *dev)
for (i = 0; i < PKTBUFSRX; i++) {
out_be16(&rxbd[i].status, RXBD_EMPTY);
out_be16(&rxbd[i].length, 0);
- out_be32(&rxbd[i].bufptr, (u32)NetRxPackets[i]);
+ out_be32(&rxbd[i].bufptr, (u32)net_rx_packets[i]);
}
status = in_be16(&rxbd[PKTBUFSRX - 1].status);
out_be16(&rxbd[PKTBUFSRX - 1].status, status | RXBD_WRAP);
@@ -430,7 +430,8 @@ static int tsec_recv(struct eth_device *dev)
/* Send the packet up if there were no errors */
if (!(status & RXBD_STATS))
- NetReceive(NetRxPackets[rx_idx], length - 4);
+ net_process_received_packet(net_rx_packets[rx_idx],
+ length - 4);
else
printf("Got error %x\n", (status & RXBD_STATS));
diff --git a/drivers/net/tsi108_eth.c b/drivers/net/tsi108_eth.c
index 72b8159d82..9da59a018a 100644
--- a/drivers/net/tsi108_eth.c
+++ b/drivers/net/tsi108_eth.c
@@ -804,11 +804,11 @@ static int tsi108_eth_probe (struct eth_device *dev, bd_t * bis)
rx_descr_current = rx_descr;
for (index = 0; index < NUM_RX_DESC; index++) {
/* make sure the receive buffers are not in cache */
- invalidate_dcache_range((unsigned long)NetRxPackets[index],
- (unsigned long)NetRxPackets[index] +
+ invalidate_dcache_range((unsigned long)net_rx_packets[index],
+ (unsigned long)net_rx_packets[index] +
RX_BUFFER_SIZE);
rx_descr->start_addr0 =
- cpu_to_le32((vuint32) NetRxPackets[index]);
+ cpu_to_le32((vuint32) net_rx_packets[index]);
rx_descr->start_addr1 = 0;
rx_descr->next_descr_addr0 =
cpu_to_le32((vuint32) (rx_descr + 1));
@@ -966,7 +966,7 @@ static int tsi108_eth_recv (struct eth_device *dev)
/*** process packet ***/
buffer = (uchar *)(le32_to_cpu(rx_descr->start_addr0));
- NetReceive(buffer, length);
+ net_process_received_packet(buffer, length);
invalidate_dcache_range ((unsigned long)buffer,
(unsigned long)buffer +
diff --git a/drivers/net/uli526x.c b/drivers/net/uli526x.c
index 9526faa4af..47cdb858c7 100644
--- a/drivers/net/uli526x.c
+++ b/drivers/net/uli526x.c
@@ -587,7 +587,8 @@ static int uli526x_rx_packet(struct eth_device *dev)
__FUNCTION__, i, rxptr->rx_buf_ptr[i]);
#endif
- NetReceive((uchar *)rxptr->rx_buf_ptr, rxlen);
+ net_process_received_packet(
+ (uchar *)rxptr->rx_buf_ptr, rxlen);
uli526x_reuse_buf(rxptr);
} else {
@@ -709,7 +710,7 @@ static void allocate_rx_buffer(struct uli526x_board_info *db)
u32 addr;
for (index = 0; index < RX_DESC_CNT; index++) {
- addr = (u32)NetRxPackets[index];
+ addr = (u32)net_rx_packets[index];
addr += (16 - (addr & 15));
rxptr->rx_buf_ptr = (char *) addr;
rxptr->rdes2 = cpu_to_le32(addr);
diff --git a/drivers/net/xilinx_axi_emac.c b/drivers/net/xilinx_axi_emac.c
index 262b67b6cf..df053feee8 100644
--- a/drivers/net/xilinx_axi_emac.c
+++ b/drivers/net/xilinx_axi_emac.c
@@ -556,7 +556,7 @@ static int axiemac_recv(struct eth_device *dev)
#endif
/* Pass the received frame up for processing */
if (length)
- NetReceive(rxframe, length);
+ net_process_received_packet(rxframe, length);
#ifdef DEBUG
/* It is useful to clear buffer to be sure that it is consistent */
diff --git a/drivers/net/xilinx_emaclite.c b/drivers/net/xilinx_emaclite.c
index 2a5cc44553..c9afa99690 100644
--- a/drivers/net/xilinx_emaclite.c
+++ b/drivers/net/xilinx_emaclite.c
@@ -322,7 +322,7 @@ static int emaclite_recv(struct eth_device *dev)
out_be32 (baseaddress + XEL_RSR_OFFSET, reg);
debug("Packet receive from 0x%x, length %dB\n", baseaddress, length);
- NetReceive((uchar *) etherrxbuff, length);
+ net_process_received_packet((uchar *)etherrxbuff, length);
return length;
}
diff --git a/drivers/net/xilinx_ll_temac_fifo.c b/drivers/net/xilinx_ll_temac_fifo.c
index b8993cdb29..78319d7d91 100644
--- a/drivers/net/xilinx_ll_temac_fifo.c
+++ b/drivers/net/xilinx_ll_temac_fifo.c
@@ -48,7 +48,7 @@ int ll_temac_reset_fifo(struct eth_device *dev)
int ll_temac_recv_fifo(struct eth_device *dev)
{
int i, length = 0;
- u32 *buf = (u32 *)NetRxPackets[0];
+ u32 *buf = (u32 *)net_rx_packets[0];
struct ll_temac *ll_temac = dev->priv;
struct fifo_ctrl *fifo_ctrl = (void *)ll_temac->ctrladdr;
@@ -93,7 +93,7 @@ int ll_temac_recv_fifo(struct eth_device *dev)
for (i = 0; i < length; i += 4)
*buf++ = in_be32(&fifo_ctrl->rdfd);
- NetReceive(NetRxPackets[0], length);
+ net_process_received_packet(net_rx_packets[0], length);
}
return 0;
diff --git a/drivers/net/xilinx_ll_temac_sdma.c b/drivers/net/xilinx_ll_temac_sdma.c
index 32a822eea5..07c5f6bf10 100644
--- a/drivers/net/xilinx_ll_temac_sdma.c
+++ b/drivers/net/xilinx_ll_temac_sdma.c
@@ -180,7 +180,7 @@ int ll_temac_init_sdma(struct eth_device *dev)
memset(rx_dp, 0, sizeof(*rx_dp));
rx_dp->next_p = rx_dp;
rx_dp->buf_len = PKTSIZE_ALIGN;
- rx_dp->phys_buf_p = (u8 *)NetRxPackets[i];
+ rx_dp->phys_buf_p = (u8 *)net_rx_packets[i];
flush_cache((u32)rx_dp->phys_buf_p, PKTSIZE_ALIGN);
}
flush_cache((u32)cdmac_bd.rx, sizeof(cdmac_bd.rx));
@@ -316,7 +316,7 @@ int ll_temac_recv_sdma(struct eth_device *dev)
ll_temac->out32(ra[RX_TAILDESC_PTR], (int)&cdmac_bd.rx[rx_idx]);
if (length > 0 && pb_idx != -1)
- NetReceive(NetRxPackets[pb_idx], length);
+ net_process_received_packet(net_rx_packets[pb_idx], length);
return 0;
}
diff --git a/drivers/net/zynq_gem.c b/drivers/net/zynq_gem.c
index 430e22821c..74fda70abe 100644
--- a/drivers/net/zynq_gem.c
+++ b/drivers/net/zynq_gem.c
@@ -439,7 +439,7 @@ static int zynq_gem_recv(struct eth_device *dev)
u32 size = roundup(frame_len, ARCH_DMA_MINALIGN);
invalidate_dcache_range(addr, addr + size);
- NetReceive((u8 *)addr, frame_len);
+ net_process_received_packet((u8 *)addr, frame_len);
if (current_bd->status & ZYNQ_GEM_RXBUF_SOF_MASK)
priv->rx_first_buf = priv->rxbd_current;
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index e69de29bb2..167d405918 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -0,0 +1,22 @@
+menu "PCI"
+
+config DM_PCI
+ bool "Enable driver mode for PCI"
+ depends on DM
+ help
+ Use driver model for PCI. Driver model is the new method for
+ orgnising devices in U-Boot. For PCI, driver model keeps track of
+ available PCI devices, allows scanning of PCI buses and provides
+ device configuration support.
+
+config PCI_SANDBOX
+ bool "Sandbox PCI support"
+ depends on SANDBOX && DM_PCI
+ help
+ Support PCI on sandbox, as an emulated bus. This permits testing of
+ PCI feature such as bus scanning, device configuration and device
+ access. The available (emulated) devices are defined statically in
+ the device tree but the normal PCI scan technique is used to find
+ then.
+
+endmenu
diff --git a/drivers/pci/Makefile b/drivers/pci/Makefile
index 50b7be53ca..adc238f0f0 100644
--- a/drivers/pci/Makefile
+++ b/drivers/pci/Makefile
@@ -5,8 +5,17 @@
# SPDX-License-Identifier: GPL-2.0+
#
+ifneq ($(CONFIG_DM_PCI),)
+obj-$(CONFIG_PCI) += pci-uclass.o pci_compat.o
+obj-$(CONFIG_PCI_SANDBOX) += pci_sandbox.o
+obj-$(CONFIG_SANDBOX) += pci-emul-uclass.o
+obj-$(CONFIG_X86) += pci_x86.o
+else
+obj-$(CONFIG_PCI) += pci.o
+endif
+obj-$(CONFIG_PCI) += pci_common.o pci_auto.o pci_rom.o
+
obj-$(CONFIG_FSL_PCI_INIT) += fsl_pci_init.o
-obj-$(CONFIG_PCI) += pci.o pci_auto.o pci_rom.o
obj-$(CONFIG_PCI_INDIRECT_BRIDGE) += pci_indirect.o
obj-$(CONFIG_PCI_GT64120) += pci_gt64120.o
obj-$(CONFIG_PCI_MSC01) += pci_msc01.o
diff --git a/drivers/pci/pci-emul-uclass.c b/drivers/pci/pci-emul-uclass.c
new file mode 100644
index 0000000000..0f8e3c9fcb
--- /dev/null
+++ b/drivers/pci/pci-emul-uclass.c
@@ -0,0 +1,67 @@
+/*
+ * Copyright (c) 2014 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <fdtdec.h>
+#include <libfdt.h>
+#include <pci.h>
+#include <dm/lists.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct sandbox_pci_priv {
+ int dev_count;
+};
+
+int sandbox_pci_get_emul(struct udevice *bus, pci_dev_t find_devfn,
+ struct udevice **emulp)
+{
+ struct udevice *dev;
+ int ret;
+
+ ret = pci_bus_find_devfn(bus, find_devfn, &dev);
+ if (ret) {
+ debug("%s: Could not find emulator for dev %x\n", __func__,
+ find_devfn);
+ return ret;
+ }
+
+ ret = device_find_first_child(dev, emulp);
+ if (ret)
+ return ret;
+
+ return *emulp ? 0 : -ENODEV;
+}
+
+static int sandbox_pci_emul_post_probe(struct udevice *dev)
+{
+ struct sandbox_pci_priv *priv = dev->uclass->priv;
+
+ priv->dev_count++;
+ sandbox_set_enable_pci_map(true);
+
+ return 0;
+}
+
+static int sandbox_pci_emul_pre_remove(struct udevice *dev)
+{
+ struct sandbox_pci_priv *priv = dev->uclass->priv;
+
+ priv->dev_count--;
+ sandbox_set_enable_pci_map(priv->dev_count > 0);
+
+ return 0;
+}
+
+UCLASS_DRIVER(pci_emul) = {
+ .id = UCLASS_PCI_EMUL,
+ .name = "pci_emul",
+ .post_probe = sandbox_pci_emul_post_probe,
+ .pre_remove = sandbox_pci_emul_pre_remove,
+ .priv_auto_alloc_size = sizeof(struct sandbox_pci_priv),
+};
diff --git a/drivers/pci/pci-uclass.c b/drivers/pci/pci-uclass.c
new file mode 100644
index 0000000000..d48d865bac
--- /dev/null
+++ b/drivers/pci/pci-uclass.c
@@ -0,0 +1,639 @@
+/*
+ * Copyright (c) 2014 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <fdtdec.h>
+#include <inttypes.h>
+#include <pci.h>
+#include <dm/lists.h>
+#include <dm/root.h>
+#include <dm/device-internal.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+struct pci_controller *pci_bus_to_hose(int busnum)
+{
+ struct udevice *bus;
+ int ret;
+
+ ret = uclass_get_device_by_seq(UCLASS_PCI, busnum, &bus);
+ if (ret) {
+ debug("%s: Cannot get bus %d: ret=%d\n", __func__, busnum, ret);
+ return NULL;
+ }
+ return dev_get_uclass_priv(bus);
+}
+
+/**
+ * pci_get_bus_max() - returns the bus number of the last active bus
+ *
+ * @return last bus number, or -1 if no active buses
+ */
+static int pci_get_bus_max(void)
+{
+ struct udevice *bus;
+ struct uclass *uc;
+ int ret = -1;
+
+ ret = uclass_get(UCLASS_PCI, &uc);
+ uclass_foreach_dev(bus, uc) {
+ if (bus->seq > ret)
+ ret = bus->seq;
+ }
+
+ debug("%s: ret=%d\n", __func__, ret);
+
+ return ret;
+}
+
+int pci_last_busno(void)
+{
+ struct pci_controller *hose;
+ struct udevice *bus;
+ struct uclass *uc;
+ int ret;
+
+ debug("pci_last_busno\n");
+ ret = uclass_get(UCLASS_PCI, &uc);
+ if (ret || list_empty(&uc->dev_head))
+ return -1;
+
+ /* Probe the last bus */
+ bus = list_entry(uc->dev_head.prev, struct udevice, uclass_node);
+ debug("bus = %p, %s\n", bus, bus->name);
+ assert(bus);
+ ret = device_probe(bus);
+ if (ret)
+ return ret;
+
+ /* If that bus has bridges, we may have new buses now. Get the last */
+ bus = list_entry(uc->dev_head.prev, struct udevice, uclass_node);
+ hose = dev_get_uclass_priv(bus);
+ debug("bus = %s, hose = %p\n", bus->name, hose);
+
+ return hose->last_busno;
+}
+
+int pci_get_ff(enum pci_size_t size)
+{
+ switch (size) {
+ case PCI_SIZE_8:
+ return 0xff;
+ case PCI_SIZE_16:
+ return 0xffff;
+ default:
+ return 0xffffffff;
+ }
+}
+
+int pci_bus_find_devfn(struct udevice *bus, pci_dev_t find_devfn,
+ struct udevice **devp)
+{
+ struct udevice *dev;
+
+ for (device_find_first_child(bus, &dev);
+ dev;
+ device_find_next_child(&dev)) {
+ struct pci_child_platdata *pplat;
+
+ pplat = dev_get_parent_platdata(dev);
+ if (pplat && pplat->devfn == find_devfn) {
+ *devp = dev;
+ return 0;
+ }
+ }
+
+ return -ENODEV;
+}
+
+int pci_bus_find_bdf(pci_dev_t bdf, struct udevice **devp)
+{
+ struct udevice *bus;
+ int ret;
+
+ ret = uclass_get_device_by_seq(UCLASS_PCI, PCI_BUS(bdf), &bus);
+ if (ret)
+ return ret;
+ return pci_bus_find_devfn(bus, PCI_MASK_BUS(bdf), devp);
+}
+
+static int pci_device_matches_ids(struct udevice *dev,
+ struct pci_device_id *ids)
+{
+ struct pci_child_platdata *pplat;
+ int i;
+
+ pplat = dev_get_parent_platdata(dev);
+ if (!pplat)
+ return -EINVAL;
+ for (i = 0; ids[i].vendor != 0; i++) {
+ if (pplat->vendor == ids[i].vendor &&
+ pplat->device == ids[i].device)
+ return i;
+ }
+
+ return -EINVAL;
+}
+
+int pci_bus_find_devices(struct udevice *bus, struct pci_device_id *ids,
+ int *indexp, struct udevice **devp)
+{
+ struct udevice *dev;
+
+ /* Scan all devices on this bus */
+ for (device_find_first_child(bus, &dev);
+ dev;
+ device_find_next_child(&dev)) {
+ if (pci_device_matches_ids(dev, ids) >= 0) {
+ if ((*indexp)-- <= 0) {
+ *devp = dev;
+ return 0;
+ }
+ }
+ }
+
+ return -ENODEV;
+}
+
+int pci_find_device_id(struct pci_device_id *ids, int index,
+ struct udevice **devp)
+{
+ struct udevice *bus;
+
+ /* Scan all known buses */
+ for (uclass_first_device(UCLASS_PCI, &bus);
+ bus;
+ uclass_next_device(&bus)) {
+ if (!pci_bus_find_devices(bus, ids, &index, devp))
+ return 0;
+ }
+ *devp = NULL;
+
+ return -ENODEV;
+}
+
+int pci_bus_write_config(struct udevice *bus, pci_dev_t bdf, int offset,
+ unsigned long value, enum pci_size_t size)
+{
+ struct dm_pci_ops *ops;
+
+ ops = pci_get_ops(bus);
+ if (!ops->write_config)
+ return -ENOSYS;
+ return ops->write_config(bus, bdf, offset, value, size);
+}
+
+int pci_write_config(pci_dev_t bdf, int offset, unsigned long value,
+ enum pci_size_t size)
+{
+ struct udevice *bus;
+ int ret;
+
+ ret = uclass_get_device_by_seq(UCLASS_PCI, PCI_BUS(bdf), &bus);
+ if (ret)
+ return ret;
+
+ return pci_bus_write_config(bus, PCI_MASK_BUS(bdf), offset, value,
+ size);
+}
+
+int pci_write_config32(pci_dev_t bdf, int offset, u32 value)
+{
+ return pci_write_config(bdf, offset, value, PCI_SIZE_32);
+}
+
+int pci_write_config16(pci_dev_t bdf, int offset, u16 value)
+{
+ return pci_write_config(bdf, offset, value, PCI_SIZE_16);
+}
+
+int pci_write_config8(pci_dev_t bdf, int offset, u8 value)
+{
+ return pci_write_config(bdf, offset, value, PCI_SIZE_8);
+}
+
+int pci_bus_read_config(struct udevice *bus, pci_dev_t bdf, int offset,
+ unsigned long *valuep, enum pci_size_t size)
+{
+ struct dm_pci_ops *ops;
+
+ ops = pci_get_ops(bus);
+ if (!ops->read_config)
+ return -ENOSYS;
+ return ops->read_config(bus, bdf, offset, valuep, size);
+}
+
+int pci_read_config(pci_dev_t bdf, int offset, unsigned long *valuep,
+ enum pci_size_t size)
+{
+ struct udevice *bus;
+ int ret;
+
+ ret = uclass_get_device_by_seq(UCLASS_PCI, PCI_BUS(bdf), &bus);
+ if (ret)
+ return ret;
+
+ return pci_bus_read_config(bus, PCI_MASK_BUS(bdf), offset, valuep,
+ size);
+}
+
+int pci_read_config32(pci_dev_t bdf, int offset, u32 *valuep)
+{
+ unsigned long value;
+ int ret;
+
+ ret = pci_read_config(bdf, offset, &value, PCI_SIZE_32);
+ if (ret)
+ return ret;
+ *valuep = value;
+
+ return 0;
+}
+
+int pci_read_config16(pci_dev_t bdf, int offset, u16 *valuep)
+{
+ unsigned long value;
+ int ret;
+
+ ret = pci_read_config(bdf, offset, &value, PCI_SIZE_16);
+ if (ret)
+ return ret;
+ *valuep = value;
+
+ return 0;
+}
+
+int pci_read_config8(pci_dev_t bdf, int offset, u8 *valuep)
+{
+ unsigned long value;
+ int ret;
+
+ ret = pci_read_config(bdf, offset, &value, PCI_SIZE_8);
+ if (ret)
+ return ret;
+ *valuep = value;
+
+ return 0;
+}
+
+int pci_auto_config_devices(struct udevice *bus)
+{
+ struct pci_controller *hose = bus->uclass_priv;
+ unsigned int sub_bus;
+ struct udevice *dev;
+ int ret;
+
+ sub_bus = bus->seq;
+ debug("%s: start\n", __func__);
+ pciauto_config_init(hose);
+ for (ret = device_find_first_child(bus, &dev);
+ !ret && dev;
+ ret = device_find_next_child(&dev)) {
+ struct pci_child_platdata *pplat;
+
+ pplat = dev_get_parent_platdata(dev);
+ unsigned int max_bus;
+ pci_dev_t bdf;
+
+ bdf = PCI_ADD_BUS(bus->seq, pplat->devfn);
+ debug("%s: device %s\n", __func__, dev->name);
+ max_bus = pciauto_config_device(hose, bdf);
+ sub_bus = max(sub_bus, max_bus);
+ }
+ debug("%s: done\n", __func__);
+
+ return sub_bus;
+}
+
+int dm_pci_hose_probe_bus(struct pci_controller *hose, pci_dev_t bdf)
+{
+ struct udevice *parent, *bus;
+ int sub_bus;
+ int ret;
+
+ debug("%s\n", __func__);
+ parent = hose->bus;
+
+ /* Find the bus within the parent */
+ ret = pci_bus_find_devfn(parent, bdf, &bus);
+ if (ret) {
+ debug("%s: Cannot find device %x on bus %s: %d\n", __func__,
+ bdf, parent->name, ret);
+ return ret;
+ }
+
+ sub_bus = pci_get_bus_max() + 1;
+ debug("%s: bus = %d/%s\n", __func__, sub_bus, bus->name);
+ pciauto_prescan_setup_bridge(hose, bdf, bus->seq);
+
+ ret = device_probe(bus);
+ if (ret) {
+ debug("%s: Cannot probe bus bus %s: %d\n", __func__, bus->name,
+ ret);
+ return ret;
+ }
+ if (sub_bus != bus->seq) {
+ printf("%s: Internal error, bus '%s' got seq %d, expected %d\n",
+ __func__, bus->name, bus->seq, sub_bus);
+ return -EPIPE;
+ }
+ sub_bus = pci_get_bus_max();
+ pciauto_postscan_setup_bridge(hose, bdf, sub_bus);
+
+ return sub_bus;
+}
+
+int pci_bind_bus_devices(struct udevice *bus)
+{
+ ulong vendor, device;
+ ulong header_type;
+ pci_dev_t devfn, end;
+ bool found_multi;
+ int ret;
+
+ found_multi = false;
+ end = PCI_DEVFN(PCI_MAX_PCI_DEVICES - 1, PCI_MAX_PCI_FUNCTIONS - 1);
+ for (devfn = PCI_DEVFN(0, 0); devfn < end; devfn += PCI_DEVFN(0, 1)) {
+ struct pci_child_platdata *pplat;
+ struct udevice *dev;
+ ulong class;
+
+ if (PCI_FUNC(devfn) && !found_multi)
+ continue;
+ /* Check only the first access, we don't expect problems */
+ ret = pci_bus_read_config(bus, devfn, PCI_HEADER_TYPE,
+ &header_type, PCI_SIZE_8);
+ if (ret)
+ goto error;
+ pci_bus_read_config(bus, devfn, PCI_VENDOR_ID, &vendor,
+ PCI_SIZE_16);
+ if (vendor == 0xffff || vendor == 0x0000)
+ continue;
+
+ if (!PCI_FUNC(devfn))
+ found_multi = header_type & 0x80;
+
+ debug("%s: bus %d/%s: found device %x, function %d\n", __func__,
+ bus->seq, bus->name, PCI_DEV(devfn), PCI_FUNC(devfn));
+ pci_bus_read_config(bus, devfn, PCI_DEVICE_ID, &device,
+ PCI_SIZE_16);
+ pci_bus_read_config(bus, devfn, PCI_CLASS_DEVICE, &class,
+ PCI_SIZE_16);
+
+ /* Find this device in the device tree */
+ ret = pci_bus_find_devfn(bus, devfn, &dev);
+
+ /* If nothing in the device tree, bind a generic device */
+ if (ret == -ENODEV) {
+ char name[30], *str;
+ const char *drv;
+
+ sprintf(name, "pci_%x:%x.%x", bus->seq,
+ PCI_DEV(devfn), PCI_FUNC(devfn));
+ str = strdup(name);
+ if (!str)
+ return -ENOMEM;
+ drv = class == PCI_CLASS_BRIDGE_PCI ?
+ "pci_bridge_drv" : "pci_generic_drv";
+ ret = device_bind_driver(bus, drv, str, &dev);
+ }
+ if (ret)
+ return ret;
+
+ /* Update the platform data */
+ pplat = dev_get_parent_platdata(dev);
+ pplat->devfn = devfn;
+ pplat->vendor = vendor;
+ pplat->device = device;
+ pplat->class = class;
+ }
+
+ return 0;
+error:
+ printf("Cannot read bus configuration: %d\n", ret);
+
+ return ret;
+}
+
+static int pci_uclass_post_bind(struct udevice *bus)
+{
+ /*
+ * Scan the device tree for devices. This does not probe the PCI bus,
+ * as this is not permitted while binding. It just finds devices
+ * mentioned in the device tree.
+ *
+ * Before relocation, only bind devices marked for pre-relocation
+ * use.
+ */
+ return dm_scan_fdt_node(bus, gd->fdt_blob, bus->of_offset,
+ gd->flags & GD_FLG_RELOC ? false : true);
+}
+
+static int decode_regions(struct pci_controller *hose, const void *blob,
+ int parent_node, int node)
+{
+ int pci_addr_cells, addr_cells, size_cells;
+ int cells_per_record;
+ const u32 *prop;
+ int len;
+ int i;
+
+ prop = fdt_getprop(blob, node, "ranges", &len);
+ if (!prop)
+ return -EINVAL;
+ pci_addr_cells = fdt_address_cells(blob, node);
+ addr_cells = fdt_address_cells(blob, parent_node);
+ size_cells = fdt_size_cells(blob, node);
+
+ /* PCI addresses are always 3-cells */
+ len /= sizeof(u32);
+ cells_per_record = pci_addr_cells + addr_cells + size_cells;
+ hose->region_count = 0;
+ debug("%s: len=%d, cells_per_record=%d\n", __func__, len,
+ cells_per_record);
+ for (i = 0; i < MAX_PCI_REGIONS; i++, len -= cells_per_record) {
+ u64 pci_addr, addr, size;
+ int space_code;
+ u32 flags;
+ int type;
+
+ if (len < cells_per_record)
+ break;
+ flags = fdt32_to_cpu(prop[0]);
+ space_code = (flags >> 24) & 3;
+ pci_addr = fdtdec_get_number(prop + 1, 2);
+ prop += pci_addr_cells;
+ addr = fdtdec_get_number(prop, addr_cells);
+ prop += addr_cells;
+ size = fdtdec_get_number(prop, size_cells);
+ prop += size_cells;
+ debug("%s: region %d, pci_addr=%" PRIx64 ", addr=%" PRIx64
+ ", size=%" PRIx64 ", space_code=%d\n", __func__,
+ hose->region_count, pci_addr, addr, size, space_code);
+ if (space_code & 2) {
+ type = flags & (1U << 30) ? PCI_REGION_PREFETCH :
+ PCI_REGION_MEM;
+ } else if (space_code & 1) {
+ type = PCI_REGION_IO;
+ } else {
+ continue;
+ }
+ debug(" - type=%d\n", type);
+ pci_set_region(hose->regions + hose->region_count++, pci_addr,
+ addr, size, type);
+ }
+
+ /* Add a region for our local memory */
+ pci_set_region(hose->regions + hose->region_count++, 0, 0,
+ gd->ram_size, PCI_REGION_MEM | PCI_REGION_SYS_MEMORY);
+
+ return 0;
+}
+
+static int pci_uclass_pre_probe(struct udevice *bus)
+{
+ struct pci_controller *hose;
+ int ret;
+
+ debug("%s, bus=%d/%s, parent=%s\n", __func__, bus->seq, bus->name,
+ bus->parent->name);
+ hose = bus->uclass_priv;
+
+ /* For bridges, use the top-level PCI controller */
+ if (device_get_uclass_id(bus->parent) == UCLASS_ROOT) {
+ hose->ctlr = bus;
+ ret = decode_regions(hose, gd->fdt_blob, bus->parent->of_offset,
+ bus->of_offset);
+ if (ret) {
+ debug("%s: Cannot decode regions\n", __func__);
+ return ret;
+ }
+ } else {
+ struct pci_controller *parent_hose;
+
+ parent_hose = dev_get_uclass_priv(bus->parent);
+ hose->ctlr = parent_hose->bus;
+ }
+ hose->bus = bus;
+ hose->first_busno = bus->seq;
+ hose->last_busno = bus->seq;
+
+ return 0;
+}
+
+static int pci_uclass_post_probe(struct udevice *bus)
+{
+ int ret;
+
+ /* Don't scan buses before relocation */
+ if (!(gd->flags & GD_FLG_RELOC))
+ return 0;
+
+ debug("%s: probing bus %d\n", __func__, bus->seq);
+ ret = pci_bind_bus_devices(bus);
+ if (ret)
+ return ret;
+
+#ifdef CONFIG_PCI_PNP
+ ret = pci_auto_config_devices(bus);
+#endif
+
+ return ret < 0 ? ret : 0;
+}
+
+static int pci_uclass_child_post_bind(struct udevice *dev)
+{
+ struct pci_child_platdata *pplat;
+ struct fdt_pci_addr addr;
+ int ret;
+
+ if (dev->of_offset == -1)
+ return 0;
+
+ /*
+ * We could read vendor, device, class if available. But for now we
+ * just check the address.
+ */
+ pplat = dev_get_parent_platdata(dev);
+ ret = fdtdec_get_pci_addr(gd->fdt_blob, dev->of_offset,
+ FDT_PCI_SPACE_CONFIG, "reg", &addr);
+
+ if (ret) {
+ if (ret != -ENOENT)
+ return -EINVAL;
+ } else {
+ /* extract the bdf from fdt_pci_addr */
+ pplat->devfn = addr.phys_hi & 0xffff00;
+ }
+
+ return 0;
+}
+
+int pci_bridge_read_config(struct udevice *bus, pci_dev_t devfn, uint offset,
+ ulong *valuep, enum pci_size_t size)
+{
+ struct pci_controller *hose = bus->uclass_priv;
+ pci_dev_t bdf = PCI_ADD_BUS(bus->seq, devfn);
+
+ return pci_bus_read_config(hose->ctlr, bdf, offset, valuep, size);
+}
+
+int pci_bridge_write_config(struct udevice *bus, pci_dev_t devfn, uint offset,
+ ulong value, enum pci_size_t size)
+{
+ struct pci_controller *hose = bus->uclass_priv;
+ pci_dev_t bdf = PCI_ADD_BUS(bus->seq, devfn);
+
+ return pci_bus_write_config(hose->ctlr, bdf, offset, value, size);
+}
+
+UCLASS_DRIVER(pci) = {
+ .id = UCLASS_PCI,
+ .name = "pci",
+ .post_bind = pci_uclass_post_bind,
+ .pre_probe = pci_uclass_pre_probe,
+ .post_probe = pci_uclass_post_probe,
+ .child_post_bind = pci_uclass_child_post_bind,
+ .per_device_auto_alloc_size = sizeof(struct pci_controller),
+ .per_child_platdata_auto_alloc_size =
+ sizeof(struct pci_child_platdata),
+};
+
+static const struct dm_pci_ops pci_bridge_ops = {
+ .read_config = pci_bridge_read_config,
+ .write_config = pci_bridge_write_config,
+};
+
+static const struct udevice_id pci_bridge_ids[] = {
+ { .compatible = "pci-bridge" },
+ { }
+};
+
+U_BOOT_DRIVER(pci_bridge_drv) = {
+ .name = "pci_bridge_drv",
+ .id = UCLASS_PCI,
+ .of_match = pci_bridge_ids,
+ .ops = &pci_bridge_ops,
+};
+
+UCLASS_DRIVER(pci_generic) = {
+ .id = UCLASS_PCI_GENERIC,
+ .name = "pci_generic",
+};
+
+static const struct udevice_id pci_generic_ids[] = {
+ { .compatible = "pci-generic" },
+ { }
+};
+
+U_BOOT_DRIVER(pci_generic_drv) = {
+ .name = "pci_generic_drv",
+ .id = UCLASS_PCI_GENERIC,
+ .of_match = pci_generic_ids,
+};
diff --git a/drivers/pci/pci.c b/drivers/pci/pci.c
index e1296cab9e..3babd94805 100644
--- a/drivers/pci/pci.c
+++ b/drivers/pci/pci.c
@@ -101,25 +101,6 @@ PCI_READ_VIA_DWORD_OP(word, u16 *, 0x02)
PCI_WRITE_VIA_DWORD_OP(byte, u8, 0x03, 0x000000ff)
PCI_WRITE_VIA_DWORD_OP(word, u16, 0x02, 0x0000ffff)
-/* Get a virtual address associated with a BAR region */
-void *pci_map_bar(pci_dev_t pdev, int bar, int flags)
-{
- pci_addr_t pci_bus_addr;
- u32 bar_response;
-
- /* read BAR address */
- pci_read_config_dword(pdev, bar, &bar_response);
- pci_bus_addr = (pci_addr_t)(bar_response & ~0xf);
-
- /*
- * Pass "0" as the length argument to pci_bus_to_virt. The arg
- * isn't actualy used on any platform because u-boot assumes a static
- * linear mapping. In the future, this could read the BAR size
- * and pass that as the size if needed.
- */
- return pci_bus_to_virt(pdev, pci_bus_addr, flags, 0, MAP_NOCACHE);
-}
-
/*
*
*/
@@ -187,106 +168,22 @@ int pci_last_busno(void)
pci_dev_t pci_find_devices(struct pci_device_id *ids, int index)
{
struct pci_controller * hose;
- u16 vendor, device;
- u8 header_type;
pci_dev_t bdf;
- int i, bus, found_multi = 0;
+ int bus;
for (hose = pci_get_hose_head(); hose; hose = hose->next) {
#ifdef CONFIG_SYS_SCSI_SCAN_BUS_REVERSE
- for (bus = hose->last_busno; bus >= hose->first_busno; bus--)
+ for (bus = hose->last_busno; bus >= hose->first_busno; bus--) {
#else
- for (bus = hose->first_busno; bus <= hose->last_busno; bus++)
+ for (bus = hose->first_busno; bus <= hose->last_busno; bus++) {
#endif
- for (bdf = PCI_BDF(bus, 0, 0);
- bdf < PCI_BDF(bus + 1, 0, 0);
- bdf += PCI_BDF(0, 0, 1)) {
- if (pci_skip_dev(hose, bdf))
- continue;
-
- if (!PCI_FUNC(bdf)) {
- pci_read_config_byte(bdf,
- PCI_HEADER_TYPE,
- &header_type);
-
- found_multi = header_type & 0x80;
- } else {
- if (!found_multi)
- continue;
- }
-
- pci_read_config_word(bdf,
- PCI_VENDOR_ID,
- &vendor);
- pci_read_config_word(bdf,
- PCI_DEVICE_ID,
- &device);
-
- for (i = 0; ids[i].vendor != 0; i++) {
- if (vendor == ids[i].vendor &&
- device == ids[i].device) {
- if (index <= 0)
- return bdf;
-
- index--;
- }
- }
- }
- }
-
- return -1;
-}
-
-pci_dev_t pci_find_class(uint find_class, int index)
-{
- int bus;
- int devnum;
- pci_dev_t bdf;
- uint32_t class;
-
- for (bus = 0; bus <= pci_last_busno(); bus++) {
- for (devnum = 0; devnum < PCI_MAX_PCI_DEVICES - 1; devnum++) {
- pci_read_config_dword(PCI_BDF(bus, devnum, 0),
- PCI_CLASS_REVISION, &class);
- if (class >> 16 == 0xffff)
- continue;
-
- for (bdf = PCI_BDF(bus, devnum, 0);
- bdf <= PCI_BDF(bus, devnum,
- PCI_MAX_PCI_FUNCTIONS - 1);
- bdf += PCI_BDF(0, 0, 1)) {
- pci_read_config_dword(bdf, PCI_CLASS_REVISION,
- &class);
- class >>= 8;
-
- if (class != find_class)
- continue;
- /*
- * Decrement the index. We want to return the
- * correct device, so index is 0 for the first
- * matching device, 1 for the second, etc.
- */
- if (index) {
- index--;
- continue;
- }
- /* Return index'th controller. */
+ bdf = pci_hose_find_devices(hose, bus, ids, &index);
+ if (bdf != -1)
return bdf;
- }
}
}
- return -ENODEV;
-}
-
-pci_dev_t pci_find_device(unsigned int vendor, unsigned int device, int index)
-{
- struct pci_device_id ids[2] = { {}, {0, 0} };
-
- ids[0].vendor = vendor;
- ids[0].device = device;
-
- return pci_find_devices(ids, index);
+ return -1;
}
/*
@@ -355,87 +252,6 @@ pci_addr_t pci_hose_phys_to_bus (struct pci_controller *hose,
return bus_addr;
}
-int __pci_hose_bus_to_phys(struct pci_controller *hose,
- pci_addr_t bus_addr,
- unsigned long flags,
- unsigned long skip_mask,
- phys_addr_t *pa)
-{
- struct pci_region *res;
- int i;
-
- for (i = 0; i < hose->region_count; i++) {
- res = &hose->regions[i];
-
- if (((res->flags ^ flags) & PCI_REGION_TYPE) != 0)
- continue;
-
- if (res->flags & skip_mask)
- continue;
-
- if (bus_addr >= res->bus_start &&
- (bus_addr - res->bus_start) < res->size) {
- *pa = (bus_addr - res->bus_start + res->phys_start);
- return 0;
- }
- }
-
- return 1;
-}
-
-phys_addr_t pci_hose_bus_to_phys(struct pci_controller* hose,
- pci_addr_t bus_addr,
- unsigned long flags)
-{
- phys_addr_t phys_addr = 0;
- int ret;
-
- if (!hose) {
- puts("pci_hose_bus_to_phys: invalid hose\n");
- return phys_addr;
- }
-
- /*
- * if PCI_REGION_MEM is set we do a two pass search with preference
- * on matches that don't have PCI_REGION_SYS_MEMORY set
- */
- if ((flags & PCI_REGION_MEM) == PCI_REGION_MEM) {
- ret = __pci_hose_bus_to_phys(hose, bus_addr,
- flags, PCI_REGION_SYS_MEMORY, &phys_addr);
- if (!ret)
- return phys_addr;
- }
-
- ret = __pci_hose_bus_to_phys(hose, bus_addr, flags, 0, &phys_addr);
-
- if (ret)
- puts("pci_hose_bus_to_phys: invalid physical address\n");
-
- return phys_addr;
-}
-
-void pci_write_bar32(struct pci_controller *hose, pci_dev_t dev, int barnum,
- u32 addr_and_ctrl)
-{
- int bar;
-
- bar = PCI_BASE_ADDRESS_0 + barnum * 4;
- pci_hose_write_config_dword(hose, dev, bar, addr_and_ctrl);
-}
-
-u32 pci_read_bar32(struct pci_controller *hose, pci_dev_t dev, int barnum)
-{
- u32 addr;
- int bar;
-
- bar = PCI_BASE_ADDRESS_0 + barnum * 4;
- pci_hose_read_config_dword(hose, dev, bar, &addr);
- if (addr & PCI_BASE_ADDRESS_SPACE_IO)
- return addr & PCI_BASE_ADDRESS_IO_MASK;
- else
- return addr & PCI_BASE_ADDRESS_MEM_MASK;
-}
-
int pci_hose_config_device(struct pci_controller *hose,
pci_dev_t dev,
unsigned long io,
@@ -576,91 +392,6 @@ void pci_cfgfunc_do_nothing(struct pci_controller *hose,
*/
extern int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev);
-#if defined(CONFIG_CMD_PCI) || defined(CONFIG_PCI_SCAN_SHOW)
-const char * pci_class_str(u8 class)
-{
- switch (class) {
- case PCI_CLASS_NOT_DEFINED:
- return "Build before PCI Rev2.0";
- break;
- case PCI_BASE_CLASS_STORAGE:
- return "Mass storage controller";
- break;
- case PCI_BASE_CLASS_NETWORK:
- return "Network controller";
- break;
- case PCI_BASE_CLASS_DISPLAY:
- return "Display controller";
- break;
- case PCI_BASE_CLASS_MULTIMEDIA:
- return "Multimedia device";
- break;
- case PCI_BASE_CLASS_MEMORY:
- return "Memory controller";
- break;
- case PCI_BASE_CLASS_BRIDGE:
- return "Bridge device";
- break;
- case PCI_BASE_CLASS_COMMUNICATION:
- return "Simple comm. controller";
- break;
- case PCI_BASE_CLASS_SYSTEM:
- return "Base system peripheral";
- break;
- case PCI_BASE_CLASS_INPUT:
- return "Input device";
- break;
- case PCI_BASE_CLASS_DOCKING:
- return "Docking station";
- break;
- case PCI_BASE_CLASS_PROCESSOR:
- return "Processor";
- break;
- case PCI_BASE_CLASS_SERIAL:
- return "Serial bus controller";
- break;
- case PCI_BASE_CLASS_INTELLIGENT:
- return "Intelligent controller";
- break;
- case PCI_BASE_CLASS_SATELLITE:
- return "Satellite controller";
- break;
- case PCI_BASE_CLASS_CRYPT:
- return "Cryptographic device";
- break;
- case PCI_BASE_CLASS_SIGNAL_PROCESSING:
- return "DSP";
- break;
- case PCI_CLASS_OTHERS:
- return "Does not fit any class";
- break;
- default:
- return "???";
- break;
- };
-}
-#endif /* CONFIG_CMD_PCI || CONFIG_PCI_SCAN_SHOW */
-
-__weak int pci_skip_dev(struct pci_controller *hose, pci_dev_t dev)
-{
- /*
- * Check if pci device should be skipped in configuration
- */
- if (dev == PCI_BDF(hose->first_busno, 0, 0)) {
-#if defined(CONFIG_PCI_CONFIG_HOST_BRIDGE) /* don't skip host bridge */
- /*
- * Only skip configuration if "pciconfighost" is not set
- */
- if (getenv("pciconfighost") == NULL)
- return 1;
-#else
- return 1;
-#endif
- }
-
- return 0;
-}
-
#ifdef CONFIG_PCI_SCAN_SHOW
__weak int pci_print_dev(struct pci_controller *hose, pci_dev_t dev)
{
diff --git a/drivers/pci/pci_auto.c b/drivers/pci/pci_auto.c
index 378efbfd9f..e8da977673 100644
--- a/drivers/pci/pci_auto.c
+++ b/drivers/pci/pci_auto.c
@@ -432,13 +432,20 @@ int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev)
switch (class) {
case PCI_CLASS_BRIDGE_PCI:
- hose->current_busno++;
+ DEBUGF("PCI Autoconfig: Found P2P bridge, device %d\n",
+ PCI_DEV(dev));
+
pciauto_setup_device(hose, dev, 2, hose->pci_mem,
hose->pci_prefetch, hose->pci_io);
- DEBUGF("PCI Autoconfig: Found P2P bridge, device %d\n", PCI_DEV(dev));
-
+#ifdef CONFIG_DM_PCI
+ n = dm_pci_hose_probe_bus(hose, dev);
+ if (n < 0)
+ return n;
+ sub_bus = (unsigned int)n;
+#else
/* Passing in current_busno allows for sibling P2P bridges */
+ hose->current_busno++;
pciauto_prescan_setup_bridge(hose, dev, hose->current_busno);
/*
* need to figure out if this is a subordinate bridge on the bus
@@ -451,6 +458,7 @@ int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev)
pciauto_postscan_setup_bridge(hose, dev, sub_bus);
sub_bus = hose->current_busno;
+#endif
break;
case PCI_CLASS_STORAGE_IDE:
@@ -475,7 +483,9 @@ int pciauto_config_device(struct pci_controller *hose, pci_dev_t dev)
DEBUGF("PCI Autoconfig: Found P2CardBus bridge, device %d\n",
PCI_DEV(dev));
+#ifndef CONFIG_DM_PCI
hose->current_busno++;
+#endif
break;
#if defined(CONFIG_PCIAUTO_SKIP_HOST_BRIDGE)
diff --git a/drivers/pci/pci_common.c b/drivers/pci/pci_common.c
new file mode 100644
index 0000000000..24c66bbef2
--- /dev/null
+++ b/drivers/pci/pci_common.c
@@ -0,0 +1,292 @@
+/*
+ * Copyright (c) 2014 Google, Inc
+ *
+ * (C) Copyright 2001 Sysgo Real-Time Solutions, GmbH <www.elinos.com>
+ * Andreas Heppel <aheppel@sysgo.de>
+ *
+ * (C) Copyright 2002, 2003
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <errno.h>
+#include <pci.h>
+#include <asm/io.h>
+
+const char *pci_class_str(u8 class)
+{
+ switch (class) {
+ case PCI_CLASS_NOT_DEFINED:
+ return "Build before PCI Rev2.0";
+ break;
+ case PCI_BASE_CLASS_STORAGE:
+ return "Mass storage controller";
+ break;
+ case PCI_BASE_CLASS_NETWORK:
+ return "Network controller";
+ break;
+ case PCI_BASE_CLASS_DISPLAY:
+ return "Display controller";
+ break;
+ case PCI_BASE_CLASS_MULTIMEDIA:
+ return "Multimedia device";
+ break;
+ case PCI_BASE_CLASS_MEMORY:
+ return "Memory controller";
+ break;
+ case PCI_BASE_CLASS_BRIDGE:
+ return "Bridge device";
+ break;
+ case PCI_BASE_CLASS_COMMUNICATION:
+ return "Simple comm. controller";
+ break;
+ case PCI_BASE_CLASS_SYSTEM:
+ return "Base system peripheral";
+ break;
+ case PCI_BASE_CLASS_INPUT:
+ return "Input device";
+ break;
+ case PCI_BASE_CLASS_DOCKING:
+ return "Docking station";
+ break;
+ case PCI_BASE_CLASS_PROCESSOR:
+ return "Processor";
+ break;
+ case PCI_BASE_CLASS_SERIAL:
+ return "Serial bus controller";
+ break;
+ case PCI_BASE_CLASS_INTELLIGENT:
+ return "Intelligent controller";
+ break;
+ case PCI_BASE_CLASS_SATELLITE:
+ return "Satellite controller";
+ break;
+ case PCI_BASE_CLASS_CRYPT:
+ return "Cryptographic device";
+ break;
+ case PCI_BASE_CLASS_SIGNAL_PROCESSING:
+ return "DSP";
+ break;
+ case PCI_CLASS_OTHERS:
+ return "Does not fit any class";
+ break;
+ default:
+ return "???";
+ break;
+ };
+}
+
+pci_dev_t pci_find_class(uint find_class, int index)
+{
+ int bus;
+ int devnum;
+ pci_dev_t bdf;
+ uint32_t class;
+
+ for (bus = 0; bus <= pci_last_busno(); bus++) {
+ for (devnum = 0; devnum < PCI_MAX_PCI_DEVICES - 1; devnum++) {
+ pci_read_config_dword(PCI_BDF(bus, devnum, 0),
+ PCI_CLASS_REVISION, &class);
+ if (class >> 16 == 0xffff)
+ continue;
+
+ for (bdf = PCI_BDF(bus, devnum, 0);
+ bdf <= PCI_BDF(bus, devnum,
+ PCI_MAX_PCI_FUNCTIONS - 1);
+ bdf += PCI_BDF(0, 0, 1)) {
+ pci_read_config_dword(bdf, PCI_CLASS_REVISION,
+ &class);
+ class >>= 8;
+
+ if (class != find_class)
+ continue;
+ /*
+ * Decrement the index. We want to return the
+ * correct device, so index is 0 for the first
+ * matching device, 1 for the second, etc.
+ */
+ if (index) {
+ index--;
+ continue;
+ }
+ /* Return index'th controller. */
+ return bdf;
+ }
+ }
+ }
+
+ return -ENODEV;
+}
+
+__weak int pci_skip_dev(struct pci_controller *hose, pci_dev_t dev)
+{
+ /*
+ * Check if pci device should be skipped in configuration
+ */
+ if (dev == PCI_BDF(hose->first_busno, 0, 0)) {
+#if defined(CONFIG_PCI_CONFIG_HOST_BRIDGE) /* don't skip host bridge */
+ /*
+ * Only skip configuration if "pciconfighost" is not set
+ */
+ if (getenv("pciconfighost") == NULL)
+ return 1;
+#else
+ return 1;
+#endif
+ }
+
+ return 0;
+}
+
+/* Get a virtual address associated with a BAR region */
+void *pci_map_bar(pci_dev_t pdev, int bar, int flags)
+{
+ pci_addr_t pci_bus_addr;
+ u32 bar_response;
+
+ /* read BAR address */
+ pci_read_config_dword(pdev, bar, &bar_response);
+ pci_bus_addr = (pci_addr_t)(bar_response & ~0xf);
+
+ /*
+ * Pass "0" as the length argument to pci_bus_to_virt. The arg
+ * isn't actualy used on any platform because u-boot assumes a static
+ * linear mapping. In the future, this could read the BAR size
+ * and pass that as the size if needed.
+ */
+ return pci_bus_to_virt(pdev, pci_bus_addr, flags, 0, MAP_NOCACHE);
+}
+
+void pci_write_bar32(struct pci_controller *hose, pci_dev_t dev, int barnum,
+ u32 addr_and_ctrl)
+{
+ int bar;
+
+ bar = PCI_BASE_ADDRESS_0 + barnum * 4;
+ pci_hose_write_config_dword(hose, dev, bar, addr_and_ctrl);
+}
+
+u32 pci_read_bar32(struct pci_controller *hose, pci_dev_t dev, int barnum)
+{
+ u32 addr;
+ int bar;
+
+ bar = PCI_BASE_ADDRESS_0 + barnum * 4;
+ pci_hose_read_config_dword(hose, dev, bar, &addr);
+ if (addr & PCI_BASE_ADDRESS_SPACE_IO)
+ return addr & PCI_BASE_ADDRESS_IO_MASK;
+ else
+ return addr & PCI_BASE_ADDRESS_MEM_MASK;
+}
+
+int __pci_hose_bus_to_phys(struct pci_controller *hose,
+ pci_addr_t bus_addr,
+ unsigned long flags,
+ unsigned long skip_mask,
+ phys_addr_t *pa)
+{
+ struct pci_region *res;
+ int i;
+
+ for (i = 0; i < hose->region_count; i++) {
+ res = &hose->regions[i];
+
+ if (((res->flags ^ flags) & PCI_REGION_TYPE) != 0)
+ continue;
+
+ if (res->flags & skip_mask)
+ continue;
+
+ if (bus_addr >= res->bus_start &&
+ (bus_addr - res->bus_start) < res->size) {
+ *pa = (bus_addr - res->bus_start + res->phys_start);
+ return 0;
+ }
+ }
+
+ return 1;
+}
+
+phys_addr_t pci_hose_bus_to_phys(struct pci_controller *hose,
+ pci_addr_t bus_addr,
+ unsigned long flags)
+{
+ phys_addr_t phys_addr = 0;
+ int ret;
+
+ if (!hose) {
+ puts("pci_hose_bus_to_phys: invalid hose\n");
+ return phys_addr;
+ }
+
+ /*
+ * if PCI_REGION_MEM is set we do a two pass search with preference
+ * on matches that don't have PCI_REGION_SYS_MEMORY set
+ */
+ if ((flags & PCI_REGION_MEM) == PCI_REGION_MEM) {
+ ret = __pci_hose_bus_to_phys(hose, bus_addr,
+ flags, PCI_REGION_SYS_MEMORY, &phys_addr);
+ if (!ret)
+ return phys_addr;
+ }
+
+ ret = __pci_hose_bus_to_phys(hose, bus_addr, flags, 0, &phys_addr);
+
+ if (ret)
+ puts("pci_hose_bus_to_phys: invalid physical address\n");
+
+ return phys_addr;
+}
+
+pci_dev_t pci_find_device(unsigned int vendor, unsigned int device, int index)
+{
+ struct pci_device_id ids[2] = { {}, {0, 0} };
+
+ ids[0].vendor = vendor;
+ ids[0].device = device;
+
+ return pci_find_devices(ids, index);
+}
+
+pci_dev_t pci_hose_find_devices(struct pci_controller *hose, int busnum,
+ struct pci_device_id *ids, int *indexp)
+{
+ int found_multi = 0;
+ u16 vendor, device;
+ u8 header_type;
+ pci_dev_t bdf;
+ int i;
+
+ for (bdf = PCI_BDF(busnum, 0, 0);
+ bdf < PCI_BDF(busnum + 1, 0, 0);
+ bdf += PCI_BDF(0, 0, 1)) {
+ if (pci_skip_dev(hose, bdf))
+ continue;
+
+ if (!PCI_FUNC(bdf)) {
+ pci_read_config_byte(bdf, PCI_HEADER_TYPE,
+ &header_type);
+ found_multi = header_type & 0x80;
+ } else {
+ if (!found_multi)
+ continue;
+ }
+
+ pci_read_config_word(bdf, PCI_VENDOR_ID, &vendor);
+ pci_read_config_word(bdf, PCI_DEVICE_ID, &device);
+
+ for (i = 0; ids[i].vendor != 0; i++) {
+ if (vendor == ids[i].vendor &&
+ device == ids[i].device) {
+ if ((*indexp) <= 0)
+ return bdf;
+
+ (*indexp)--;
+ }
+ }
+ }
+
+ return -1;
+}
diff --git a/drivers/pci/pci_compat.c b/drivers/pci/pci_compat.c
new file mode 100644
index 0000000000..d6938c198f
--- /dev/null
+++ b/drivers/pci/pci_compat.c
@@ -0,0 +1,43 @@
+/*
+ * Compatibility functions for pre-driver-model code
+ *
+ * Copyright (C) 2014 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#define DEBUG
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <malloc.h>
+#include <pci.h>
+#include <dm/device-internal.h>
+#include <dm/lists.h>
+
+#define PCI_HOSE_OP(rw, name, size, type) \
+int pci_hose_##rw##_config_##name(struct pci_controller *hose, \
+ pci_dev_t dev, \
+ int offset, type value) \
+{ \
+ return pci_##rw##_config##size(dev, offset, value); \
+}
+
+PCI_HOSE_OP(read, byte, 8, u8 *)
+PCI_HOSE_OP(read, word, 16, u16 *)
+PCI_HOSE_OP(read, dword, 32, u32 *)
+PCI_HOSE_OP(write, byte, 8, u8)
+PCI_HOSE_OP(write, word, 16, u16)
+PCI_HOSE_OP(write, dword, 32, u32)
+
+pci_dev_t pci_find_devices(struct pci_device_id *ids, int index)
+{
+ struct pci_child_platdata *pplat;
+ struct udevice *bus, *dev;
+
+ if (pci_find_device_id(ids, index, &dev))
+ return -1;
+ bus = dev->parent;
+ pplat = dev_get_parent_platdata(dev);
+
+ return PCI_ADD_BUS(bus->seq, pplat->devfn);
+}
diff --git a/drivers/pci/pci_sandbox.c b/drivers/pci/pci_sandbox.c
new file mode 100644
index 0000000000..6de5130c2a
--- /dev/null
+++ b/drivers/pci/pci_sandbox.c
@@ -0,0 +1,79 @@
+/*
+ * Copyright (c) 2014 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <fdtdec.h>
+#include <inttypes.h>
+#include <pci.h>
+#include <dm/root.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static int sandbox_pci_write_config(struct udevice *bus, pci_dev_t devfn,
+ uint offset, ulong value,
+ enum pci_size_t size)
+{
+ struct dm_pci_emul_ops *ops;
+ struct udevice *emul;
+ int ret;
+
+ ret = sandbox_pci_get_emul(bus, devfn, &emul);
+ if (ret)
+ return ret == -ENODEV ? 0 : ret;
+ ops = pci_get_emul_ops(emul);
+ if (!ops || !ops->write_config)
+ return -ENOSYS;
+
+ return ops->write_config(emul, offset, value, size);
+}
+
+static int sandbox_pci_read_config(struct udevice *bus, pci_dev_t devfn,
+ uint offset, ulong *valuep,
+ enum pci_size_t size)
+{
+ struct dm_pci_emul_ops *ops;
+ struct udevice *emul;
+ int ret;
+
+ /* Prepare the default response */
+ *valuep = pci_get_ff(size);
+ ret = sandbox_pci_get_emul(bus, devfn, &emul);
+ if (ret)
+ return ret == -ENODEV ? 0 : ret;
+ ops = pci_get_emul_ops(emul);
+ if (!ops || !ops->read_config)
+ return -ENOSYS;
+
+ return ops->read_config(emul, offset, valuep, size);
+}
+
+static int sandbox_pci_child_post_bind(struct udevice *dev)
+{
+ /* Attach an emulator if we can */
+ return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false);
+}
+
+static const struct dm_pci_ops sandbox_pci_ops = {
+ .read_config = sandbox_pci_read_config,
+ .write_config = sandbox_pci_write_config,
+};
+
+static const struct udevice_id sandbox_pci_ids[] = {
+ { .compatible = "sandbox,pci" },
+ { }
+};
+
+U_BOOT_DRIVER(pci_sandbox) = {
+ .name = "pci_sandbox",
+ .id = UCLASS_PCI,
+ .of_match = sandbox_pci_ids,
+ .ops = &sandbox_pci_ops,
+ .child_post_bind = sandbox_pci_child_post_bind,
+ .per_child_platdata_auto_alloc_size =
+ sizeof(struct pci_child_platdata),
+};
diff --git a/drivers/pci/pci_x86.c b/drivers/pci/pci_x86.c
new file mode 100644
index 0000000000..901bdcacce
--- /dev/null
+++ b/drivers/pci/pci_x86.c
@@ -0,0 +1,24 @@
+/*
+ * Copyright (c) 2015 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <pci.h>
+
+static const struct dm_pci_ops x86_pci_ops = {
+};
+
+static const struct udevice_id x86_pci_ids[] = {
+ { .compatible = "x86,pci" },
+ { }
+};
+
+U_BOOT_DRIVER(pci_x86) = {
+ .name = "pci_x86",
+ .id = UCLASS_PCI,
+ .of_match = x86_pci_ids,
+ .ops = &x86_pci_ops,
+};
diff --git a/drivers/qe/uec.c b/drivers/qe/uec.c
index c91f084a7c..e0ab04abc2 100644
--- a/drivers/qe/uec.c
+++ b/drivers/qe/uec.c
@@ -1333,7 +1333,7 @@ static int uec_recv(struct eth_device* dev)
if (!(status & RxBD_ERROR)) {
data = BD_DATA(bd);
len = BD_LENGTH(bd);
- NetReceive(data, len);
+ net_process_received_packet(data, len);
} else {
printf("%s: Rx error\n", dev->name);
}
diff --git a/drivers/serial/ns16550.c b/drivers/serial/ns16550.c
index 03beab5a14..67b1d60171 100644
--- a/drivers/serial/ns16550.c
+++ b/drivers/serial/ns16550.c
@@ -8,6 +8,7 @@
#include <dm.h>
#include <errno.h>
#include <fdtdec.h>
+#include <mapmem.h>
#include <ns16550.h>
#include <serial.h>
#include <watchdog.h>
diff --git a/drivers/serial/serial-uclass.c b/drivers/serial/serial-uclass.c
index 2de3737739..b239691efe 100644
--- a/drivers/serial/serial-uclass.c
+++ b/drivers/serial/serial-uclass.c
@@ -251,7 +251,7 @@ static int serial_post_probe(struct udevice *dev)
{
struct dm_serial_ops *ops = serial_get_ops(dev);
#ifdef CONFIG_DM_STDIO
- struct serial_dev_priv *upriv = dev->uclass_priv;
+ struct serial_dev_priv *upriv = dev_get_uclass_priv(dev);
struct stdio_dev sdev;
#endif
int ret;
@@ -299,7 +299,7 @@ static int serial_post_probe(struct udevice *dev)
static int serial_pre_remove(struct udevice *dev)
{
#ifdef CONFIG_SYS_STDIO_DEREGISTER
- struct serial_dev_priv *upriv = dev->uclass_priv;
+ struct serial_dev_priv *upriv = dev_get_uclass_priv(dev);
if (stdio_deregister_dev(upriv->sdev, 0))
return -EPERM;
diff --git a/drivers/serial/serial_uniphier.c b/drivers/serial/serial_uniphier.c
index 98e3b812e0..74547eb692 100644
--- a/drivers/serial/serial_uniphier.c
+++ b/drivers/serial/serial_uniphier.c
@@ -11,6 +11,7 @@
#include <asm/errno.h>
#include <dm/device.h>
#include <dm/platform_data/serial-uniphier.h>
+#include <mapmem.h>
#include <serial.h>
#include <fdtdec.h>
diff --git a/drivers/sound/Kconfig b/drivers/sound/Kconfig
index e69de29bb2..3b96e84480 100644
--- a/drivers/sound/Kconfig
+++ b/drivers/sound/Kconfig
@@ -0,0 +1,55 @@
+config SOUND
+ bool "Enable sound support"
+ help
+ Support making sounds through an audio codec. This is normally a
+ beep at a chosen frequency for a selected length of time. However
+ the drivers support playing arbitrary sound samples using a
+ PCM interface.
+
+ Note: At present the sound setup is somewhat tangled up in that the
+ audio codecs are called from the sound-i2s code. This could be
+ converted to driver model.
+
+config I2S
+ bool "Enable I2S support"
+ depends on SOUND
+ help
+ I2S is a serial bus often used to transmit audio data from the
+ SoC to the audio codec. This option enables sound support using
+ I2S. It calls either of the two supported codecs (no use is made
+ of driver model at present).
+
+config I2S_SAMSUNG
+ bool "Enable I2C support for Samsung SoCs"
+ depends on SOUND
+ help
+ Samsung Exynos SoCs support an I2S interface for sending audio
+ data to an audio codec. This option enables support for this,
+ using one of the available audio codec drivers. Enabling this
+ option provides an implementation for sound_init() and
+ sound_play().
+
+config SOUND_MAX98095
+ bool "Support Maxim max98095 audio codec"
+ depends on I2S_SAMSUNG
+ help
+ Enable the max98095 audio codec. This is connected via I2S for
+ audio data and I2C for codec control. At present it only works
+ with the Samsung I2S driver.
+
+config SOUND_SANDBOX
+ bool "Support sandbox emulated audio codec"
+ depends on SANDBOX && SOUND
+ help
+ U-Boot sandbox can emulate a sound device using SDL, playing the
+ sound on the host machine. This option implements the sound_init()
+ and sound_play() functions for sandbox. Note that you must install
+ the SDL libraries for this to work.
+
+config SOUND_WM8994
+ bool "Support Wolfson Micro wm8994 audio codec"
+ depends on I2S_SAMSUNG
+ help
+ Enable the wm8994 audio codec. This is connected via I2S for
+ audio data and I2C for codec control. At present it only works
+ with the Samsung I2S driver.
diff --git a/drivers/spi/Kconfig b/drivers/spi/Kconfig
index 7ae2727cf7..c4c112c5ae 100644
--- a/drivers/spi/Kconfig
+++ b/drivers/spi/Kconfig
@@ -10,3 +10,28 @@ config DM_SPI
as 'parent data' to every slave on each bus. Slaves
typically use driver-private data instead of extending the
spi_slave structure.
+
+config SANDBOX_SPI
+ bool "Sandbox SPI driver"
+ depends on SANDBOX && DM
+ help
+ Enable SPI support for sandbox. This is an emulation of a real SPI
+ bus. Devices can be attached to the bus using the device tree
+ which specifies the driver to use. As an example, see this device
+ tree fragment from sandbox.dts. It shows that the SPI bus has a
+ single flash device on chip select 0 which is emulated by the driver
+ for "sandbox,spi-flash", which is in drivers/mtd/spi/sandbox.c.
+
+ spi@0 {
+ #address-cells = <1>;
+ #size-cells = <0>;
+ reg = <0>;
+ compatible = "sandbox,spi";
+ cs-gpios = <0>, <&gpio_a 0>;
+ flash@0 {
+ reg = <0>;
+ compatible = "spansion,m25p16", "sandbox,spi-flash";
+ spi-max-frequency = <40000000>;
+ sandbox,filename = "spi.bin";
+ };
+ };
diff --git a/drivers/spi/Makefile b/drivers/spi/Makefile
index ce6f1cc74e..e288692f26 100644
--- a/drivers/spi/Makefile
+++ b/drivers/spi/Makefile
@@ -50,3 +50,4 @@ obj-$(CONFIG_TI_QSPI) += ti_qspi.o
obj-$(CONFIG_XILINX_SPI) += xilinx_spi.o
obj-$(CONFIG_ZYNQ_SPI) += zynq_spi.o
obj-$(CONFIG_FSL_QSPI) += fsl_qspi.o
+obj-$(CONFIG_FSL_DSPI) += fsl_dspi.o
diff --git a/drivers/spi/fsl_dspi.c b/drivers/spi/fsl_dspi.c
new file mode 100644
index 0000000000..6476f913c8
--- /dev/null
+++ b/drivers/spi/fsl_dspi.c
@@ -0,0 +1,737 @@
+/*
+ * (C) Copyright 2000-2003
+ * Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ *
+ * Copyright (C) 2004-2009, 2015 Freescale Semiconductor, Inc.
+ * TsiChung Liew (Tsi-Chung.Liew@freescale.com)
+ * Chao Fu (B44548@freescale.com)
+ * Haikun Wang (B53464@freescale.com)
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+#include <dm.h>
+#include <errno.h>
+#include <common.h>
+#include <spi.h>
+#include <malloc.h>
+#include <asm/io.h>
+#include <fdtdec.h>
+#ifndef CONFIG_M68K
+#include <asm/arch/clock.h>
+#endif
+#include <fsl_dspi.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* fsl_dspi_platdata flags */
+#define DSPI_FLAG_REGMAP_ENDIAN_BIG (1 << 0)
+
+/* idle data value */
+#define DSPI_IDLE_VAL 0x0
+
+/* max chipselect signals number */
+#define FSL_DSPI_MAX_CHIPSELECT 6
+
+/* default SCK frequency, unit: HZ */
+#define FSL_DSPI_DEFAULT_SCK_FREQ 10000000
+
+/* tx/rx data wait timeout value, unit: us */
+#define DSPI_TXRX_WAIT_TIMEOUT 1000000
+
+/* CTAR register pre-configure value */
+#define DSPI_CTAR_DEFAULT_VALUE (DSPI_CTAR_TRSZ(7) | \
+ DSPI_CTAR_PCSSCK_1CLK | \
+ DSPI_CTAR_PASC(0) | \
+ DSPI_CTAR_PDT(0) | \
+ DSPI_CTAR_CSSCK(0) | \
+ DSPI_CTAR_ASC(0) | \
+ DSPI_CTAR_DT(0))
+
+/* CTAR register pre-configure mask */
+#define DSPI_CTAR_SET_MODE_MASK (DSPI_CTAR_TRSZ(15) | \
+ DSPI_CTAR_PCSSCK(3) | \
+ DSPI_CTAR_PASC(3) | \
+ DSPI_CTAR_PDT(3) | \
+ DSPI_CTAR_CSSCK(15) | \
+ DSPI_CTAR_ASC(15) | \
+ DSPI_CTAR_DT(15))
+
+/**
+ * struct fsl_dspi_platdata - platform data for Freescale DSPI
+ *
+ * @flags: Flags for DSPI DSPI_FLAG_...
+ * @speed_hz: Default SCK frequency
+ * @num_chipselect: Number of DSPI chipselect signals
+ * @regs_addr: Base address of DSPI registers
+ */
+struct fsl_dspi_platdata {
+ uint flags;
+ uint speed_hz;
+ uint num_chipselect;
+ fdt_addr_t regs_addr;
+};
+
+/**
+ * struct fsl_dspi_priv - private data for Freescale DSPI
+ *
+ * @flags: Flags for DSPI DSPI_FLAG_...
+ * @mode: SPI mode to use for slave device (see SPI mode flags)
+ * @mcr_val: MCR register configure value
+ * @bus_clk: DSPI input clk frequency
+ * @speed_hz: Default SCK frequency
+ * @charbit: How many bits in every transfer
+ * @num_chipselect: Number of DSPI chipselect signals
+ * @ctar_val: CTAR register configure value of per chipselect slave device
+ * @regs: Point to DSPI register structure for I/O access
+ */
+struct fsl_dspi_priv {
+ uint flags;
+ uint mode;
+ uint mcr_val;
+ uint bus_clk;
+ uint speed_hz;
+ uint charbit;
+ uint num_chipselect;
+ uint ctar_val[FSL_DSPI_MAX_CHIPSELECT];
+ struct dspi *regs;
+};
+
+#ifndef CONFIG_DM_SPI
+struct fsl_dspi {
+ struct spi_slave slave;
+ struct fsl_dspi_priv priv;
+};
+#endif
+
+__weak void cpu_dspi_port_conf(void)
+{
+}
+
+__weak int cpu_dspi_claim_bus(uint bus, uint cs)
+{
+ return 0;
+}
+
+__weak void cpu_dspi_release_bus(uint bus, uint cs)
+{
+}
+
+static uint dspi_read32(uint flags, uint *addr)
+{
+ return flags & DSPI_FLAG_REGMAP_ENDIAN_BIG ?
+ in_be32(addr) : in_le32(addr);
+}
+
+static void dspi_write32(uint flags, uint *addr, uint val)
+{
+ flags & DSPI_FLAG_REGMAP_ENDIAN_BIG ?
+ out_be32(addr, val) : out_le32(addr, val);
+}
+
+static void dspi_halt(struct fsl_dspi_priv *priv, u8 halt)
+{
+ uint mcr_val;
+
+ mcr_val = dspi_read32(priv->flags, &priv->regs->mcr);
+
+ if (halt)
+ mcr_val |= DSPI_MCR_HALT;
+ else
+ mcr_val &= ~DSPI_MCR_HALT;
+
+ dspi_write32(priv->flags, &priv->regs->mcr, mcr_val);
+}
+
+static void fsl_dspi_init_mcr(struct fsl_dspi_priv *priv, uint cfg_val)
+{
+ /* halt DSPI module */
+ dspi_halt(priv, 1);
+
+ dspi_write32(priv->flags, &priv->regs->mcr, cfg_val);
+
+ /* resume module */
+ dspi_halt(priv, 0);
+
+ priv->mcr_val = cfg_val;
+}
+
+static void fsl_dspi_cfg_cs_active_state(struct fsl_dspi_priv *priv,
+ uint cs, uint state)
+{
+ uint mcr_val;
+
+ dspi_halt(priv, 1);
+
+ mcr_val = dspi_read32(priv->flags, &priv->regs->mcr);
+ if (state & SPI_CS_HIGH)
+ /* CSx inactive state is low */
+ mcr_val &= ~DSPI_MCR_PCSIS(cs);
+ else
+ /* CSx inactive state is high */
+ mcr_val |= DSPI_MCR_PCSIS(cs);
+ dspi_write32(priv->flags, &priv->regs->mcr, mcr_val);
+
+ dspi_halt(priv, 0);
+}
+
+static int fsl_dspi_cfg_ctar_mode(struct fsl_dspi_priv *priv,
+ uint cs, uint mode)
+{
+ uint bus_setup;
+
+ bus_setup = dspi_read32(priv->flags, &priv->regs->ctar[0]);
+
+ bus_setup &= ~DSPI_CTAR_SET_MODE_MASK;
+ bus_setup |= priv->ctar_val[cs];
+ bus_setup &= ~(DSPI_CTAR_CPOL | DSPI_CTAR_CPHA | DSPI_CTAR_LSBFE);
+
+ if (mode & SPI_CPOL)
+ bus_setup |= DSPI_CTAR_CPOL;
+ if (mode & SPI_CPHA)
+ bus_setup |= DSPI_CTAR_CPHA;
+ if (mode & SPI_LSB_FIRST)
+ bus_setup |= DSPI_CTAR_LSBFE;
+
+ dspi_write32(priv->flags, &priv->regs->ctar[0], bus_setup);
+
+ priv->charbit =
+ ((dspi_read32(priv->flags, &priv->regs->ctar[0]) &
+ DSPI_CTAR_TRSZ(15)) == DSPI_CTAR_TRSZ(15)) ? 16 : 8;
+
+ return 0;
+}
+
+static void fsl_dspi_clr_fifo(struct fsl_dspi_priv *priv)
+{
+ uint mcr_val;
+
+ dspi_halt(priv, 1);
+ mcr_val = dspi_read32(priv->flags, &priv->regs->mcr);
+ /* flush RX and TX FIFO */
+ mcr_val |= (DSPI_MCR_CTXF | DSPI_MCR_CRXF);
+ dspi_write32(priv->flags, &priv->regs->mcr, mcr_val);
+ dspi_halt(priv, 0);
+}
+
+static void dspi_tx(struct fsl_dspi_priv *priv, u32 ctrl, u16 data)
+{
+ int timeout = DSPI_TXRX_WAIT_TIMEOUT;
+
+ /* wait for empty entries in TXFIFO or timeout */
+ while (DSPI_SR_TXCTR(dspi_read32(priv->flags, &priv->regs->sr)) >= 4 &&
+ timeout--)
+ udelay(1);
+
+ if (timeout >= 0)
+ dspi_write32(priv->flags, &priv->regs->tfr, (ctrl | data));
+ else
+ debug("dspi_tx: waiting timeout!\n");
+}
+
+static u16 dspi_rx(struct fsl_dspi_priv *priv)
+{
+ int timeout = DSPI_TXRX_WAIT_TIMEOUT;
+
+ /* wait for valid entries in RXFIFO or timeout */
+ while (DSPI_SR_RXCTR(dspi_read32(priv->flags, &priv->regs->sr)) == 0 &&
+ timeout--)
+ udelay(1);
+
+ if (timeout >= 0)
+ return (u16)DSPI_RFR_RXDATA(
+ dspi_read32(priv->flags, &priv->regs->rfr));
+ else {
+ debug("dspi_rx: waiting timeout!\n");
+ return (u16)(~0);
+ }
+}
+
+static int dspi_xfer(struct fsl_dspi_priv *priv, uint cs, unsigned int bitlen,
+ const void *dout, void *din, unsigned long flags)
+{
+ u16 *spi_rd16 = NULL, *spi_wr16 = NULL;
+ u8 *spi_rd = NULL, *spi_wr = NULL;
+ static u32 ctrl;
+ uint len = bitlen >> 3;
+
+ if (priv->charbit == 16) {
+ bitlen >>= 1;
+ spi_wr16 = (u16 *)dout;
+ spi_rd16 = (u16 *)din;
+ } else {
+ spi_wr = (u8 *)dout;
+ spi_rd = (u8 *)din;
+ }
+
+ if ((flags & SPI_XFER_BEGIN) == SPI_XFER_BEGIN)
+ ctrl |= DSPI_TFR_CONT;
+
+ ctrl = ctrl & DSPI_TFR_CONT;
+ ctrl = ctrl | DSPI_TFR_CTAS(0) | DSPI_TFR_PCS(cs);
+
+ if (len > 1) {
+ int tmp_len = len - 1;
+ while (tmp_len--) {
+ if (dout != NULL) {
+ if (priv->charbit == 16)
+ dspi_tx(priv, ctrl, *spi_wr16++);
+ else
+ dspi_tx(priv, ctrl, *spi_wr++);
+ dspi_rx(priv);
+ }
+
+ if (din != NULL) {
+ dspi_tx(priv, ctrl, DSPI_IDLE_VAL);
+ if (priv->charbit == 16)
+ *spi_rd16++ = dspi_rx(priv);
+ else
+ *spi_rd++ = dspi_rx(priv);
+ }
+ }
+
+ len = 1; /* remaining byte */
+ }
+
+ if ((flags & SPI_XFER_END) == SPI_XFER_END)
+ ctrl &= ~DSPI_TFR_CONT;
+
+ if (len) {
+ if (dout != NULL) {
+ if (priv->charbit == 16)
+ dspi_tx(priv, ctrl, *spi_wr16);
+ else
+ dspi_tx(priv, ctrl, *spi_wr);
+ dspi_rx(priv);
+ }
+
+ if (din != NULL) {
+ dspi_tx(priv, ctrl, DSPI_IDLE_VAL);
+ if (priv->charbit == 16)
+ *spi_rd16 = dspi_rx(priv);
+ else
+ *spi_rd = dspi_rx(priv);
+ }
+ } else {
+ /* dummy read */
+ dspi_tx(priv, ctrl, DSPI_IDLE_VAL);
+ dspi_rx(priv);
+ }
+
+ return 0;
+}
+
+/**
+ * Calculate the divide value between input clk frequency and expected SCK frequency
+ * Formula: SCK = (clkrate/pbr) x ((1+dbr)/br)
+ * Dbr: use default value 0
+ *
+ * @pbr: return Baud Rate Prescaler value
+ * @br: return Baud Rate Scaler value
+ * @speed_hz: expected SCK frequency
+ * @clkrate: input clk frequency
+ */
+static int fsl_dspi_hz_to_spi_baud(int *pbr, int *br,
+ int speed_hz, uint clkrate)
+{
+ /* Valid baud rate pre-scaler values */
+ int pbr_tbl[4] = {2, 3, 5, 7};
+ int brs[16] = {2, 4, 6, 8,
+ 16, 32, 64, 128,
+ 256, 512, 1024, 2048,
+ 4096, 8192, 16384, 32768};
+ int temp, i = 0, j = 0;
+
+ temp = clkrate / speed_hz;
+
+ for (i = 0; i < ARRAY_SIZE(pbr_tbl); i++)
+ for (j = 0; j < ARRAY_SIZE(brs); j++) {
+ if (pbr_tbl[i] * brs[j] >= temp) {
+ *pbr = i;
+ *br = j;
+ return 0;
+ }
+ }
+
+ debug("Can not find valid baud rate,speed_hz is %d, ", speed_hz);
+ debug("clkrate is %d, we use the max prescaler value.\n", clkrate);
+
+ *pbr = ARRAY_SIZE(pbr_tbl) - 1;
+ *br = ARRAY_SIZE(brs) - 1;
+ return -EINVAL;
+}
+
+static int fsl_dspi_cfg_speed(struct fsl_dspi_priv *priv, uint speed)
+{
+ int ret;
+ uint bus_setup;
+ int best_i, best_j, bus_clk;
+
+ bus_clk = priv->bus_clk;
+
+ debug("DSPI set_speed: expected SCK speed %u, bus_clk %u.\n",
+ speed, bus_clk);
+
+ bus_setup = dspi_read32(priv->flags, &priv->regs->ctar[0]);
+ bus_setup &= ~(DSPI_CTAR_DBR | DSPI_CTAR_PBR(0x3) | DSPI_CTAR_BR(0xf));
+
+ ret = fsl_dspi_hz_to_spi_baud(&best_i, &best_j, speed, bus_clk);
+ if (ret) {
+ speed = priv->speed_hz;
+ debug("DSPI set_speed use default SCK rate %u.\n", speed);
+ fsl_dspi_hz_to_spi_baud(&best_i, &best_j, speed, bus_clk);
+ }
+
+ bus_setup |= (DSPI_CTAR_PBR(best_i) | DSPI_CTAR_BR(best_j));
+ dspi_write32(priv->flags, &priv->regs->ctar[0], bus_setup);
+
+ priv->speed_hz = speed;
+
+ return 0;
+}
+#ifndef CONFIG_DM_SPI
+void spi_init(void)
+{
+ /* Nothing to do */
+}
+
+void spi_init_f(void)
+{
+ /* Nothing to do */
+}
+
+void spi_init_r(void)
+{
+ /* Nothing to do */
+}
+
+int spi_cs_is_valid(unsigned int bus, unsigned int cs)
+{
+ if (((cs >= 0) && (cs < 8)) && ((bus >= 0) && (bus < 8)))
+ return 1;
+ else
+ return 0;
+}
+
+struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
+ unsigned int max_hz, unsigned int mode)
+{
+ struct fsl_dspi *dspi;
+ uint mcr_cfg_val;
+
+ dspi = spi_alloc_slave(struct fsl_dspi, bus, cs);
+ if (!dspi)
+ return NULL;
+
+ cpu_dspi_port_conf();
+
+#ifdef CONFIG_SYS_FSL_DSPI_BE
+ dspi->priv.flags |= DSPI_FLAG_REGMAP_ENDIAN_BIG;
+#endif
+
+ dspi->priv.regs = (struct dspi *)MMAP_DSPI;
+
+#ifdef CONFIG_M68K
+ dspi->priv.bus_clk = gd->bus_clk;
+#else
+ dspi->priv.bus_clk = mxc_get_clock(MXC_DSPI_CLK);
+#endif
+ dspi->priv.speed_hz = FSL_DSPI_DEFAULT_SCK_FREQ;
+
+ /* default: all CS signals inactive state is high */
+ mcr_cfg_val = DSPI_MCR_MSTR | DSPI_MCR_PCSIS_MASK |
+ DSPI_MCR_CRXF | DSPI_MCR_CTXF;
+ fsl_dspi_init_mcr(&dspi->priv, mcr_cfg_val);
+
+ for (i = 0; i < FSL_DSPI_MAX_CHIPSELECT; i++)
+ dspi->priv.ctar_val[i] = DSPI_CTAR_DEFAULT_VALUE;
+
+#ifdef CONFIG_SYS_DSPI_CTAR0
+ if (FSL_DSPI_MAX_CHIPSELECT > 0)
+ dspi->priv.ctar_val[0] = CONFIG_SYS_DSPI_CTAR0;
+#endif
+#ifdef CONFIG_SYS_DSPI_CTAR1
+ if (FSL_DSPI_MAX_CHIPSELECT > 1)
+ dspi->priv.ctar_val[1] = CONFIG_SYS_DSPI_CTAR1;
+#endif
+#ifdef CONFIG_SYS_DSPI_CTAR2
+ if (FSL_DSPI_MAX_CHIPSELECT > 2)
+ dspi->priv.ctar_val[2] = CONFIG_SYS_DSPI_CTAR2;
+#endif
+#ifdef CONFIG_SYS_DSPI_CTAR3
+ if (FSL_DSPI_MAX_CHIPSELECT > 3)
+ dspi->priv.ctar_val[3] = CONFIG_SYS_DSPI_CTAR3;
+#endif
+#ifdef CONFIG_SYS_DSPI_CTAR4
+ if (FSL_DSPI_MAX_CHIPSELECT > 4)
+ dspi->priv.ctar_val[4] = CONFIG_SYS_DSPI_CTAR4;
+#endif
+#ifdef CONFIG_SYS_DSPI_CTAR5
+ if (FSL_DSPI_MAX_CHIPSELECT > 5)
+ dspi->priv.ctar_val[5] = CONFIG_SYS_DSPI_CTAR5;
+#endif
+#ifdef CONFIG_SYS_DSPI_CTAR6
+ if (FSL_DSPI_MAX_CHIPSELECT > 6)
+ dspi->priv.ctar_val[6] = CONFIG_SYS_DSPI_CTAR6;
+#endif
+#ifdef CONFIG_SYS_DSPI_CTAR7
+ if (FSL_DSPI_MAX_CHIPSELECT > 7)
+ dspi->priv.ctar_val[7] = CONFIG_SYS_DSPI_CTAR7;
+#endif
+
+ fsl_dspi_cfg_speed(&dspi->priv, max_hz);
+
+ /* configure transfer mode */
+ fsl_dspi_cfg_ctar_mode(&dspi->priv, cs, mode);
+
+ /* configure active state of CSX */
+ fsl_dspi_cfg_cs_active_state(&dspi->priv, cs, mode);
+
+ return &dspi->slave;
+}
+
+void spi_free_slave(struct spi_slave *slave)
+{
+ free(slave);
+}
+
+int spi_claim_bus(struct spi_slave *slave)
+{
+ uint sr_val;
+ struct fsl_dspi *dspi = (struct fsl_dspi *)slave;
+
+ cpu_dspi_claim_bus(slave->bus, slave->cs);
+
+ fsl_dspi_clr_fifo(&dspi->priv);
+
+ /* check module TX and RX status */
+ sr_val = dspi_read32(dspi->priv.flags, &dspi->priv.regs->sr);
+ if ((sr_val & DSPI_SR_TXRXS) != DSPI_SR_TXRXS) {
+ debug("DSPI RX/TX not ready!\n");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+void spi_release_bus(struct spi_slave *slave)
+{
+ struct fsl_dspi *dspi = (struct fsl_dspi *)slave;
+
+ dspi_halt(&dspi->priv, 1);
+ cpu_dspi_release_bus(slave->bus.slave->cs);
+}
+
+int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
+ void *din, unsigned long flags)
+{
+ struct fsl_dspi *dspi = (struct fsl_dspi *)slave;
+ return dspi_xfer(&dspi->priv, slave->cs, bitlen, dout, din, flags);
+}
+#else
+static int fsl_dspi_child_pre_probe(struct udevice *dev)
+{
+ struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
+ struct fsl_dspi_priv *priv = dev_get_priv(dev->parent);
+
+ if (slave_plat->cs >= priv->num_chipselect) {
+ debug("DSPI invalid chipselect number %d(max %d)!\n",
+ slave_plat->cs, priv->num_chipselect - 1);
+ return -EINVAL;
+ }
+
+ priv->ctar_val[slave_plat->cs] = DSPI_CTAR_DEFAULT_VALUE;
+
+ debug("DSPI pre_probe slave device on CS %u, max_hz %u, mode 0x%x.\n",
+ slave_plat->cs, slave_plat->max_hz, slave_plat->mode);
+
+ return 0;
+}
+
+static int fsl_dspi_probe(struct udevice *bus)
+{
+ struct fsl_dspi_platdata *plat = dev_get_platdata(bus);
+ struct fsl_dspi_priv *priv = dev_get_priv(bus);
+ struct dm_spi_bus *dm_spi_bus;
+ uint mcr_cfg_val;
+
+ dm_spi_bus = bus->uclass_priv;
+
+ /* cpu speical pin muxing configure */
+ cpu_dspi_port_conf();
+
+ /* get input clk frequency */
+ priv->regs = (struct dspi *)plat->regs_addr;
+ priv->flags = plat->flags;
+#ifdef CONFIG_M68K
+ priv->bus_clk = gd->bus_clk;
+#else
+ priv->bus_clk = mxc_get_clock(MXC_DSPI_CLK);
+#endif
+ priv->num_chipselect = plat->num_chipselect;
+ priv->speed_hz = plat->speed_hz;
+ /* frame data length in bits, default 8bits */
+ priv->charbit = 8;
+
+ dm_spi_bus->max_hz = plat->speed_hz;
+
+ /* default: all CS signals inactive state is high */
+ mcr_cfg_val = DSPI_MCR_MSTR | DSPI_MCR_PCSIS_MASK |
+ DSPI_MCR_CRXF | DSPI_MCR_CTXF;
+ fsl_dspi_init_mcr(priv, mcr_cfg_val);
+
+ debug("%s probe done, bus-num %d.\n", bus->name, bus->seq);
+
+ return 0;
+}
+
+static int fsl_dspi_claim_bus(struct udevice *dev)
+{
+ uint sr_val;
+ struct fsl_dspi_priv *priv;
+ struct udevice *bus = dev->parent;
+ struct dm_spi_slave_platdata *slave_plat =
+ dev_get_parent_platdata(dev);
+
+ priv = dev_get_priv(bus);
+
+ /* processor special prepartion work */
+ cpu_dspi_claim_bus(bus->seq, slave_plat->cs);
+
+ /* configure transfer mode */
+ fsl_dspi_cfg_ctar_mode(priv, slave_plat->cs, priv->mode);
+
+ /* configure active state of CSX */
+ fsl_dspi_cfg_cs_active_state(priv, slave_plat->cs,
+ priv->mode);
+
+ fsl_dspi_clr_fifo(priv);
+
+ /* check module TX and RX status */
+ sr_val = dspi_read32(priv->flags, &priv->regs->sr);
+ if ((sr_val & DSPI_SR_TXRXS) != DSPI_SR_TXRXS) {
+ debug("DSPI RX/TX not ready!\n");
+ return -EIO;
+ }
+
+ return 0;
+}
+
+static int fsl_dspi_release_bus(struct udevice *dev)
+{
+ struct udevice *bus = dev->parent;
+ struct fsl_dspi_priv *priv = dev_get_priv(bus);
+ struct dm_spi_slave_platdata *slave_plat =
+ dev_get_parent_platdata(dev);
+
+ /* halt module */
+ dspi_halt(priv, 1);
+
+ /* processor special release work */
+ cpu_dspi_release_bus(bus->seq, slave_plat->cs);
+
+ return 0;
+}
+
+/**
+ * This function doesn't do anything except help with debugging
+ */
+static int fsl_dspi_bind(struct udevice *bus)
+{
+ debug("%s assigned req_seq %d.\n", bus->name, bus->req_seq);
+ return 0;
+}
+
+static int fsl_dspi_ofdata_to_platdata(struct udevice *bus)
+{
+ fdt_addr_t addr;
+ struct fsl_dspi_platdata *plat = bus->platdata;
+ const void *blob = gd->fdt_blob;
+ int node = bus->of_offset;
+
+ if (fdtdec_get_bool(blob, node, "big-endian"))
+ plat->flags |= DSPI_FLAG_REGMAP_ENDIAN_BIG;
+
+ plat->num_chipselect =
+ fdtdec_get_int(blob, node, "num-cs", FSL_DSPI_MAX_CHIPSELECT);
+
+ addr = fdtdec_get_addr(blob, node, "reg");
+ if (addr == FDT_ADDR_T_NONE) {
+ debug("DSPI: Can't get base address or size\n");
+ return -ENOMEM;
+ }
+ plat->regs_addr = addr;
+
+ plat->speed_hz = fdtdec_get_int(blob,
+ node, "spi-max-frequency", FSL_DSPI_DEFAULT_SCK_FREQ);
+
+ debug("DSPI: regs=0x%x, max-frequency=%d, endianess=%s, num-cs=%d\n",
+ plat->regs_addr, plat->speed_hz,
+ plat->flags & DSPI_FLAG_REGMAP_ENDIAN_BIG ? "be" : "le",
+ plat->num_chipselect);
+
+ return 0;
+}
+
+static int fsl_dspi_xfer(struct udevice *dev, unsigned int bitlen,
+ const void *dout, void *din, unsigned long flags)
+{
+ struct fsl_dspi_priv *priv;
+ struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
+ struct udevice *bus;
+
+ bus = dev->parent;
+ priv = dev_get_priv(bus);
+
+ return dspi_xfer(priv, slave_plat->cs, bitlen, dout, din, flags);
+}
+
+static int fsl_dspi_set_speed(struct udevice *bus, uint speed)
+{
+ struct fsl_dspi_priv *priv = dev_get_priv(bus);
+
+ return fsl_dspi_cfg_speed(priv, speed);
+}
+
+static int fsl_dspi_set_mode(struct udevice *bus, uint mode)
+{
+ struct fsl_dspi_priv *priv = dev_get_priv(bus);
+
+ debug("DSPI set_mode: mode 0x%x.\n", mode);
+
+ /*
+ * We store some chipselect special configure value in priv->ctar_val,
+ * and we can't get the correct chipselect number here,
+ * so just store mode value.
+ * Do really configuration when claim_bus.
+ */
+ priv->mode = mode;
+
+ return 0;
+}
+
+static const struct dm_spi_ops fsl_dspi_ops = {
+ .claim_bus = fsl_dspi_claim_bus,
+ .release_bus = fsl_dspi_release_bus,
+ .xfer = fsl_dspi_xfer,
+ .set_speed = fsl_dspi_set_speed,
+ .set_mode = fsl_dspi_set_mode,
+};
+
+static const struct udevice_id fsl_dspi_ids[] = {
+ { .compatible = "fsl,vf610-dspi" },
+ { }
+};
+
+U_BOOT_DRIVER(fsl_dspi) = {
+ .name = "fsl_dspi",
+ .id = UCLASS_SPI,
+ .of_match = fsl_dspi_ids,
+ .ops = &fsl_dspi_ops,
+ .ofdata_to_platdata = fsl_dspi_ofdata_to_platdata,
+ .platdata_auto_alloc_size = sizeof(struct fsl_dspi_platdata),
+ .priv_auto_alloc_size = sizeof(struct fsl_dspi_priv),
+ .probe = fsl_dspi_probe,
+ .child_pre_probe = fsl_dspi_child_pre_probe,
+ .bind = fsl_dspi_bind,
+};
+#endif
diff --git a/drivers/spi/fsl_qspi.c b/drivers/spi/fsl_qspi.c
index 5e0b069274..868df5f121 100644
--- a/drivers/spi/fsl_qspi.c
+++ b/drivers/spi/fsl_qspi.c
@@ -1,5 +1,5 @@
/*
- * Copyright 2013-2014 Freescale Semiconductor, Inc.
+ * Copyright 2013-2015 Freescale Semiconductor, Inc.
*
* Freescale Quad Serial Peripheral Interface (QSPI) driver
*
@@ -11,8 +11,12 @@
#include <spi.h>
#include <asm/io.h>
#include <linux/sizes.h>
+#include <dm.h>
+#include <errno.h>
#include "fsl_qspi.h"
+DECLARE_GLOBAL_DATA_PTR;
+
#define RX_BUFFER_SIZE 0x80
#ifdef CONFIG_MX6SX
#define TX_BUFFER_SIZE 0x200
@@ -63,35 +67,85 @@
#define QSPI_CMD_PP_4B 0x12 /* Page program (up to 256 bytes) */
#define QSPI_CMD_SE_4B 0xdc /* Sector erase (usually 64KiB) */
-#ifdef CONFIG_SYS_FSL_QSPI_LE
-#define qspi_read32 in_le32
-#define qspi_write32 out_le32
-#elif defined(CONFIG_SYS_FSL_QSPI_BE)
-#define qspi_read32 in_be32
-#define qspi_write32 out_be32
-#endif
+/* fsl_qspi_platdata flags */
+#define QSPI_FLAG_REGMAP_ENDIAN_BIG (1 << 0)
-static unsigned long spi_bases[] = {
- QSPI0_BASE_ADDR,
-#ifdef CONFIG_MX6SX
- QSPI1_BASE_ADDR,
-#endif
-};
+/* default SCK frequency, unit: HZ */
+#define FSL_QSPI_DEFAULT_SCK_FREQ 50000000
-static unsigned long amba_bases[] = {
- QSPI0_AMBA_BASE,
-#ifdef CONFIG_MX6SX
- QSPI1_AMBA_BASE,
+/* QSPI max chipselect signals number */
+#define FSL_QSPI_MAX_CHIPSELECT_NUM 4
+
+#ifdef CONFIG_DM_SPI
+/**
+ * struct fsl_qspi_platdata - platform data for Freescale QSPI
+ *
+ * @flags: Flags for QSPI QSPI_FLAG_...
+ * @speed_hz: Default SCK frequency
+ * @reg_base: Base address of QSPI registers
+ * @amba_base: Base address of QSPI memory mapping
+ * @amba_total_size: size of QSPI memory mapping
+ * @flash_num: Number of active slave devices
+ * @num_chipselect: Number of QSPI chipselect signals
+ */
+struct fsl_qspi_platdata {
+ u32 flags;
+ u32 speed_hz;
+ u32 reg_base;
+ u32 amba_base;
+ u32 amba_total_size;
+ u32 flash_num;
+ u32 num_chipselect;
+};
#endif
+
+/**
+ * struct fsl_qspi_priv - private data for Freescale QSPI
+ *
+ * @flags: Flags for QSPI QSPI_FLAG_...
+ * @bus_clk: QSPI input clk frequency
+ * @speed_hz: Default SCK frequency
+ * @cur_seqid: current LUT table sequence id
+ * @sf_addr: flash access offset
+ * @amba_base: Base address of QSPI memory mapping of every CS
+ * @amba_total_size: size of QSPI memory mapping
+ * @cur_amba_base: Base address of QSPI memory mapping of current CS
+ * @flash_num: Number of active slave devices
+ * @num_chipselect: Number of QSPI chipselect signals
+ * @regs: Point to QSPI register structure for I/O access
+ */
+struct fsl_qspi_priv {
+ u32 flags;
+ u32 bus_clk;
+ u32 speed_hz;
+ u32 cur_seqid;
+ u32 sf_addr;
+ u32 amba_base[FSL_QSPI_MAX_CHIPSELECT_NUM];
+ u32 amba_total_size;
+ u32 cur_amba_base;
+ u32 flash_num;
+ u32 num_chipselect;
+ struct fsl_qspi_regs *regs;
};
+#ifndef CONFIG_DM_SPI
struct fsl_qspi {
struct spi_slave slave;
- unsigned long reg_base;
- unsigned long amba_base;
- u32 sf_addr;
- u8 cur_seqid;
+ struct fsl_qspi_priv priv;
};
+#endif
+
+static u32 qspi_read32(u32 flags, u32 *addr)
+{
+ return flags & QSPI_FLAG_REGMAP_ENDIAN_BIG ?
+ in_be32(addr) : in_le32(addr);
+}
+
+static void qspi_write32(u32 flags, u32 *addr, u32 val)
+{
+ flags & QSPI_FLAG_REGMAP_ENDIAN_BIG ?
+ out_be32(addr, val) : out_le32(addr, val);
+}
/* QSPI support swapping the flash read/write data
* in hardware for LS102xA, but not for VF610 */
@@ -104,131 +158,135 @@ static inline u32 qspi_endian_xchg(u32 data)
#endif
}
-static inline struct fsl_qspi *to_qspi_spi(struct spi_slave *slave)
-{
- return container_of(slave, struct fsl_qspi, slave);
-}
-
-static void qspi_set_lut(struct fsl_qspi *qspi)
+static void qspi_set_lut(struct fsl_qspi_priv *priv)
{
- struct fsl_qspi_regs *regs = (struct fsl_qspi_regs *)qspi->reg_base;
+ struct fsl_qspi_regs *regs = priv->regs;
u32 lut_base;
/* Unlock the LUT */
- qspi_write32(&regs->lutkey, LUT_KEY_VALUE);
- qspi_write32(&regs->lckcr, QSPI_LCKCR_UNLOCK);
+ qspi_write32(priv->flags, &regs->lutkey, LUT_KEY_VALUE);
+ qspi_write32(priv->flags, &regs->lckcr, QSPI_LCKCR_UNLOCK);
/* Write Enable */
lut_base = SEQID_WREN * 4;
- qspi_write32(&regs->lut[lut_base], OPRND0(QSPI_CMD_WREN) |
+ qspi_write32(priv->flags, &regs->lut[lut_base], OPRND0(QSPI_CMD_WREN) |
PAD0(LUT_PAD1) | INSTR0(LUT_CMD));
- qspi_write32(&regs->lut[lut_base + 1], 0);
- qspi_write32(&regs->lut[lut_base + 2], 0);
- qspi_write32(&regs->lut[lut_base + 3], 0);
+ qspi_write32(priv->flags, &regs->lut[lut_base + 1], 0);
+ qspi_write32(priv->flags, &regs->lut[lut_base + 2], 0);
+ qspi_write32(priv->flags, &regs->lut[lut_base + 3], 0);
/* Fast Read */
lut_base = SEQID_FAST_READ * 4;
#ifdef CONFIG_SPI_FLASH_BAR
- qspi_write32(&regs->lut[lut_base], OPRND0(QSPI_CMD_FAST_READ) |
- PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) |
+ qspi_write32(priv->flags, &regs->lut[lut_base],
+ OPRND0(QSPI_CMD_FAST_READ) | PAD0(LUT_PAD1) |
+ INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) |
PAD1(LUT_PAD1) | INSTR1(LUT_ADDR));
#else
if (FSL_QSPI_FLASH_SIZE <= SZ_16M)
- qspi_write32(&regs->lut[lut_base], OPRND0(QSPI_CMD_FAST_READ) |
- PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) |
- PAD1(LUT_PAD1) | INSTR1(LUT_ADDR));
+ qspi_write32(priv->flags, &regs->lut[lut_base],
+ OPRND0(QSPI_CMD_FAST_READ) | PAD0(LUT_PAD1) |
+ INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) |
+ PAD1(LUT_PAD1) | INSTR1(LUT_ADDR));
else
- qspi_write32(&regs->lut[lut_base],
+ qspi_write32(priv->flags, &regs->lut[lut_base],
OPRND0(QSPI_CMD_FAST_READ_4B) |
PAD0(LUT_PAD1) | INSTR0(LUT_CMD) |
OPRND1(ADDR32BIT) | PAD1(LUT_PAD1) |
INSTR1(LUT_ADDR));
#endif
- qspi_write32(&regs->lut[lut_base + 1], OPRND0(8) | PAD0(LUT_PAD1) |
- INSTR0(LUT_DUMMY) | OPRND1(RX_BUFFER_SIZE) | PAD1(LUT_PAD1) |
- INSTR1(LUT_READ));
- qspi_write32(&regs->lut[lut_base + 2], 0);
- qspi_write32(&regs->lut[lut_base + 3], 0);
+ qspi_write32(priv->flags, &regs->lut[lut_base + 1],
+ OPRND0(8) | PAD0(LUT_PAD1) | INSTR0(LUT_DUMMY) |
+ OPRND1(RX_BUFFER_SIZE) | PAD1(LUT_PAD1) |
+ INSTR1(LUT_READ));
+ qspi_write32(priv->flags, &regs->lut[lut_base + 2], 0);
+ qspi_write32(priv->flags, &regs->lut[lut_base + 3], 0);
/* Read Status */
lut_base = SEQID_RDSR * 4;
- qspi_write32(&regs->lut[lut_base], OPRND0(QSPI_CMD_RDSR) |
+ qspi_write32(priv->flags, &regs->lut[lut_base], OPRND0(QSPI_CMD_RDSR) |
PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(1) |
PAD1(LUT_PAD1) | INSTR1(LUT_READ));
- qspi_write32(&regs->lut[lut_base + 1], 0);
- qspi_write32(&regs->lut[lut_base + 2], 0);
- qspi_write32(&regs->lut[lut_base + 3], 0);
+ qspi_write32(priv->flags, &regs->lut[lut_base + 1], 0);
+ qspi_write32(priv->flags, &regs->lut[lut_base + 2], 0);
+ qspi_write32(priv->flags, &regs->lut[lut_base + 3], 0);
/* Erase a sector */
lut_base = SEQID_SE * 4;
#ifdef CONFIG_SPI_FLASH_BAR
- qspi_write32(&regs->lut[lut_base], OPRND0(QSPI_CMD_SE) |
+ qspi_write32(priv->flags, &regs->lut[lut_base], OPRND0(QSPI_CMD_SE) |
PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) |
PAD1(LUT_PAD1) | INSTR1(LUT_ADDR));
#else
if (FSL_QSPI_FLASH_SIZE <= SZ_16M)
- qspi_write32(&regs->lut[lut_base], OPRND0(QSPI_CMD_SE) |
- PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) |
- PAD1(LUT_PAD1) | INSTR1(LUT_ADDR));
+ qspi_write32(priv->flags, &regs->lut[lut_base],
+ OPRND0(QSPI_CMD_SE) | PAD0(LUT_PAD1) |
+ INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) |
+ PAD1(LUT_PAD1) | INSTR1(LUT_ADDR));
else
- qspi_write32(&regs->lut[lut_base], OPRND0(QSPI_CMD_SE_4B) |
- PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(ADDR32BIT) |
- PAD1(LUT_PAD1) | INSTR1(LUT_ADDR));
+ qspi_write32(priv->flags, &regs->lut[lut_base],
+ OPRND0(QSPI_CMD_SE_4B) | PAD0(LUT_PAD1) |
+ INSTR0(LUT_CMD) | OPRND1(ADDR32BIT) |
+ PAD1(LUT_PAD1) | INSTR1(LUT_ADDR));
#endif
- qspi_write32(&regs->lut[lut_base + 1], 0);
- qspi_write32(&regs->lut[lut_base + 2], 0);
- qspi_write32(&regs->lut[lut_base + 3], 0);
+ qspi_write32(priv->flags, &regs->lut[lut_base + 1], 0);
+ qspi_write32(priv->flags, &regs->lut[lut_base + 2], 0);
+ qspi_write32(priv->flags, &regs->lut[lut_base + 3], 0);
/* Erase the whole chip */
lut_base = SEQID_CHIP_ERASE * 4;
- qspi_write32(&regs->lut[lut_base], OPRND0(QSPI_CMD_CHIP_ERASE) |
- PAD0(LUT_PAD1) | INSTR0(LUT_CMD));
- qspi_write32(&regs->lut[lut_base + 1], 0);
- qspi_write32(&regs->lut[lut_base + 2], 0);
- qspi_write32(&regs->lut[lut_base + 3], 0);
+ qspi_write32(priv->flags, &regs->lut[lut_base],
+ OPRND0(QSPI_CMD_CHIP_ERASE) |
+ PAD0(LUT_PAD1) | INSTR0(LUT_CMD));
+ qspi_write32(priv->flags, &regs->lut[lut_base + 1], 0);
+ qspi_write32(priv->flags, &regs->lut[lut_base + 2], 0);
+ qspi_write32(priv->flags, &regs->lut[lut_base + 3], 0);
/* Page Program */
lut_base = SEQID_PP * 4;
#ifdef CONFIG_SPI_FLASH_BAR
- qspi_write32(&regs->lut[lut_base], OPRND0(QSPI_CMD_PP) |
+ qspi_write32(priv->flags, &regs->lut[lut_base], OPRND0(QSPI_CMD_PP) |
PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) |
PAD1(LUT_PAD1) | INSTR1(LUT_ADDR));
#else
if (FSL_QSPI_FLASH_SIZE <= SZ_16M)
- qspi_write32(&regs->lut[lut_base], OPRND0(QSPI_CMD_PP) |
- PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) |
- PAD1(LUT_PAD1) | INSTR1(LUT_ADDR));
+ qspi_write32(priv->flags, &regs->lut[lut_base],
+ OPRND0(QSPI_CMD_PP) | PAD0(LUT_PAD1) |
+ INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) |
+ PAD1(LUT_PAD1) | INSTR1(LUT_ADDR));
else
- qspi_write32(&regs->lut[lut_base], OPRND0(QSPI_CMD_PP_4B) |
- PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(ADDR32BIT) |
- PAD1(LUT_PAD1) | INSTR1(LUT_ADDR));
+ qspi_write32(priv->flags, &regs->lut[lut_base],
+ OPRND0(QSPI_CMD_PP_4B) | PAD0(LUT_PAD1) |
+ INSTR0(LUT_CMD) | OPRND1(ADDR32BIT) |
+ PAD1(LUT_PAD1) | INSTR1(LUT_ADDR));
#endif
#ifdef CONFIG_MX6SX
/*
* To MX6SX, OPRND0(TX_BUFFER_SIZE) can not work correctly.
* So, Use IDATSZ in IPCR to determine the size and here set 0.
*/
- qspi_write32(&regs->lut[lut_base + 1], OPRND0(0) |
+ qspi_write32(priv->flags, &regs->lut[lut_base + 1], OPRND0(0) |
PAD0(LUT_PAD1) | INSTR0(LUT_WRITE));
#else
- qspi_write32(&regs->lut[lut_base + 1], OPRND0(TX_BUFFER_SIZE) |
- PAD0(LUT_PAD1) | INSTR0(LUT_WRITE));
+ qspi_write32(priv->flags, &regs->lut[lut_base + 1],
+ OPRND0(TX_BUFFER_SIZE) |
+ PAD0(LUT_PAD1) | INSTR0(LUT_WRITE));
#endif
- qspi_write32(&regs->lut[lut_base + 2], 0);
- qspi_write32(&regs->lut[lut_base + 3], 0);
+ qspi_write32(priv->flags, &regs->lut[lut_base + 2], 0);
+ qspi_write32(priv->flags, &regs->lut[lut_base + 3], 0);
/* READ ID */
lut_base = SEQID_RDID * 4;
- qspi_write32(&regs->lut[lut_base], OPRND0(QSPI_CMD_RDID) |
+ qspi_write32(priv->flags, &regs->lut[lut_base], OPRND0(QSPI_CMD_RDID) |
PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(8) |
PAD1(LUT_PAD1) | INSTR1(LUT_READ));
- qspi_write32(&regs->lut[lut_base + 1], 0);
- qspi_write32(&regs->lut[lut_base + 2], 0);
- qspi_write32(&regs->lut[lut_base + 3], 0);
+ qspi_write32(priv->flags, &regs->lut[lut_base + 1], 0);
+ qspi_write32(priv->flags, &regs->lut[lut_base + 2], 0);
+ qspi_write32(priv->flags, &regs->lut[lut_base + 3], 0);
/* SUB SECTOR 4K ERASE */
lut_base = SEQID_BE_4K * 4;
- qspi_write32(&regs->lut[lut_base], OPRND0(QSPI_CMD_BE_4K) |
+ qspi_write32(priv->flags, &regs->lut[lut_base], OPRND0(QSPI_CMD_BE_4K) |
PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(ADDR24BIT) |
PAD1(LUT_PAD1) | INSTR1(LUT_ADDR));
@@ -239,28 +297,28 @@ static void qspi_set_lut(struct fsl_qspi *qspi)
* initialization.
*/
lut_base = SEQID_BRRD * 4;
- qspi_write32(&regs->lut[lut_base], OPRND0(QSPI_CMD_BRRD) |
+ qspi_write32(priv->flags, &regs->lut[lut_base], OPRND0(QSPI_CMD_BRRD) |
PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(1) |
PAD1(LUT_PAD1) | INSTR1(LUT_READ));
lut_base = SEQID_BRWR * 4;
- qspi_write32(&regs->lut[lut_base], OPRND0(QSPI_CMD_BRWR) |
+ qspi_write32(priv->flags, &regs->lut[lut_base], OPRND0(QSPI_CMD_BRWR) |
PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(1) |
PAD1(LUT_PAD1) | INSTR1(LUT_WRITE));
lut_base = SEQID_RDEAR * 4;
- qspi_write32(&regs->lut[lut_base], OPRND0(QSPI_CMD_RDEAR) |
+ qspi_write32(priv->flags, &regs->lut[lut_base], OPRND0(QSPI_CMD_RDEAR) |
PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(1) |
PAD1(LUT_PAD1) | INSTR1(LUT_READ));
lut_base = SEQID_WREAR * 4;
- qspi_write32(&regs->lut[lut_base], OPRND0(QSPI_CMD_WREAR) |
+ qspi_write32(priv->flags, &regs->lut[lut_base], OPRND0(QSPI_CMD_WREAR) |
PAD0(LUT_PAD1) | INSTR0(LUT_CMD) | OPRND1(1) |
PAD1(LUT_PAD1) | INSTR1(LUT_WRITE));
#endif
/* Lock the LUT */
- qspi_write32(&regs->lutkey, LUT_KEY_VALUE);
- qspi_write32(&regs->lckcr, QSPI_LCKCR_LOCK);
+ qspi_write32(priv->flags, &regs->lutkey, LUT_KEY_VALUE);
+ qspi_write32(priv->flags, &regs->lckcr, QSPI_LCKCR_LOCK);
}
#if defined(CONFIG_SYS_FSL_QSPI_AHB)
@@ -270,14 +328,14 @@ static void qspi_set_lut(struct fsl_qspi *qspi)
* the wrong data. The spec tells us reset the AHB domain and Serial Flash
* domain at the same time.
*/
-static inline void qspi_ahb_invalid(struct fsl_qspi *q)
+static inline void qspi_ahb_invalid(struct fsl_qspi_priv *priv)
{
- struct fsl_qspi_regs *regs = (struct fsl_qspi_regs *)q->reg_base;
+ struct fsl_qspi_regs *regs = priv->regs;
u32 reg;
- reg = qspi_read32(&regs->mcr);
+ reg = qspi_read32(priv->flags, &regs->mcr);
reg |= QSPI_MCR_SWRSTHD_MASK | QSPI_MCR_SWRSTSD_MASK;
- qspi_write32(&regs->mcr, reg);
+ qspi_write32(priv->flags, &regs->mcr, reg);
/*
* The minimum delay : 1 AHB + 2 SFCK clocks.
@@ -286,46 +344,48 @@ static inline void qspi_ahb_invalid(struct fsl_qspi *q)
udelay(1);
reg &= ~(QSPI_MCR_SWRSTHD_MASK | QSPI_MCR_SWRSTSD_MASK);
- qspi_write32(&regs->mcr, reg);
+ qspi_write32(priv->flags, &regs->mcr, reg);
}
/* Read out the data from the AHB buffer. */
-static inline void qspi_ahb_read(struct fsl_qspi *q, u8 *rxbuf, int len)
+static inline void qspi_ahb_read(struct fsl_qspi_priv *priv, u8 *rxbuf, int len)
{
- struct fsl_qspi_regs *regs = (struct fsl_qspi_regs *)q->reg_base;
+ struct fsl_qspi_regs *regs = priv->regs;
u32 mcr_reg;
- mcr_reg = qspi_read32(&regs->mcr);
+ mcr_reg = qspi_read32(priv->flags, &regs->mcr);
- qspi_write32(&regs->mcr, QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK |
+ qspi_write32(priv->flags, &regs->mcr,
+ QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK |
QSPI_MCR_RESERVED_MASK | QSPI_MCR_END_CFD_LE);
/* Read out the data directly from the AHB buffer. */
- memcpy(rxbuf, (u8 *)(q->amba_base + q->sf_addr), len);
+ memcpy(rxbuf, (u8 *)(priv->cur_amba_base + priv->sf_addr), len);
- qspi_write32(&regs->mcr, mcr_reg);
+ qspi_write32(priv->flags, &regs->mcr, mcr_reg);
}
-static void qspi_enable_ddr_mode(struct fsl_qspi_regs *regs)
+static void qspi_enable_ddr_mode(struct fsl_qspi_priv *priv)
{
u32 reg, reg2;
+ struct fsl_qspi_regs *regs = priv->regs;
- reg = qspi_read32(&regs->mcr);
+ reg = qspi_read32(priv->flags, &regs->mcr);
/* Disable the module */
- qspi_write32(&regs->mcr, reg | QSPI_MCR_MDIS_MASK);
+ qspi_write32(priv->flags, &regs->mcr, reg | QSPI_MCR_MDIS_MASK);
/* Set the Sampling Register for DDR */
- reg2 = qspi_read32(&regs->smpr);
+ reg2 = qspi_read32(priv->flags, &regs->smpr);
reg2 &= ~QSPI_SMPR_DDRSMP_MASK;
reg2 |= (2 << QSPI_SMPR_DDRSMP_SHIFT);
- qspi_write32(&regs->smpr, reg2);
+ qspi_write32(priv->flags, &regs->smpr, reg2);
/* Enable the module again (enable the DDR too) */
reg |= QSPI_MCR_DDR_EN_MASK;
/* Enable bit 29 for imx6sx */
reg |= (1 << 29);
- qspi_write32(&regs->mcr, reg);
+ qspi_write32(priv->flags, &regs->mcr, reg);
}
/*
@@ -341,180 +401,103 @@ static void qspi_enable_ddr_mode(struct fsl_qspi_regs *regs)
* causes the controller to clear the buffer, and use the sequence pointed
* by the QUADSPI_BFGENCR[SEQID] to initiate a read from the flash.
*/
-static void qspi_init_ahb_read(struct fsl_qspi_regs *regs)
+static void qspi_init_ahb_read(struct fsl_qspi_priv *priv)
{
+ struct fsl_qspi_regs *regs = priv->regs;
+
/* AHB configuration for access buffer 0/1/2 .*/
- qspi_write32(&regs->buf0cr, QSPI_BUFXCR_INVALID_MSTRID);
- qspi_write32(&regs->buf1cr, QSPI_BUFXCR_INVALID_MSTRID);
- qspi_write32(&regs->buf2cr, QSPI_BUFXCR_INVALID_MSTRID);
- qspi_write32(&regs->buf3cr, QSPI_BUF3CR_ALLMST_MASK |
+ qspi_write32(priv->flags, &regs->buf0cr, QSPI_BUFXCR_INVALID_MSTRID);
+ qspi_write32(priv->flags, &regs->buf1cr, QSPI_BUFXCR_INVALID_MSTRID);
+ qspi_write32(priv->flags, &regs->buf2cr, QSPI_BUFXCR_INVALID_MSTRID);
+ qspi_write32(priv->flags, &regs->buf3cr, QSPI_BUF3CR_ALLMST_MASK |
(0x80 << QSPI_BUF3CR_ADATSZ_SHIFT));
/* We only use the buffer3 */
- qspi_write32(&regs->buf0ind, 0);
- qspi_write32(&regs->buf1ind, 0);
- qspi_write32(&regs->buf2ind, 0);
+ qspi_write32(priv->flags, &regs->buf0ind, 0);
+ qspi_write32(priv->flags, &regs->buf1ind, 0);
+ qspi_write32(priv->flags, &regs->buf2ind, 0);
/*
* Set the default lut sequence for AHB Read.
* Parallel mode is disabled.
*/
- qspi_write32(&regs->bfgencr,
+ qspi_write32(priv->flags, &regs->bfgencr,
SEQID_FAST_READ << QSPI_BFGENCR_SEQID_SHIFT);
/*Enable DDR Mode*/
- qspi_enable_ddr_mode(regs);
+ qspi_enable_ddr_mode(priv);
}
#endif
-void spi_init()
-{
- /* do nothing */
-}
-
-struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
- unsigned int max_hz, unsigned int mode)
-{
- struct fsl_qspi *qspi;
- struct fsl_qspi_regs *regs;
- u32 smpr_val;
- u32 total_size;
-
- if (bus >= ARRAY_SIZE(spi_bases))
- return NULL;
-
- if (cs >= FSL_QSPI_FLASH_NUM)
- return NULL;
-
- qspi = spi_alloc_slave(struct fsl_qspi, bus, cs);
- if (!qspi)
- return NULL;
-
- qspi->reg_base = spi_bases[bus];
- /*
- * According cs, use different amba_base to choose the
- * corresponding flash devices.
- *
- * If not, only one flash device is used even if passing
- * different cs using `sf probe`
- */
- qspi->amba_base = amba_bases[bus] + cs * FSL_QSPI_FLASH_SIZE;
-
- qspi->slave.max_write_size = TX_BUFFER_SIZE;
-
- regs = (struct fsl_qspi_regs *)qspi->reg_base;
- qspi_write32(&regs->mcr, QSPI_MCR_RESERVED_MASK | QSPI_MCR_MDIS_MASK);
-
- smpr_val = qspi_read32(&regs->smpr);
- qspi_write32(&regs->smpr, smpr_val & ~(QSPI_SMPR_FSDLY_MASK |
- QSPI_SMPR_FSPHS_MASK | QSPI_SMPR_HSENA_MASK));
- qspi_write32(&regs->mcr, QSPI_MCR_RESERVED_MASK);
-
- total_size = FSL_QSPI_FLASH_SIZE * FSL_QSPI_FLASH_NUM;
- /*
- * Any read access to non-implemented addresses will provide
- * undefined results.
- *
- * In case single die flash devices, TOP_ADDR_MEMA2 and
- * TOP_ADDR_MEMB2 should be initialized/programmed to
- * TOP_ADDR_MEMA1 and TOP_ADDR_MEMB1 respectively - in effect,
- * setting the size of these devices to 0. This would ensure
- * that the complete memory map is assigned to only one flash device.
- */
- qspi_write32(&regs->sfa1ad, FSL_QSPI_FLASH_SIZE | amba_bases[bus]);
- qspi_write32(&regs->sfa2ad, FSL_QSPI_FLASH_SIZE | amba_bases[bus]);
- qspi_write32(&regs->sfb1ad, total_size | amba_bases[bus]);
- qspi_write32(&regs->sfb2ad, total_size | amba_bases[bus]);
-
- qspi_set_lut(qspi);
-
- smpr_val = qspi_read32(&regs->smpr);
- smpr_val &= ~QSPI_SMPR_DDRSMP_MASK;
- qspi_write32(&regs->smpr, smpr_val);
- qspi_write32(&regs->mcr, QSPI_MCR_RESERVED_MASK);
-
-#ifdef CONFIG_SYS_FSL_QSPI_AHB
- qspi_init_ahb_read(regs);
-#endif
- return &qspi->slave;
-}
-
-void spi_free_slave(struct spi_slave *slave)
-{
- struct fsl_qspi *qspi = to_qspi_spi(slave);
-
- free(qspi);
-}
-
-int spi_claim_bus(struct spi_slave *slave)
-{
- return 0;
-}
-
#ifdef CONFIG_SPI_FLASH_BAR
/* Bank register read/write, EAR register read/write */
-static void qspi_op_rdbank(struct fsl_qspi *qspi, u8 *rxbuf, u32 len)
+static void qspi_op_rdbank(struct fsl_qspi_priv *priv, u8 *rxbuf, u32 len)
{
- struct fsl_qspi_regs *regs = (struct fsl_qspi_regs *)qspi->reg_base;
+ struct fsl_qspi_regs *regs = priv->regs;
u32 reg, mcr_reg, data, seqid;
- mcr_reg = qspi_read32(&regs->mcr);
- qspi_write32(&regs->mcr, QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK |
+ mcr_reg = qspi_read32(priv->flags, &regs->mcr);
+ qspi_write32(priv->flags, &regs->mcr,
+ QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK |
QSPI_MCR_RESERVED_MASK | QSPI_MCR_END_CFD_LE);
- qspi_write32(&regs->rbct, QSPI_RBCT_RXBRD_USEIPS);
+ qspi_write32(priv->flags, &regs->rbct, QSPI_RBCT_RXBRD_USEIPS);
- qspi_write32(&regs->sfar, qspi->amba_base);
+ qspi_write32(priv->flags, &regs->sfar, priv->cur_amba_base);
- if (qspi->cur_seqid == QSPI_CMD_BRRD)
+ if (priv->cur_seqid == QSPI_CMD_BRRD)
seqid = SEQID_BRRD;
else
seqid = SEQID_RDEAR;
- qspi_write32(&regs->ipcr, (seqid << QSPI_IPCR_SEQID_SHIFT) | len);
+ qspi_write32(priv->flags, &regs->ipcr,
+ (seqid << QSPI_IPCR_SEQID_SHIFT) | len);
/* Wait previous command complete */
- while (qspi_read32(&regs->sr) & QSPI_SR_BUSY_MASK)
+ while (qspi_read32(priv->flags, &regs->sr) & QSPI_SR_BUSY_MASK)
;
while (1) {
- reg = qspi_read32(&regs->rbsr);
+ reg = qspi_read32(priv->flags, &regs->rbsr);
if (reg & QSPI_RBSR_RDBFL_MASK) {
- data = qspi_read32(&regs->rbdr[0]);
+ data = qspi_read32(priv->flags, &regs->rbdr[0]);
data = qspi_endian_xchg(data);
memcpy(rxbuf, &data, len);
- qspi_write32(&regs->mcr, qspi_read32(&regs->mcr) |
+ qspi_write32(priv->flags, &regs->mcr,
+ qspi_read32(priv->flags, &regs->mcr) |
QSPI_MCR_CLR_RXF_MASK);
break;
}
}
- qspi_write32(&regs->mcr, mcr_reg);
+ qspi_write32(priv->flags, &regs->mcr, mcr_reg);
}
#endif
-static void qspi_op_rdid(struct fsl_qspi *qspi, u32 *rxbuf, u32 len)
+static void qspi_op_rdid(struct fsl_qspi_priv *priv, u32 *rxbuf, u32 len)
{
- struct fsl_qspi_regs *regs = (struct fsl_qspi_regs *)qspi->reg_base;
+ struct fsl_qspi_regs *regs = priv->regs;
u32 mcr_reg, rbsr_reg, data;
int i, size;
- mcr_reg = qspi_read32(&regs->mcr);
- qspi_write32(&regs->mcr, QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK |
- QSPI_MCR_RESERVED_MASK | QSPI_MCR_END_CFD_LE);
- qspi_write32(&regs->rbct, QSPI_RBCT_RXBRD_USEIPS);
+ mcr_reg = qspi_read32(priv->flags, &regs->mcr);
+ qspi_write32(priv->flags, &regs->mcr,
+ QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK |
+ QSPI_MCR_RESERVED_MASK | QSPI_MCR_END_CFD_LE);
+ qspi_write32(priv->flags, &regs->rbct, QSPI_RBCT_RXBRD_USEIPS);
- qspi_write32(&regs->sfar, qspi->amba_base);
+ qspi_write32(priv->flags, &regs->sfar, priv->cur_amba_base);
- qspi_write32(&regs->ipcr, (SEQID_RDID << QSPI_IPCR_SEQID_SHIFT) | 0);
- while (qspi_read32(&regs->sr) & QSPI_SR_BUSY_MASK)
+ qspi_write32(priv->flags, &regs->ipcr,
+ (SEQID_RDID << QSPI_IPCR_SEQID_SHIFT) | 0);
+ while (qspi_read32(priv->flags, &regs->sr) & QSPI_SR_BUSY_MASK)
;
i = 0;
size = len;
while ((RX_BUFFER_SIZE >= size) && (size > 0)) {
- rbsr_reg = qspi_read32(&regs->rbsr);
+ rbsr_reg = qspi_read32(priv->flags, &regs->rbsr);
if (rbsr_reg & QSPI_RBSR_RDBFL_MASK) {
- data = qspi_read32(&regs->rbdr[i]);
+ data = qspi_read32(priv->flags, &regs->rbdr[i]);
data = qspi_endian_xchg(data);
memcpy(rxbuf, &data, 4);
rxbuf++;
@@ -523,34 +506,36 @@ static void qspi_op_rdid(struct fsl_qspi *qspi, u32 *rxbuf, u32 len)
}
}
- qspi_write32(&regs->mcr, mcr_reg);
+ qspi_write32(priv->flags, &regs->mcr, mcr_reg);
}
#ifndef CONFIG_SYS_FSL_QSPI_AHB
/* If not use AHB read, read data from ip interface */
-static void qspi_op_read(struct fsl_qspi *qspi, u32 *rxbuf, u32 len)
+static void qspi_op_read(struct fsl_qspi_priv *priv, u32 *rxbuf, u32 len)
{
- struct fsl_qspi_regs *regs = (struct fsl_qspi_regs *)qspi->reg_base;
+ struct fsl_qspi_regs *regs = priv->regs;
u32 mcr_reg, data;
int i, size;
u32 to_or_from;
- mcr_reg = qspi_read32(&regs->mcr);
- qspi_write32(&regs->mcr, QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK |
- QSPI_MCR_RESERVED_MASK | QSPI_MCR_END_CFD_LE);
- qspi_write32(&regs->rbct, QSPI_RBCT_RXBRD_USEIPS);
+ mcr_reg = qspi_read32(priv->flags, &regs->mcr);
+ qspi_write32(priv->flags, &regs->mcr,
+ QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK |
+ QSPI_MCR_RESERVED_MASK | QSPI_MCR_END_CFD_LE);
+ qspi_write32(priv->flags, &regs->rbct, QSPI_RBCT_RXBRD_USEIPS);
- to_or_from = qspi->sf_addr + qspi->amba_base;
+ to_or_from = priv->sf_addr + priv->cur_amba_base;
while (len > 0) {
- qspi_write32(&regs->sfar, to_or_from);
+ qspi_write32(priv->flags, &regs->sfar, to_or_from);
size = (len > RX_BUFFER_SIZE) ?
RX_BUFFER_SIZE : len;
- qspi_write32(&regs->ipcr,
- (SEQID_FAST_READ << QSPI_IPCR_SEQID_SHIFT) | size);
- while (qspi_read32(&regs->sr) & QSPI_SR_BUSY_MASK)
+ qspi_write32(priv->flags, &regs->ipcr,
+ (SEQID_FAST_READ << QSPI_IPCR_SEQID_SHIFT) |
+ size);
+ while (qspi_read32(priv->flags, &regs->sr) & QSPI_SR_BUSY_MASK)
;
to_or_from += size;
@@ -558,66 +543,69 @@ static void qspi_op_read(struct fsl_qspi *qspi, u32 *rxbuf, u32 len)
i = 0;
while ((RX_BUFFER_SIZE >= size) && (size > 0)) {
- data = qspi_read32(&regs->rbdr[i]);
+ data = qspi_read32(priv->flags, &regs->rbdr[i]);
data = qspi_endian_xchg(data);
memcpy(rxbuf, &data, 4);
rxbuf++;
size -= 4;
i++;
}
- qspi_write32(&regs->mcr, qspi_read32(&regs->mcr) |
- QSPI_MCR_CLR_RXF_MASK);
+ qspi_write32(priv->flags, &regs->mcr,
+ qspi_read32(priv->flags, &regs->mcr) |
+ QSPI_MCR_CLR_RXF_MASK);
}
- qspi_write32(&regs->mcr, mcr_reg);
+ qspi_write32(priv->flags, &regs->mcr, mcr_reg);
}
#endif
-static void qspi_op_write(struct fsl_qspi *qspi, u8 *txbuf, u32 len)
+static void qspi_op_write(struct fsl_qspi_priv *priv, u8 *txbuf, u32 len)
{
- struct fsl_qspi_regs *regs = (struct fsl_qspi_regs *)qspi->reg_base;
+ struct fsl_qspi_regs *regs = priv->regs;
u32 mcr_reg, data, reg, status_reg, seqid;
int i, size, tx_size;
u32 to_or_from = 0;
- mcr_reg = qspi_read32(&regs->mcr);
- qspi_write32(&regs->mcr, QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK |
- QSPI_MCR_RESERVED_MASK | QSPI_MCR_END_CFD_LE);
- qspi_write32(&regs->rbct, QSPI_RBCT_RXBRD_USEIPS);
+ mcr_reg = qspi_read32(priv->flags, &regs->mcr);
+ qspi_write32(priv->flags, &regs->mcr,
+ QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK |
+ QSPI_MCR_RESERVED_MASK | QSPI_MCR_END_CFD_LE);
+ qspi_write32(priv->flags, &regs->rbct, QSPI_RBCT_RXBRD_USEIPS);
status_reg = 0;
while ((status_reg & FLASH_STATUS_WEL) != FLASH_STATUS_WEL) {
- qspi_write32(&regs->ipcr,
- (SEQID_WREN << QSPI_IPCR_SEQID_SHIFT) | 0);
- while (qspi_read32(&regs->sr) & QSPI_SR_BUSY_MASK)
+ qspi_write32(priv->flags, &regs->ipcr,
+ (SEQID_WREN << QSPI_IPCR_SEQID_SHIFT) | 0);
+ while (qspi_read32(priv->flags, &regs->sr) & QSPI_SR_BUSY_MASK)
;
- qspi_write32(&regs->ipcr,
- (SEQID_RDSR << QSPI_IPCR_SEQID_SHIFT) | 1);
- while (qspi_read32(&regs->sr) & QSPI_SR_BUSY_MASK)
+ qspi_write32(priv->flags, &regs->ipcr,
+ (SEQID_RDSR << QSPI_IPCR_SEQID_SHIFT) | 1);
+ while (qspi_read32(priv->flags, &regs->sr) & QSPI_SR_BUSY_MASK)
;
- reg = qspi_read32(&regs->rbsr);
+ reg = qspi_read32(priv->flags, &regs->rbsr);
if (reg & QSPI_RBSR_RDBFL_MASK) {
- status_reg = qspi_read32(&regs->rbdr[0]);
+ status_reg = qspi_read32(priv->flags, &regs->rbdr[0]);
status_reg = qspi_endian_xchg(status_reg);
}
- qspi_write32(&regs->mcr,
- qspi_read32(&regs->mcr) | QSPI_MCR_CLR_RXF_MASK);
+ qspi_write32(priv->flags, &regs->mcr,
+ qspi_read32(priv->flags, &regs->mcr) |
+ QSPI_MCR_CLR_RXF_MASK);
}
/* Default is page programming */
seqid = SEQID_PP;
#ifdef CONFIG_SPI_FLASH_BAR
- if (qspi->cur_seqid == QSPI_CMD_BRWR)
+ if (priv->cur_seqid == QSPI_CMD_BRWR)
seqid = SEQID_BRWR;
- else if (qspi->cur_seqid == QSPI_CMD_WREAR)
+ else if (priv->cur_seqid == QSPI_CMD_WREAR)
seqid = SEQID_WREAR;
#endif
- to_or_from = qspi->sf_addr + qspi->amba_base;
+ to_or_from = priv->sf_addr + priv->cur_amba_base;
- qspi_write32(&regs->sfar, to_or_from);
+ qspi_write32(priv->flags, &regs->sfar, to_or_from);
tx_size = (len > TX_BUFFER_SIZE) ?
TX_BUFFER_SIZE : len;
@@ -626,7 +614,7 @@ static void qspi_op_write(struct fsl_qspi *qspi, u8 *txbuf, u32 len)
for (i = 0; i < size; i++) {
memcpy(&data, txbuf, 4);
data = qspi_endian_xchg(data);
- qspi_write32(&regs->tbdr, data);
+ qspi_write32(priv->flags, &regs->tbdr, data);
txbuf += 4;
}
@@ -635,146 +623,273 @@ static void qspi_op_write(struct fsl_qspi *qspi, u8 *txbuf, u32 len)
data = 0;
memcpy(&data, txbuf, size);
data = qspi_endian_xchg(data);
- qspi_write32(&regs->tbdr, data);
+ qspi_write32(priv->flags, &regs->tbdr, data);
}
- qspi_write32(&regs->ipcr, (seqid << QSPI_IPCR_SEQID_SHIFT) | tx_size);
- while (qspi_read32(&regs->sr) & QSPI_SR_BUSY_MASK)
+ qspi_write32(priv->flags, &regs->ipcr,
+ (seqid << QSPI_IPCR_SEQID_SHIFT) | tx_size);
+ while (qspi_read32(priv->flags, &regs->sr) & QSPI_SR_BUSY_MASK)
;
- qspi_write32(&regs->mcr, mcr_reg);
+ qspi_write32(priv->flags, &regs->mcr, mcr_reg);
}
-static void qspi_op_rdsr(struct fsl_qspi *qspi, u32 *rxbuf)
+static void qspi_op_rdsr(struct fsl_qspi_priv *priv, u32 *rxbuf)
{
- struct fsl_qspi_regs *regs = (struct fsl_qspi_regs *)qspi->reg_base;
+ struct fsl_qspi_regs *regs = priv->regs;
u32 mcr_reg, reg, data;
- mcr_reg = qspi_read32(&regs->mcr);
- qspi_write32(&regs->mcr, QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK |
- QSPI_MCR_RESERVED_MASK | QSPI_MCR_END_CFD_LE);
- qspi_write32(&regs->rbct, QSPI_RBCT_RXBRD_USEIPS);
+ mcr_reg = qspi_read32(priv->flags, &regs->mcr);
+ qspi_write32(priv->flags, &regs->mcr,
+ QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK |
+ QSPI_MCR_RESERVED_MASK | QSPI_MCR_END_CFD_LE);
+ qspi_write32(priv->flags, &regs->rbct, QSPI_RBCT_RXBRD_USEIPS);
- qspi_write32(&regs->sfar, qspi->amba_base);
+ qspi_write32(priv->flags, &regs->sfar, priv->cur_amba_base);
- qspi_write32(&regs->ipcr,
- (SEQID_RDSR << QSPI_IPCR_SEQID_SHIFT) | 0);
- while (qspi_read32(&regs->sr) & QSPI_SR_BUSY_MASK)
+ qspi_write32(priv->flags, &regs->ipcr,
+ (SEQID_RDSR << QSPI_IPCR_SEQID_SHIFT) | 0);
+ while (qspi_read32(priv->flags, &regs->sr) & QSPI_SR_BUSY_MASK)
;
while (1) {
- reg = qspi_read32(&regs->rbsr);
+ reg = qspi_read32(priv->flags, &regs->rbsr);
if (reg & QSPI_RBSR_RDBFL_MASK) {
- data = qspi_read32(&regs->rbdr[0]);
+ data = qspi_read32(priv->flags, &regs->rbdr[0]);
data = qspi_endian_xchg(data);
memcpy(rxbuf, &data, 4);
- qspi_write32(&regs->mcr, qspi_read32(&regs->mcr) |
- QSPI_MCR_CLR_RXF_MASK);
+ qspi_write32(priv->flags, &regs->mcr,
+ qspi_read32(priv->flags, &regs->mcr) |
+ QSPI_MCR_CLR_RXF_MASK);
break;
}
}
- qspi_write32(&regs->mcr, mcr_reg);
+ qspi_write32(priv->flags, &regs->mcr, mcr_reg);
}
-static void qspi_op_erase(struct fsl_qspi *qspi)
+static void qspi_op_erase(struct fsl_qspi_priv *priv)
{
- struct fsl_qspi_regs *regs = (struct fsl_qspi_regs *)qspi->reg_base;
+ struct fsl_qspi_regs *regs = priv->regs;
u32 mcr_reg;
u32 to_or_from = 0;
- mcr_reg = qspi_read32(&regs->mcr);
- qspi_write32(&regs->mcr, QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK |
- QSPI_MCR_RESERVED_MASK | QSPI_MCR_END_CFD_LE);
- qspi_write32(&regs->rbct, QSPI_RBCT_RXBRD_USEIPS);
+ mcr_reg = qspi_read32(priv->flags, &regs->mcr);
+ qspi_write32(priv->flags, &regs->mcr,
+ QSPI_MCR_CLR_RXF_MASK | QSPI_MCR_CLR_TXF_MASK |
+ QSPI_MCR_RESERVED_MASK | QSPI_MCR_END_CFD_LE);
+ qspi_write32(priv->flags, &regs->rbct, QSPI_RBCT_RXBRD_USEIPS);
- to_or_from = qspi->sf_addr + qspi->amba_base;
- qspi_write32(&regs->sfar, to_or_from);
+ to_or_from = priv->sf_addr + priv->cur_amba_base;
+ qspi_write32(priv->flags, &regs->sfar, to_or_from);
- qspi_write32(&regs->ipcr,
- (SEQID_WREN << QSPI_IPCR_SEQID_SHIFT) | 0);
- while (qspi_read32(&regs->sr) & QSPI_SR_BUSY_MASK)
+ qspi_write32(priv->flags, &regs->ipcr,
+ (SEQID_WREN << QSPI_IPCR_SEQID_SHIFT) | 0);
+ while (qspi_read32(priv->flags, &regs->sr) & QSPI_SR_BUSY_MASK)
;
- if (qspi->cur_seqid == QSPI_CMD_SE) {
- qspi_write32(&regs->ipcr,
+ if (priv->cur_seqid == QSPI_CMD_SE) {
+ qspi_write32(priv->flags, &regs->ipcr,
(SEQID_SE << QSPI_IPCR_SEQID_SHIFT) | 0);
- } else if (qspi->cur_seqid == QSPI_CMD_BE_4K) {
- qspi_write32(&regs->ipcr,
+ } else if (priv->cur_seqid == QSPI_CMD_BE_4K) {
+ qspi_write32(priv->flags, &regs->ipcr,
(SEQID_BE_4K << QSPI_IPCR_SEQID_SHIFT) | 0);
}
- while (qspi_read32(&regs->sr) & QSPI_SR_BUSY_MASK)
+ while (qspi_read32(priv->flags, &regs->sr) & QSPI_SR_BUSY_MASK)
;
- qspi_write32(&regs->mcr, mcr_reg);
+ qspi_write32(priv->flags, &regs->mcr, mcr_reg);
}
-int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
+int qspi_xfer(struct fsl_qspi_priv *priv, unsigned int bitlen,
const void *dout, void *din, unsigned long flags)
{
- struct fsl_qspi *qspi = to_qspi_spi(slave);
u32 bytes = DIV_ROUND_UP(bitlen, 8);
static u32 wr_sfaddr;
u32 txbuf;
if (dout) {
if (flags & SPI_XFER_BEGIN) {
- qspi->cur_seqid = *(u8 *)dout;
+ priv->cur_seqid = *(u8 *)dout;
memcpy(&txbuf, dout, 4);
}
if (flags == SPI_XFER_END) {
- qspi->sf_addr = wr_sfaddr;
- qspi_op_write(qspi, (u8 *)dout, bytes);
+ priv->sf_addr = wr_sfaddr;
+ qspi_op_write(priv, (u8 *)dout, bytes);
return 0;
}
- if (qspi->cur_seqid == QSPI_CMD_FAST_READ) {
- qspi->sf_addr = swab32(txbuf) & OFFSET_BITS_MASK;
- } else if ((qspi->cur_seqid == QSPI_CMD_SE) ||
- (qspi->cur_seqid == QSPI_CMD_BE_4K)) {
- qspi->sf_addr = swab32(txbuf) & OFFSET_BITS_MASK;
- qspi_op_erase(qspi);
- } else if (qspi->cur_seqid == QSPI_CMD_PP)
+ if (priv->cur_seqid == QSPI_CMD_FAST_READ) {
+ priv->sf_addr = swab32(txbuf) & OFFSET_BITS_MASK;
+ } else if ((priv->cur_seqid == QSPI_CMD_SE) ||
+ (priv->cur_seqid == QSPI_CMD_BE_4K)) {
+ priv->sf_addr = swab32(txbuf) & OFFSET_BITS_MASK;
+ qspi_op_erase(priv);
+ } else if (priv->cur_seqid == QSPI_CMD_PP) {
wr_sfaddr = swab32(txbuf) & OFFSET_BITS_MASK;
+ } else if ((priv->cur_seqid == QSPI_CMD_BRWR) ||
+ (priv->cur_seqid == QSPI_CMD_WREAR)) {
#ifdef CONFIG_SPI_FLASH_BAR
- else if ((qspi->cur_seqid == QSPI_CMD_BRWR) ||
- (qspi->cur_seqid == QSPI_CMD_WREAR)) {
wr_sfaddr = 0;
- }
#endif
+ }
}
if (din) {
- if (qspi->cur_seqid == QSPI_CMD_FAST_READ) {
+ if (priv->cur_seqid == QSPI_CMD_FAST_READ) {
#ifdef CONFIG_SYS_FSL_QSPI_AHB
- qspi_ahb_read(qspi, din, bytes);
+ qspi_ahb_read(priv, din, bytes);
#else
- qspi_op_read(qspi, din, bytes);
+ qspi_op_read(priv, din, bytes);
#endif
- }
- else if (qspi->cur_seqid == QSPI_CMD_RDID)
- qspi_op_rdid(qspi, din, bytes);
- else if (qspi->cur_seqid == QSPI_CMD_RDSR)
- qspi_op_rdsr(qspi, din);
+ } else if (priv->cur_seqid == QSPI_CMD_RDID)
+ qspi_op_rdid(priv, din, bytes);
+ else if (priv->cur_seqid == QSPI_CMD_RDSR)
+ qspi_op_rdsr(priv, din);
#ifdef CONFIG_SPI_FLASH_BAR
- else if ((qspi->cur_seqid == QSPI_CMD_BRRD) ||
- (qspi->cur_seqid == QSPI_CMD_RDEAR)) {
- qspi->sf_addr = 0;
- qspi_op_rdbank(qspi, din, bytes);
+ else if ((priv->cur_seqid == QSPI_CMD_BRRD) ||
+ (priv->cur_seqid == QSPI_CMD_RDEAR)) {
+ priv->sf_addr = 0;
+ qspi_op_rdbank(priv, din, bytes);
}
#endif
}
#ifdef CONFIG_SYS_FSL_QSPI_AHB
- if ((qspi->cur_seqid == QSPI_CMD_SE) ||
- (qspi->cur_seqid == QSPI_CMD_PP) ||
- (qspi->cur_seqid == QSPI_CMD_BE_4K) ||
- (qspi->cur_seqid == QSPI_CMD_WREAR) ||
- (qspi->cur_seqid == QSPI_CMD_BRWR))
- qspi_ahb_invalid(qspi);
+ if ((priv->cur_seqid == QSPI_CMD_SE) ||
+ (priv->cur_seqid == QSPI_CMD_PP) ||
+ (priv->cur_seqid == QSPI_CMD_BE_4K) ||
+ (priv->cur_seqid == QSPI_CMD_WREAR) ||
+ (priv->cur_seqid == QSPI_CMD_BRWR))
+ qspi_ahb_invalid(priv);
+#endif
+
+ return 0;
+}
+
+void qspi_module_disable(struct fsl_qspi_priv *priv, u8 disable)
+{
+ u32 mcr_val;
+
+ mcr_val = qspi_read32(priv->flags, &priv->regs->mcr);
+ if (disable)
+ mcr_val |= QSPI_MCR_MDIS_MASK;
+ else
+ mcr_val &= ~QSPI_MCR_MDIS_MASK;
+ qspi_write32(priv->flags, &priv->regs->mcr, mcr_val);
+}
+
+void qspi_cfg_smpr(struct fsl_qspi_priv *priv, u32 clear_bits, u32 set_bits)
+{
+ u32 smpr_val;
+
+ smpr_val = qspi_read32(priv->flags, &priv->regs->smpr);
+ smpr_val &= ~clear_bits;
+ smpr_val |= set_bits;
+ qspi_write32(priv->flags, &priv->regs->smpr, smpr_val);
+}
+#ifndef CONFIG_DM_SPI
+static unsigned long spi_bases[] = {
+ QSPI0_BASE_ADDR,
+#ifdef CONFIG_MX6SX
+ QSPI1_BASE_ADDR,
+#endif
+};
+
+static unsigned long amba_bases[] = {
+ QSPI0_AMBA_BASE,
+#ifdef CONFIG_MX6SX
+ QSPI1_AMBA_BASE,
+#endif
+};
+
+static inline struct fsl_qspi *to_qspi_spi(struct spi_slave *slave)
+{
+ return container_of(slave, struct fsl_qspi, slave);
+}
+
+struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
+ unsigned int max_hz, unsigned int mode)
+{
+ struct fsl_qspi *qspi;
+ struct fsl_qspi_regs *regs;
+ u32 total_size;
+
+ if (bus >= ARRAY_SIZE(spi_bases))
+ return NULL;
+
+ if (cs >= FSL_QSPI_FLASH_NUM)
+ return NULL;
+
+ qspi = spi_alloc_slave(struct fsl_qspi, bus, cs);
+ if (!qspi)
+ return NULL;
+
+#ifdef CONFIG_SYS_FSL_QSPI_BE
+ qspi->priv.flags |= QSPI_FLAG_REGMAP_ENDIAN_BIG;
+#endif
+
+ regs = (struct fsl_qspi_regs *)spi_bases[bus];
+ qspi->priv.regs = regs;
+ /*
+ * According cs, use different amba_base to choose the
+ * corresponding flash devices.
+ *
+ * If not, only one flash device is used even if passing
+ * different cs using `sf probe`
+ */
+ qspi->priv.cur_amba_base = amba_bases[bus] + cs * FSL_QSPI_FLASH_SIZE;
+
+ qspi->slave.max_write_size = TX_BUFFER_SIZE;
+
+ qspi_write32(qspi->priv.flags, &regs->mcr,
+ QSPI_MCR_RESERVED_MASK | QSPI_MCR_MDIS_MASK);
+
+ qspi_cfg_smpr(&qspi->priv,
+ ~(QSPI_SMPR_FSDLY_MASK | QSPI_SMPR_DDRSMP_MASK |
+ QSPI_SMPR_FSPHS_MASK | QSPI_SMPR_HSENA_MASK), 0);
+
+ total_size = FSL_QSPI_FLASH_SIZE * FSL_QSPI_FLASH_NUM;
+ /*
+ * Any read access to non-implemented addresses will provide
+ * undefined results.
+ *
+ * In case single die flash devices, TOP_ADDR_MEMA2 and
+ * TOP_ADDR_MEMB2 should be initialized/programmed to
+ * TOP_ADDR_MEMA1 and TOP_ADDR_MEMB1 respectively - in effect,
+ * setting the size of these devices to 0. This would ensure
+ * that the complete memory map is assigned to only one flash device.
+ */
+ qspi_write32(qspi->priv.flags, &regs->sfa1ad,
+ FSL_QSPI_FLASH_SIZE | amba_bases[bus]);
+ qspi_write32(qspi->priv.flags, &regs->sfa2ad,
+ FSL_QSPI_FLASH_SIZE | amba_bases[bus]);
+ qspi_write32(qspi->priv.flags, &regs->sfb1ad,
+ total_size | amba_bases[bus]);
+ qspi_write32(qspi->priv.flags, &regs->sfb2ad,
+ total_size | amba_bases[bus]);
+
+ qspi_set_lut(&qspi->priv);
+
+#ifdef CONFIG_SYS_FSL_QSPI_AHB
+ qspi_init_ahb_read(&qspi->priv);
#endif
+ qspi_module_disable(&qspi->priv, 0);
+
+ return &qspi->slave;
+}
+
+void spi_free_slave(struct spi_slave *slave)
+{
+ struct fsl_qspi *qspi = to_qspi_spi(slave);
+
+ free(qspi);
+}
+
+int spi_claim_bus(struct spi_slave *slave)
+{
return 0;
}
@@ -782,3 +897,215 @@ void spi_release_bus(struct spi_slave *slave)
{
/* Nothing to do */
}
+
+int spi_xfer(struct spi_slave *slave, unsigned int bitlen,
+ const void *dout, void *din, unsigned long flags)
+{
+ struct fsl_qspi *qspi = to_qspi_spi(slave);
+
+ return qspi_xfer(&qspi->priv, bitlen, dout, din, flags);
+}
+
+void spi_init(void)
+{
+ /* Nothing to do */
+}
+#else
+static int fsl_qspi_child_pre_probe(struct udevice *dev)
+{
+ struct spi_slave *slave = dev_get_parentdata(dev);
+
+ slave->max_write_size = TX_BUFFER_SIZE;
+
+ return 0;
+}
+
+static int fsl_qspi_probe(struct udevice *bus)
+{
+ u32 total_size;
+ struct fsl_qspi_platdata *plat = dev_get_platdata(bus);
+ struct fsl_qspi_priv *priv = dev_get_priv(bus);
+ struct dm_spi_bus *dm_spi_bus;
+
+ dm_spi_bus = bus->uclass_priv;
+
+ dm_spi_bus->max_hz = plat->speed_hz;
+
+ priv->regs = (struct fsl_qspi_regs *)plat->reg_base;
+ priv->flags = plat->flags;
+
+ priv->speed_hz = plat->speed_hz;
+ priv->amba_base[0] = plat->amba_base;
+ priv->amba_total_size = plat->amba_total_size;
+ priv->flash_num = plat->flash_num;
+ priv->num_chipselect = plat->num_chipselect;
+
+ qspi_write32(priv->flags, &priv->regs->mcr,
+ QSPI_MCR_RESERVED_MASK | QSPI_MCR_MDIS_MASK);
+
+ qspi_cfg_smpr(priv, ~(QSPI_SMPR_FSDLY_MASK | QSPI_SMPR_DDRSMP_MASK |
+ QSPI_SMPR_FSPHS_MASK | QSPI_SMPR_HSENA_MASK), 0);
+
+ total_size = FSL_QSPI_FLASH_SIZE * FSL_QSPI_FLASH_NUM;
+ /*
+ * Any read access to non-implemented addresses will provide
+ * undefined results.
+ *
+ * In case single die flash devices, TOP_ADDR_MEMA2 and
+ * TOP_ADDR_MEMB2 should be initialized/programmed to
+ * TOP_ADDR_MEMA1 and TOP_ADDR_MEMB1 respectively - in effect,
+ * setting the size of these devices to 0. This would ensure
+ * that the complete memory map is assigned to only one flash device.
+ */
+ qspi_write32(priv->flags, &priv->regs->sfa1ad,
+ FSL_QSPI_FLASH_SIZE | priv->amba_base[0]);
+ qspi_write32(priv->flags, &priv->regs->sfa2ad,
+ FSL_QSPI_FLASH_SIZE | priv->amba_base[0]);
+ qspi_write32(priv->flags, &priv->regs->sfb1ad,
+ total_size | priv->amba_base[0]);
+ qspi_write32(priv->flags, &priv->regs->sfb2ad,
+ total_size | priv->amba_base[0]);
+
+ qspi_set_lut(priv);
+
+#ifdef CONFIG_SYS_FSL_QSPI_AHB
+ qspi_init_ahb_read(priv);
+#endif
+
+ qspi_module_disable(priv, 0);
+
+ return 0;
+}
+
+static int fsl_qspi_ofdata_to_platdata(struct udevice *bus)
+{
+ struct reg_data {
+ u32 addr;
+ u32 size;
+ } regs_data[2];
+ struct fsl_qspi_platdata *plat = bus->platdata;
+ const void *blob = gd->fdt_blob;
+ int node = bus->of_offset;
+ int ret, flash_num = 0, subnode;
+
+ if (fdtdec_get_bool(blob, node, "big-endian"))
+ plat->flags |= QSPI_FLAG_REGMAP_ENDIAN_BIG;
+
+ ret = fdtdec_get_int_array(blob, node, "reg", (u32 *)regs_data,
+ sizeof(regs_data)/sizeof(u32));
+ if (ret) {
+ debug("Error: can't get base addresses (ret = %d)!\n", ret);
+ return -ENOMEM;
+ }
+
+ /* Count flash numbers */
+ fdt_for_each_subnode(blob, subnode, node)
+ ++flash_num;
+
+ if (flash_num == 0) {
+ debug("Error: Missing flashes!\n");
+ return -ENODEV;
+ }
+
+ plat->speed_hz = fdtdec_get_int(blob, node, "spi-max-frequency",
+ FSL_QSPI_DEFAULT_SCK_FREQ);
+ plat->num_chipselect = fdtdec_get_int(blob, node, "num-cs",
+ FSL_QSPI_MAX_CHIPSELECT_NUM);
+
+ plat->reg_base = regs_data[0].addr;
+ plat->amba_base = regs_data[1].addr;
+ plat->amba_total_size = regs_data[1].size;
+ plat->flash_num = flash_num;
+
+ debug("%s: regs=<0x%x> <0x%x, 0x%x>, max-frequency=%d, endianess=%s\n",
+ __func__,
+ plat->reg_base,
+ plat->amba_base,
+ plat->amba_total_size,
+ plat->speed_hz,
+ plat->flags & QSPI_FLAG_REGMAP_ENDIAN_BIG ? "be" : "le"
+ );
+
+ return 0;
+}
+
+static int fsl_qspi_xfer(struct udevice *dev, unsigned int bitlen,
+ const void *dout, void *din, unsigned long flags)
+{
+ struct fsl_qspi_priv *priv;
+ struct udevice *bus;
+
+ bus = dev->parent;
+ priv = dev_get_priv(bus);
+
+ return qspi_xfer(priv, bitlen, dout, din, flags);
+}
+
+static int fsl_qspi_claim_bus(struct udevice *dev)
+{
+ struct fsl_qspi_priv *priv;
+ struct udevice *bus;
+ struct dm_spi_slave_platdata *slave_plat = dev_get_parent_platdata(dev);
+
+ bus = dev->parent;
+ priv = dev_get_priv(bus);
+
+ priv->cur_amba_base =
+ priv->amba_base[0] + FSL_QSPI_FLASH_SIZE * slave_plat->cs;
+
+ qspi_module_disable(priv, 0);
+
+ return 0;
+}
+
+static int fsl_qspi_release_bus(struct udevice *dev)
+{
+ struct fsl_qspi_priv *priv;
+ struct udevice *bus;
+
+ bus = dev->parent;
+ priv = dev_get_priv(bus);
+
+ qspi_module_disable(priv, 1);
+
+ return 0;
+}
+
+static int fsl_qspi_set_speed(struct udevice *bus, uint speed)
+{
+ /* Nothing to do */
+ return 0;
+}
+
+static int fsl_qspi_set_mode(struct udevice *bus, uint mode)
+{
+ /* Nothing to do */
+ return 0;
+}
+
+static const struct dm_spi_ops fsl_qspi_ops = {
+ .claim_bus = fsl_qspi_claim_bus,
+ .release_bus = fsl_qspi_release_bus,
+ .xfer = fsl_qspi_xfer,
+ .set_speed = fsl_qspi_set_speed,
+ .set_mode = fsl_qspi_set_mode,
+};
+
+static const struct udevice_id fsl_qspi_ids[] = {
+ { .compatible = "fsl,vf610-qspi" },
+ { .compatible = "fsl,imx6sx-qspi" },
+ { }
+};
+
+U_BOOT_DRIVER(fsl_qspi) = {
+ .name = "fsl_qspi",
+ .id = UCLASS_SPI,
+ .of_match = fsl_qspi_ids,
+ .ops = &fsl_qspi_ops,
+ .ofdata_to_platdata = fsl_qspi_ofdata_to_platdata,
+ .platdata_auto_alloc_size = sizeof(struct fsl_qspi_platdata),
+ .priv_auto_alloc_size = sizeof(struct fsl_qspi_priv),
+ .probe = fsl_qspi_probe,
+ .child_pre_probe = fsl_qspi_child_pre_probe,
+};
+#endif
diff --git a/drivers/spi/ich.c b/drivers/spi/ich.c
index 194e882302..50354fdde1 100644
--- a/drivers/spi/ich.c
+++ b/drivers/spi/ich.c
@@ -7,6 +7,7 @@
*/
#include <common.h>
+#include <dm.h>
#include <errno.h>
#include <malloc.h>
#include <spi.h>
@@ -19,154 +20,99 @@
#define SPI_OPCODE_WREN 0x06
#define SPI_OPCODE_FAST_READ 0x0b
-struct ich_ctlr {
+struct ich_spi_platdata {
pci_dev_t dev; /* PCI device number */
int ich_version; /* Controller version, 7 or 9 */
bool use_sbase; /* Use SBASE instead of RCB */
+};
+
+struct ich_spi_priv {
int ichspi_lock;
int locked;
- uint8_t *opmenu;
+ int opmenu;
int menubytes;
void *base; /* Base of register set */
- uint16_t *preop;
- uint16_t *optype;
- uint32_t *addr;
- uint8_t *data;
+ int preop;
+ int optype;
+ int addr;
+ int data;
unsigned databytes;
- uint8_t *status;
- uint16_t *control;
- uint32_t *bbar;
+ int status;
+ int control;
+ int bbar;
uint32_t *pr; /* only for ich9 */
- uint8_t *speed; /* pointer to speed control */
+ int speed; /* pointer to speed control */
ulong max_speed; /* Maximum bus speed in MHz */
+ ulong cur_speed; /* Current bus speed */
+ struct spi_trans trans; /* current transaction in progress */
};
-struct ich_ctlr ctlr;
-
-static inline struct ich_spi_slave *to_ich_spi(struct spi_slave *slave)
-{
- return container_of(slave, struct ich_spi_slave, slave);
-}
-
-static unsigned int ich_reg(const void *addr)
-{
- return (unsigned)(addr - ctlr.base) & 0xffff;
-}
-
-static u8 ich_readb(const void *addr)
+static u8 ich_readb(struct ich_spi_priv *priv, int reg)
{
- u8 value = readb(addr);
+ u8 value = readb(priv->base + reg);
- debug("read %2.2x from %4.4x\n", value, ich_reg(addr));
+ debug("read %2.2x from %4.4x\n", value, reg);
return value;
}
-static u16 ich_readw(const void *addr)
+static u16 ich_readw(struct ich_spi_priv *priv, int reg)
{
- u16 value = readw(addr);
+ u16 value = readw(priv->base + reg);
- debug("read %4.4x from %4.4x\n", value, ich_reg(addr));
+ debug("read %4.4x from %4.4x\n", value, reg);
return value;
}
-static u32 ich_readl(const void *addr)
+static u32 ich_readl(struct ich_spi_priv *priv, int reg)
{
- u32 value = readl(addr);
+ u32 value = readl(priv->base + reg);
- debug("read %8.8x from %4.4x\n", value, ich_reg(addr));
+ debug("read %8.8x from %4.4x\n", value, reg);
return value;
}
-static void ich_writeb(u8 value, void *addr)
+static void ich_writeb(struct ich_spi_priv *priv, u8 value, int reg)
{
- writeb(value, addr);
- debug("wrote %2.2x to %4.4x\n", value, ich_reg(addr));
+ writeb(value, priv->base + reg);
+ debug("wrote %2.2x to %4.4x\n", value, reg);
}
-static void ich_writew(u16 value, void *addr)
+static void ich_writew(struct ich_spi_priv *priv, u16 value, int reg)
{
- writew(value, addr);
- debug("wrote %4.4x to %4.4x\n", value, ich_reg(addr));
+ writew(value, priv->base + reg);
+ debug("wrote %4.4x to %4.4x\n", value, reg);
}
-static void ich_writel(u32 value, void *addr)
+static void ich_writel(struct ich_spi_priv *priv, u32 value, int reg)
{
- writel(value, addr);
- debug("wrote %8.8x to %4.4x\n", value, ich_reg(addr));
+ writel(value, priv->base + reg);
+ debug("wrote %8.8x to %4.4x\n", value, reg);
}
-static void write_reg(const void *value, void *dest, uint32_t size)
+static void write_reg(struct ich_spi_priv *priv, const void *value,
+ int dest_reg, uint32_t size)
{
- memcpy_toio(dest, value, size);
+ memcpy_toio(priv->base + dest_reg, value, size);
}
-static void read_reg(const void *src, void *value, uint32_t size)
+static void read_reg(struct ich_spi_priv *priv, int src_reg, void *value,
+ uint32_t size)
{
- memcpy_fromio(value, src, size);
+ memcpy_fromio(value, priv->base + src_reg, size);
}
-static void ich_set_bbar(struct ich_ctlr *ctlr, uint32_t minaddr)
+static void ich_set_bbar(struct ich_spi_priv *ctlr, uint32_t minaddr)
{
const uint32_t bbar_mask = 0x00ffff00;
uint32_t ichspi_bbar;
minaddr &= bbar_mask;
- ichspi_bbar = ich_readl(ctlr->bbar) & ~bbar_mask;
+ ichspi_bbar = ich_readl(ctlr, ctlr->bbar) & ~bbar_mask;
ichspi_bbar |= minaddr;
- ich_writel(ichspi_bbar, ctlr->bbar);
-}
-
-int spi_cs_is_valid(unsigned int bus, unsigned int cs)
-{
- puts("spi_cs_is_valid used but not implemented\n");
- return 0;
-}
-
-struct spi_slave *spi_setup_slave(unsigned int bus, unsigned int cs,
- unsigned int max_hz, unsigned int mode)
-{
- struct ich_spi_slave *ich;
-
- ich = spi_alloc_slave(struct ich_spi_slave, bus, cs);
- if (!ich) {
- puts("ICH SPI: Out of memory\n");
- return NULL;
- }
-
- /*
- * Yes this controller can only write a small number of bytes at
- * once! The limit is typically 64 bytes.
- */
- ich->slave.max_write_size = ctlr.databytes;
- ich->speed = max_hz;
-
- /*
- * ICH 7 SPI controller only supports array read command
- * and byte program command for SST flash
- */
- if (ctlr.ich_version == 7 || ctlr.use_sbase) {
- ich->slave.op_mode_rx = SPI_OPM_RX_AS;
- ich->slave.op_mode_tx = SPI_OPM_TX_BP;
- }
-
- return &ich->slave;
-}
-
-struct spi_slave *spi_setup_slave_fdt(const void *blob, int slave_node,
- int spi_node)
-{
- /* We only support a single SPI at present */
- return spi_setup_slave(0, 0, 20000000, 0);
-}
-
-void spi_free_slave(struct spi_slave *slave)
-{
- struct ich_spi_slave *ich = to_ich_spi(slave);
-
- free(ich);
+ ich_writel(ctlr, ichspi_bbar, ctlr->bbar);
}
/*
@@ -185,7 +131,8 @@ static int get_ich_version(uint16_t device_id)
device_id <= PCI_DEVICE_ID_INTEL_COUGARPOINT_LPC_MAX) ||
(device_id >= PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MIN &&
device_id <= PCI_DEVICE_ID_INTEL_PANTHERPOINT_LPC_MAX) ||
- device_id == PCI_DEVICE_ID_INTEL_VALLEYVIEW_LPC)
+ device_id == PCI_DEVICE_ID_INTEL_VALLEYVIEW_LPC ||
+ device_id == PCI_DEVICE_ID_INTEL_LYNXPOINT_LPC)
return 9;
return 0;
@@ -208,7 +155,7 @@ static int ich9_can_do_33mhz(pci_dev_t dev)
return speed == 1;
}
-static int ich_find_spi_controller(struct ich_ctlr *ich)
+static int ich_find_spi_controller(struct ich_spi_platdata *ich)
{
int last_bus = pci_last_busno();
int bus;
@@ -241,131 +188,77 @@ static int ich_find_spi_controller(struct ich_ctlr *ich)
return -ENODEV;
}
-static int ich_init_controller(struct ich_ctlr *ctlr)
+static int ich_init_controller(struct ich_spi_platdata *plat,
+ struct ich_spi_priv *ctlr)
{
uint8_t *rcrb; /* Root Complex Register Block */
uint32_t rcba; /* Root Complex Base Address */
uint32_t sbase_addr;
uint8_t *sbase;
- pci_read_config_dword(ctlr->dev, 0xf0, &rcba);
+ pci_read_config_dword(plat->dev, 0xf0, &rcba);
/* Bits 31-14 are the base address, 13-1 are reserved, 0 is enable. */
rcrb = (uint8_t *)(rcba & 0xffffc000);
/* SBASE is similar */
- pci_read_config_dword(ctlr->dev, 0x54, &sbase_addr);
+ pci_read_config_dword(plat->dev, 0x54, &sbase_addr);
sbase = (uint8_t *)(sbase_addr & 0xfffffe00);
- if (ctlr->ich_version == 7) {
+ if (plat->ich_version == 7) {
struct ich7_spi_regs *ich7_spi;
ich7_spi = (struct ich7_spi_regs *)(rcrb + 0x3020);
- ctlr->ichspi_lock = ich_readw(&ich7_spi->spis) & SPIS_LOCK;
- ctlr->opmenu = ich7_spi->opmenu;
+ ctlr->ichspi_lock = readw(&ich7_spi->spis) & SPIS_LOCK;
+ ctlr->opmenu = offsetof(struct ich7_spi_regs, opmenu);
ctlr->menubytes = sizeof(ich7_spi->opmenu);
- ctlr->optype = &ich7_spi->optype;
- ctlr->addr = &ich7_spi->spia;
- ctlr->data = (uint8_t *)ich7_spi->spid;
+ ctlr->optype = offsetof(struct ich7_spi_regs, optype);
+ ctlr->addr = offsetof(struct ich7_spi_regs, spia);
+ ctlr->data = offsetof(struct ich7_spi_regs, spid);
ctlr->databytes = sizeof(ich7_spi->spid);
- ctlr->status = (uint8_t *)&ich7_spi->spis;
- ctlr->control = &ich7_spi->spic;
- ctlr->bbar = &ich7_spi->bbar;
- ctlr->preop = &ich7_spi->preop;
+ ctlr->status = offsetof(struct ich7_spi_regs, spis);
+ ctlr->control = offsetof(struct ich7_spi_regs, spic);
+ ctlr->bbar = offsetof(struct ich7_spi_regs, bbar);
+ ctlr->preop = offsetof(struct ich7_spi_regs, preop);
ctlr->base = ich7_spi;
- } else if (ctlr->ich_version == 9) {
+ } else if (plat->ich_version == 9) {
struct ich9_spi_regs *ich9_spi;
- if (ctlr->use_sbase)
+ if (plat->use_sbase)
ich9_spi = (struct ich9_spi_regs *)sbase;
else
ich9_spi = (struct ich9_spi_regs *)(rcrb + 0x3800);
- ctlr->ichspi_lock = ich_readw(&ich9_spi->hsfs) & HSFS_FLOCKDN;
- ctlr->opmenu = ich9_spi->opmenu;
+ ctlr->ichspi_lock = readw(&ich9_spi->hsfs) & HSFS_FLOCKDN;
+ ctlr->opmenu = offsetof(struct ich9_spi_regs, opmenu);
ctlr->menubytes = sizeof(ich9_spi->opmenu);
- ctlr->optype = &ich9_spi->optype;
- ctlr->addr = &ich9_spi->faddr;
- ctlr->data = (uint8_t *)ich9_spi->fdata;
+ ctlr->optype = offsetof(struct ich9_spi_regs, optype);
+ ctlr->addr = offsetof(struct ich9_spi_regs, faddr);
+ ctlr->data = offsetof(struct ich9_spi_regs, fdata);
ctlr->databytes = sizeof(ich9_spi->fdata);
- ctlr->status = &ich9_spi->ssfs;
- ctlr->control = (uint16_t *)ich9_spi->ssfc;
- ctlr->speed = ich9_spi->ssfc + 2;
- ctlr->bbar = &ich9_spi->bbar;
- ctlr->preop = &ich9_spi->preop;
+ ctlr->status = offsetof(struct ich9_spi_regs, ssfs);
+ ctlr->control = offsetof(struct ich9_spi_regs, ssfc);
+ ctlr->speed = ctlr->control + 2;
+ ctlr->bbar = offsetof(struct ich9_spi_regs, bbar);
+ ctlr->preop = offsetof(struct ich9_spi_regs, preop);
ctlr->pr = &ich9_spi->pr[0];
ctlr->base = ich9_spi;
} else {
- debug("ICH SPI: Unrecognized ICH version %d.\n",
- ctlr->ich_version);
- return -1;
+ debug("ICH SPI: Unrecognised ICH version %d\n",
+ plat->ich_version);
+ return -EINVAL;
}
/* Work out the maximum speed we can support */
ctlr->max_speed = 20000000;
- if (ctlr->ich_version == 9 && ich9_can_do_33mhz(ctlr->dev))
+ if (plat->ich_version == 9 && ich9_can_do_33mhz(plat->dev))
ctlr->max_speed = 33000000;
debug("ICH SPI: Version %d detected at %p, speed %ld\n",
- ctlr->ich_version, ctlr->base, ctlr->max_speed);
+ plat->ich_version, ctlr->base, ctlr->max_speed);
ich_set_bbar(ctlr, 0);
return 0;
}
-void spi_init(void)
-{
- uint8_t bios_cntl;
-
- if (ich_find_spi_controller(&ctlr)) {
- printf("ICH SPI: Cannot find device\n");
- return;
- }
-
- if (ich_init_controller(&ctlr)) {
- printf("ICH SPI: Cannot setup controller\n");
- return;
- }
-
- /*
- * Disable the BIOS write protect so write commands are allowed. On
- * v9, deassert SMM BIOS Write Protect Disable.
- */
- if (ctlr.use_sbase) {
- struct ich9_spi_regs *ich9_spi;
-
- ich9_spi = (struct ich9_spi_regs *)ctlr.base;
- bios_cntl = ich_readb(&ich9_spi->bcr);
- bios_cntl &= ~(1 << 5); /* clear Enable InSMM_STS (EISS) */
- bios_cntl |= 1; /* Write Protect Disable (WPD) */
- ich_writeb(bios_cntl, &ich9_spi->bcr);
- } else {
- pci_read_config_byte(ctlr.dev, 0xdc, &bios_cntl);
- if (ctlr.ich_version == 9)
- bios_cntl &= ~(1 << 5);
- pci_write_config_byte(ctlr.dev, 0xdc, bios_cntl | 0x1);
- }
-}
-
-int spi_claim_bus(struct spi_slave *slave)
-{
- /* Handled by ICH automatically. */
- return 0;
-}
-
-void spi_release_bus(struct spi_slave *slave)
-{
- /* Handled by ICH automatically. */
-}
-
-void spi_cs_activate(struct spi_slave *slave)
-{
- /* Handled by ICH automatically. */
-}
-
-void spi_cs_deactivate(struct spi_slave *slave)
-{
- /* Handled by ICH automatically. */
-}
-
static inline void spi_use_out(struct spi_trans *trans, unsigned bytes)
{
trans->out += bytes;
@@ -411,19 +304,19 @@ static void spi_setup_type(struct spi_trans *trans, int data_bytes)
}
}
-static int spi_setup_opcode(struct spi_trans *trans)
+static int spi_setup_opcode(struct ich_spi_priv *ctlr, struct spi_trans *trans)
{
uint16_t optypes;
- uint8_t opmenu[ctlr.menubytes];
+ uint8_t opmenu[ctlr->menubytes];
trans->opcode = trans->out[0];
spi_use_out(trans, 1);
- if (!ctlr.ichspi_lock) {
+ if (!ctlr->ichspi_lock) {
/* The lock is off, so just use index 0. */
- ich_writeb(trans->opcode, ctlr.opmenu);
- optypes = ich_readw(ctlr.optype);
+ ich_writeb(ctlr, trans->opcode, ctlr->opmenu);
+ optypes = ich_readw(ctlr, ctlr->optype);
optypes = (optypes & 0xfffc) | (trans->type & 0x3);
- ich_writew(optypes, ctlr.optype);
+ ich_writew(ctlr, optypes, ctlr->optype);
return 0;
} else {
/* The lock is on. See if what we need is on the menu. */
@@ -434,20 +327,20 @@ static int spi_setup_opcode(struct spi_trans *trans)
if (trans->opcode == SPI_OPCODE_WREN)
return 0;
- read_reg(ctlr.opmenu, opmenu, sizeof(opmenu));
- for (opcode_index = 0; opcode_index < ctlr.menubytes;
+ read_reg(ctlr, ctlr->opmenu, opmenu, sizeof(opmenu));
+ for (opcode_index = 0; opcode_index < ctlr->menubytes;
opcode_index++) {
if (opmenu[opcode_index] == trans->opcode)
break;
}
- if (opcode_index == ctlr.menubytes) {
+ if (opcode_index == ctlr->menubytes) {
printf("ICH SPI: Opcode %x not found\n",
trans->opcode);
- return -1;
+ return -EINVAL;
}
- optypes = ich_readw(ctlr.optype);
+ optypes = ich_readw(ctlr, ctlr->optype);
optype = (optypes >> (opcode_index * 2)) & 0x3;
if (trans->type == SPI_OPCODE_TYPE_WRITE_NO_ADDRESS &&
optype == SPI_OPCODE_TYPE_WRITE_WITH_ADDRESS &&
@@ -458,7 +351,7 @@ static int spi_setup_opcode(struct spi_trans *trans)
if (optype != trans->type) {
printf("ICH SPI: Transaction doesn't fit type %d\n",
optype);
- return -1;
+ return -ENOSPC;
}
return opcode_index;
}
@@ -480,7 +373,7 @@ static int spi_setup_offset(struct spi_trans *trans)
return 1;
default:
printf("Unrecognized SPI transaction type %#x\n", trans->type);
- return -1;
+ return -EPROTO;
}
}
@@ -491,16 +384,19 @@ static int spi_setup_offset(struct spi_trans *trans)
*
* Return the last read status value on success or -1 on failure.
*/
-static int ich_status_poll(u16 bitmask, int wait_til_set)
+static int ich_status_poll(struct ich_spi_priv *ctlr, u16 bitmask,
+ int wait_til_set)
{
int timeout = 600000; /* This will result in 6s */
u16 status = 0;
while (timeout--) {
- status = ich_readw(ctlr.status);
+ status = ich_readw(ctlr, ctlr->status);
if (wait_til_set ^ ((status & bitmask) == 0)) {
- if (wait_til_set)
- ich_writew((status & bitmask), ctlr.status);
+ if (wait_til_set) {
+ ich_writew(ctlr, status & bitmask,
+ ctlr->status);
+ }
return status;
}
udelay(10);
@@ -508,30 +404,28 @@ static int ich_status_poll(u16 bitmask, int wait_til_set)
printf("ICH SPI: SCIP timeout, read %x, expected %x\n",
status, bitmask);
- return -1;
+ return -ETIMEDOUT;
}
-/*
-int spi_xfer(struct spi_slave *slave, const void *dout,
- unsigned int bitsout, void *din, unsigned int bitsin)
-*/
-int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
- void *din, unsigned long flags)
+static int ich_spi_xfer(struct udevice *dev, unsigned int bitlen,
+ const void *dout, void *din, unsigned long flags)
{
- struct ich_spi_slave *ich = to_ich_spi(slave);
+ struct udevice *bus = dev_get_parent(dev);
+ struct ich_spi_priv *ctlr = dev_get_priv(bus);
uint16_t control;
int16_t opcode_index;
int with_address;
int status;
int bytes = bitlen / 8;
- struct spi_trans *trans = &ich->trans;
+ struct spi_trans *trans = &ctlr->trans;
unsigned type = flags & (SPI_XFER_BEGIN | SPI_XFER_END);
int using_cmd = 0;
+ int ret;
/* Ee don't support writing partial bytes. */
if (bitlen % 8) {
debug("ICH SPI: Accessing partial bytes not supported\n");
- return -1;
+ return -EPROTONOSUPPORT;
}
/* An empty end transaction can be ignored */
@@ -545,7 +439,7 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
if (dout && type == SPI_XFER_BEGIN) {
if (bytes > ICH_MAX_CMD_LEN) {
debug("ICH SPI: Command length limit exceeded\n");
- return -1;
+ return -ENOSPC;
}
memcpy(trans->cmd, dout, bytes);
trans->cmd_len = bytes;
@@ -576,21 +470,22 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
/* There has to always at least be an opcode. */
if (!trans->bytesout) {
debug("ICH SPI: No opcode for transfer\n");
- return -1;
+ return -EPROTO;
}
- if (ich_status_poll(SPIS_SCIP, 0) == -1)
- return -1;
+ ret = ich_status_poll(ctlr, SPIS_SCIP, 0);
+ if (ret < 0)
+ return ret;
- ich_writew(SPIS_CDS | SPIS_FCERR, ctlr.status);
+ ich_writew(ctlr, SPIS_CDS | SPIS_FCERR, ctlr->status);
spi_setup_type(trans, using_cmd ? bytes : 0);
- opcode_index = spi_setup_opcode(trans);
+ opcode_index = spi_setup_opcode(ctlr, trans);
if (opcode_index < 0)
- return -1;
+ return -EINVAL;
with_address = spi_setup_offset(trans);
if (with_address < 0)
- return -1;
+ return -EINVAL;
if (trans->opcode == SPI_OPCODE_WREN) {
/*
@@ -598,20 +493,20 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
* in order to prevent the Management Engine from
* issuing a transaction between WREN and DATA.
*/
- if (!ctlr.ichspi_lock)
- ich_writew(trans->opcode, ctlr.preop);
+ if (!ctlr->ichspi_lock)
+ ich_writew(ctlr, trans->opcode, ctlr->preop);
return 0;
}
- if (ctlr.speed && ctlr.max_speed >= 33000000) {
+ if (ctlr->speed && ctlr->max_speed >= 33000000) {
int byte;
- byte = ich_readb(ctlr.speed);
- if (ich->speed >= 33000000)
+ byte = ich_readb(ctlr, ctlr->speed);
+ if (ctlr->cur_speed >= 33000000)
byte |= SSFC_SCF_33MHZ;
else
byte &= ~SSFC_SCF_33MHZ;
- ich_writeb(byte, ctlr.speed);
+ ich_writeb(ctlr, byte, ctlr->speed);
}
/* See if we have used up the command data */
@@ -622,35 +517,36 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
}
/* Preset control fields */
- control = ich_readw(ctlr.control);
+ control = ich_readw(ctlr, ctlr->control);
control &= ~SSFC_RESERVED;
control = SPIC_SCGO | ((opcode_index & 0x07) << 4);
/* Issue atomic preop cycle if needed */
- if (ich_readw(ctlr.preop))
+ if (ich_readw(ctlr, ctlr->preop))
control |= SPIC_ACS;
if (!trans->bytesout && !trans->bytesin) {
/* SPI addresses are 24 bit only */
- if (with_address)
- ich_writel(trans->offset & 0x00FFFFFF, ctlr.addr);
-
+ if (with_address) {
+ ich_writel(ctlr, trans->offset & 0x00FFFFFF,
+ ctlr->addr);
+ }
/*
* This is a 'no data' command (like Write Enable), its
* bitesout size was 1, decremented to zero while executing
* spi_setup_opcode() above. Tell the chip to send the
* command.
*/
- ich_writew(control, ctlr.control);
+ ich_writew(ctlr, control, ctlr->control);
/* wait for the result */
- status = ich_status_poll(SPIS_CDS | SPIS_FCERR, 1);
- if (status == -1)
- return -1;
+ status = ich_status_poll(ctlr, SPIS_CDS | SPIS_FCERR, 1);
+ if (status < 0)
+ return status;
if (status & SPIS_FCERR) {
debug("ICH SPI: Command transaction error\n");
- return -1;
+ return -EIO;
}
return 0;
@@ -663,9 +559,9 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
* and followed by other SPI commands, and this sequence is controlled
* by the SPI chip driver.
*/
- if (trans->bytesout > ctlr.databytes) {
+ if (trans->bytesout > ctlr->databytes) {
debug("ICH SPI: Too much to write. This should be prevented by the driver's max_write_size?\n");
- return -1;
+ return -EPROTO;
}
/*
@@ -676,41 +572,41 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
uint32_t data_length;
/* SPI addresses are 24 bit only */
- ich_writel(trans->offset & 0x00FFFFFF, ctlr.addr);
+ ich_writel(ctlr, trans->offset & 0x00FFFFFF, ctlr->addr);
if (trans->bytesout)
- data_length = min(trans->bytesout, ctlr.databytes);
+ data_length = min(trans->bytesout, ctlr->databytes);
else
- data_length = min(trans->bytesin, ctlr.databytes);
+ data_length = min(trans->bytesin, ctlr->databytes);
/* Program data into FDATA0 to N */
if (trans->bytesout) {
- write_reg(trans->out, ctlr.data, data_length);
+ write_reg(ctlr, trans->out, ctlr->data, data_length);
spi_use_out(trans, data_length);
if (with_address)
trans->offset += data_length;
}
/* Add proper control fields' values */
- control &= ~((ctlr.databytes - 1) << 8);
+ control &= ~((ctlr->databytes - 1) << 8);
control |= SPIC_DS;
control |= (data_length - 1) << 8;
/* write it */
- ich_writew(control, ctlr.control);
+ ich_writew(ctlr, control, ctlr->control);
/* Wait for Cycle Done Status or Flash Cycle Error. */
- status = ich_status_poll(SPIS_CDS | SPIS_FCERR, 1);
- if (status == -1)
- return -1;
+ status = ich_status_poll(ctlr, SPIS_CDS | SPIS_FCERR, 1);
+ if (status < 0)
+ return status;
if (status & SPIS_FCERR) {
debug("ICH SPI: Data transaction error\n");
- return -1;
+ return -EIO;
}
if (trans->bytesin) {
- read_reg(ctlr.data, trans->in, data_length);
+ read_reg(ctlr, ctlr->data, trans->in, data_length);
spi_use_in(trans, data_length);
if (with_address)
trans->offset += data_length;
@@ -718,7 +614,7 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
}
/* Clear atomic preop now that xfer is done */
- ich_writew(0, ctlr.preop);
+ ich_writew(ctlr, 0, ctlr->preop);
return 0;
}
@@ -730,15 +626,18 @@ int spi_xfer(struct spi_slave *slave, unsigned int bitlen, const void *dout,
* don't actually take effect until the HSFS[FLOCKDN] bit is set, but that's
* done elsewhere.
*/
-int spi_write_protect_region(uint32_t lower_limit, uint32_t length, int hint)
+int spi_write_protect_region(struct udevice *dev, uint32_t lower_limit,
+ uint32_t length, int hint)
{
+ struct udevice *bus = dev->parent;
+ struct ich_spi_priv *ctlr = dev_get_priv(bus);
uint32_t tmplong;
uint32_t upper_limit;
- if (!ctlr.pr) {
+ if (!ctlr->pr) {
printf("%s: operation not supported on this chipset\n",
__func__);
- return -1;
+ return -ENOSYS;
}
if (length == 0 ||
@@ -746,7 +645,7 @@ int spi_write_protect_region(uint32_t lower_limit, uint32_t length, int hint)
hint < 0 || hint > 4) {
printf("%s(0x%x, 0x%x, %d): invalid args\n", __func__,
lower_limit, length, hint);
- return -1;
+ return -EPERM;
}
upper_limit = lower_limit + length - 1;
@@ -765,8 +664,121 @@ int spi_write_protect_region(uint32_t lower_limit, uint32_t length, int hint)
((lower_limit & 0x01fff000) >> 12);
printf("%s: writing 0x%08x to %p\n", __func__, tmplong,
- &ctlr.pr[hint]);
- ctlr.pr[hint] = tmplong;
+ &ctlr->pr[hint]);
+ ctlr->pr[hint] = tmplong;
+
+ return 0;
+}
+
+static int ich_spi_probe(struct udevice *bus)
+{
+ struct ich_spi_platdata *plat = dev_get_platdata(bus);
+ struct ich_spi_priv *priv = dev_get_priv(bus);
+ uint8_t bios_cntl;
+ int ret;
+
+ ret = ich_init_controller(plat, priv);
+ if (ret)
+ return ret;
+ /*
+ * Disable the BIOS write protect so write commands are allowed. On
+ * v9, deassert SMM BIOS Write Protect Disable.
+ */
+ if (plat->use_sbase) {
+ struct ich9_spi_regs *ich9_spi;
+
+ ich9_spi = priv->base;
+ bios_cntl = ich_readb(priv, ich9_spi->bcr);
+ bios_cntl &= ~(1 << 5); /* clear Enable InSMM_STS (EISS) */
+ bios_cntl |= 1; /* Write Protect Disable (WPD) */
+ ich_writeb(priv, bios_cntl, ich9_spi->bcr);
+ } else {
+ pci_read_config_byte(plat->dev, 0xdc, &bios_cntl);
+ if (plat->ich_version == 9)
+ bios_cntl &= ~(1 << 5);
+ pci_write_config_byte(plat->dev, 0xdc, bios_cntl | 0x1);
+ }
+
+ priv->cur_speed = priv->max_speed;
+
+ return 0;
+}
+
+static int ich_spi_ofdata_to_platdata(struct udevice *bus)
+{
+ struct ich_spi_platdata *plat = dev_get_platdata(bus);
+ int ret;
+
+ ret = ich_find_spi_controller(plat);
+ if (ret)
+ return ret;
return 0;
}
+
+static int ich_spi_set_speed(struct udevice *bus, uint speed)
+{
+ struct ich_spi_priv *priv = dev_get_priv(bus);
+
+ priv->cur_speed = speed;
+
+ return 0;
+}
+
+static int ich_spi_set_mode(struct udevice *bus, uint mode)
+{
+ debug("%s: mode=%d\n", __func__, mode);
+
+ return 0;
+}
+
+static int ich_spi_child_pre_probe(struct udevice *dev)
+{
+ struct udevice *bus = dev_get_parent(dev);
+ struct ich_spi_platdata *plat = dev_get_platdata(bus);
+ struct ich_spi_priv *priv = dev_get_priv(bus);
+ struct spi_slave *slave = dev_get_parentdata(dev);
+
+ /*
+ * Yes this controller can only write a small number of bytes at
+ * once! The limit is typically 64 bytes.
+ */
+ slave->max_write_size = priv->databytes;
+ /*
+ * ICH 7 SPI controller only supports array read command
+ * and byte program command for SST flash
+ */
+ if (plat->ich_version == 7) {
+ slave->op_mode_rx = SPI_OPM_RX_AS;
+ slave->op_mode_tx = SPI_OPM_TX_BP;
+ }
+
+ return 0;
+}
+
+static const struct dm_spi_ops ich_spi_ops = {
+ .xfer = ich_spi_xfer,
+ .set_speed = ich_spi_set_speed,
+ .set_mode = ich_spi_set_mode,
+ /*
+ * cs_info is not needed, since we require all chip selects to be
+ * in the device tree explicitly
+ */
+};
+
+static const struct udevice_id ich_spi_ids[] = {
+ { .compatible = "intel,ich-spi" },
+ { }
+};
+
+U_BOOT_DRIVER(ich_spi) = {
+ .name = "ich_spi",
+ .id = UCLASS_SPI,
+ .of_match = ich_spi_ids,
+ .ops = &ich_spi_ops,
+ .ofdata_to_platdata = ich_spi_ofdata_to_platdata,
+ .platdata_auto_alloc_size = sizeof(struct ich_spi_platdata),
+ .priv_auto_alloc_size = sizeof(struct ich_spi_priv),
+ .child_pre_probe = ich_spi_child_pre_probe,
+ .probe = ich_spi_probe,
+};
diff --git a/drivers/spi/spi-uclass.c b/drivers/spi/spi-uclass.c
index 63a6217cc6..866c48f243 100644
--- a/drivers/spi/spi-uclass.c
+++ b/drivers/spi/spi-uclass.c
@@ -50,7 +50,7 @@ int spi_claim_bus(struct spi_slave *slave)
struct udevice *dev = slave->dev;
struct udevice *bus = dev->parent;
struct dm_spi_ops *ops = spi_get_ops(bus);
- struct dm_spi_bus *spi = bus->uclass_priv;
+ struct dm_spi_bus *spi = dev_get_uclass_priv(bus);
int speed;
int ret;
@@ -110,7 +110,7 @@ int spi_child_post_bind(struct udevice *dev)
int spi_post_probe(struct udevice *bus)
{
- struct dm_spi_bus *spi = bus->uclass_priv;
+ struct dm_spi_bus *spi = dev_get_uclass_priv(bus);
spi->max_hz = fdtdec_get_int(gd->fdt_blob, bus->of_offset,
"spi-max-frequency", 0);
diff --git a/drivers/tpm/Kconfig b/drivers/tpm/Kconfig
index e69de29bb2..f408b8a81d 100644
--- a/drivers/tpm/Kconfig
+++ b/drivers/tpm/Kconfig
@@ -0,0 +1,7 @@
+config TPM_TIS_SANDBOX
+ bool "Enable sandbox TPM driver"
+ help
+ This driver emulates a TPM, providing access to base functions
+ such as reading and writing TPM private data. This is enough to
+ support Chrome OS verified boot. Extend functionality is not
+ implemented.
diff --git a/drivers/usb/Kconfig b/drivers/usb/Kconfig
index b4a9442703..637ef3d567 100644
--- a/drivers/usb/Kconfig
+++ b/drivers/usb/Kconfig
@@ -35,8 +35,24 @@ config USB
if USB
+config DM_USB
+ bool "Enable driver model for USB"
+ depends on USB && DM
+ help
+ Enable driver model for USB. The USB interface is then implemented
+ by the USB uclass. Multiple USB controllers of different types
+ (XHCI, EHCI) can be attached and used. The 'usb' command works as
+ normal. OCHI is not supported at present.
+
+ Much of the code is shared but with this option enabled the USB
+ uclass takes care of device enumeration. USB devices can be
+ declared with the USB_DEVICE() macro and will be automatically
+ probed when found on the bus.
+
source "drivers/usb/host/Kconfig"
+source "drivers/usb/emul/Kconfig"
+
config USB_STORAGE
bool "USB Mass Storage support"
---help---
diff --git a/drivers/usb/emul/Kconfig b/drivers/usb/emul/Kconfig
new file mode 100644
index 0000000000..ae1ab23a3d
--- /dev/null
+++ b/drivers/usb/emul/Kconfig
@@ -0,0 +1,8 @@
+config USB_EMUL
+ bool "Support for USB device emulation"
+ depends on DM_USB && SANDBOX
+ help
+ Since sandbox does not have access to a real USB bus, it is possible
+ to use device emulators instead. This allows testing of the USB
+ stack on sandbox without needing a real device, or any host machine
+ USB resources.
diff --git a/drivers/usb/emul/Makefile b/drivers/usb/emul/Makefile
new file mode 100644
index 0000000000..8fd83d5d06
--- /dev/null
+++ b/drivers/usb/emul/Makefile
@@ -0,0 +1,10 @@
+#
+# (C) Copyright 2015 Google, Inc
+# Written by Simon Glass <sjg@chromium.org>
+#
+# SPDX-License-Identifier: GPL-2.0+
+#
+
+obj-$(CONFIG_USB_EMUL) += sandbox_flash.o
+obj-$(CONFIG_USB_EMUL) += sandbox_hub.o
+obj-$(CONFIG_USB_EMUL) += usb-emul-uclass.o
diff --git a/drivers/usb/emul/sandbox_flash.c b/drivers/usb/emul/sandbox_flash.c
new file mode 100644
index 0000000000..6e0808ded8
--- /dev/null
+++ b/drivers/usb/emul/sandbox_flash.c
@@ -0,0 +1,423 @@
+/*
+ * (C) Copyright 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <os.h>
+#include <scsi.h>
+#include <usb.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/*
+ * This driver emulates a flash stick using the UFI command specification and
+ * the BBB (bulk/bulk/bulk) protocol. It supports only a single logical unit
+ * number (LUN 0).
+ */
+
+enum {
+ SANDBOX_FLASH_EP_OUT = 1, /* endpoints */
+ SANDBOX_FLASH_EP_IN = 2,
+ SANDBOX_FLASH_BLOCK_LEN = 512,
+};
+
+enum cmd_phase {
+ PHASE_START,
+ PHASE_DATA,
+ PHASE_STATUS,
+};
+
+/**
+ * struct sandbox_flash_priv - private state for this driver
+ *
+ * @error: true if there is an error condition
+ * @alloc_len: Allocation length from the last incoming command
+ * @transfer_len: Transfer length from CBW header
+ * @read_len: Number of blocks of data left in the current read command
+ * @tag: Tag value from last command
+ * @fd: File descriptor of backing file
+ * @file_size: Size of file in bytes
+ * @status_buff: Data buffer for outgoing status
+ * @buff_used: Number of bytes ready to transfer back to host
+ * @buff: Data buffer for outgoing data
+ */
+struct sandbox_flash_priv {
+ bool error;
+ int alloc_len;
+ int transfer_len;
+ int read_len;
+ enum cmd_phase phase;
+ u32 tag;
+ int fd;
+ loff_t file_size;
+ struct umass_bbb_csw status;
+ int buff_used;
+ u8 buff[512];
+};
+
+struct sandbox_flash_plat {
+ const char *pathname;
+};
+
+struct scsi_inquiry_resp {
+ u8 type;
+ u8 flags;
+ u8 version;
+ u8 data_format;
+ u8 additional_len;
+ u8 spare[3];
+ char vendor[8];
+ char product[16];
+ char revision[4];
+};
+
+struct scsi_read_capacity_resp {
+ u32 last_block_addr;
+ u32 block_len;
+};
+
+struct __packed scsi_read10_req {
+ u8 cmd;
+ u8 lun_flags;
+ u32 lba;
+ u8 spare;
+ u16 transfer_len;
+ u8 spare2[3];
+};
+
+enum {
+ STRINGID_MANUFACTURER = 1,
+ STRINGID_PRODUCT,
+ STRINGID_SERIAL,
+
+ STRINGID_COUNT,
+};
+
+static struct usb_string flash_strings[] = {
+ {STRINGID_MANUFACTURER, "sandbox"},
+ {STRINGID_PRODUCT, "flash"},
+ {STRINGID_SERIAL, "2345"},
+ {},
+};
+
+static struct usb_device_descriptor flash_device_desc = {
+ .bLength = sizeof(flash_device_desc),
+ .bDescriptorType = USB_DT_DEVICE,
+
+ .bcdUSB = __constant_cpu_to_le16(0x0200),
+
+ .bDeviceClass = 0,
+ .bDeviceSubClass = 0,
+ .bDeviceProtocol = 0,
+
+ .idVendor = __constant_cpu_to_le16(0x1234),
+ .idProduct = __constant_cpu_to_le16(0x5678),
+ .iManufacturer = STRINGID_MANUFACTURER,
+ .iProduct = STRINGID_PRODUCT,
+ .iSerialNumber = STRINGID_SERIAL,
+ .bNumConfigurations = 1,
+};
+
+static struct usb_config_descriptor flash_config0 = {
+ .bLength = sizeof(flash_config0),
+ .bDescriptorType = USB_DT_CONFIG,
+
+ /* wTotalLength is set up by usb-emul-uclass */
+ .bNumInterfaces = 1,
+ .bConfigurationValue = 0,
+ .iConfiguration = 0,
+ .bmAttributes = 1 << 7,
+ .bMaxPower = 50,
+};
+
+static struct usb_interface_descriptor flash_interface0 = {
+ .bLength = sizeof(flash_interface0),
+ .bDescriptorType = USB_DT_INTERFACE,
+
+ .bInterfaceNumber = 0,
+ .bAlternateSetting = 0,
+ .bNumEndpoints = 2,
+ .bInterfaceClass = USB_CLASS_MASS_STORAGE,
+ .bInterfaceSubClass = US_SC_UFI,
+ .bInterfaceProtocol = US_PR_BULK,
+ .iInterface = 0,
+};
+
+static struct usb_endpoint_descriptor flash_endpoint0_out = {
+ .bLength = USB_DT_ENDPOINT_SIZE,
+ .bDescriptorType = USB_DT_ENDPOINT,
+
+ .bEndpointAddress = SANDBOX_FLASH_EP_OUT,
+ .bmAttributes = USB_ENDPOINT_XFER_BULK,
+ .wMaxPacketSize = __constant_cpu_to_le16(1024),
+ .bInterval = 0,
+};
+
+static struct usb_endpoint_descriptor flash_endpoint1_in = {
+ .bLength = USB_DT_ENDPOINT_SIZE,
+ .bDescriptorType = USB_DT_ENDPOINT,
+
+ .bEndpointAddress = SANDBOX_FLASH_EP_IN | USB_ENDPOINT_DIR_MASK,
+ .bmAttributes = USB_ENDPOINT_XFER_BULK,
+ .wMaxPacketSize = __constant_cpu_to_le16(1024),
+ .bInterval = 0,
+};
+
+static void *flash_desc_list[] = {
+ &flash_device_desc,
+ &flash_config0,
+ &flash_interface0,
+ &flash_endpoint0_out,
+ &flash_endpoint1_in,
+ NULL,
+};
+
+static int sandbox_flash_control(struct udevice *dev, struct usb_device *udev,
+ unsigned long pipe, void *buff, int len,
+ struct devrequest *setup)
+{
+ struct sandbox_flash_priv *priv = dev_get_priv(dev);
+
+ if (pipe == usb_rcvctrlpipe(udev, 0)) {
+ switch (setup->request) {
+ case US_BBB_RESET:
+ priv->error = false;
+ return 0;
+ case US_BBB_GET_MAX_LUN:
+ *(char *)buff = '\0';
+ return 1;
+ default:
+ debug("request=%x\n", setup->request);
+ break;
+ }
+ }
+ debug("pipe=%lx\n", pipe);
+
+ return -EIO;
+}
+
+static void setup_fail_response(struct sandbox_flash_priv *priv)
+{
+ struct umass_bbb_csw *csw = &priv->status;
+
+ csw->dCSWSignature = CSWSIGNATURE;
+ csw->dCSWTag = priv->tag;
+ csw->dCSWDataResidue = 0;
+ csw->bCSWStatus = CSWSTATUS_FAILED;
+ priv->buff_used = 0;
+}
+
+/**
+ * setup_response() - set up a response to send back to the host
+ *
+ * @priv: Sandbox flash private data
+ * @resp: Response to send, or NULL if none
+ * @size: Size of response
+ */
+static void setup_response(struct sandbox_flash_priv *priv, void *resp,
+ int size)
+{
+ struct umass_bbb_csw *csw = &priv->status;
+
+ csw->dCSWSignature = CSWSIGNATURE;
+ csw->dCSWTag = priv->tag;
+ csw->dCSWDataResidue = 0;
+ csw->bCSWStatus = CSWSTATUS_GOOD;
+
+ assert(!resp || resp == priv->buff);
+ priv->buff_used = size;
+}
+
+static void handle_read(struct sandbox_flash_priv *priv, ulong lba,
+ ulong transfer_len)
+{
+ debug("%s: lba=%lx, transfer_len=%lx\n", __func__, lba, transfer_len);
+ if (priv->fd != -1) {
+ os_lseek(priv->fd, lba * SANDBOX_FLASH_BLOCK_LEN, OS_SEEK_SET);
+ priv->read_len = transfer_len;
+ setup_response(priv, priv->buff,
+ transfer_len * SANDBOX_FLASH_BLOCK_LEN);
+ } else {
+ setup_fail_response(priv);
+ }
+}
+
+static int handle_ufi_command(struct sandbox_flash_priv *priv, const void *buff,
+ int len)
+{
+ const struct SCSI_cmd_block *req = buff;
+
+ switch (*req->cmd) {
+ case SCSI_INQUIRY: {
+ struct scsi_inquiry_resp *resp = (void *)priv->buff;
+
+ priv->alloc_len = req->cmd[4];
+ memset(resp, '\0', sizeof(*resp));
+ resp->data_format = 1;
+ resp->additional_len = 0x1f;
+ strncpy(resp->vendor,
+ flash_strings[STRINGID_MANUFACTURER - 1].s,
+ sizeof(resp->vendor));
+ strncpy(resp->product, flash_strings[STRINGID_PRODUCT - 1].s,
+ sizeof(resp->product));
+ strncpy(resp->revision, "1.0", sizeof(resp->revision));
+ setup_response(priv, resp, sizeof(*resp));
+ break;
+ }
+ case SCSI_TST_U_RDY:
+ setup_response(priv, NULL, 0);
+ break;
+ case SCSI_RD_CAPAC: {
+ struct scsi_read_capacity_resp *resp = (void *)priv->buff;
+ uint blocks;
+
+ if (priv->file_size)
+ blocks = priv->file_size / SANDBOX_FLASH_BLOCK_LEN - 1;
+ else
+ blocks = 0;
+ resp->last_block_addr = cpu_to_be32(blocks);
+ resp->block_len = cpu_to_be32(SANDBOX_FLASH_BLOCK_LEN);
+ setup_response(priv, resp, sizeof(*resp));
+ break;
+ }
+ case SCSI_READ10: {
+ struct scsi_read10_req *req = (void *)buff;
+
+ handle_read(priv, be32_to_cpu(req->lba),
+ be16_to_cpu(req->transfer_len));
+ break;
+ }
+ default:
+ debug("Command not supported: %x\n", req->cmd[0]);
+ return -EPROTONOSUPPORT;
+ }
+
+ priv->phase = priv->transfer_len ? PHASE_DATA : PHASE_STATUS;
+ return 0;
+}
+
+static int sandbox_flash_bulk(struct udevice *dev, struct usb_device *udev,
+ unsigned long pipe, void *buff, int len)
+{
+ struct sandbox_flash_priv *priv = dev_get_priv(dev);
+ int ep = usb_pipeendpoint(pipe);
+ struct umass_bbb_cbw *cbw = buff;
+
+ debug("%s: dev=%s, pipe=%lx, ep=%x, len=%x, phase=%d\n", __func__,
+ dev->name, pipe, ep, len, priv->phase);
+ switch (ep) {
+ case SANDBOX_FLASH_EP_OUT:
+ switch (priv->phase) {
+ case PHASE_START:
+ priv->alloc_len = 0;
+ priv->read_len = 0;
+ if (priv->error || len != UMASS_BBB_CBW_SIZE ||
+ cbw->dCBWSignature != CBWSIGNATURE)
+ goto err;
+ if ((cbw->bCBWFlags & CBWFLAGS_SBZ) ||
+ cbw->bCBWLUN != 0)
+ goto err;
+ if (cbw->bCDBLength < 1 || cbw->bCDBLength >= 0x10)
+ goto err;
+ priv->transfer_len = cbw->dCBWDataTransferLength;
+ priv->tag = cbw->dCBWTag;
+ return handle_ufi_command(priv, cbw->CBWCDB,
+ cbw->bCDBLength);
+ case PHASE_DATA:
+ debug("data out\n");
+ break;
+ default:
+ break;
+ }
+ case SANDBOX_FLASH_EP_IN:
+ switch (priv->phase) {
+ case PHASE_DATA:
+ debug("data in, len=%x, alloc_len=%x, priv->read_len=%x\n",
+ len, priv->alloc_len, priv->read_len);
+ if (priv->read_len) {
+ ulong bytes_read;
+
+ bytes_read = os_read(priv->fd, buff, len);
+ if (bytes_read != len)
+ return -EIO;
+ priv->read_len -= len / SANDBOX_FLASH_BLOCK_LEN;
+ if (!priv->read_len)
+ priv->phase = PHASE_STATUS;
+ } else {
+ if (priv->alloc_len && len > priv->alloc_len)
+ len = priv->alloc_len;
+ memcpy(buff, priv->buff, len);
+ priv->phase = PHASE_STATUS;
+ }
+ return len;
+ case PHASE_STATUS:
+ debug("status in, len=%x\n", len);
+ if (len > sizeof(priv->status))
+ len = sizeof(priv->status);
+ memcpy(buff, &priv->status, len);
+ priv->phase = PHASE_START;
+ return len;
+ default:
+ break;
+ }
+ }
+err:
+ priv->error = true;
+ debug("%s: Detected transfer error\n", __func__);
+ return 0;
+}
+
+static int sandbox_flash_ofdata_to_platdata(struct udevice *dev)
+{
+ struct sandbox_flash_plat *plat = dev_get_platdata(dev);
+ const void *blob = gd->fdt_blob;
+
+ plat->pathname = fdt_getprop(blob, dev->of_offset, "sandbox,filepath",
+ NULL);
+
+ return 0;
+}
+
+static int sandbox_flash_bind(struct udevice *dev)
+{
+ return usb_emul_setup_device(dev, PACKET_SIZE_64, flash_strings,
+ flash_desc_list);
+}
+
+static int sandbox_flash_probe(struct udevice *dev)
+{
+ struct sandbox_flash_plat *plat = dev_get_platdata(dev);
+ struct sandbox_flash_priv *priv = dev_get_priv(dev);
+
+ priv->fd = os_open(plat->pathname, OS_O_RDONLY);
+ if (priv->fd != -1)
+ return os_get_filesize(plat->pathname, &priv->file_size);
+
+ return 0;
+}
+
+static const struct dm_usb_ops sandbox_usb_flash_ops = {
+ .control = sandbox_flash_control,
+ .bulk = sandbox_flash_bulk,
+};
+
+static const struct udevice_id sandbox_usb_flash_ids[] = {
+ { .compatible = "sandbox,usb-flash" },
+ { }
+};
+
+U_BOOT_DRIVER(usb_sandbox_flash) = {
+ .name = "usb_sandbox_flash",
+ .id = UCLASS_USB_EMUL,
+ .of_match = sandbox_usb_flash_ids,
+ .bind = sandbox_flash_bind,
+ .probe = sandbox_flash_probe,
+ .ofdata_to_platdata = sandbox_flash_ofdata_to_platdata,
+ .ops = &sandbox_usb_flash_ops,
+ .priv_auto_alloc_size = sizeof(struct sandbox_flash_priv),
+ .platdata_auto_alloc_size = sizeof(struct sandbox_flash_plat),
+};
diff --git a/drivers/usb/emul/sandbox_hub.c b/drivers/usb/emul/sandbox_hub.c
new file mode 100644
index 0000000000..280c7080f2
--- /dev/null
+++ b/drivers/usb/emul/sandbox_hub.c
@@ -0,0 +1,303 @@
+/*
+ * (C) Copyright 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <usb.h>
+#include <dm/device-internal.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+/* We only support up to 8 */
+#define SANDBOX_NUM_PORTS 2
+
+struct sandbox_hub_platdata {
+ struct usb_dev_platdata plat;
+ int port; /* Port number (numbered from 0) */
+};
+
+enum {
+ STRING_MANUFACTURER = 1,
+ STRING_PRODUCT,
+ STRING_SERIAL,
+
+ STRING_count,
+};
+
+static struct usb_string hub_strings[] = {
+ {STRING_MANUFACTURER, "sandbox"},
+ {STRING_PRODUCT, "hub"},
+ {STRING_SERIAL, "2345"},
+};
+
+static struct usb_device_descriptor hub_device_desc = {
+ .bLength = sizeof(hub_device_desc),
+ .bDescriptorType = USB_DT_DEVICE,
+
+ .bcdUSB = __constant_cpu_to_le16(0x0200),
+
+ .bDeviceClass = USB_CLASS_HUB,
+ .bDeviceSubClass = 0,
+ .bDeviceProtocol = 0,
+
+ .idVendor = __constant_cpu_to_le16(0x1234),
+ .idProduct = __constant_cpu_to_le16(0x5678),
+ .iManufacturer = STRING_MANUFACTURER,
+ .iProduct = STRING_PRODUCT,
+ .iSerialNumber = STRING_SERIAL,
+ .bNumConfigurations = 1,
+};
+
+static struct usb_config_descriptor hub_config1 = {
+ .bLength = sizeof(hub_config1),
+ .bDescriptorType = USB_DT_CONFIG,
+
+ /* wTotalLength is set up by usb-emul-uclass */
+ .bNumInterfaces = 1,
+ .bConfigurationValue = 0,
+ .iConfiguration = 0,
+ .bmAttributes = 1 << 7,
+ .bMaxPower = 50,
+};
+
+static struct usb_interface_descriptor hub_interface0 = {
+ .bLength = sizeof(hub_interface0),
+ .bDescriptorType = USB_DT_INTERFACE,
+
+ .bInterfaceNumber = 0,
+ .bAlternateSetting = 0,
+ .bNumEndpoints = 1,
+ .bInterfaceClass = USB_CLASS_HUB,
+ .bInterfaceSubClass = 0,
+ .bInterfaceProtocol = US_PR_CB,
+ .iInterface = 0,
+};
+
+static struct usb_endpoint_descriptor hub_endpoint0_in = {
+ .bLength = USB_DT_ENDPOINT_SIZE,
+ .bDescriptorType = USB_DT_ENDPOINT,
+
+ .bEndpointAddress = 1 | USB_DIR_IN,
+ .bmAttributes = USB_ENDPOINT_XFER_INT,
+ .wMaxPacketSize = __constant_cpu_to_le16(1024),
+ .bInterval = 0,
+};
+
+static struct usb_hub_descriptor hub_desc = {
+ .bLength = sizeof(hub_desc),
+ .bDescriptorType = USB_DT_HUB,
+ .bNbrPorts = SANDBOX_NUM_PORTS,
+ .wHubCharacteristics = __constant_cpu_to_le16(1 << 0 | 1 << 3 |
+ 1 << 7),
+ .bPwrOn2PwrGood = 2,
+ .bHubContrCurrent = 5,
+ .DeviceRemovable = {0, 0xff}, /* all ports removeable */
+#if SANDBOX_NUM_PORTS > 8
+#error "This code sets up an incorrect mask"
+#endif
+};
+
+static void *hub_desc_list[] = {
+ &hub_device_desc,
+ &hub_config1,
+ &hub_interface0,
+ &hub_endpoint0_in,
+ &hub_desc,
+ NULL,
+};
+
+struct sandbox_hub_priv {
+ int status[SANDBOX_NUM_PORTS];
+ int change[SANDBOX_NUM_PORTS];
+};
+
+static struct udevice *hub_find_device(struct udevice *hub, int port)
+{
+ struct udevice *dev;
+
+ for (device_find_first_child(hub, &dev);
+ dev;
+ device_find_next_child(&dev)) {
+ struct sandbox_hub_platdata *plat;
+
+ plat = dev_get_parent_platdata(dev);
+ if (plat->port == port)
+ return dev;
+ }
+
+ return NULL;
+}
+
+static int clrset_post_state(struct udevice *hub, int port, int clear, int set)
+{
+ struct sandbox_hub_priv *priv = dev_get_priv(hub);
+ int *status = &priv->status[port];
+ int *change = &priv->change[port];
+ int ret = 0;
+
+ if ((clear | set) & USB_PORT_STAT_POWER) {
+ struct udevice *dev = hub_find_device(hub, port);
+
+ if (dev) {
+ if (set & USB_PORT_STAT_POWER) {
+ ret = device_probe(dev);
+ debug("%s: %s: power on, probed, ret=%d\n",
+ __func__, dev->name, ret);
+ if (!ret) {
+ set |= USB_PORT_STAT_CONNECTION |
+ USB_PORT_STAT_ENABLE;
+ }
+
+ } else if (clear & USB_PORT_STAT_POWER) {
+ debug("%s: %s: power off, removed, ret=%d\n",
+ __func__, dev->name, ret);
+ ret = device_remove(dev);
+ clear |= USB_PORT_STAT_CONNECTION;
+ }
+ }
+ }
+ *change |= *status & clear;
+ *change |= ~*status & set;
+ *change &= 0x1f;
+ *status = (*status & ~clear) | set;
+
+ return ret;
+}
+
+static int sandbox_hub_submit_control_msg(struct udevice *bus,
+ struct usb_device *udev,
+ unsigned long pipe,
+ void *buffer, int length,
+ struct devrequest *setup)
+{
+ struct sandbox_hub_priv *priv = dev_get_priv(bus);
+ int ret = 0;
+
+ if (pipe == usb_rcvctrlpipe(udev, 0)) {
+ switch (setup->requesttype) {
+ case USB_RT_HUB | USB_DIR_IN:
+ switch (setup->request) {
+ case USB_REQ_GET_STATUS: {
+ struct usb_hub_status *hubsts = buffer;
+
+ hubsts->wHubStatus = 0;
+ hubsts->wHubChange = 0;
+ udev->status = 0;
+ udev->act_len = sizeof(*hubsts);
+ return 0;
+ }
+ default:
+ debug("%s: rx ctl requesttype=%x, request=%x\n",
+ __func__, setup->requesttype,
+ setup->request);
+ break;
+ }
+ case USB_RT_PORT | USB_DIR_IN:
+ switch (setup->request) {
+ case USB_REQ_GET_STATUS: {
+ struct usb_port_status *portsts = buffer;
+ int port;
+
+ port = (setup->index & USB_HUB_PORT_MASK) - 1;
+ portsts->wPortStatus = priv->status[port];
+ portsts->wPortChange = priv->change[port];
+ udev->status = 0;
+ udev->act_len = sizeof(*portsts);
+ return 0;
+ }
+ }
+ default:
+ debug("%s: rx ctl requesttype=%x, request=%x\n",
+ __func__, setup->requesttype, setup->request);
+ break;
+ }
+ } else if (pipe == usb_sndctrlpipe(udev, 0)) {
+ switch (setup->requesttype) {
+ case USB_RT_PORT:
+ switch (setup->request) {
+ case USB_REQ_SET_FEATURE: {
+ int port;
+
+ port = (setup->index & USB_HUB_PORT_MASK) - 1;
+ debug("set feature port=%x, feature=%x\n",
+ port, setup->value);
+ if (setup->value < USB_PORT_FEAT_C_CONNECTION) {
+ ret = clrset_post_state(bus, port, 0,
+ 1 << setup->value);
+ } else {
+ debug(" ** Invalid feature\n");
+ }
+ return ret;
+ }
+ case USB_REQ_CLEAR_FEATURE: {
+ int port;
+
+ port = (setup->index & USB_HUB_PORT_MASK) - 1;
+ debug("clear feature port=%x, feature=%x\n",
+ port, setup->value);
+ if (setup->value < USB_PORT_FEAT_C_CONNECTION) {
+ ret = clrset_post_state(bus, port,
+ 1 << setup->value, 0);
+ } else {
+ priv->change[port] &= 1 <<
+ (setup->value - 16);
+ }
+ udev->status = 0;
+ return 0;
+ }
+ default:
+ debug("%s: tx ctl requesttype=%x, request=%x\n",
+ __func__, setup->requesttype,
+ setup->request);
+ break;
+ }
+ default:
+ debug("%s: tx ctl requesttype=%x, request=%x\n",
+ __func__, setup->requesttype, setup->request);
+ break;
+ }
+ }
+ debug("pipe=%lx\n", pipe);
+
+ return -EIO;
+}
+
+static int sandbox_hub_bind(struct udevice *dev)
+{
+ return usb_emul_setup_device(dev, PACKET_SIZE_64, hub_strings,
+ hub_desc_list);
+}
+
+static int sandbox_child_post_bind(struct udevice *dev)
+{
+ struct sandbox_hub_platdata *plat = dev_get_parent_platdata(dev);
+
+ plat->port = fdtdec_get_int(gd->fdt_blob, dev->of_offset, "reg", -1);
+
+ return 0;
+}
+
+static const struct dm_usb_ops sandbox_usb_hub_ops = {
+ .control = sandbox_hub_submit_control_msg,
+};
+
+static const struct udevice_id sandbox_usb_hub_ids[] = {
+ { .compatible = "sandbox,usb-hub" },
+ { }
+};
+
+U_BOOT_DRIVER(usb_sandbox_hub) = {
+ .name = "usb_sandbox_hub",
+ .id = UCLASS_USB_EMUL,
+ .of_match = sandbox_usb_hub_ids,
+ .bind = sandbox_hub_bind,
+ .ops = &sandbox_usb_hub_ops,
+ .priv_auto_alloc_size = sizeof(struct sandbox_hub_priv),
+ .per_child_platdata_auto_alloc_size =
+ sizeof(struct sandbox_hub_platdata),
+ .child_post_bind = sandbox_child_post_bind,
+};
diff --git a/drivers/usb/emul/usb-emul-uclass.c b/drivers/usb/emul/usb-emul-uclass.c
new file mode 100644
index 0000000000..205f2c54df
--- /dev/null
+++ b/drivers/usb/emul/usb-emul-uclass.c
@@ -0,0 +1,263 @@
+/*
+ * (C) Copyright 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <usb.h>
+#include <dm/root.h>
+#include <dm/device-internal.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static int copy_to_unicode(char *buff, int length, const char *str)
+{
+ int ptr;
+ int i;
+
+ if (length < 2)
+ return 0;
+ buff[1] = USB_DT_STRING;
+ for (ptr = 2, i = 0; ptr + 1 < length && *str; i++, ptr += 2) {
+ buff[ptr] = str[i];
+ buff[ptr + 1] = 0;
+ }
+ buff[0] = ptr;
+
+ return ptr;
+}
+
+static int usb_emul_get_string(struct usb_string *strings, int index,
+ char *buff, int length)
+{
+ if (index == 0) {
+ char *desc = buff;
+
+ desc[0] = 4;
+ desc[1] = USB_DT_STRING;
+ desc[2] = 0x09;
+ desc[3] = 0x14;
+ return 4;
+ } else if (strings) {
+ struct usb_string *ptr;
+
+ for (ptr = strings; ptr->s; ptr++) {
+ if (ptr->id == index)
+ return copy_to_unicode(buff, length, ptr->s);
+ }
+ }
+
+ return -EINVAL;
+}
+
+static struct usb_generic_descriptor **find_descriptor(
+ struct usb_generic_descriptor **ptr, int type, int index)
+{
+ debug("%s: type=%x, index=%d\n", __func__, type, index);
+ for (; *ptr; ptr++) {
+ if ((*ptr)->bDescriptorType != type)
+ continue;
+ switch (type) {
+ case USB_DT_CONFIG: {
+ struct usb_config_descriptor *cdesc;
+
+ cdesc = (struct usb_config_descriptor *)*ptr;
+ if (cdesc && cdesc->bConfigurationValue == index)
+ return ptr;
+ break;
+ }
+ default:
+ return ptr;
+ }
+ }
+ debug("%s: config ptr=%p\n", __func__, *ptr);
+
+ return ptr;
+}
+
+static int usb_emul_get_descriptor(struct usb_dev_platdata *plat, int value,
+ void *buffer, int length)
+{
+ struct usb_generic_descriptor **ptr;
+ int type = value >> 8;
+ int index = value & 0xff;
+ int upto, todo;
+
+ debug("%s: type=%d, index=%d, plat=%p\n", __func__, type, index, plat);
+ if (type == USB_DT_STRING) {
+ return usb_emul_get_string(plat->strings, index, buffer,
+ length);
+ }
+
+ ptr = find_descriptor((struct usb_generic_descriptor **)plat->desc_list,
+ type, index);
+ if (!ptr) {
+ debug("%s: Could not find descriptor type %d, index %d\n",
+ __func__, type, index);
+ return -ENOENT;
+ }
+ for (upto = 0; *ptr && upto < length; ptr++, upto += todo) {
+ todo = min(length - upto, (int)(*ptr)->bLength);
+
+ memcpy(buffer + upto, *ptr, todo);
+ }
+
+ return upto ? upto : length ? -EIO : 0;
+}
+
+int usb_emul_find(struct udevice *bus, ulong pipe, struct udevice **emulp)
+{
+ int devnum = usb_pipedevice(pipe);
+ struct udevice *dev;
+ struct uclass *uc;
+ int ret;
+
+ *emulp = NULL;
+ ret = uclass_get(UCLASS_USB_EMUL, &uc);
+ if (ret)
+ return ret;
+ uclass_foreach_dev(dev, uc) {
+ struct usb_dev_platdata *udev = dev_get_parent_platdata(dev);
+
+ if (udev->devnum == devnum) {
+ debug("%s: Found emulator '%s', addr %d\n", __func__,
+ dev->name, udev->devnum);
+ *emulp = dev;
+ return 0;
+ }
+ }
+
+ debug("%s: No emulator found, addr %d\n", __func__, devnum);
+ return -ENOENT;
+}
+
+int usb_emul_control(struct udevice *emul, struct usb_device *udev,
+ unsigned long pipe, void *buffer, int length,
+ struct devrequest *setup)
+{
+ struct dm_usb_ops *ops = usb_get_emul_ops(emul);
+ struct usb_dev_platdata *plat;
+ int ret;
+
+ /* We permit getting the descriptor before we are probed */
+ plat = dev_get_parent_platdata(emul);
+ if (!ops->control)
+ return -ENOSYS;
+ debug("%s: dev=%s\n", __func__, emul->name);
+ if (pipe == usb_rcvctrlpipe(udev, 0)) {
+ switch (setup->request) {
+ case USB_REQ_GET_DESCRIPTOR: {
+ return usb_emul_get_descriptor(plat, setup->value,
+ buffer, length);
+ }
+ default:
+ ret = device_probe(emul);
+ if (ret)
+ return ret;
+ return ops->control(emul, udev, pipe, buffer, length,
+ setup);
+ }
+ } else if (pipe == usb_snddefctrl(udev)) {
+ switch (setup->request) {
+ case USB_REQ_SET_ADDRESS:
+ debug(" ** set address %s %d\n", emul->name,
+ setup->value);
+ plat->devnum = setup->value;
+ return 0;
+ default:
+ debug("requestsend =%x\n", setup->request);
+ break;
+ }
+ } else if (pipe == usb_sndctrlpipe(udev, 0)) {
+ switch (setup->request) {
+ case USB_REQ_SET_CONFIGURATION:
+ plat->configno = setup->value;
+ return 0;
+ default:
+ ret = device_probe(emul);
+ if (ret)
+ return ret;
+ return ops->control(emul, udev, pipe, buffer, length,
+ setup);
+ }
+ }
+ debug("pipe=%lx\n", pipe);
+
+ return -EIO;
+}
+
+int usb_emul_bulk(struct udevice *emul, struct usb_device *udev,
+ unsigned long pipe, void *buffer, int length)
+{
+ struct dm_usb_ops *ops = usb_get_emul_ops(emul);
+ int ret;
+
+ /* We permit getting the descriptor before we are probed */
+ if (!ops->bulk)
+ return -ENOSYS;
+ debug("%s: dev=%s\n", __func__, emul->name);
+ ret = device_probe(emul);
+ if (ret)
+ return ret;
+ return ops->bulk(emul, udev, pipe, buffer, length);
+}
+
+int usb_emul_setup_device(struct udevice *dev, int maxpacketsize,
+ struct usb_string *strings, void **desc_list)
+{
+ struct usb_dev_platdata *plat = dev_get_parent_platdata(dev);
+ struct usb_generic_descriptor **ptr;
+ struct usb_config_descriptor *cdesc;
+ int upto;
+
+ plat->strings = strings;
+ plat->desc_list = (struct usb_generic_descriptor **)desc_list;
+
+ /* Fill in wTotalLength for each configuration descriptor */
+ ptr = plat->desc_list;
+ for (cdesc = NULL, upto = 0; *ptr; upto += (*ptr)->bLength, ptr++) {
+ debug(" - upto=%d, type=%d\n", upto, (*ptr)->bDescriptorType);
+ if ((*ptr)->bDescriptorType == USB_DT_CONFIG) {
+ if (cdesc) {
+ cdesc->wTotalLength = upto;
+ debug("%s: config %d length %d\n", __func__,
+ cdesc->bConfigurationValue,
+ cdesc->bLength);
+ }
+ cdesc = (struct usb_config_descriptor *)*ptr;
+ upto = 0;
+ }
+ }
+ if (cdesc) {
+ cdesc->wTotalLength = upto;
+ debug("%s: config %d length %d\n", __func__,
+ cdesc->bConfigurationValue, cdesc->wTotalLength);
+ }
+
+ return 0;
+}
+
+int usb_emul_post_bind(struct udevice *dev)
+{
+ /* Scan the bus for devices */
+ return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false);
+}
+
+void usb_emul_reset(struct udevice *dev)
+{
+ struct usb_dev_platdata *plat = dev_get_parent_platdata(dev);
+
+ plat->devnum = 0;
+ plat->configno = 0;
+}
+
+UCLASS_DRIVER(usb_emul) = {
+ .id = UCLASS_USB_EMUL,
+ .name = "usb_emul",
+ .post_bind = usb_emul_post_bind,
+ .per_child_auto_alloc_size = sizeof(struct usb_device),
+ .per_child_platdata_auto_alloc_size = sizeof(struct usb_dev_platdata),
+};
diff --git a/drivers/usb/eth/asix.c b/drivers/usb/eth/asix.c
index 1cd179baae..c8697ae78d 100644
--- a/drivers/usb/eth/asix.c
+++ b/drivers/usb/eth/asix.c
@@ -534,7 +534,8 @@ static int asix_recv(struct eth_device *eth)
}
/* Notify net stack */
- NetReceive(buf_ptr + sizeof(packet_len), packet_len);
+ net_process_received_packet(buf_ptr + sizeof(packet_len),
+ packet_len);
/* Adjust for next iteration. Packets are padded to 16-bits */
if (packet_len & 1)
diff --git a/drivers/usb/eth/asix88179.c b/drivers/usb/eth/asix88179.c
index 0ef85db7b5..94dfe85eff 100644
--- a/drivers/usb/eth/asix88179.c
+++ b/drivers/usb/eth/asix88179.c
@@ -558,7 +558,7 @@ static int asix_recv(struct eth_device *eth)
frame_pos += 2;
- NetReceive(recv_buf + frame_pos, pkt_len);
+ net_process_received_packet(recv_buf + frame_pos, pkt_len);
pkt_hdr++;
frame_pos += ((pkt_len + 7) & 0xFFF8)-2;
diff --git a/drivers/usb/eth/mcs7830.c b/drivers/usb/eth/mcs7830.c
index 8e738d40e3..c1b708600e 100644
--- a/drivers/usb/eth/mcs7830.c
+++ b/drivers/usb/eth/mcs7830.c
@@ -600,7 +600,7 @@ static int mcs7830_recv(struct eth_device *eth)
if (sts == STAT_RX_FRAME_CORRECT) {
debug("%s() got a frame, len=%d\n", __func__, gotlen);
- NetReceive(buf, gotlen);
+ net_process_received_packet(buf, gotlen);
return 0;
}
diff --git a/drivers/usb/eth/smsc95xx.c b/drivers/usb/eth/smsc95xx.c
index 6bca34dcf5..a7e50d6a6c 100644
--- a/drivers/usb/eth/smsc95xx.c
+++ b/drivers/usb/eth/smsc95xx.c
@@ -355,7 +355,7 @@ static int smsc95xx_init_mac_address(struct eth_device *eth,
/* try reading mac address from EEPROM */
if (smsc95xx_read_eeprom(dev, EEPROM_MAC_OFFSET, ETH_ALEN,
eth->enetaddr) == 0) {
- if (is_valid_ether_addr(eth->enetaddr)) {
+ if (is_valid_ethaddr(eth->enetaddr)) {
/* eeprom values are valid so use them */
debug("MAC address read from EEPROM\n");
return 0;
@@ -760,7 +760,8 @@ static int smsc95xx_recv(struct eth_device *eth)
}
/* Notify net stack */
- NetReceive(buf_ptr + sizeof(packet_len), packet_len - 4);
+ net_process_received_packet(buf_ptr + sizeof(packet_len),
+ packet_len - 4);
/* Adjust for next iteration */
actual_len -= sizeof(packet_len) + packet_len;
diff --git a/drivers/usb/eth/usb_ether.c b/drivers/usb/eth/usb_ether.c
index 7cb96e3bf6..c72b7e47c4 100644
--- a/drivers/usb/eth/usb_ether.c
+++ b/drivers/usb/eth/usb_ether.c
@@ -5,7 +5,9 @@
*/
#include <common.h>
+#include <dm.h>
#include <usb.h>
+#include <dm/device-internal.h>
#include "usb_ether.h"
@@ -118,8 +120,6 @@ static void probe_valid_drivers(struct usb_device *dev)
int usb_host_eth_scan(int mode)
{
int i, old_async;
- struct usb_device *dev;
-
if (mode == 1)
printf(" scanning usb for ethernet devices... ");
@@ -138,23 +138,59 @@ int usb_host_eth_scan(int mode)
}
usb_max_eth_dev = 0;
+#ifdef CONFIG_DM_USB
+ /*
+ * TODO: We should add USB_DEVICE() declarations to each USB ethernet
+ * driver and then most of this file can be removed.
+ */
+ struct udevice *bus;
+ struct uclass *uc;
+ int ret;
+
+ ret = uclass_get(UCLASS_USB, &uc);
+ if (ret)
+ return ret;
+ uclass_foreach_dev(bus, uc) {
+ for (i = 0; i < USB_MAX_DEVICE; i++) {
+ struct usb_device *dev;
+
+ dev = usb_get_dev_index(bus, i); /* get device */
+ debug("i=%d, %s\n", i, dev ? dev->dev->name : "(done)");
+ if (!dev)
+ break; /* no more devices available */
+
+ /*
+ * find valid usb_ether driver for this device,
+ * if any
+ */
+ probe_valid_drivers(dev);
+
+ /* check limit */
+ if (usb_max_eth_dev == USB_MAX_ETH_DEV)
+ break;
+ } /* for */
+ }
+#else
for (i = 0; i < USB_MAX_DEVICE; i++) {
+ struct usb_device *dev;
+
dev = usb_get_dev_index(i); /* get device */
debug("i=%d\n", i);
- if (dev == NULL)
+ if (!dev)
break; /* no more devices available */
/* find valid usb_ether driver for this device, if any */
probe_valid_drivers(dev);
/* check limit */
- if (usb_max_eth_dev == USB_MAX_ETH_DEV) {
- printf("max USB Ethernet Device reached: %d stopping\n",
- usb_max_eth_dev);
+ if (usb_max_eth_dev == USB_MAX_ETH_DEV)
break;
- }
} /* for */
-
+#endif
+ if (usb_max_eth_dev == USB_MAX_ETH_DEV) {
+ printf("max USB Ethernet Device reached: %d stopping\n",
+ usb_max_eth_dev);
+ }
usb_disable_asynch(old_async); /* restore asynch value */
printf("%d Ethernet Device(s) found\n", usb_max_eth_dev);
if (usb_max_eth_dev > 0)
diff --git a/drivers/usb/gadget/ci_udc.c b/drivers/usb/gadget/ci_udc.c
index 3b7024c498..22d288c711 100644
--- a/drivers/usb/gadget/ci_udc.c
+++ b/drivers/usb/gadget/ci_udc.c
@@ -883,7 +883,11 @@ int usb_gadget_register_driver(struct usb_gadget_driver *driver)
if (driver->speed != USB_SPEED_FULL && driver->speed != USB_SPEED_HIGH)
return -EINVAL;
+#ifdef CONFIG_DM_USB
+ ret = usb_setup_ehci_gadget(&controller.ctrl);
+#else
ret = usb_lowlevel_init(0, USB_INIT_DEVICE, (void **)&controller.ctrl);
+#endif
if (ret)
return ret;
diff --git a/drivers/usb/gadget/ether.c b/drivers/usb/gadget/ether.c
index 7e3b3ed859..141ff8be59 100644
--- a/drivers/usb/gadget/ether.c
+++ b/drivers/usb/gadget/ether.c
@@ -1522,7 +1522,7 @@ static int rx_submit(struct eth_dev *dev, struct usb_request *req,
* RNDIS headers involve variable numbers of LE32 values.
*/
- req->buf = (u8 *) NetRxPackets[0];
+ req->buf = (u8 *)net_rx_packets[0];
req->length = size;
req->complete = rx_complete;
@@ -1645,13 +1645,13 @@ static int eth_start_xmit (struct sk_buff *skb, struct net_device *net)
if (!eth_is_promisc (dev)) {
u8 *dest = skb->data;
- if (is_multicast_ether_addr(dest)) {
+ if (is_multicast_ethaddr(dest)) {
u16 type;
/* ignores USB_CDC_PACKET_TYPE_MULTICAST and host
* SET_ETHERNET_MULTICAST_FILTERS requests
*/
- if (is_broadcast_ether_addr(dest))
+ if (is_broadcast_ethaddr(dest))
type = USB_CDC_PACKET_TYPE_BROADCAST;
else
type = USB_CDC_PACKET_TYPE_ALL_MULTICAST;
@@ -1942,7 +1942,7 @@ static int is_eth_addr_valid(char *str)
}
/* Now check the contents. */
- return is_valid_ether_addr(ea);
+ return is_valid_ethaddr(ea);
}
return 0;
}
@@ -1971,7 +1971,7 @@ static int get_ether_addr(const char *str, u8 *dev_addr)
num |= (nibble(*str++));
dev_addr[i] = num;
}
- if (is_valid_ether_addr(dev_addr))
+ if (is_valid_ethaddr(dev_addr))
return 0;
}
return 1;
@@ -2446,7 +2446,8 @@ static int usb_eth_recv(struct eth_device *netdev)
if (packet_received) {
debug("%s: packet received\n", __func__);
if (dev->rx_req) {
- NetReceive(NetRxPackets[0], dev->rx_req->length);
+ net_process_received_packet(net_rx_packets[0],
+ dev->rx_req->length);
packet_received = 0;
rx_submit(dev, dev->rx_req, 0);
diff --git a/drivers/usb/host/Makefile b/drivers/usb/host/Makefile
index eb6f34b53c..7658f873e0 100644
--- a/drivers/usb/host/Makefile
+++ b/drivers/usb/host/Makefile
@@ -5,6 +5,11 @@
# SPDX-License-Identifier: GPL-2.0+
#
+ifdef CONFIG_DM_USB
+obj-$(CONFIG_CMD_USB) += usb-uclass.o
+obj-$(CONFIG_SANDBOX) += usb-sandbox.o
+endif
+
# ohci
obj-$(CONFIG_USB_OHCI_NEW) += ohci-hcd.o
obj-$(CONFIG_USB_ATMEL) += ohci-at91.o
diff --git a/drivers/usb/host/ehci-exynos.c b/drivers/usb/host/ehci-exynos.c
index f3c077d82e..86cf6312fe 100644
--- a/drivers/usb/host/ehci-exynos.c
+++ b/drivers/usb/host/ehci-exynos.c
@@ -8,6 +8,7 @@
*/
#include <common.h>
+#include <dm.h>
#include <fdtdec.h>
#include <libfdt.h>
#include <malloc.h>
@@ -24,19 +25,73 @@
/* Declare global data pointer */
DECLARE_GLOBAL_DATA_PTR;
+#ifdef CONFIG_DM_USB
+struct exynos_ehci_platdata {
+ struct usb_platdata usb_plat;
+ fdt_addr_t hcd_base;
+ fdt_addr_t phy_base;
+ struct gpio_desc vbus_gpio;
+};
+#endif
+
/**
* Contains pointers to register base addresses
* for the usb controller.
*/
struct exynos_ehci {
+ struct ehci_ctrl ctrl;
struct exynos_usb_phy *usb;
struct ehci_hccr *hcd;
+#ifndef CONFIG_DM_USB
struct gpio_desc vbus_gpio;
+#endif
};
+#ifndef CONFIG_DM_USB
static struct exynos_ehci exynos;
+#endif
-#ifdef CONFIG_OF_CONTROL
+#ifdef CONFIG_DM_USB
+static int ehci_usb_ofdata_to_platdata(struct udevice *dev)
+{
+ struct exynos_ehci_platdata *plat = dev_get_platdata(dev);
+ const void *blob = gd->fdt_blob;
+ unsigned int node;
+ int depth;
+
+ /*
+ * Get the base address for XHCI controller from the device node
+ */
+ plat->hcd_base = dev_get_addr(dev);
+ if (plat->hcd_base == FDT_ADDR_T_NONE) {
+ debug("Can't get the XHCI register base address\n");
+ return -ENXIO;
+ }
+
+ depth = 0;
+ node = fdtdec_next_compatible_subnode(blob, dev->of_offset,
+ COMPAT_SAMSUNG_EXYNOS_USB_PHY, &depth);
+ if (node <= 0) {
+ debug("XHCI: Can't get device node for usb3-phy controller\n");
+ return -ENODEV;
+ }
+
+ /*
+ * Get the base address for usbphy from the device node
+ */
+ plat->phy_base = fdtdec_get_addr(blob, node, "reg");
+ if (plat->phy_base == FDT_ADDR_T_NONE) {
+ debug("Can't get the usbphy register address\n");
+ return -ENXIO;
+ }
+
+ /* Vbus gpio */
+ gpio_request_by_name(dev, "samsung,vbus-gpio", 0,
+ &plat->vbus_gpio, GPIOD_IS_OUT);
+
+ return 0;
+}
+#else
static int exynos_usb_parse_dt(const void *blob, struct exynos_ehci *exynos)
{
fdt_addr_t addr;
@@ -215,6 +270,7 @@ static void reset_usb_phy(struct exynos_usb_phy *usb)
set_usbhost_phy_ctrl(POWER_USB_HOST_PHY_CTRL_DISABLE);
}
+#ifndef CONFIG_DM_USB
/*
* EHCI-initialization
* Create the appropriate control structures to manage
@@ -268,3 +324,57 @@ int ehci_hcd_stop(int index)
return 0;
}
+#endif
+
+#ifdef CONFIG_DM_USB
+static int ehci_usb_probe(struct udevice *dev)
+{
+ struct exynos_ehci_platdata *plat = dev_get_platdata(dev);
+ struct exynos_ehci *ctx = dev_get_priv(dev);
+ struct ehci_hcor *hcor;
+
+ ctx->hcd = (struct ehci_hccr *)plat->hcd_base;
+ ctx->usb = (struct exynos_usb_phy *)plat->phy_base;
+ hcor = (struct ehci_hcor *)((uint32_t)ctx->hcd +
+ HC_LENGTH(ehci_readl(&ctx->hcd->cr_capbase)));
+
+ /* setup the Vbus gpio here */
+ if (dm_gpio_is_valid(&plat->vbus_gpio))
+ dm_gpio_set_value(&plat->vbus_gpio, 1);
+
+ setup_usb_phy(ctx->usb);
+
+ return ehci_register(dev, ctx->hcd, hcor, NULL, 0, USB_INIT_HOST);
+}
+
+static int ehci_usb_remove(struct udevice *dev)
+{
+ struct exynos_ehci *ctx = dev_get_priv(dev);
+ int ret;
+
+ ret = ehci_deregister(dev);
+ if (ret)
+ return ret;
+ reset_usb_phy(ctx->usb);
+
+ return 0;
+}
+
+static const struct udevice_id ehci_usb_ids[] = {
+ { .compatible = "samsung,exynos-ehci" },
+ { }
+};
+
+U_BOOT_DRIVER(usb_ehci) = {
+ .name = "ehci_exynos",
+ .id = UCLASS_USB,
+ .of_match = ehci_usb_ids,
+ .ofdata_to_platdata = ehci_usb_ofdata_to_platdata,
+ .probe = ehci_usb_probe,
+ .remove = ehci_usb_remove,
+ .ops = &ehci_usb_ops,
+ .priv_auto_alloc_size = sizeof(struct exynos_ehci),
+ .platdata_auto_alloc_size = sizeof(struct exynos_ehci_platdata),
+ .flags = DM_FLAG_ALLOC_PRIV_DMA,
+};
+#endif
diff --git a/drivers/usb/host/ehci-faraday.c b/drivers/usb/host/ehci-faraday.c
index 3b761bc326..821222cc5d 100644
--- a/drivers/usb/host/ehci-faraday.c
+++ b/drivers/usb/host/ehci-faraday.c
@@ -29,6 +29,59 @@ static inline int ehci_is_fotg2xx(union ehci_faraday_regs *regs)
return !readl(&regs->usb.easstr);
}
+void faraday_ehci_set_usbmode(struct ehci_ctrl *ctrl)
+{
+ /* nothing needs to be done */
+}
+
+int faraday_ehci_get_port_speed(struct ehci_ctrl *ctrl, uint32_t reg)
+{
+ int spd, ret = PORTSC_PSPD_HS;
+ union ehci_faraday_regs *regs;
+
+ ret = (void __iomem *)((ulong)ctrl->hcor - 0x10);
+ if (ehci_is_fotg2xx(regs))
+ spd = OTGCSR_SPD(readl(&regs->otg.otgcsr));
+ else
+ spd = BMCSR_SPD(readl(&regs->usb.bmcsr));
+
+ switch (spd) {
+ case 0: /* full speed */
+ ret = PORTSC_PSPD_FS;
+ break;
+ case 1: /* low speed */
+ ret = PORTSC_PSPD_LS;
+ break;
+ case 2: /* high speed */
+ ret = PORTSC_PSPD_HS;
+ break;
+ default:
+ printf("ehci-faraday: invalid device speed\n");
+ break;
+ }
+
+ return ret;
+}
+
+uint32_t *faraday_ehci_get_portsc_register(struct ehci_ctrl *ctrl, int port)
+{
+ /* Faraday EHCI has one and only one portsc register */
+ if (port) {
+ /* Printing the message would cause a scan failure! */
+ debug("The request port(%d) is not configured\n", port);
+ return NULL;
+ }
+
+ /* Faraday EHCI PORTSC register offset is 0x20 from hcor */
+ return (uint32_t *)((uint8_t *)ctrl->hcor + 0x20);
+}
+
+static const struct ehci_ops faraday_ehci_ops = {
+ .set_usb_mode = faraday_ehci_set_usbmode,
+ .get_port_speed = faraday_ehci_get_port_speed,
+ .get_portsc_register = faraday_ehci_get_portsc_register,
+};
+
/*
* Create the appropriate control structures to manage
* a new EHCI host controller.
@@ -43,6 +96,7 @@ int ehci_hcd_init(int index, enum usb_init_type init,
if (index < 0 || index >= ARRAY_SIZE(base_list))
return -1;
+ ehci_set_controller_priv(index, NULL, &faraday_ehci_ops);
regs = (void __iomem *)base_list[index];
hccr = (struct ehci_hccr *)&regs->usb.hccr;
hcor = (struct ehci_hcor *)&regs->usb.hcor;
@@ -87,61 +141,3 @@ int ehci_hcd_stop(int index)
{
return 0;
}
-
-/*
- * This ehci_set_usbmode() overrides the weak function
- * in "ehci-hcd.c".
- */
-void ehci_set_usbmode(int index)
-{
- /* nothing needs to be done */
-}
-
-/*
- * This ehci_get_port_speed() overrides the weak function
- * in "ehci-hcd.c".
- */
-int ehci_get_port_speed(struct ehci_hcor *hcor, uint32_t reg)
-{
- int spd, ret = PORTSC_PSPD_HS;
- union ehci_faraday_regs *regs = (void __iomem *)((ulong)hcor - 0x10);
-
- if (ehci_is_fotg2xx(regs))
- spd = OTGCSR_SPD(readl(&regs->otg.otgcsr));
- else
- spd = BMCSR_SPD(readl(&regs->usb.bmcsr));
-
- switch (spd) {
- case 0: /* full speed */
- ret = PORTSC_PSPD_FS;
- break;
- case 1: /* low speed */
- ret = PORTSC_PSPD_LS;
- break;
- case 2: /* high speed */
- ret = PORTSC_PSPD_HS;
- break;
- default:
- printf("ehci-faraday: invalid device speed\n");
- break;
- }
-
- return ret;
-}
-
-/*
- * This ehci_get_portsc_register() overrides the weak function
- * in "ehci-hcd.c".
- */
-uint32_t *ehci_get_portsc_register(struct ehci_hcor *hcor, int port)
-{
- /* Faraday EHCI has one and only one portsc register */
- if (port) {
- /* Printing the message would cause a scan failure! */
- debug("The request port(%d) is not configured\n", port);
- return NULL;
- }
-
- /* Faraday EHCI PORTSC register offset is 0x20 from hcor */
- return (uint32_t *)((uint8_t *)hcor + 0x20);
-}
diff --git a/drivers/usb/host/ehci-hcd.c b/drivers/usb/host/ehci-hcd.c
index 86f1646596..bd9861dd68 100644
--- a/drivers/usb/host/ehci-hcd.c
+++ b/drivers/usb/host/ehci-hcd.c
@@ -21,6 +21,7 @@
* MA 02111-1307 USA
*/
#include <common.h>
+#include <dm.h>
#include <errno.h>
#include <asm/byteorder.h>
#include <asm/unaligned.h>
@@ -42,7 +43,9 @@
*/
#define HCHALT_TIMEOUT (8 * 1000)
+#ifndef CONFIG_DM_USB
static struct ehci_ctrl ehcic[CONFIG_USB_MAX_CONTROLLER_COUNT];
+#endif
#define ALIGN_END_ADDR(type, ptr, size) \
((unsigned long)(ptr) + roundup((size) * sizeof(type), USB_DMA_MINALIGN))
@@ -119,17 +122,33 @@ static struct descriptor {
#define ehci_is_TDI() (0)
#endif
-__weak int ehci_get_port_speed(struct ehci_hcor *hcor, uint32_t reg)
+static struct ehci_ctrl *ehci_get_ctrl(struct usb_device *udev)
+{
+#ifdef CONFIG_DM_USB
+ struct udevice *dev;
+
+ /* Find the USB controller */
+ for (dev = udev->dev;
+ device_get_uclass_id(dev) != UCLASS_USB;
+ dev = dev->parent)
+ ;
+ return dev_get_priv(dev);
+#else
+ return udev->controller;
+#endif
+}
+
+static int ehci_get_port_speed(struct ehci_ctrl *ctrl, uint32_t reg)
{
return PORTSC_PSPD(reg);
}
-__weak void ehci_set_usbmode(int index)
+static void ehci_set_usbmode(struct ehci_ctrl *ctrl)
{
uint32_t tmp;
uint32_t *reg_ptr;
- reg_ptr = (uint32_t *)((u8 *)&ehcic[index].hcor->or_usbcmd + USBMODE);
+ reg_ptr = (uint32_t *)((u8 *)&ctrl->hcor->or_usbcmd + USBMODE);
tmp = ehci_readl(reg_ptr);
tmp |= USBMODE_CM_HC;
#if defined(CONFIG_EHCI_MMIO_BIG_ENDIAN)
@@ -138,11 +157,23 @@ __weak void ehci_set_usbmode(int index)
ehci_writel(reg_ptr, tmp);
}
-__weak void ehci_powerup_fixup(uint32_t *status_reg, uint32_t *reg)
+static void ehci_powerup_fixup(struct ehci_ctrl *ctrl, uint32_t *status_reg,
+ uint32_t *reg)
{
mdelay(50);
}
+static uint32_t *ehci_get_portsc_register(struct ehci_ctrl *ctrl, int port)
+{
+ if (port < 0 || port >= CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) {
+ /* Printing the message would cause a scan failure! */
+ debug("The request port(%u) is not configured\n", port);
+ return NULL;
+ }
+
+ return (uint32_t *)&ctrl->hcor->or_portsc[port];
+}
+
static int handshake(uint32_t *ptr, uint32_t mask, uint32_t done, int usec)
{
uint32_t result;
@@ -159,15 +190,15 @@ static int handshake(uint32_t *ptr, uint32_t mask, uint32_t done, int usec)
return -1;
}
-static int ehci_reset(int index)
+static int ehci_reset(struct ehci_ctrl *ctrl)
{
uint32_t cmd;
int ret = 0;
- cmd = ehci_readl(&ehcic[index].hcor->or_usbcmd);
+ cmd = ehci_readl(&ctrl->hcor->or_usbcmd);
cmd = (cmd & ~CMD_RUN) | CMD_RESET;
- ehci_writel(&ehcic[index].hcor->or_usbcmd, cmd);
- ret = handshake((uint32_t *)&ehcic[index].hcor->or_usbcmd,
+ ehci_writel(&ctrl->hcor->or_usbcmd, cmd);
+ ret = handshake((uint32_t *)&ctrl->hcor->or_usbcmd,
CMD_RESET, 0, 250 * 1000);
if (ret < 0) {
printf("EHCI fail to reset\n");
@@ -175,13 +206,13 @@ static int ehci_reset(int index)
}
if (ehci_is_TDI())
- ehci_set_usbmode(index);
+ ctrl->ops.set_usb_mode(ctrl);
#ifdef CONFIG_USB_EHCI_TXFIFO_THRESH
- cmd = ehci_readl(&ehcic[index].hcor->or_txfilltuning);
+ cmd = ehci_readl(&ctrl->hcor->or_txfilltuning);
cmd &= ~TXFIFO_THRESH_MASK;
cmd |= TXFIFO_THRESH(CONFIG_USB_EHCI_TXFIFO_THRESH);
- ehci_writel(&ehcic[index].hcor->or_txfilltuning, cmd);
+ ehci_writel(&ctrl->hcor->or_txfilltuning, cmd);
#endif
out:
return ret;
@@ -264,12 +295,13 @@ static inline u8 ehci_encode_speed(enum usb_device_speed speed)
return QH_FULL_SPEED;
}
-static void ehci_update_endpt2_dev_n_port(struct usb_device *dev,
+static void ehci_update_endpt2_dev_n_port(struct usb_device *udev,
struct QH *qh)
{
struct usb_device *ttdev;
+ int parent_devnum;
- if (dev->speed != USB_SPEED_LOW && dev->speed != USB_SPEED_FULL)
+ if (udev->speed != USB_SPEED_LOW && udev->speed != USB_SPEED_FULL)
return;
/*
@@ -277,14 +309,35 @@ static void ehci_update_endpt2_dev_n_port(struct usb_device *dev,
* the tt, so of the first upstream usb-2 hub, there may be usb-1 hubs
* in the tree before that one!
*/
- ttdev = dev;
+#ifdef CONFIG_DM_USB
+ struct udevice *parent;
+
+ for (ttdev = udev; ; ) {
+ struct udevice *dev = ttdev->dev;
+
+ if (dev->parent &&
+ device_get_uclass_id(dev->parent) == UCLASS_USB_HUB)
+ parent = dev->parent;
+ else
+ parent = NULL;
+ if (!parent)
+ return;
+ ttdev = dev_get_parentdata(parent);
+ if (!ttdev->speed != USB_SPEED_HIGH)
+ break;
+ }
+ parent_devnum = ttdev->devnum;
+#else
+ ttdev = udev;
while (ttdev->parent && ttdev->parent->speed != USB_SPEED_HIGH)
ttdev = ttdev->parent;
if (!ttdev->parent)
return;
+ parent_devnum = ttdev->parent->devnum;
+#endif
qh->qh_endpt2 |= cpu_to_hc32(QH_ENDPT2_PORTNUM(ttdev->portnr) |
- QH_ENDPT2_HUBADDR(ttdev->parent->devnum));
+ QH_ENDPT2_HUBADDR(parent_devnum));
}
static int
@@ -303,7 +356,7 @@ ehci_submit_async(struct usb_device *dev, unsigned long pipe, void *buffer,
uint32_t cmd;
int timeout;
int ret = 0;
- struct ehci_ctrl *ctrl = dev->controller;
+ struct ehci_ctrl *ctrl = ehci_get_ctrl(dev);
debug("dev=%p, pipe=%lx, buffer=%p, length=%d, req=%p\n", dev, pipe,
buffer, length, req);
@@ -649,20 +702,8 @@ fail:
return -1;
}
-__weak uint32_t *ehci_get_portsc_register(struct ehci_hcor *hcor, int port)
-{
- if (port < 0 || port >= CONFIG_SYS_USB_EHCI_MAX_ROOT_PORTS) {
- /* Printing the message would cause a scan failure! */
- debug("The request port(%u) is not configured\n", port);
- return NULL;
- }
-
- return (uint32_t *)&hcor->or_portsc[port];
-}
-
-int
-ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
- int length, struct devrequest *req)
+static int ehci_submit_root(struct usb_device *dev, unsigned long pipe,
+ void *buffer, int length, struct devrequest *req)
{
uint8_t tmpbuf[4];
u16 typeReq;
@@ -671,7 +712,7 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
uint32_t reg;
uint32_t *status_reg;
int port = le16_to_cpu(req->index) & 0xff;
- struct ehci_ctrl *ctrl = dev->controller;
+ struct ehci_ctrl *ctrl = ehci_get_ctrl(dev);
srclen = 0;
@@ -686,7 +727,7 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
case USB_REQ_GET_STATUS | ((USB_RT_PORT | USB_DIR_IN) << 8):
case USB_REQ_SET_FEATURE | ((USB_DIR_OUT | USB_RT_PORT) << 8):
case USB_REQ_CLEAR_FEATURE | ((USB_DIR_OUT | USB_RT_PORT) << 8):
- status_reg = ehci_get_portsc_register(ctrl->hcor, port - 1);
+ status_reg = ctrl->ops.get_portsc_register(ctrl, port - 1);
if (!status_reg)
return -1;
break;
@@ -781,7 +822,7 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
tmpbuf[1] |= USB_PORT_STAT_POWER >> 8;
if (ehci_is_TDI()) {
- switch (ehci_get_port_speed(ctrl->hcor, reg)) {
+ switch (ctrl->ops.get_port_speed(ctrl, reg)) {
case PORTSC_PSPD_FS:
break;
case PORTSC_PSPD_LS:
@@ -843,7 +884,7 @@ ehci_submit_root(struct usb_device *dev, unsigned long pipe, void *buffer,
* usb 2.0 specification say 50 ms resets on
* root
*/
- ehci_powerup_fixup(status_reg, &reg);
+ ctrl->ops.powerup_fixup(ctrl, status_reg, &reg);
ehci_writel(status_reg, reg & ~EHCI_PS_PR);
/*
@@ -930,41 +971,59 @@ unknown:
return -1;
}
-int usb_lowlevel_stop(int index)
+const struct ehci_ops default_ehci_ops = {
+ .set_usb_mode = ehci_set_usbmode,
+ .get_port_speed = ehci_get_port_speed,
+ .powerup_fixup = ehci_powerup_fixup,
+ .get_portsc_register = ehci_get_portsc_register,
+};
+
+static void ehci_setup_ops(struct ehci_ctrl *ctrl, const struct ehci_ops *ops)
{
- ehci_shutdown(&ehcic[index]);
- return ehci_hcd_stop(index);
+ if (!ops) {
+ ctrl->ops = default_ehci_ops;
+ } else {
+ ctrl->ops = *ops;
+ if (!ctrl->ops.set_usb_mode)
+ ctrl->ops.set_usb_mode = ehci_set_usbmode;
+ if (!ctrl->ops.get_port_speed)
+ ctrl->ops.get_port_speed = ehci_get_port_speed;
+ if (!ctrl->ops.powerup_fixup)
+ ctrl->ops.powerup_fixup = ehci_powerup_fixup;
+ if (!ctrl->ops.get_portsc_register)
+ ctrl->ops.get_portsc_register =
+ ehci_get_portsc_register;
+ }
}
-int usb_lowlevel_init(int index, enum usb_init_type init, void **controller)
+#ifndef CONFIG_DM_USB
+void ehci_set_controller_priv(int index, void *priv, const struct ehci_ops *ops)
+{
+ struct ehci_ctrl *ctrl = &ehcic[index];
+
+ ctrl->priv = priv;
+ ehci_setup_ops(ctrl, ops);
+}
+
+void *ehci_get_controller_priv(int index)
+{
+ return ehcic[index].priv;
+}
+#endif
+
+static int ehci_common_init(struct ehci_ctrl *ctrl, uint tweaks)
{
- uint32_t reg;
- uint32_t cmd;
struct QH *qh_list;
struct QH *periodic;
+ uint32_t reg;
+ uint32_t cmd;
int i;
- int rc;
-
- rc = ehci_hcd_init(index, init, &ehcic[index].hccr, &ehcic[index].hcor);
- if (rc)
- return rc;
- if (init == USB_INIT_DEVICE)
- goto done;
- /* EHCI spec section 4.1 */
- if (ehci_reset(index))
- return -1;
-
-#if defined(CONFIG_EHCI_HCD_INIT_AFTER_RESET)
- rc = ehci_hcd_init(index, init, &ehcic[index].hccr, &ehcic[index].hcor);
- if (rc)
- return rc;
-#endif
/* Set the high address word (aka segment) for 64-bit controller */
- if (ehci_readl(&ehcic[index].hccr->cr_hccparams) & 1)
- ehci_writel(&ehcic[index].hcor->or_ctrldssegment, 0);
+ if (ehci_readl(&ctrl->hccr->cr_hccparams) & 1)
+ ehci_writel(&ctrl->hcor->or_ctrldssegment, 0);
- qh_list = &ehcic[index].qh_list;
+ qh_list = &ctrl->qh_list;
/* Set head of reclaim list */
memset(qh_list, 0, sizeof(*qh_list));
@@ -980,14 +1039,14 @@ int usb_lowlevel_init(int index, enum usb_init_type init, void **controller)
ALIGN_END_ADDR(struct QH, qh_list, 1));
/* Set async. queue head pointer. */
- ehci_writel(&ehcic[index].hcor->or_asynclistaddr, (unsigned long)qh_list);
+ ehci_writel(&ctrl->hcor->or_asynclistaddr, (unsigned long)qh_list);
/*
* Set up periodic list
* Step 1: Parent QH for all periodic transfers.
*/
- ehcic[index].periodic_schedules = 0;
- periodic = &ehcic[index].periodic_queue;
+ ctrl->periodic_schedules = 0;
+ periodic = &ctrl->periodic_queue;
memset(periodic, 0, sizeof(*periodic));
periodic->qh_link = cpu_to_hc32(QH_LINK_TERMINATE);
periodic->qh_overlay.qt_next = cpu_to_hc32(QT_NEXT_TERMINATE);
@@ -1005,25 +1064,25 @@ int usb_lowlevel_init(int index, enum usb_init_type init, void **controller)
* Split Transactions will be spread across microframes using
* S-mask and C-mask.
*/
- if (ehcic[index].periodic_list == NULL)
- ehcic[index].periodic_list = memalign(4096, 1024 * 4);
+ if (ctrl->periodic_list == NULL)
+ ctrl->periodic_list = memalign(4096, 1024 * 4);
- if (!ehcic[index].periodic_list)
+ if (!ctrl->periodic_list)
return -ENOMEM;
for (i = 0; i < 1024; i++) {
- ehcic[index].periodic_list[i] = cpu_to_hc32((unsigned long)periodic
+ ctrl->periodic_list[i] = cpu_to_hc32((unsigned long)periodic
| QH_LINK_TYPE_QH);
}
- flush_dcache_range((unsigned long)ehcic[index].periodic_list,
- ALIGN_END_ADDR(uint32_t, ehcic[index].periodic_list,
+ flush_dcache_range((unsigned long)ctrl->periodic_list,
+ ALIGN_END_ADDR(uint32_t, ctrl->periodic_list,
1024));
/* Set periodic list base address */
- ehci_writel(&ehcic[index].hcor->or_periodiclistbase,
- (unsigned long)ehcic[index].periodic_list);
+ ehci_writel(&ctrl->hcor->or_periodiclistbase,
+ (unsigned long)ctrl->periodic_list);
- reg = ehci_readl(&ehcic[index].hccr->cr_hcsparams);
+ reg = ehci_readl(&ctrl->hccr->cr_hcsparams);
descriptor.hub.bNbrPorts = HCS_N_PORTS(reg);
debug("Register %x NbrPorts %d\n", reg, descriptor.hub.bNbrPorts);
/* Port Indicators */
@@ -1036,37 +1095,81 @@ int usb_lowlevel_init(int index, enum usb_init_type init, void **controller)
| 0x01, &descriptor.hub.wHubCharacteristics);
/* Start the host controller. */
- cmd = ehci_readl(&ehcic[index].hcor->or_usbcmd);
+ cmd = ehci_readl(&ctrl->hcor->or_usbcmd);
/*
* Philips, Intel, and maybe others need CMD_RUN before the
* root hub will detect new devices (why?); NEC doesn't
*/
cmd &= ~(CMD_LRESET|CMD_IAAD|CMD_PSE|CMD_ASE|CMD_RESET);
cmd |= CMD_RUN;
- ehci_writel(&ehcic[index].hcor->or_usbcmd, cmd);
+ ehci_writel(&ctrl->hcor->or_usbcmd, cmd);
-#ifndef CONFIG_USB_EHCI_FARADAY
- /* take control over the ports */
- cmd = ehci_readl(&ehcic[index].hcor->or_configflag);
- cmd |= FLAG_CF;
- ehci_writel(&ehcic[index].hcor->or_configflag, cmd);
-#endif
+ if (!(tweaks & EHCI_TWEAK_NO_INIT_CF)) {
+ /* take control over the ports */
+ cmd = ehci_readl(&ctrl->hcor->or_configflag);
+ cmd |= FLAG_CF;
+ ehci_writel(&ctrl->hcor->or_configflag, cmd);
+ }
/* unblock posted write */
- cmd = ehci_readl(&ehcic[index].hcor->or_usbcmd);
+ cmd = ehci_readl(&ctrl->hcor->or_usbcmd);
mdelay(5);
- reg = HC_VERSION(ehci_readl(&ehcic[index].hccr->cr_capbase));
+ reg = HC_VERSION(ehci_readl(&ctrl->hccr->cr_capbase));
printf("USB EHCI %x.%02x\n", reg >> 8, reg & 0xff);
- ehcic[index].rootdev = 0;
+ return 0;
+}
+
+#ifndef CONFIG_DM_USB
+int usb_lowlevel_stop(int index)
+{
+ ehci_shutdown(&ehcic[index]);
+ return ehci_hcd_stop(index);
+}
+
+int usb_lowlevel_init(int index, enum usb_init_type init, void **controller)
+{
+ struct ehci_ctrl *ctrl = &ehcic[index];
+ uint tweaks = 0;
+ int rc;
+
+ /**
+ * Set ops to default_ehci_ops, ehci_hcd_init should call
+ * ehci_set_controller_priv to change any of these function pointers.
+ */
+ ctrl->ops = default_ehci_ops;
+
+ rc = ehci_hcd_init(index, init, &ctrl->hccr, &ctrl->hcor);
+ if (rc)
+ return rc;
+ if (init == USB_INIT_DEVICE)
+ goto done;
+
+ /* EHCI spec section 4.1 */
+ if (ehci_reset(ctrl))
+ return -1;
+
+#if defined(CONFIG_EHCI_HCD_INIT_AFTER_RESET)
+ rc = ehci_hcd_init(index, init, &ctrl->hccr, &ctrl->hcor);
+ if (rc)
+ return rc;
+#endif
+#ifdef CONFIG_USB_EHCI_FARADAY
+ tweaks |= EHCI_TWEAK_NO_INIT_CF;
+#endif
+ rc = ehci_common_init(ctrl, tweaks);
+ if (rc)
+ return rc;
+
+ ctrl->rootdev = 0;
done:
*controller = &ehcic[index];
return 0;
}
+#endif
-int
-submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
- int length)
+static int _ehci_submit_bulk_msg(struct usb_device *dev, unsigned long pipe,
+ void *buffer, int length)
{
if (usb_pipetype(pipe) != PIPE_BULK) {
@@ -1076,11 +1179,11 @@ submit_bulk_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
return ehci_submit_async(dev, pipe, buffer, length, NULL);
}
-int
-submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
- int length, struct devrequest *setup)
+static int _ehci_submit_control_msg(struct usb_device *dev, unsigned long pipe,
+ void *buffer, int length,
+ struct devrequest *setup)
{
- struct ehci_ctrl *ctrl = dev->controller;
+ struct ehci_ctrl *ctrl = ehci_get_ctrl(dev);
if (usb_pipetype(pipe) != PIPE_CONTROL) {
debug("non-control pipe (type=%lu)", usb_pipetype(pipe));
@@ -1150,7 +1253,7 @@ struct int_queue *
create_int_queue(struct usb_device *dev, unsigned long pipe, int queuesize,
int elementsize, void *buffer, int interval)
{
- struct ehci_ctrl *ctrl = dev->controller;
+ struct ehci_ctrl *ctrl = ehci_get_ctrl(dev);
struct int_queue *result = NULL;
int i;
@@ -1342,7 +1445,7 @@ void *poll_int_queue(struct usb_device *dev, struct int_queue *queue)
int
destroy_int_queue(struct usb_device *dev, struct int_queue *queue)
{
- struct ehci_ctrl *ctrl = dev->controller;
+ struct ehci_ctrl *ctrl = ehci_get_ctrl(dev);
int result = -1;
unsigned long timeout;
@@ -1386,9 +1489,8 @@ out:
return result;
}
-int
-submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
- int length, int interval)
+static int _ehci_submit_int_msg(struct usb_device *dev, unsigned long pipe,
+ void *buffer, int length, int interval)
{
void *backbuffer;
struct int_queue *queue;
@@ -1423,3 +1525,98 @@ submit_int_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
/* everything worked out fine */
return result;
}
+
+#ifndef CONFIG_DM_USB
+int submit_bulk_msg(struct usb_device *dev, unsigned long pipe,
+ void *buffer, int length)
+{
+ return _ehci_submit_bulk_msg(dev, pipe, buffer, length);
+}
+
+int submit_control_msg(struct usb_device *dev, unsigned long pipe, void *buffer,
+ int length, struct devrequest *setup)
+{
+ return _ehci_submit_control_msg(dev, pipe, buffer, length, setup);
+}
+
+int submit_int_msg(struct usb_device *dev, unsigned long pipe,
+ void *buffer, int length, int interval)
+{
+ return _ehci_submit_int_msg(dev, pipe, buffer, length, interval);
+}
+#endif
+
+#ifdef CONFIG_DM_USB
+static int ehci_submit_control_msg(struct udevice *dev, struct usb_device *udev,
+ unsigned long pipe, void *buffer, int length,
+ struct devrequest *setup)
+{
+ debug("%s: dev='%s', udev=%p, udev->dev='%s', portnr=%d\n", __func__,
+ dev->name, udev, udev->dev->name, udev->portnr);
+
+ return _ehci_submit_control_msg(udev, pipe, buffer, length, setup);
+}
+
+static int ehci_submit_bulk_msg(struct udevice *dev, struct usb_device *udev,
+ unsigned long pipe, void *buffer, int length)
+{
+ debug("%s: dev='%s', udev=%p\n", __func__, dev->name, udev);
+ return _ehci_submit_bulk_msg(udev, pipe, buffer, length);
+}
+
+static int ehci_submit_int_msg(struct udevice *dev, struct usb_device *udev,
+ unsigned long pipe, void *buffer, int length,
+ int interval)
+{
+ debug("%s: dev='%s', udev=%p\n", __func__, dev->name, udev);
+ return _ehci_submit_int_msg(udev, pipe, buffer, length, interval);
+}
+
+int ehci_register(struct udevice *dev, struct ehci_hccr *hccr,
+ struct ehci_hcor *hcor, const struct ehci_ops *ops,
+ uint tweaks, enum usb_init_type init)
+{
+ struct ehci_ctrl *ctrl = dev_get_priv(dev);
+ int ret;
+
+ debug("%s: dev='%s', ctrl=%p, hccr=%p, hcor=%p, init=%d\n", __func__,
+ dev->name, ctrl, hccr, hcor, init);
+
+ ehci_setup_ops(ctrl, ops);
+ ctrl->hccr = hccr;
+ ctrl->hcor = hcor;
+ ctrl->priv = ctrl;
+
+ if (init == USB_INIT_DEVICE)
+ goto done;
+ ret = ehci_reset(ctrl);
+ if (ret)
+ goto err;
+
+ ret = ehci_common_init(ctrl, tweaks);
+ if (ret)
+ goto err;
+done:
+ return 0;
+err:
+ free(ctrl);
+ debug("%s: failed, ret=%d\n", __func__, ret);
+ return ret;
+}
+
+int ehci_deregister(struct udevice *dev)
+{
+ struct ehci_ctrl *ctrl = dev_get_priv(dev);
+
+ ehci_shutdown(ctrl);
+
+ return 0;
+}
+
+struct dm_usb_ops ehci_usb_ops = {
+ .control = ehci_submit_control_msg,
+ .bulk = ehci_submit_bulk_msg,
+ .interrupt = ehci_submit_int_msg,
+};
+
+#endif
diff --git a/drivers/usb/host/ehci-mx5.c b/drivers/usb/host/ehci-mx5.c
index 7566c61284..d3199622eb 100644
--- a/drivers/usb/host/ehci-mx5.c
+++ b/drivers/usb/host/ehci-mx5.c
@@ -218,11 +218,23 @@ void __weak board_ehci_hcd_postinit(struct usb_ehci *ehci, int port)
{
}
+__weak void mx5_ehci_powerup_fixup(struct ehci_ctrl *ctrl, uint32_t *status_reg,
+ uint32_t *reg)
+{
+ mdelay(50);
+}
+
+static const struct ehci_ops mx5_ehci_ops = {
+ .powerup_fixup = mx5_ehci_powerup_fixup,
+};
+
int ehci_hcd_init(int index, enum usb_init_type init,
struct ehci_hccr **hccr, struct ehci_hcor **hcor)
{
struct usb_ehci *ehci;
+ /* The only user for this is efikamx-usb */
+ ehci_set_controller_priv(index, NULL, &mx5_ehci_ops);
set_usboh3_clk();
enable_usboh3_clk(true);
set_usb_phy_clk();
diff --git a/drivers/usb/host/ehci-tegra.c b/drivers/usb/host/ehci-tegra.c
index c6bfbe3999..27705d6627 100644
--- a/drivers/usb/host/ehci-tegra.c
+++ b/drivers/usb/host/ehci-tegra.c
@@ -7,6 +7,7 @@
*/
#include <common.h>
+#include <dm.h>
#include <asm/errno.h>
#include <asm/io.h>
#include <asm-generic/gpio.h>
@@ -20,6 +21,8 @@
#include "ehci.h"
+DECLARE_GLOBAL_DATA_PTR;
+
#define USB1_ADDR_MASK 0xFFFF0000
#define HOSTPC1_DEVLC 0x84
@@ -32,9 +35,11 @@
#endif
#endif
+#ifndef CONFIG_DM_USB
enum {
USB_PORTS_MAX = 3, /* Maximum ports we allow */
};
+#endif
/* Parameters we need for USB */
enum {
@@ -61,14 +66,26 @@ enum dr_mode {
DR_MODE_OTG, /* supports both */
};
+enum usb_ctlr_type {
+ USB_CTLR_T20,
+ USB_CTLR_T30,
+ USB_CTLR_T114,
+
+ USB_CTRL_COUNT,
+};
+
/* Information about a USB port */
struct fdt_usb {
+ struct ehci_ctrl ehci;
struct usb_ctlr *reg; /* address of registers in physical memory */
unsigned utmi:1; /* 1 if port has external tranceiver, else 0 */
unsigned ulpi:1; /* 1 if port has external ULPI transceiver */
unsigned enabled:1; /* 1 to enable, 0 to disable */
unsigned has_legacy_mode:1; /* 1 if this port has legacy mode */
+#ifndef CONFIG_DM_USB
unsigned initialized:1; /* has this port already been initialized? */
+#endif
+ enum usb_ctlr_type type;
enum usb_init_type init_type;
enum dr_mode dr_mode; /* dual role mode */
enum periph_id periph_id;/* peripheral id */
@@ -76,10 +93,10 @@ struct fdt_usb {
struct gpio_desc phy_reset_gpio; /* GPIO to reset ULPI phy */
};
+#ifndef CONFIG_DM_USB
static struct fdt_usb port[USB_PORTS_MAX]; /* List of valid USB ports */
static unsigned port_count; /* Number of available ports */
-/* Port that needs to clear CSC after Port Reset */
-static u32 port_addr_clear_csc;
+#endif
/*
* This table has USB timing parameters for each Oscillator frequency we
@@ -156,13 +173,14 @@ static const u8 utmip_elastic_limit = 16;
static const u8 utmip_hs_sync_start_delay = 9;
struct fdt_usb_controller {
+ /* TODO(sjg@chromium.org): Remove when we only use driver model */
int compat;
/* flag to determine whether controller supports hostpc register */
u32 has_hostpc:1;
const unsigned *pll_parameter;
};
-static struct fdt_usb_controller fdt_usb_controllers[] = {
+static struct fdt_usb_controller fdt_usb_controllers[USB_CTRL_COUNT] = {
{
.compat = COMPAT_NVIDIA_TEGRA20_USB,
.has_hostpc = 0,
@@ -180,40 +198,36 @@ static struct fdt_usb_controller fdt_usb_controllers[] = {
},
};
-static struct fdt_usb_controller *controller;
-
/*
* A known hardware issue where Connect Status Change bit of PORTSC register
* of USB1 controller will be set after Port Reset.
* We have to clear it in order for later device enumeration to proceed.
- * This ehci_powerup_fixup overrides the weak function ehci_powerup_fixup
- * in "ehci-hcd.c".
*/
-void ehci_powerup_fixup(uint32_t *status_reg, uint32_t *reg)
+static void tegra_ehci_powerup_fixup(struct ehci_ctrl *ctrl,
+ uint32_t *status_reg, uint32_t *reg)
{
+ struct fdt_usb *config = ctrl->priv;
+ struct fdt_usb_controller *controller;
+
+ controller = &fdt_usb_controllers[config->type];
mdelay(50);
/* This is to avoid PORT_ENABLE bit to be cleared in "ehci-hcd.c". */
if (controller->has_hostpc)
*reg |= EHCI_PS_PE;
- if (((unsigned long)status_reg & TEGRA_USB_ADDR_MASK) != port_addr_clear_csc)
+ if (!config->has_legacy_mode)
return;
/* For EHCI_PS_CSC to be cleared in ehci_hcd.c */
if (ehci_readl(status_reg) & EHCI_PS_CSC)
*reg |= EHCI_PS_CSC;
}
-/*
- * This ehci_set_usbmode overrides the weak function ehci_set_usbmode
- * in "ehci-hcd.c".
- */
-void ehci_set_usbmode(int index)
+static void tegra_ehci_set_usbmode(struct ehci_ctrl *ctrl)
{
- struct fdt_usb *config;
+ struct fdt_usb *config = ctrl->priv;
struct usb_ctlr *usbctlr;
uint32_t tmp;
- config = &port[index];
usbctlr = config->reg;
tmp = ehci_readl(&usbctlr->usb_mode);
@@ -221,17 +235,17 @@ void ehci_set_usbmode(int index)
ehci_writel(&usbctlr->usb_mode, tmp);
}
-/*
- * This ehci_get_port_speed overrides the weak function ehci_get_port_speed
- * in "ehci-hcd.c".
- */
-int ehci_get_port_speed(struct ehci_hcor *hcor, uint32_t reg)
+static int tegra_ehci_get_port_speed(struct ehci_ctrl *ctrl, uint32_t reg)
{
+ struct fdt_usb *config = ctrl->priv;
+ struct fdt_usb_controller *controller;
uint32_t tmp;
uint32_t *reg_ptr;
+ controller = &fdt_usb_controllers[config->type];
if (controller->has_hostpc) {
- reg_ptr = (uint32_t *)((u8 *)&hcor->or_usbcmd + HOSTPC1_DEVLC);
+ reg_ptr = (uint32_t *)((u8 *)&ctrl->hcor->or_usbcmd +
+ HOSTPC1_DEVLC);
tmp = ehci_readl(reg_ptr);
return HOSTPC1_PSPD(tmp);
} else
@@ -263,7 +277,8 @@ static void set_up_vbus(struct fdt_usb *config, enum usb_init_type init)
}
}
-void usbf_reset_controller(struct fdt_usb *config, struct usb_ctlr *usbctlr)
+static void usbf_reset_controller(struct fdt_usb *config,
+ struct usb_ctlr *usbctlr)
{
/* Reset the USB controller with 2us delay */
reset_periph(config->periph_id, 2);
@@ -283,7 +298,7 @@ void usbf_reset_controller(struct fdt_usb *config, struct usb_ctlr *usbctlr)
setbits_le32(&usbctlr->susp_ctrl, UTMIP_PHY_ENB);
}
-static const unsigned *get_pll_timing(void)
+static const unsigned *get_pll_timing(struct fdt_usb_controller *controller)
{
const unsigned *timing;
@@ -330,6 +345,7 @@ static void init_phy_mux(struct fdt_usb *config, uint pts,
static int init_utmi_usb_controller(struct fdt_usb *config,
enum usb_init_type init)
{
+ struct fdt_usb_controller *controller;
u32 b_sess_valid_mask, val;
int loop_count;
const unsigned *timing;
@@ -362,11 +378,14 @@ static int init_utmi_usb_controller(struct fdt_usb *config,
VBUS_SENSE_CTL_MASK,
VBUS_SENSE_CTL_A_SESS_VLD << VBUS_SENSE_CTL_SHIFT);
+ controller = &fdt_usb_controllers[config->type];
+ debug("controller=%p, type=%d\n", controller, config->type);
+
/*
* PLL Delay CONFIGURATION settings. The following parameters control
* the bring up of the plls.
*/
- timing = get_pll_timing();
+ timing = get_pll_timing(controller);
if (!controller->has_hostpc) {
val = readl(&usbctlr->utmip_misc_cfg1);
@@ -517,7 +536,7 @@ static int init_utmi_usb_controller(struct fdt_usb *config,
udelay(1);
}
if (!loop_count)
- return -1;
+ return -ETIMEDOUT;
/* Disable ICUSB FS/LS transceiver */
clrbits_le32(&usbctlr->icusb_ctrl, IC_ENB1);
@@ -560,6 +579,7 @@ static int init_ulpi_usb_controller(struct fdt_usb *config,
int loop_count;
struct ulpi_viewport ulpi_vp;
struct usb_ctlr *usbctlr = config->reg;
+ int ret;
/* set up ULPI reference clock on pllp_out4 */
clock_enable(PERIPH_ID_DEV2_OUT);
@@ -605,9 +625,10 @@ static int init_ulpi_usb_controller(struct fdt_usb *config,
ulpi_vp.port_num = 0;
ulpi_vp.viewport_addr = (u32)&usbctlr->ulpi_viewport;
- if (ulpi_init(&ulpi_vp)) {
+ ret = ulpi_init(&ulpi_vp);
+ if (ret) {
printf("Tegra ULPI viewport init failed\n");
- return -1;
+ return ret;
}
ulpi_set_vbus(&ulpi_vp, 1, 1);
@@ -624,7 +645,7 @@ static int init_ulpi_usb_controller(struct fdt_usb *config,
udelay(1);
}
if (!loop_count)
- return -1;
+ return -ETIMEDOUT;
clrbits_le32(&usbctlr->susp_ctrl, USB_SUSP_CLR);
return 0;
@@ -635,7 +656,7 @@ static int init_ulpi_usb_controller(struct fdt_usb *config,
{
printf("No code to set up ULPI controller, please enable"
"CONFIG_USB_ULPI and CONFIG_USB_ULPI_VIEWPORT");
- return -1;
+ return -ENOSYS;
}
#endif
@@ -662,7 +683,7 @@ static int fdt_decode_usb(const void *blob, int node, struct fdt_usb *config)
else {
debug("%s: Cannot decode dr_mode '%s'\n", __func__,
mode);
- return -FDT_ERR_NOTFOUND;
+ return -EINVAL;
}
} else {
config->dr_mode = DR_MODE_HOST;
@@ -674,12 +695,10 @@ static int fdt_decode_usb(const void *blob, int node, struct fdt_usb *config)
config->enabled = fdtdec_get_is_enabled(blob, node);
config->has_legacy_mode = fdtdec_get_bool(blob, node,
"nvidia,has-legacy-mode");
- if (config->has_legacy_mode)
- port_addr_clear_csc = (unsigned long)config->reg;
config->periph_id = clock_decode_periph_id(blob, node);
if (config->periph_id == PERIPH_ID_NONE) {
debug("%s: Missing/invalid peripheral ID\n", __func__);
- return -FDT_ERR_NOTFOUND;
+ return -EINVAL;
}
gpio_request_by_name_nodev(blob, node, "nvidia,vbus-gpio", 0,
&config->vbus_gpio, GPIOD_IS_OUT);
@@ -695,16 +714,101 @@ static int fdt_decode_usb(const void *blob, int node, struct fdt_usb *config)
return 0;
}
+int usb_common_init(struct fdt_usb *config, enum usb_init_type init)
+{
+ int ret = 0;
+
+ switch (init) {
+ case USB_INIT_HOST:
+ switch (config->dr_mode) {
+ case DR_MODE_HOST:
+ case DR_MODE_OTG:
+ break;
+ default:
+ printf("tegrausb: Invalid dr_mode %d for host mode\n",
+ config->dr_mode);
+ return -1;
+ }
+ break;
+ case USB_INIT_DEVICE:
+ if (config->periph_id != PERIPH_ID_USBD) {
+ printf("tegrausb: Device mode only supported on first USB controller\n");
+ return -1;
+ }
+ if (!config->utmi) {
+ printf("tegrausb: Device mode only supported with UTMI PHY\n");
+ return -1;
+ }
+ switch (config->dr_mode) {
+ case DR_MODE_DEVICE:
+ case DR_MODE_OTG:
+ break;
+ default:
+ printf("tegrausb: Invalid dr_mode %d for device mode\n",
+ config->dr_mode);
+ return -1;
+ }
+ break;
+ default:
+ printf("tegrausb: Unknown USB_INIT_* %d\n", init);
+ return -1;
+ }
+
+#ifndef CONFIG_DM_USB
+ /* skip init, if the port is already initialized */
+ if (config->initialized && config->init_type == init)
+ return 0;
+#endif
+
+ debug("%d, %d\n", config->utmi, config->ulpi);
+ if (config->utmi)
+ ret = init_utmi_usb_controller(config, init);
+ else if (config->ulpi)
+ ret = init_ulpi_usb_controller(config, init);
+ if (ret)
+ return ret;
+
+ set_up_vbus(config, init);
+
+ config->init_type = init;
+
+ return 0;
+}
+
+void usb_common_uninit(struct fdt_usb *priv)
+{
+ struct usb_ctlr *usbctlr;
+
+ usbctlr = priv->reg;
+
+ /* Stop controller */
+ writel(0, &usbctlr->usb_cmd);
+ udelay(1000);
+
+ /* Initiate controller reset */
+ writel(2, &usbctlr->usb_cmd);
+ udelay(1000);
+}
+
+static const struct ehci_ops tegra_ehci_ops = {
+ .set_usb_mode = tegra_ehci_set_usbmode,
+ .get_port_speed = tegra_ehci_get_port_speed,
+ .powerup_fixup = tegra_ehci_powerup_fixup,
+};
+
+#ifndef CONFIG_DM_USB
/*
* process_usb_nodes() - Process a list of USB nodes, adding them to our list
* of USB ports.
* @blob: fdt blob
* @node_list: list of nodes to process (any <=0 are ignored)
* @count: number of nodes to process
+ * @id: controller type (enum usb_ctlr_type)
*
* Return: 0 - ok, -1 - error
*/
-static int process_usb_nodes(const void *blob, int node_list[], int count)
+static int process_usb_nodes(const void *blob, int node_list[], int count,
+ enum usb_ctlr_type id)
{
struct fdt_usb config;
int node, i;
@@ -728,9 +832,11 @@ static int process_usb_nodes(const void *blob, int node_list[], int count)
return -1;
}
if (!clk_done) {
- config_clock(get_pll_timing());
+ config_clock(get_pll_timing(
+ &fdt_usb_controllers[id]));
clk_done = 1;
}
+ config.type = id;
config.initialized = 0;
/* add new USB port to the list of available ports */
@@ -747,20 +853,17 @@ int usb_process_devicetree(const void *blob)
int i;
for (i = 0; i < ARRAY_SIZE(fdt_usb_controllers); i++) {
- controller = &fdt_usb_controllers[i];
-
count = fdtdec_find_aliases_for_id(blob, "usb",
- controller->compat, node_list, USB_PORTS_MAX);
+ fdt_usb_controllers[i].compat, node_list,
+ USB_PORTS_MAX);
if (count) {
- err = process_usb_nodes(blob, node_list, count);
+ err = process_usb_nodes(blob, node_list, count, i);
if (err)
printf("%s: Error processing USB node!\n",
__func__);
return err;
}
}
- if (i == ARRAY_SIZE(fdt_usb_controllers))
- controller = NULL;
return err;
}
@@ -780,68 +883,22 @@ int ehci_hcd_init(int index, enum usb_init_type init,
{
struct fdt_usb *config;
struct usb_ctlr *usbctlr;
+ int ret;
if (index >= port_count)
return -1;
config = &port[index];
+ ehci_set_controller_priv(index, config, &tegra_ehci_ops);
- switch (init) {
- case USB_INIT_HOST:
- switch (config->dr_mode) {
- case DR_MODE_HOST:
- case DR_MODE_OTG:
- break;
- default:
- printf("tegrausb: Invalid dr_mode %d for host mode\n",
- config->dr_mode);
- return -1;
- }
- break;
- case USB_INIT_DEVICE:
- if (config->periph_id != PERIPH_ID_USBD) {
- printf("tegrausb: Device mode only supported on first USB controller\n");
- return -1;
- }
- if (!config->utmi) {
- printf("tegrausb: Device mode only supported with UTMI PHY\n");
- return -1;
- }
- switch (config->dr_mode) {
- case DR_MODE_DEVICE:
- case DR_MODE_OTG:
- break;
- default:
- printf("tegrausb: Invalid dr_mode %d for device mode\n",
- config->dr_mode);
- return -1;
- }
- break;
- default:
- printf("tegrausb: Unknown USB_INIT_* %d\n", init);
- return -1;
- }
-
- /* skip init, if the port is already initialized */
- if (config->initialized && config->init_type == init)
- goto success;
-
- if (config->utmi && init_utmi_usb_controller(config, init)) {
- printf("tegrausb: Cannot init port %d\n", index);
- return -1;
- }
-
- if (config->ulpi && init_ulpi_usb_controller(config, init)) {
+ ret = usb_common_init(config, init);
+ if (ret) {
printf("tegrausb: Cannot init port %d\n", index);
- return -1;
+ return ret;
}
- set_up_vbus(config, init);
-
config->initialized = 1;
- config->init_type = init;
-success:
usbctlr = config->reg;
*hccr = (struct ehci_hccr *)&usbctlr->cap_length;
*hcor = (struct ehci_hcor *)&usbctlr->usb_cmd;
@@ -854,19 +911,80 @@ success:
*/
int ehci_hcd_stop(int index)
{
- struct usb_ctlr *usbctlr;
+ usb_common_uninit(&port[index]);
- usbctlr = port[index].reg;
+ port[index].initialized = 0;
- /* Stop controller */
- writel(0, &usbctlr->usb_cmd);
- udelay(1000);
+ return 0;
+}
+#endif /* !CONFIG_DM_USB */
- /* Initiate controller reset */
- writel(2, &usbctlr->usb_cmd);
- udelay(1000);
+#ifdef CONFIG_DM_USB
+static int ehci_usb_ofdata_to_platdata(struct udevice *dev)
+{
+ struct fdt_usb *priv = dev_get_priv(dev);
+ int ret;
- port[index].initialized = 0;
+ ret = fdt_decode_usb(gd->fdt_blob, dev->of_offset, priv);
+ if (ret)
+ return ret;
+
+ priv->type = dev_get_driver_data(dev);
+
+ return 0;
+}
+
+static int ehci_usb_probe(struct udevice *dev)
+{
+ struct usb_platdata *plat = dev_get_platdata(dev);
+ struct fdt_usb *priv = dev_get_priv(dev);
+ struct ehci_hccr *hccr;
+ struct ehci_hcor *hcor;
+ static bool clk_done;
+ int ret;
+
+ ret = usb_common_init(priv, plat->init_type);
+ if (ret)
+ return ret;
+ hccr = (struct ehci_hccr *)&priv->reg->cap_length;
+ hcor = (struct ehci_hcor *)&priv->reg->usb_cmd;
+ if (!clk_done) {
+ config_clock(get_pll_timing(&fdt_usb_controllers[priv->type]));
+ clk_done = true;
+ }
+
+ return ehci_register(dev, hccr, hcor, &tegra_ehci_ops, 0,
+ plat->init_type);
+}
+
+static int ehci_usb_remove(struct udevice *dev)
+{
+ int ret;
+
+ ret = ehci_deregister(dev);
+ if (ret)
+ return ret;
return 0;
}
+
+static const struct udevice_id ehci_usb_ids[] = {
+ { .compatible = "nvidia,tegra20-ehci", .data = USB_CTLR_T20 },
+ { .compatible = "nvidia,tegra30-ehci", .data = USB_CTLR_T30 },
+ { .compatible = "nvidia,tegra114-ehci", .data = USB_CTLR_T114 },
+ { }
+};
+
+U_BOOT_DRIVER(usb_ehci) = {
+ .name = "ehci_tegra",
+ .id = UCLASS_USB,
+ .of_match = ehci_usb_ids,
+ .ofdata_to_platdata = ehci_usb_ofdata_to_platdata,
+ .probe = ehci_usb_probe,
+ .remove = ehci_usb_remove,
+ .ops = &ehci_usb_ops,
+ .platdata_auto_alloc_size = sizeof(struct usb_platdata),
+ .priv_auto_alloc_size = sizeof(struct fdt_usb),
+ .flags = DM_FLAG_ALLOC_PRIV_DMA,
+};
+#endif
diff --git a/drivers/usb/host/ehci.h b/drivers/usb/host/ehci.h
index 79aecd414e..774282d287 100644
--- a/drivers/usb/host/ehci.h
+++ b/drivers/usb/host/ehci.h
@@ -238,6 +238,22 @@ struct QH {
};
};
+/* Tweak flags for EHCI, used to control operation */
+enum {
+ /* don't use or_configflag in init */
+ EHCI_TWEAK_NO_INIT_CF = 1 << 0,
+};
+
+struct ehci_ctrl;
+
+struct ehci_ops {
+ void (*set_usb_mode)(struct ehci_ctrl *ctrl);
+ int (*get_port_speed)(struct ehci_ctrl *ctrl, uint32_t reg);
+ void (*powerup_fixup)(struct ehci_ctrl *ctrl, uint32_t *status_reg,
+ uint32_t *reg);
+ uint32_t *(*get_portsc_register)(struct ehci_ctrl *ctrl, int port);
+};
+
struct ehci_ctrl {
struct ehci_hccr *hccr; /* R/O registers, not need for volatile */
struct ehci_hcor *hcor;
@@ -248,11 +264,42 @@ struct ehci_ctrl {
uint32_t *periodic_list;
int periodic_schedules;
int ntds;
+ struct ehci_ops ops;
+ void *priv; /* client's private data */
};
+/**
+ * ehci_set_controller_info() - Set up private data for the controller
+ *
+ * This function can be called in ehci_hcd_init() to tell the EHCI layer
+ * about the controller's private data pointer. Then in the above functions
+ * this can be accessed given the struct ehci_ctrl pointer. Also special
+ * EHCI operation methods can be provided if required
+ *
+ * @index: Controller number to set
+ * @priv: Controller pointer
+ * @ops: Controller operations, or NULL to use default
+ */
+void ehci_set_controller_priv(int index, void *priv,
+ const struct ehci_ops *ops);
+
+/**
+ * ehci_get_controller_priv() - Get controller private data
+ *
+ * @index Controller number to get
+ * @return controller pointer for this index
+ */
+void *ehci_get_controller_priv(int index);
+
/* Low level init functions */
int ehci_hcd_init(int index, enum usb_init_type init,
struct ehci_hccr **hccr, struct ehci_hcor **hcor);
int ehci_hcd_stop(int index);
+int ehci_register(struct udevice *dev, struct ehci_hccr *hccr,
+ struct ehci_hcor *hcor, const struct ehci_ops *ops,
+ uint tweaks, enum usb_init_type init);
+int ehci_deregister(struct udevice *dev);
+extern struct dm_usb_ops ehci_usb_ops;
+
#endif /* USB_EHCI_H */
diff --git a/drivers/usb/host/usb-sandbox.c b/drivers/usb/host/usb-sandbox.c
new file mode 100644
index 0000000000..c5f9822040
--- /dev/null
+++ b/drivers/usb/host/usb-sandbox.c
@@ -0,0 +1,117 @@
+/*
+ * (C) Copyright 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <usb.h>
+#include <dm/root.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static void usbmon_trace(struct udevice *bus, ulong pipe,
+ struct devrequest *setup, struct udevice *emul)
+{
+ static const char types[] = "ZICB";
+ int type;
+
+ type = (pipe & USB_PIPE_TYPE_MASK) >> USB_PIPE_TYPE_SHIFT;
+ debug("0 0 S %c%c:%d:%03ld:%ld", types[type],
+ pipe & USB_DIR_IN ? 'i' : 'o',
+ bus->seq,
+ (pipe & USB_PIPE_DEV_MASK) >> USB_PIPE_DEV_SHIFT,
+ (pipe & USB_PIPE_EP_MASK) >> USB_PIPE_EP_SHIFT);
+ if (setup) {
+ debug(" s %02x %02x %04x %04x %04x", setup->requesttype,
+ setup->request, setup->value, setup->index,
+ setup->length);
+ }
+ debug(" %s", emul ? emul->name : "(no emul found)");
+
+ debug("\n");
+}
+
+static int sandbox_submit_control(struct udevice *bus,
+ struct usb_device *udev,
+ unsigned long pipe,
+ void *buffer, int length,
+ struct devrequest *setup)
+{
+ struct udevice *emul;
+ int ret;
+
+ /* Just use child of dev as emulator? */
+ debug("%s: bus=%s\n", __func__, bus->name);
+ ret = usb_emul_find(bus, pipe, &emul);
+ usbmon_trace(bus, pipe, setup, emul);
+ if (ret)
+ return ret;
+ ret = usb_emul_control(emul, udev, pipe, buffer, length, setup);
+ if (ret < 0) {
+ debug("ret=%d\n", ret);
+ udev->status = ret;
+ udev->act_len = 0;
+ } else {
+ udev->status = 0;
+ udev->act_len = ret;
+ }
+
+ return ret;
+}
+
+static int sandbox_submit_bulk(struct udevice *bus, struct usb_device *udev,
+ unsigned long pipe, void *buffer, int length)
+{
+ struct udevice *emul;
+ int ret;
+
+ /* Just use child of dev as emulator? */
+ debug("%s: bus=%s\n", __func__, bus->name);
+ ret = usb_emul_find(bus, pipe, &emul);
+ usbmon_trace(bus, pipe, NULL, emul);
+ if (ret)
+ return ret;
+ ret = usb_emul_bulk(emul, udev, pipe, buffer, length);
+ if (ret < 0) {
+ debug("ret=%d\n", ret);
+ udev->status = ret;
+ udev->act_len = 0;
+ } else {
+ udev->status = 0;
+ udev->act_len = ret;
+ }
+
+ return ret;
+}
+
+static int sandbox_alloc_device(struct udevice *dev, struct usb_device *udev)
+{
+ return 0;
+}
+
+static int sandbox_usb_probe(struct udevice *dev)
+{
+ return 0;
+}
+
+static const struct dm_usb_ops sandbox_usb_ops = {
+ .control = sandbox_submit_control,
+ .bulk = sandbox_submit_bulk,
+ .alloc_device = sandbox_alloc_device,
+};
+
+static const struct udevice_id sandbox_usb_ids[] = {
+ { .compatible = "sandbox,usb" },
+ { }
+};
+
+U_BOOT_DRIVER(usb_sandbox) = {
+ .name = "usb_sandbox",
+ .id = UCLASS_USB,
+ .of_match = sandbox_usb_ids,
+ .probe = sandbox_usb_probe,
+ .ops = &sandbox_usb_ops,
+};
diff --git a/drivers/usb/host/usb-uclass.c b/drivers/usb/host/usb-uclass.c
new file mode 100644
index 0000000000..714bc0e958
--- /dev/null
+++ b/drivers/usb/host/usb-uclass.c
@@ -0,0 +1,645 @@
+/*
+ * (C) Copyright 2015 Google, Inc
+ * Written by Simon Glass <sjg@chromium.org>
+ *
+ * usb_match_device() modified from Linux kernel v4.0.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <errno.h>
+#include <usb.h>
+#include <dm/device-internal.h>
+#include <dm/lists.h>
+#include <dm/root.h>
+#include <dm/uclass-internal.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+extern bool usb_started; /* flag for the started/stopped USB status */
+static bool asynch_allowed;
+
+int usb_disable_asynch(int disable)
+{
+ int old_value = asynch_allowed;
+
+ asynch_allowed = !disable;
+ return old_value;
+}
+
+int submit_int_msg(struct usb_device *udev, unsigned long pipe, void *buffer,
+ int length, int interval)
+{
+ struct udevice *bus = udev->controller_dev;
+ struct dm_usb_ops *ops = usb_get_ops(bus);
+
+ if (!ops->interrupt)
+ return -ENOSYS;
+
+ return ops->interrupt(bus, udev, pipe, buffer, length, interval);
+}
+
+int submit_control_msg(struct usb_device *udev, unsigned long pipe,
+ void *buffer, int length, struct devrequest *setup)
+{
+ struct udevice *bus = udev->controller_dev;
+ struct dm_usb_ops *ops = usb_get_ops(bus);
+
+ if (!ops->control)
+ return -ENOSYS;
+
+ return ops->control(bus, udev, pipe, buffer, length, setup);
+}
+
+int submit_bulk_msg(struct usb_device *udev, unsigned long pipe, void *buffer,
+ int length)
+{
+ struct udevice *bus = udev->controller_dev;
+ struct dm_usb_ops *ops = usb_get_ops(bus);
+
+ if (!ops->bulk)
+ return -ENOSYS;
+
+ return ops->bulk(bus, udev, pipe, buffer, length);
+}
+
+int usb_alloc_device(struct usb_device *udev)
+{
+ struct udevice *bus = udev->controller_dev;
+ struct dm_usb_ops *ops = usb_get_ops(bus);
+
+ /* This is only requird by some controllers - current XHCI */
+ if (!ops->alloc_device)
+ return 0;
+
+ return ops->alloc_device(bus, udev);
+}
+
+int usb_stop(void)
+{
+ struct udevice *bus;
+ struct uclass *uc;
+ int err = 0, ret;
+
+ /* De-activate any devices that have been activated */
+ ret = uclass_get(UCLASS_USB, &uc);
+ if (ret)
+ return ret;
+ uclass_foreach_dev(bus, uc) {
+ ret = device_remove(bus);
+ if (ret && !err)
+ err = ret;
+ }
+
+#ifdef CONFIG_SANDBOX
+ struct udevice *dev;
+
+ /* Reset all enulation devices */
+ ret = uclass_get(UCLASS_USB_EMUL, &uc);
+ if (ret)
+ return ret;
+
+ uclass_foreach_dev(dev, uc)
+ usb_emul_reset(dev);
+#endif
+ usb_stor_reset();
+ usb_hub_reset();
+ usb_started = 0;
+
+ return err;
+}
+
+static int usb_scan_bus(struct udevice *bus, bool recurse)
+{
+ struct usb_bus_priv *priv;
+ struct udevice *dev;
+ int ret;
+
+ priv = dev_get_uclass_priv(bus);
+
+ assert(recurse); /* TODO: Support non-recusive */
+
+ ret = usb_scan_device(bus, 0, USB_SPEED_FULL, &dev);
+ if (ret)
+ return ret;
+
+ return priv->next_addr;
+}
+
+int usb_init(void)
+{
+ int controllers_initialized = 0;
+ struct udevice *bus;
+ struct uclass *uc;
+ int count = 0;
+ int ret;
+
+ asynch_allowed = 1;
+ usb_hub_reset();
+
+ ret = uclass_get(UCLASS_USB, &uc);
+ if (ret)
+ return ret;
+
+ uclass_foreach_dev(bus, uc) {
+ /* init low_level USB */
+ count++;
+ printf("USB");
+ printf("%d: ", bus->seq);
+ ret = device_probe(bus);
+ if (ret == -ENODEV) { /* No such device. */
+ puts("Port not available.\n");
+ controllers_initialized++;
+ continue;
+ }
+
+ if (ret) { /* Other error. */
+ printf("probe failed, error %d\n", ret);
+ continue;
+ }
+ /*
+ * lowlevel init is OK, now scan the bus for devices
+ * i.e. search HUBs and configure them
+ */
+ controllers_initialized++;
+ printf("scanning bus %d for devices... ", bus->seq);
+ debug("\n");
+ ret = usb_scan_bus(bus, true);
+ if (ret < 0)
+ printf("failed, error %d\n", ret);
+ else if (!ret)
+ printf("No USB Device found\n");
+ else
+ printf("%d USB Device(s) found\n", ret);
+ usb_started = true;
+ }
+
+ debug("scan end\n");
+ /* if we were not able to find at least one working bus, bail out */
+ if (!count)
+ printf("No controllers found\n");
+ else if (controllers_initialized == 0)
+ printf("USB error: all controllers failed lowlevel init\n");
+
+ return usb_started ? 0 : -1;
+}
+
+int usb_reset_root_port(void)
+{
+ return -ENOSYS;
+}
+
+static struct usb_device *find_child_devnum(struct udevice *parent, int devnum)
+{
+ struct usb_device *udev;
+ struct udevice *dev;
+
+ if (!device_active(parent))
+ return NULL;
+ udev = dev_get_parentdata(parent);
+ if (udev->devnum == devnum)
+ return udev;
+
+ for (device_find_first_child(parent, &dev);
+ dev;
+ device_find_next_child(&dev)) {
+ udev = find_child_devnum(dev, devnum);
+ if (udev)
+ return udev;
+ }
+
+ return NULL;
+}
+
+struct usb_device *usb_get_dev_index(struct udevice *bus, int index)
+{
+ struct udevice *hub;
+ int devnum = index + 1; /* Addresses are allocated from 1 on USB */
+
+ device_find_first_child(bus, &hub);
+ if (device_get_uclass_id(hub) == UCLASS_USB_HUB)
+ return find_child_devnum(hub, devnum);
+
+ return NULL;
+}
+
+int usb_post_bind(struct udevice *dev)
+{
+ /* Scan the bus for devices */
+ return dm_scan_fdt_node(dev, gd->fdt_blob, dev->of_offset, false);
+}
+
+int usb_port_reset(struct usb_device *parent, int portnr)
+{
+ unsigned short portstatus;
+ int ret;
+
+ debug("%s: start\n", __func__);
+
+ if (parent) {
+ /* reset the port for the second time */
+ assert(portnr > 0);
+ debug("%s: reset %d\n", __func__, portnr - 1);
+ ret = legacy_hub_port_reset(parent, portnr - 1, &portstatus);
+ if (ret < 0) {
+ printf("\n Couldn't reset port %i\n", portnr);
+ return ret;
+ }
+ } else {
+ debug("%s: reset root\n", __func__);
+ usb_reset_root_port();
+ }
+
+ return 0;
+}
+
+int usb_legacy_port_reset(struct usb_device *parent, int portnr)
+{
+ return usb_port_reset(parent, portnr);
+}
+
+int usb_setup_ehci_gadget(struct ehci_ctrl **ctlrp)
+{
+ struct usb_platdata *plat;
+ struct udevice *dev;
+ int ret;
+
+ /* Find the old device and remove it */
+ ret = uclass_find_device_by_seq(UCLASS_USB, 0, true, &dev);
+ if (ret)
+ return ret;
+ ret = device_remove(dev);
+ if (ret)
+ return ret;
+
+ plat = dev_get_platdata(dev);
+ plat->init_type = USB_INIT_DEVICE;
+ ret = device_probe(dev);
+ if (ret)
+ return ret;
+ *ctlrp = dev_get_priv(dev);
+
+ return 0;
+}
+
+/* returns 0 if no match, 1 if match */
+int usb_match_device(const struct usb_device_descriptor *desc,
+ const struct usb_device_id *id)
+{
+ if ((id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&
+ id->idVendor != le16_to_cpu(desc->idVendor))
+ return 0;
+
+ if ((id->match_flags & USB_DEVICE_ID_MATCH_PRODUCT) &&
+ id->idProduct != le16_to_cpu(desc->idProduct))
+ return 0;
+
+ /* No need to test id->bcdDevice_lo != 0, since 0 is never
+ greater than any unsigned number. */
+ if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_LO) &&
+ (id->bcdDevice_lo > le16_to_cpu(desc->bcdDevice)))
+ return 0;
+
+ if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_HI) &&
+ (id->bcdDevice_hi < le16_to_cpu(desc->bcdDevice)))
+ return 0;
+
+ if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_CLASS) &&
+ (id->bDeviceClass != desc->bDeviceClass))
+ return 0;
+
+ if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_SUBCLASS) &&
+ (id->bDeviceSubClass != desc->bDeviceSubClass))
+ return 0;
+
+ if ((id->match_flags & USB_DEVICE_ID_MATCH_DEV_PROTOCOL) &&
+ (id->bDeviceProtocol != desc->bDeviceProtocol))
+ return 0;
+
+ return 1;
+}
+
+/* returns 0 if no match, 1 if match */
+int usb_match_one_id_intf(const struct usb_device_descriptor *desc,
+ const struct usb_interface_descriptor *int_desc,
+ const struct usb_device_id *id)
+{
+ /* The interface class, subclass, protocol and number should never be
+ * checked for a match if the device class is Vendor Specific,
+ * unless the match record specifies the Vendor ID. */
+ if (desc->bDeviceClass == USB_CLASS_VENDOR_SPEC &&
+ !(id->match_flags & USB_DEVICE_ID_MATCH_VENDOR) &&
+ (id->match_flags & (USB_DEVICE_ID_MATCH_INT_CLASS |
+ USB_DEVICE_ID_MATCH_INT_SUBCLASS |
+ USB_DEVICE_ID_MATCH_INT_PROTOCOL |
+ USB_DEVICE_ID_MATCH_INT_NUMBER)))
+ return 0;
+
+ if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_CLASS) &&
+ (id->bInterfaceClass != int_desc->bInterfaceClass))
+ return 0;
+
+ if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_SUBCLASS) &&
+ (id->bInterfaceSubClass != int_desc->bInterfaceSubClass))
+ return 0;
+
+ if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_PROTOCOL) &&
+ (id->bInterfaceProtocol != int_desc->bInterfaceProtocol))
+ return 0;
+
+ if ((id->match_flags & USB_DEVICE_ID_MATCH_INT_NUMBER) &&
+ (id->bInterfaceNumber != int_desc->bInterfaceNumber))
+ return 0;
+
+ return 1;
+}
+
+/* returns 0 if no match, 1 if match */
+int usb_match_one_id(struct usb_device_descriptor *desc,
+ struct usb_interface_descriptor *int_desc,
+ const struct usb_device_id *id)
+{
+ if (!usb_match_device(desc, id))
+ return 0;
+
+ return usb_match_one_id_intf(desc, int_desc, id);
+}
+
+/**
+ * usb_find_and_bind_driver() - Find and bind the right USB driver
+ *
+ * This only looks at certain fields in the descriptor.
+ */
+static int usb_find_and_bind_driver(struct udevice *parent,
+ struct usb_device_descriptor *desc,
+ struct usb_interface_descriptor *iface,
+ int bus_seq, int devnum,
+ struct udevice **devp)
+{
+ struct usb_driver_entry *start, *entry;
+ int n_ents;
+ int ret;
+ char name[30], *str;
+
+ *devp = NULL;
+ debug("%s: Searching for driver\n", __func__);
+ start = ll_entry_start(struct usb_driver_entry, usb_driver_entry);
+ n_ents = ll_entry_count(struct usb_driver_entry, usb_driver_entry);
+ for (entry = start; entry != start + n_ents; entry++) {
+ const struct usb_device_id *id;
+ struct udevice *dev;
+ const struct driver *drv;
+ struct usb_dev_platdata *plat;
+
+ for (id = entry->match; id->match_flags; id++) {
+ if (!usb_match_one_id(desc, iface, id))
+ continue;
+
+ drv = entry->driver;
+ /*
+ * We could pass the descriptor to the driver as
+ * platdata (instead of NULL) and allow its bind()
+ * method to return -ENOENT if it doesn't support this
+ * device. That way we could continue the search to
+ * find another driver. For now this doesn't seem
+ * necesssary, so just bind the first match.
+ */
+ ret = device_bind(parent, drv, drv->name, NULL, -1,
+ &dev);
+ if (ret)
+ goto error;
+ debug("%s: Match found: %s\n", __func__, drv->name);
+ dev->driver_data = id->driver_info;
+ plat = dev_get_parent_platdata(dev);
+ plat->id = *id;
+ *devp = dev;
+ return 0;
+ }
+ }
+
+ /* Bind a generic driver so that the device can be used */
+ snprintf(name, sizeof(name), "generic_bus_%x_dev_%x", bus_seq, devnum);
+ str = strdup(name);
+ if (!str)
+ return -ENOMEM;
+ ret = device_bind_driver(parent, "usb_dev_generic_drv", str, devp);
+
+error:
+ debug("%s: No match found: %d\n", __func__, ret);
+ return ret;
+}
+
+/**
+ * usb_find_child() - Find an existing device which matches our needs
+ *
+ *
+ */
+static int usb_find_child(struct udevice *parent,
+ struct usb_device_descriptor *desc,
+ struct usb_interface_descriptor *iface,
+ struct udevice **devp)
+{
+ struct udevice *dev;
+
+ *devp = NULL;
+ for (device_find_first_child(parent, &dev);
+ dev;
+ device_find_next_child(&dev)) {
+ struct usb_dev_platdata *plat = dev_get_parent_platdata(dev);
+
+ /* If this device is already in use, skip it */
+ if (device_active(dev))
+ continue;
+ debug(" %s: name='%s', plat=%d, desc=%d\n", __func__,
+ dev->name, plat->id.bDeviceClass, desc->bDeviceClass);
+ if (usb_match_one_id(desc, iface, &plat->id)) {
+ *devp = dev;
+ return 0;
+ }
+ }
+
+ return -ENOENT;
+}
+
+int usb_scan_device(struct udevice *parent, int port,
+ enum usb_device_speed speed, struct udevice **devp)
+{
+ struct udevice *dev;
+ bool created = false;
+ struct usb_dev_platdata *plat;
+ struct usb_bus_priv *priv;
+ struct usb_device *parent_udev;
+ int ret;
+ ALLOC_CACHE_ALIGN_BUFFER(struct usb_device, udev, 1);
+ struct usb_interface_descriptor *iface = &udev->config.if_desc[0].desc;
+
+ *devp = NULL;
+ memset(udev, '\0', sizeof(*udev));
+ ret = usb_get_bus(parent, &udev->controller_dev);
+ if (ret)
+ return ret;
+ priv = dev_get_uclass_priv(udev->controller_dev);
+
+ /*
+ * Somewhat nasty, this. We create a local device and use the normal
+ * USB stack to read its descriptor. Then we know what type of device
+ * to create for real.
+ *
+ * udev->dev is set to the parent, since we don't have a real device
+ * yet. The USB stack should not access udev.dev anyway, except perhaps
+ * to find the controller, and the controller will either be @parent,
+ * or some parent of @parent.
+ *
+ * Another option might be to create the device as a generic USB
+ * device, then morph it into the correct one when we know what it
+ * should be. This means that a generic USB device would morph into
+ * a network controller, or a USB flash stick, for example. However,
+ * we don't support such morphing and it isn't clear that it would
+ * be easy to do.
+ *
+ * Yet another option is to split out the USB stack parts of udev
+ * into something like a 'struct urb' (as Linux does) which can exist
+ * independently of any device. This feels cleaner, but calls for quite
+ * a big change to the USB stack.
+ *
+ * For now, the approach is to set up an empty udev, read its
+ * descriptor and assign it an address, then bind a real device and
+ * stash the resulting information into the device's parent
+ * platform data. Then when we probe it, usb_child_pre_probe() is called
+ * and it will pull the information out of the stash.
+ */
+ udev->dev = parent;
+ udev->speed = speed;
+ udev->devnum = priv->next_addr + 1;
+ udev->portnr = port;
+ debug("Calling usb_setup_device(), portnr=%d\n", udev->portnr);
+ parent_udev = device_get_uclass_id(parent) == UCLASS_USB_HUB ?
+ dev_get_parentdata(parent) : NULL;
+ ret = usb_setup_device(udev, priv->desc_before_addr, parent_udev, port);
+ debug("read_descriptor for '%s': ret=%d\n", parent->name, ret);
+ if (ret)
+ return ret;
+ ret = usb_find_child(parent, &udev->descriptor, iface, &dev);
+ debug("** usb_find_child returns %d\n", ret);
+ if (ret) {
+ if (ret != -ENOENT)
+ return ret;
+ ret = usb_find_and_bind_driver(parent, &udev->descriptor, iface,
+ udev->controller_dev->seq,
+ udev->devnum, &dev);
+ if (ret)
+ return ret;
+ created = true;
+ }
+ plat = dev_get_parent_platdata(dev);
+ debug("%s: Probing '%s', plat=%p\n", __func__, dev->name, plat);
+ plat->devnum = udev->devnum;
+ plat->speed = udev->speed;
+ plat->slot_id = udev->slot_id;
+ plat->portnr = port;
+ debug("** device '%s': stashing slot_id=%d\n", dev->name,
+ plat->slot_id);
+ priv->next_addr++;
+ ret = device_probe(dev);
+ if (ret) {
+ debug("%s: Device '%s' probe failed\n", __func__, dev->name);
+ priv->next_addr--;
+ if (created)
+ device_unbind(dev);
+ return ret;
+ }
+ *devp = dev;
+
+ return 0;
+}
+
+int usb_child_post_bind(struct udevice *dev)
+{
+ struct usb_dev_platdata *plat = dev_get_parent_platdata(dev);
+ const void *blob = gd->fdt_blob;
+ int val;
+
+ if (dev->of_offset == -1)
+ return 0;
+
+ /* We only support matching a few things */
+ val = fdtdec_get_int(blob, dev->of_offset, "usb,device-class", -1);
+ if (val != -1) {
+ plat->id.match_flags |= USB_DEVICE_ID_MATCH_DEV_CLASS;
+ plat->id.bDeviceClass = val;
+ }
+ val = fdtdec_get_int(blob, dev->of_offset, "usb,interface-class", -1);
+ if (val != -1) {
+ plat->id.match_flags |= USB_DEVICE_ID_MATCH_INT_CLASS;
+ plat->id.bInterfaceClass = val;
+ }
+
+ return 0;
+}
+
+int usb_get_bus(struct udevice *dev, struct udevice **busp)
+{
+ struct udevice *bus;
+
+ *busp = NULL;
+ for (bus = dev; bus && device_get_uclass_id(bus) != UCLASS_USB; )
+ bus = bus->parent;
+ if (!bus) {
+ /* By design this cannot happen */
+ assert(bus);
+ debug("USB HUB '%s' does not have a controller\n", dev->name);
+ return -EXDEV;
+ }
+ *busp = bus;
+
+ return 0;
+}
+
+int usb_child_pre_probe(struct udevice *dev)
+{
+ struct udevice *bus;
+ struct usb_device *udev = dev_get_parentdata(dev);
+ struct usb_dev_platdata *plat = dev_get_parent_platdata(dev);
+ int ret;
+
+ ret = usb_get_bus(dev, &bus);
+ if (ret)
+ return ret;
+ udev->controller_dev = bus;
+ udev->dev = dev;
+ udev->devnum = plat->devnum;
+ udev->slot_id = plat->slot_id;
+ udev->portnr = plat->portnr;
+ udev->speed = plat->speed;
+ debug("** device '%s': getting slot_id=%d\n", dev->name, plat->slot_id);
+
+ ret = usb_select_config(udev);
+ if (ret)
+ return ret;
+
+ return 0;
+}
+
+UCLASS_DRIVER(usb) = {
+ .id = UCLASS_USB,
+ .name = "usb",
+ .flags = DM_UC_FLAG_SEQ_ALIAS,
+ .post_bind = usb_post_bind,
+ .per_child_auto_alloc_size = sizeof(struct usb_device),
+ .per_device_auto_alloc_size = sizeof(struct usb_bus_priv),
+ .child_post_bind = usb_child_post_bind,
+ .child_pre_probe = usb_child_pre_probe,
+ .per_child_platdata_auto_alloc_size = sizeof(struct usb_dev_platdata),
+};
+
+UCLASS_DRIVER(usb_dev_generic) = {
+ .id = UCLASS_USB_DEV_GENERIC,
+ .name = "usb_dev_generic",
+};
+
+U_BOOT_DRIVER(usb_dev_generic_drv) = {
+ .id = UCLASS_USB_DEV_GENERIC,
+ .name = "usb_dev_generic_drv",
+};
diff --git a/drivers/usb/host/xhci-exynos5.c b/drivers/usb/host/xhci-exynos5.c
index 3f86fdca89..23c7ecc5d8 100644
--- a/drivers/usb/host/xhci-exynos5.c
+++ b/drivers/usb/host/xhci-exynos5.c
@@ -14,6 +14,7 @@
*/
#include <common.h>
+#include <dm.h>
#include <fdtdec.h>
#include <libfdt.h>
#include <malloc.h>
@@ -32,20 +33,76 @@
/* Declare global data pointer */
DECLARE_GLOBAL_DATA_PTR;
+#ifdef CONFIG_DM_USB
+struct exynos_xhci_platdata {
+ fdt_addr_t hcd_base;
+ fdt_addr_t phy_base;
+ struct gpio_desc vbus_gpio;
+};
+#endif
+
/**
* Contains pointers to register base addresses
* for the usb controller.
*/
struct exynos_xhci {
+#ifdef CONFIG_DM_USB
+ struct usb_platdata usb_plat;
+#endif
+ struct xhci_ctrl ctrl;
struct exynos_usb3_phy *usb3_phy;
struct xhci_hccr *hcd;
struct dwc3 *dwc3_reg;
+#ifndef CONFIG_DM_USB
struct gpio_desc vbus_gpio;
+#endif
};
+#ifndef CONFIG_DM_USB
static struct exynos_xhci exynos;
+#endif
-#ifdef CONFIG_OF_CONTROL
+#ifdef CONFIG_DM_USB
+static int xhci_usb_ofdata_to_platdata(struct udevice *dev)
+{
+ struct exynos_xhci_platdata *plat = dev_get_platdata(dev);
+ const void *blob = gd->fdt_blob;
+ unsigned int node;
+ int depth;
+
+ /*
+ * Get the base address for XHCI controller from the device node
+ */
+ plat->hcd_base = fdtdec_get_addr(blob, dev->of_offset, "reg");
+ if (plat->hcd_base == FDT_ADDR_T_NONE) {
+ debug("Can't get the XHCI register base address\n");
+ return -ENXIO;
+ }
+
+ depth = 0;
+ node = fdtdec_next_compatible_subnode(blob, dev->of_offset,
+ COMPAT_SAMSUNG_EXYNOS5_USB3_PHY, &depth);
+ if (node <= 0) {
+ debug("XHCI: Can't get device node for usb3-phy controller\n");
+ return -ENODEV;
+ }
+
+ /*
+ * Get the base address for usbphy from the device node
+ */
+ plat->phy_base = fdtdec_get_addr(blob, node, "reg");
+ if (plat->phy_base == FDT_ADDR_T_NONE) {
+ debug("Can't get the usbphy register address\n");
+ return -ENXIO;
+ }
+
+ /* Vbus gpio */
+ gpio_request_by_name(dev, "samsung,vbus-gpio", 0,
+ &plat->vbus_gpio, GPIOD_IS_OUT);
+
+ return 0;
+}
+#else
static int exynos_usb3_parse_dt(const void *blob, struct exynos_xhci *exynos)
{
fdt_addr_t addr;
@@ -283,6 +340,7 @@ static void exynos_xhci_core_exit(struct exynos_xhci *exynos)
exynos5_usb3_phy_exit(exynos->usb3_phy);
}
+#ifndef CONFIG_DM_USB
int xhci_hcd_init(int index, struct xhci_hccr **hccr, struct xhci_hcor **hcor)
{
struct exynos_xhci *ctx = &exynos;
@@ -326,3 +384,63 @@ void xhci_hcd_stop(int index)
exynos_xhci_core_exit(ctx);
}
+#endif
+
+#ifdef CONFIG_DM_USB
+static int xhci_usb_probe(struct udevice *dev)
+{
+ struct exynos_xhci_platdata *plat = dev_get_platdata(dev);
+ struct exynos_xhci *ctx = dev_get_priv(dev);
+ struct xhci_hcor *hcor;
+ int ret;
+
+ ctx->hcd = (struct xhci_hccr *)plat->hcd_base;
+ ctx->usb3_phy = (struct exynos_usb3_phy *)plat->phy_base;
+ ctx->dwc3_reg = (struct dwc3 *)((char *)(ctx->hcd) + DWC3_REG_OFFSET);
+ hcor = (struct xhci_hcor *)((uint32_t)ctx->hcd +
+ HC_LENGTH(xhci_readl(&ctx->hcd->cr_capbase)));
+
+ /* setup the Vbus gpio here */
+ if (dm_gpio_is_valid(&plat->vbus_gpio))
+ dm_gpio_set_value(&plat->vbus_gpio, 1);
+
+ ret = exynos_xhci_core_init(ctx);
+ if (ret) {
+ puts("XHCI: failed to initialize controller\n");
+ return -EINVAL;
+ }
+
+ return xhci_register(dev, ctx->hcd, hcor);
+}
+
+static int xhci_usb_remove(struct udevice *dev)
+{
+ struct exynos_xhci *ctx = dev_get_priv(dev);
+ int ret;
+
+ ret = xhci_deregister(dev);
+ if (ret)
+ return ret;
+ exynos_xhci_core_exit(ctx);
+
+ return 0;
+}
+
+static const struct udevice_id xhci_usb_ids[] = {
+ { .compatible = "samsung,exynos5250-xhci" },
+ { }
+};
+
+U_BOOT_DRIVER(usb_xhci) = {
+ .name = "xhci_exynos",
+ .id = UCLASS_USB,
+ .of_match = xhci_usb_ids,
+ .ofdata_to_platdata = xhci_usb_ofdata_to_platdata,
+ .probe = xhci_usb_probe,
+ .remove = xhci_usb_remove,
+ .ops = &xhci_usb_ops,
+ .platdata_auto_alloc_size = sizeof(struct exynos_xhci_platdata),
+ .priv_auto_alloc_size = sizeof(struct exynos_xhci),
+ .flags = DM_FLAG_ALLOC_PRIV_DMA,
+};
+#endif
diff --git a/drivers/usb/host/xhci-mem.c b/drivers/usb/host/xhci-mem.c
index 10f11cd547..37444526f7 100644
--- a/drivers/usb/host/xhci-mem.c
+++ b/drivers/usb/host/xhci-mem.c
@@ -15,6 +15,7 @@
*/
#include <common.h>
+#include <dm.h>
#include <asm/byteorder.h>
#include <usb.h>
#include <malloc.h>
@@ -352,12 +353,10 @@ static struct xhci_container_ctx
* @param udev pointer to USB deivce structure
* @return 0 on success else -1 on failure
*/
-int xhci_alloc_virt_device(struct usb_device *udev)
+int xhci_alloc_virt_device(struct xhci_ctrl *ctrl, unsigned int slot_id)
{
u64 byte_64 = 0;
- unsigned int slot_id = udev->slot_id;
struct xhci_virt_device *virt_dev;
- struct xhci_ctrl *ctrl = udev->controller;
/* Slot ID 0 is reserved */
if (ctrl->devs[slot_id]) {
@@ -627,17 +626,16 @@ void xhci_slot_copy(struct xhci_ctrl *ctrl, struct xhci_container_ctx *in_ctx,
* @param udev pointer to the Device Data Structure
* @return returns negative value on failure else 0 on success
*/
-void xhci_setup_addressable_virt_dev(struct usb_device *udev)
+void xhci_setup_addressable_virt_dev(struct xhci_ctrl *ctrl, int slot_id,
+ int speed, int hop_portnr)
{
- struct usb_device *hop = udev;
struct xhci_virt_device *virt_dev;
struct xhci_ep_ctx *ep0_ctx;
struct xhci_slot_ctx *slot_ctx;
u32 port_num = 0;
u64 trb_64 = 0;
- struct xhci_ctrl *ctrl = udev->controller;
- virt_dev = ctrl->devs[udev->slot_id];
+ virt_dev = ctrl->devs[slot_id];
BUG_ON(!virt_dev);
@@ -648,7 +646,7 @@ void xhci_setup_addressable_virt_dev(struct usb_device *udev)
/* Only the control endpoint is valid - one endpoint context */
slot_ctx->dev_info |= cpu_to_le32(LAST_CTX(1) | 0);
- switch (udev->speed) {
+ switch (speed) {
case USB_SPEED_SUPER:
slot_ctx->dev_info |= cpu_to_le32(SLOT_SPEED_SS);
break;
@@ -666,11 +664,7 @@ void xhci_setup_addressable_virt_dev(struct usb_device *udev)
BUG();
}
- /* Extract the root hub port number */
- if (hop->parent)
- while (hop->parent->parent)
- hop = hop->parent;
- port_num = hop->portnr;
+ port_num = hop_portnr;
debug("port_num = %d\n", port_num);
slot_ctx->dev_info2 |=
@@ -680,9 +674,9 @@ void xhci_setup_addressable_virt_dev(struct usb_device *udev)
/* Step 4 - ring already allocated */
/* Step 5 */
ep0_ctx->ep_info2 = cpu_to_le32(CTRL_EP << EP_TYPE_SHIFT);
- debug("SPEED = %d\n", udev->speed);
+ debug("SPEED = %d\n", speed);
- switch (udev->speed) {
+ switch (speed) {
case USB_SPEED_SUPER:
ep0_ctx->ep_info2 |= cpu_to_le32(((512 & MAX_PACKET_MASK) <<
MAX_PACKET_SHIFT));
diff --git a/drivers/usb/host/xhci-ring.c b/drivers/usb/host/xhci-ring.c
index f3759d4036..5a1391fbe3 100644
--- a/drivers/usb/host/xhci-ring.c
+++ b/drivers/usb/host/xhci-ring.c
@@ -353,7 +353,7 @@ static void giveback_first_trb(struct usb_device *udev, int ep_index,
int start_cycle,
struct xhci_generic_trb *start_trb)
{
- struct xhci_ctrl *ctrl = udev->controller;
+ struct xhci_ctrl *ctrl = xhci_get_ctrl(udev);
/*
* Pass all the TRBs to the hardware at once and make sure this write
@@ -477,7 +477,7 @@ union xhci_trb *xhci_wait_for_event(struct xhci_ctrl *ctrl, trb_type expected)
*/
static void abort_td(struct usb_device *udev, int ep_index)
{
- struct xhci_ctrl *ctrl = udev->controller;
+ struct xhci_ctrl *ctrl = xhci_get_ctrl(udev);
struct xhci_ring *ring = ctrl->devs[udev->slot_id]->eps[ep_index].ring;
union xhci_trb *event;
u32 field;
@@ -554,7 +554,7 @@ int xhci_bulk_tx(struct usb_device *udev, unsigned long pipe,
int start_cycle;
u32 field = 0;
u32 length_field = 0;
- struct xhci_ctrl *ctrl = udev->controller;
+ struct xhci_ctrl *ctrl = xhci_get_ctrl(udev);
int slot_id = udev->slot_id;
int ep_index;
struct xhci_virt_device *virt_dev;
@@ -748,7 +748,7 @@ int xhci_ctrl_tx(struct usb_device *udev, unsigned long pipe,
u32 length_field;
u64 buf_64 = 0;
struct xhci_generic_trb *start_trb;
- struct xhci_ctrl *ctrl = udev->controller;
+ struct xhci_ctrl *ctrl = xhci_get_ctrl(udev);
int slot_id = udev->slot_id;
int ep_index;
u32 trb_fields[4];
diff --git a/drivers/usb/host/xhci.c b/drivers/usb/host/xhci.c
index f8b5ce4c36..0b09643e09 100644
--- a/drivers/usb/host/xhci.c
+++ b/drivers/usb/host/xhci.c
@@ -21,6 +21,7 @@
*/
#include <common.h>
+#include <dm.h>
#include <asm/byteorder.h>
#include <usb.h>
#include <malloc.h>
@@ -108,7 +109,25 @@ static struct descriptor {
},
};
+#ifndef CONFIG_DM_USB
static struct xhci_ctrl xhcic[CONFIG_USB_MAX_CONTROLLER_COUNT];
+#endif
+
+struct xhci_ctrl *xhci_get_ctrl(struct usb_device *udev)
+{
+#ifdef CONFIG_DM_USB
+ struct udevice *dev;
+
+ /* Find the USB controller */
+ for (dev = udev->dev;
+ device_get_uclass_id(dev) != UCLASS_USB;
+ dev = dev->parent)
+ ;
+ return dev_get_priv(dev);
+#else
+ return udev->controller;
+#endif
+}
/**
* Waits for as per specified amount of time
@@ -250,7 +269,7 @@ static int xhci_configure_endpoints(struct usb_device *udev, bool ctx_change)
{
struct xhci_container_ctx *in_ctx;
struct xhci_virt_device *virt_dev;
- struct xhci_ctrl *ctrl = udev->controller;
+ struct xhci_ctrl *ctrl = xhci_get_ctrl(udev);
union xhci_trb *event;
virt_dev = ctrl->devs[udev->slot_id];
@@ -298,7 +317,7 @@ static int xhci_set_configuration(struct usb_device *udev)
int ep_index;
unsigned int dir;
unsigned int ep_type;
- struct xhci_ctrl *ctrl = udev->controller;
+ struct xhci_ctrl *ctrl = xhci_get_ctrl(udev);
int num_of_ep;
int ep_flag = 0;
u64 trb_64 = 0;
@@ -379,10 +398,10 @@ static int xhci_set_configuration(struct usb_device *udev)
* @param udev pointer to the Device Data Structure
* @return 0 if successful else error code on failure
*/
-static int xhci_address_device(struct usb_device *udev)
+static int xhci_address_device(struct usb_device *udev, int root_portnr)
{
int ret = 0;
- struct xhci_ctrl *ctrl = udev->controller;
+ struct xhci_ctrl *ctrl = xhci_get_ctrl(udev);
struct xhci_slot_ctx *slot_ctx;
struct xhci_input_control_ctx *ctrl_ctx;
struct xhci_virt_device *virt_dev;
@@ -395,8 +414,9 @@ static int xhci_address_device(struct usb_device *udev)
* This is the first Set Address since device plug-in
* so setting up the slot context.
*/
- debug("Setting up addressable devices\n");
- xhci_setup_addressable_virt_dev(udev);
+ debug("Setting up addressable devices %p\n", ctrl->dcbaa);
+ xhci_setup_addressable_virt_dev(ctrl, udev->slot_id, udev->speed,
+ root_portnr);
ctrl_ctx = xhci_get_input_control_ctx(virt_dev->in_ctx);
ctrl_ctx->add_flags = cpu_to_le32(SLOT_FLAG | EP0_FLAG);
@@ -461,10 +481,10 @@ static int xhci_address_device(struct usb_device *udev)
* @param udev pointer to the Device Data Structure
* @return Returns 0 on succes else return error code on failure
*/
-int usb_alloc_device(struct usb_device *udev)
+int _xhci_alloc_device(struct usb_device *udev)
{
+ struct xhci_ctrl *ctrl = xhci_get_ctrl(udev);
union xhci_trb *event;
- struct xhci_ctrl *ctrl = udev->controller;
int ret;
/*
@@ -486,7 +506,7 @@ int usb_alloc_device(struct usb_device *udev)
xhci_acknowledge_event(ctrl);
- ret = xhci_alloc_virt_device(udev);
+ ret = xhci_alloc_virt_device(ctrl, udev->slot_id);
if (ret < 0) {
/*
* TODO: Unsuccessful Address Device command shall leave
@@ -499,6 +519,13 @@ int usb_alloc_device(struct usb_device *udev)
return 0;
}
+#ifndef CONFIG_DM_USB
+int usb_alloc_device(struct usb_device *udev)
+{
+ return _xhci_alloc_device(udev);
+}
+#endif
+
/*
* Full speed devices may have a max packet size greater than 8 bytes, but the
* USB core doesn't know that until it reads the first 8 bytes of the
@@ -510,7 +537,7 @@ int usb_alloc_device(struct usb_device *udev)
*/
int xhci_check_maxpacket(struct usb_device *udev)
{
- struct xhci_ctrl *ctrl = udev->controller;
+ struct xhci_ctrl *ctrl = xhci_get_ctrl(udev);
unsigned int slot_id = udev->slot_id;
int ep_index = 0; /* control endpoint */
struct xhci_container_ctx *in_ctx;
@@ -640,7 +667,7 @@ static int xhci_submit_root(struct usb_device *udev, unsigned long pipe,
int len, srclen;
uint32_t reg;
volatile uint32_t *status_reg;
- struct xhci_ctrl *ctrl = udev->controller;
+ struct xhci_ctrl *ctrl = xhci_get_ctrl(udev);
struct xhci_hcor *hcor = ctrl->hcor;
if ((req->requesttype & USB_RT_PORT) &&
@@ -677,7 +704,7 @@ static int xhci_submit_root(struct usb_device *udev, unsigned long pipe,
srclen = 4;
break;
case 1: /* Vendor String */
- srcptr = "\16\3u\0-\0b\0o\0o\0t\0";
+ srcptr = "\16\3U\0-\0B\0o\0o\0t\0";
srclen = 14;
break;
case 2: /* Product Name */
@@ -858,9 +885,8 @@ unknown:
* @param interval interval of the interrupt
* @return 0
*/
-int
-submit_int_msg(struct usb_device *udev, unsigned long pipe, void *buffer,
- int length, int interval)
+static int _xhci_submit_int_msg(struct usb_device *udev, unsigned long pipe,
+ void *buffer, int length, int interval)
{
/*
* TODO: Not addressing any interrupt type transfer requests
@@ -878,9 +904,8 @@ submit_int_msg(struct usb_device *udev, unsigned long pipe, void *buffer,
* @param length length of the buffer
* @return returns 0 if successful else -1 on failure
*/
-int
-submit_bulk_msg(struct usb_device *udev, unsigned long pipe, void *buffer,
- int length)
+static int _xhci_submit_bulk_msg(struct usb_device *udev, unsigned long pipe,
+ void *buffer, int length)
{
if (usb_pipetype(pipe) != PIPE_BULK) {
printf("non-bulk pipe (type=%lu)", usb_pipetype(pipe));
@@ -898,13 +923,14 @@ submit_bulk_msg(struct usb_device *udev, unsigned long pipe, void *buffer,
* @param buffer buffer to be read/written based on the request
* @param length length of the buffer
* @param setup Request type
+ * @param root_portnr Root port number that this device is on
* @return returns 0 if successful else -1 on failure
*/
-int
-submit_control_msg(struct usb_device *udev, unsigned long pipe, void *buffer,
- int length, struct devrequest *setup)
+static int _xhci_submit_control_msg(struct usb_device *udev, unsigned long pipe,
+ void *buffer, int length,
+ struct devrequest *setup, int root_portnr)
{
- struct xhci_ctrl *ctrl = udev->controller;
+ struct xhci_ctrl *ctrl = xhci_get_ctrl(udev);
int ret = 0;
if (usb_pipetype(pipe) != PIPE_CONTROL) {
@@ -916,7 +942,7 @@ submit_control_msg(struct usb_device *udev, unsigned long pipe, void *buffer,
return xhci_submit_root(udev, pipe, buffer, setup);
if (setup->request == USB_REQ_SET_ADDRESS)
- return xhci_address_device(udev);
+ return xhci_address_device(udev, root_portnr);
if (setup->request == USB_REQ_SET_CONFIGURATION) {
ret = xhci_set_configuration(udev);
@@ -929,33 +955,16 @@ submit_control_msg(struct usb_device *udev, unsigned long pipe, void *buffer,
return xhci_ctrl_tx(udev, pipe, setup, length, buffer);
}
-/**
- * Intialises the XHCI host controller
- * and allocates the necessary data structures
- *
- * @param index index to the host controller data structure
- * @return pointer to the intialised controller
- */
-int usb_lowlevel_init(int index, enum usb_init_type init, void **controller)
+static int xhci_lowlevel_init(struct xhci_ctrl *ctrl)
{
+ struct xhci_hccr *hccr;
+ struct xhci_hcor *hcor;
uint32_t val;
uint32_t val2;
uint32_t reg;
- struct xhci_hccr *hccr;
- struct xhci_hcor *hcor;
- struct xhci_ctrl *ctrl;
-
- if (xhci_hcd_init(index, &hccr, (struct xhci_hcor **)&hcor) != 0)
- return -ENODEV;
-
- if (xhci_reset(hcor) != 0)
- return -ENODEV;
-
- ctrl = &xhcic[index];
-
- ctrl->hccr = hccr;
- ctrl->hcor = hcor;
+ hccr = ctrl->hccr;
+ hcor = ctrl->hcor;
/*
* Program the Number of Device Slots Enabled field in the CONFIG
* register with the max value of slots the HC can handle.
@@ -997,11 +1006,82 @@ int usb_lowlevel_init(int index, enum usb_init_type init, void **controller)
reg = HC_VERSION(xhci_readl(&hccr->cr_capbase));
printf("USB XHCI %x.%02x\n", reg >> 8, reg & 0xff);
- *controller = &xhcic[index];
+ return 0;
+}
+
+static int xhci_lowlevel_stop(struct xhci_ctrl *ctrl)
+{
+ u32 temp;
+
+ xhci_reset(ctrl->hcor);
+
+ debug("// Disabling event ring interrupts\n");
+ temp = xhci_readl(&ctrl->hcor->or_usbsts);
+ xhci_writel(&ctrl->hcor->or_usbsts, temp & ~STS_EINT);
+ temp = xhci_readl(&ctrl->ir_set->irq_pending);
+ xhci_writel(&ctrl->ir_set->irq_pending, ER_IRQ_DISABLE(temp));
return 0;
}
+#ifndef CONFIG_DM_USB
+int submit_control_msg(struct usb_device *udev, unsigned long pipe,
+ void *buffer, int length, struct devrequest *setup)
+{
+ struct usb_device *hop = udev;
+
+ if (hop->parent)
+ while (hop->parent->parent)
+ hop = hop->parent;
+
+ return _xhci_submit_control_msg(udev, pipe, buffer, length, setup,
+ hop->portnr);
+}
+
+int submit_bulk_msg(struct usb_device *udev, unsigned long pipe, void *buffer,
+ int length)
+{
+ return _xhci_submit_bulk_msg(udev, pipe, buffer, length);
+}
+
+int submit_int_msg(struct usb_device *udev, unsigned long pipe, void *buffer,
+ int length, int interval)
+{
+ return _xhci_submit_int_msg(udev, pipe, buffer, length, interval);
+}
+
+/**
+ * Intialises the XHCI host controller
+ * and allocates the necessary data structures
+ *
+ * @param index index to the host controller data structure
+ * @return pointer to the intialised controller
+ */
+int usb_lowlevel_init(int index, enum usb_init_type init, void **controller)
+{
+ struct xhci_hccr *hccr;
+ struct xhci_hcor *hcor;
+ struct xhci_ctrl *ctrl;
+ int ret;
+
+ if (xhci_hcd_init(index, &hccr, (struct xhci_hcor **)&hcor) != 0)
+ return -ENODEV;
+
+ if (xhci_reset(hcor) != 0)
+ return -ENODEV;
+
+ ctrl = &xhcic[index];
+
+ ctrl->hccr = hccr;
+ ctrl->hcor = hcor;
+
+ ret = xhci_lowlevel_init(ctrl);
+
+ *controller = &xhcic[index];
+
+ return ret;
+}
+
/**
* Stops the XHCI host controller
* and cleans up all the related data structures
@@ -1012,19 +1092,143 @@ int usb_lowlevel_init(int index, enum usb_init_type init, void **controller)
int usb_lowlevel_stop(int index)
{
struct xhci_ctrl *ctrl = (xhcic + index);
- u32 temp;
- xhci_reset(ctrl->hcor);
+ xhci_lowlevel_stop(ctrl);
+ xhci_hcd_stop(index);
+ xhci_cleanup(ctrl);
- debug("// Disabling event ring interrupts\n");
- temp = xhci_readl(&ctrl->hcor->or_usbsts);
- xhci_writel(&ctrl->hcor->or_usbsts, temp & ~STS_EINT);
- temp = xhci_readl(&ctrl->ir_set->irq_pending);
- xhci_writel(&ctrl->ir_set->irq_pending, ER_IRQ_DISABLE(temp));
+ return 0;
+}
+#endif /* CONFIG_DM_USB */
- xhci_hcd_stop(index);
+#ifdef CONFIG_DM_USB
+/*
+static struct usb_device *get_usb_device(struct udevice *dev)
+{
+ struct usb_device *udev;
+ if (device_get_uclass_id(dev) == UCLASS_USB)
+ udev = dev_get_uclass_priv(dev);
+ else
+ udev = dev_get_parentdata(dev);
+
+ return udev;
+}
+*/
+static bool is_root_hub(struct udevice *dev)
+{
+ if (device_get_uclass_id(dev->parent) != UCLASS_USB_HUB)
+ return true;
+
+ return false;
+}
+
+static int xhci_submit_control_msg(struct udevice *dev, struct usb_device *udev,
+ unsigned long pipe, void *buffer, int length,
+ struct devrequest *setup)
+{
+ struct usb_device *uhop;
+ struct udevice *hub;
+ int root_portnr = 0;
+
+ debug("%s: dev='%s', udev=%p, udev->dev='%s', portnr=%d\n", __func__,
+ dev->name, udev, udev->dev->name, udev->portnr);
+ hub = udev->dev;
+ if (device_get_uclass_id(hub) == UCLASS_USB_HUB) {
+ /* Figure out our port number on the root hub */
+ if (is_root_hub(hub)) {
+ root_portnr = udev->portnr;
+ } else {
+ while (!is_root_hub(hub->parent))
+ hub = hub->parent;
+ uhop = dev_get_parentdata(hub);
+ root_portnr = uhop->portnr;
+ }
+ }
+/*
+ struct usb_device *hop = udev;
+
+ if (hop->parent)
+ while (hop->parent->parent)
+ hop = hop->parent;
+*/
+ return _xhci_submit_control_msg(udev, pipe, buffer, length, setup,
+ root_portnr);
+}
+
+static int xhci_submit_bulk_msg(struct udevice *dev, struct usb_device *udev,
+ unsigned long pipe, void *buffer, int length)
+{
+ debug("%s: dev='%s', udev=%p\n", __func__, dev->name, udev);
+ return _xhci_submit_bulk_msg(udev, pipe, buffer, length);
+}
+
+static int xhci_submit_int_msg(struct udevice *dev, struct usb_device *udev,
+ unsigned long pipe, void *buffer, int length,
+ int interval)
+{
+ debug("%s: dev='%s', udev=%p\n", __func__, dev->name, udev);
+ return _xhci_submit_int_msg(udev, pipe, buffer, length, interval);
+}
+
+static int xhci_alloc_device(struct udevice *dev, struct usb_device *udev)
+{
+ debug("%s: dev='%s', udev=%p\n", __func__, dev->name, udev);
+ return _xhci_alloc_device(udev);
+}
+
+int xhci_register(struct udevice *dev, struct xhci_hccr *hccr,
+ struct xhci_hcor *hcor)
+{
+ struct xhci_ctrl *ctrl = dev_get_priv(dev);
+ struct usb_bus_priv *priv = dev_get_uclass_priv(dev);
+ int ret;
+
+ debug("%s: dev='%s', ctrl=%p, hccr=%p, hcor=%p\n", __func__, dev->name,
+ ctrl, hccr, hcor);
+
+ ctrl->dev = dev;
+
+ /*
+ * XHCI needs to issue a Address device command to setup
+ * proper device context structures, before it can interact
+ * with the device. So a get_descriptor will fail before any
+ * of that is done for XHCI unlike EHCI.
+ */
+ priv->desc_before_addr = false;
+
+ ret = xhci_reset(hcor);
+ if (ret)
+ goto err;
+
+ ctrl->hccr = hccr;
+ ctrl->hcor = hcor;
+ ret = xhci_lowlevel_init(ctrl);
+ if (ret)
+ goto err;
+
+ return 0;
+err:
+ free(ctrl);
+ debug("%s: failed, ret=%d\n", __func__, ret);
+ return ret;
+}
+
+int xhci_deregister(struct udevice *dev)
+{
+ struct xhci_ctrl *ctrl = dev_get_priv(dev);
+
+ xhci_lowlevel_stop(ctrl);
xhci_cleanup(ctrl);
return 0;
}
+
+struct dm_usb_ops xhci_usb_ops = {
+ .control = xhci_submit_control_msg,
+ .bulk = xhci_submit_bulk_msg,
+ .interrupt = xhci_submit_int_msg,
+ .alloc_device = xhci_alloc_device,
+};
+
+#endif
diff --git a/drivers/usb/host/xhci.h b/drivers/usb/host/xhci.h
index 0951e87436..2afa38694b 100644
--- a/drivers/usb/host/xhci.h
+++ b/drivers/usb/host/xhci.h
@@ -1209,6 +1209,9 @@ void xhci_hcd_stop(int index);
#define XHCI_STS_CNR (1 << 11)
struct xhci_ctrl {
+#ifdef CONFIG_DM_USB
+ struct udevice *dev;
+#endif
struct xhci_hccr *hccr; /* R/O registers, not need for volatile */
struct xhci_hcor *hcor;
struct xhci_doorbell_array *dba;
@@ -1241,7 +1244,8 @@ void xhci_endpoint_copy(struct xhci_ctrl *ctrl,
void xhci_slot_copy(struct xhci_ctrl *ctrl,
struct xhci_container_ctx *in_ctx,
struct xhci_container_ctx *out_ctx);
-void xhci_setup_addressable_virt_dev(struct usb_device *udev);
+void xhci_setup_addressable_virt_dev(struct xhci_ctrl *ctrl, int slot_id,
+ int speed, int hop_portnr);
void xhci_queue_command(struct xhci_ctrl *ctrl, u8 *ptr,
u32 slot_id, u32 ep_index, trb_type cmd);
void xhci_acknowledge_event(struct xhci_ctrl *ctrl);
@@ -1255,8 +1259,31 @@ void xhci_flush_cache(uintptr_t addr, u32 type_len);
void xhci_inval_cache(uintptr_t addr, u32 type_len);
void xhci_cleanup(struct xhci_ctrl *ctrl);
struct xhci_ring *xhci_ring_alloc(unsigned int num_segs, bool link_trbs);
-int xhci_alloc_virt_device(struct usb_device *udev);
+int xhci_alloc_virt_device(struct xhci_ctrl *ctrl, unsigned int slot_id);
int xhci_mem_init(struct xhci_ctrl *ctrl, struct xhci_hccr *hccr,
struct xhci_hcor *hcor);
+/**
+ * xhci_deregister() - Unregister an XHCI controller
+ *
+ * @dev: Controller device
+ * @return 0 if registered, -ve on error
+ */
+int xhci_deregister(struct udevice *dev);
+
+/**
+ * xhci_register() - Register a new XHCI controller
+ *
+ * @dev: Controller device
+ * @hccr: Host controller control registers
+ * @hcor: Not sure what this means
+ * @return 0 if registered, -ve on error
+ */
+int xhci_register(struct udevice *dev, struct xhci_hccr *hccr,
+ struct xhci_hcor *hcor);
+
+extern struct dm_usb_ops xhci_usb_ops;
+
+struct xhci_ctrl *xhci_get_ctrl(struct usb_device *udev);
+
#endif /* HOST_XHCI_H_ */
diff --git a/drivers/usb/musb-new/musb_uboot.c b/drivers/usb/musb-new/musb_uboot.c
index 053d94560d..7d90ebc1f5 100644
--- a/drivers/usb/musb-new/musb_uboot.c
+++ b/drivers/usb/musb-new/musb_uboot.c
@@ -180,7 +180,7 @@ void *poll_int_queue(struct usb_device *dev, struct int_queue *queue)
return NULL; /* URB still pending */
}
-void usb_reset_root_port(void)
+int usb_reset_root_port(void)
{
void *mbase = host->mregs;
u8 power;
@@ -208,6 +208,8 @@ void usb_reset_root_port(void)
(musb_readb(mbase, MUSB_DEVCTL) & MUSB_DEVCTL_FSDEV) ?
USB_SPEED_FULL : USB_SPEED_LOW;
mdelay((host_speed == USB_SPEED_LOW) ? 200 : 50);
+
+ return 0;
}
int usb_lowlevel_init(int index, enum usb_init_type init, void **controller)
diff --git a/drivers/video/cfb_console.c b/drivers/video/cfb_console.c
index a81affa333..f4231b8e62 100644
--- a/drivers/video/cfb_console.c
+++ b/drivers/video/cfb_console.c
@@ -87,6 +87,7 @@
*/
#include <common.h>
+#include <fdtdec.h>
#include <version.h>
#include <malloc.h>
#include <linux/compiler.h>
@@ -2251,6 +2252,7 @@ int drv_video_init(void)
{
int skip_dev_init;
struct stdio_dev console_dev;
+ bool have_keyboard;
/* Check if video initialization should be skipped */
if (board_video_skip())
@@ -2262,11 +2264,20 @@ int drv_video_init(void)
if (board_cfb_skip())
return 0;
+#if defined(CONFIG_VGA_AS_SINGLE_DEVICE)
+ have_keyboard = false;
+#elif defined(CONFIG_OF_CONTROL)
+ have_keyboard = !fdtdec_get_config_bool(gd->fdt_blob,
+ "u-boot,no-keyboard");
+#else
+ have_keyboard = true;
+#endif
+ if (have_keyboard) {
+ debug("KBD: Keyboard init ...\n");
#if !defined(CONFIG_VGA_AS_SINGLE_DEVICE)
- debug("KBD: Keyboard init ...\n");
- skip_dev_init |= (VIDEO_KBD_INIT_FCT == -1);
+ skip_dev_init |= (VIDEO_KBD_INIT_FCT == -1);
#endif
-
+ }
if (skip_dev_init)
return 0;
@@ -2279,11 +2290,13 @@ int drv_video_init(void)
console_dev.puts = video_puts; /* 'puts' function */
#if !defined(CONFIG_VGA_AS_SINGLE_DEVICE)
- /* Also init console device */
- console_dev.flags |= DEV_FLAGS_INPUT;
- console_dev.tstc = VIDEO_TSTC_FCT; /* 'tstc' function */
- console_dev.getc = VIDEO_GETC_FCT; /* 'getc' function */
-#endif /* CONFIG_VGA_AS_SINGLE_DEVICE */
+ if (have_keyboard) {
+ /* Also init console device */
+ console_dev.flags |= DEV_FLAGS_INPUT;
+ console_dev.tstc = VIDEO_TSTC_FCT; /* 'tstc' function */
+ console_dev.getc = VIDEO_GETC_FCT; /* 'getc' function */
+ }
+#endif
if (stdio_register(&console_dev) != 0)
return 0;
diff --git a/fs/fs.c b/fs/fs.c
index 483273fe20..ac0897d94a 100644
--- a/fs/fs.c
+++ b/fs/fs.c
@@ -17,6 +17,7 @@
#include <config.h>
#include <errno.h>
#include <common.h>
+#include <mapmem.h>
#include <part.h>
#include <ext4fs.h>
#include <fat.h>
diff --git a/fs/sandbox/sandboxfs.c b/fs/sandbox/sandboxfs.c
index a920bc0877..5acfc03704 100644
--- a/fs/sandbox/sandboxfs.c
+++ b/fs/sandbox/sandboxfs.c
@@ -10,7 +10,11 @@
int sandbox_fs_set_blk_dev(block_dev_desc_t *rbdd, disk_partition_t *info)
{
- return 0;
+ /*
+ * Only accept a NULL block_dev_desc_t for the sandbox, which is when
+ * hostfs interface is used
+ */
+ return rbdd != NULL;
}
int sandbox_fs_read_at(const char *filename, loff_t pos, void *buffer,
diff --git a/include/ahci.h b/include/ahci.h
index e8dee53575..6d917121c6 100644
--- a/include/ahci.h
+++ b/include/ahci.h
@@ -151,7 +151,7 @@ struct ahci_probe_ent {
u32 hard_port_no;
u32 host_flags;
u32 host_set_flags;
- u32 mmio_base;
+ void __iomem *mmio_base;
u32 pio_mask;
u32 udma_mask;
u32 flags;
@@ -160,7 +160,7 @@ struct ahci_probe_ent {
u32 link_port_map; /*linkup port map*/
};
-int ahci_init(u32 base);
-int ahci_reset(u32 base);
+int ahci_init(void __iomem *base);
+int ahci_reset(void __iomem *base);
#endif
diff --git a/include/bootstage.h b/include/bootstage.h
index 0276cb3f60..be440148dd 100644
--- a/include/bootstage.h
+++ b/include/bootstage.h
@@ -11,7 +11,7 @@
#ifndef _BOOTSTAGE_H
#define _BOOTSTAGE_H
-/* The number of boot stage records available for the user */
+/* Define this for host tools */
#ifndef CONFIG_BOOTSTAGE_USER_COUNT
#define CONFIG_BOOTSTAGE_USER_COUNT 20
#endif
diff --git a/include/common.h b/include/common.h
index 6df05b8bb1..a079f13bdc 100644
--- a/include/common.h
+++ b/include/common.h
@@ -253,6 +253,17 @@ int update_flash_size(int flash_size);
int arch_early_init_r(void);
/**
+ * arch_cpu_init_dm() - init CPU after driver model is available
+ *
+ * This is called immediately after driver model is available before
+ * relocation. This is similar to arch_cpu_init() but is able to reference
+ * devices
+ *
+ * @return 0 if OK, -ve on error
+ */
+int arch_cpu_init_dm(void);
+
+/**
* Reserve all necessary stacks
*
* This is used in generic board init sequence in common/board_f.c. Each
@@ -815,7 +826,7 @@ int zzip(void *dst, unsigned long *lenp, unsigned char *src,
/* lib/net_utils.c */
#include <net.h>
-static inline IPaddr_t getenv_IPaddr(char *var)
+static inline struct in_addr getenv_ip(char *var)
{
return string_to_ip(getenv(var));
}
@@ -847,23 +858,6 @@ int cpu_disable(int nr);
int cpu_release(int nr, int argc, char * const argv[]);
#endif
-/* Define a null map_sysmem() if the architecture doesn't use it */
-# ifndef CONFIG_ARCH_MAP_SYSMEM
-static inline void *map_sysmem(phys_addr_t paddr, unsigned long len)
-{
- return (void *)(uintptr_t)paddr;
-}
-
-static inline void unmap_sysmem(const void *vaddr)
-{
-}
-
-static inline phys_addr_t map_to_sysmem(const void *ptr)
-{
- return (phys_addr_t)(uintptr_t)ptr;
-}
-# endif
-
#endif /* __ASSEMBLY__ */
#ifdef CONFIG_PPC
diff --git a/include/config_distro_bootcmd.h b/include/config_distro_bootcmd.h
index d71e58dae1..3a360ca49a 100644
--- a/include/config_distro_bootcmd.h
+++ b/include/config_distro_bootcmd.h
@@ -48,6 +48,18 @@
#define BOOTENV_DEV_NAME_BLKDEV(devtypeu, devtypel, instance) \
#devtypel #instance " "
+#ifdef CONFIG_SANDBOX
+#define BOOTENV_SHARED_HOST BOOTENV_SHARED_BLKDEV(host)
+#define BOOTENV_DEV_HOST BOOTENV_DEV_BLKDEV
+#define BOOTENV_DEV_NAME_HOST BOOTENV_DEV_NAME_BLKDEV
+#else
+#define BOOTENV_SHARED_HOST
+#define BOOTENV_DEV_HOST \
+ BOOT_TARGET_DEVICES_references_HOST_without_CONFIG_SANDBOX
+#define BOOTENV_DEV_NAME_HOST \
+ BOOT_TARGET_DEVICES_references_HOST_without_CONFIG_SANDBOX
+#endif
+
#ifdef CONFIG_CMD_MMC
#define BOOTENV_SHARED_MMC BOOTENV_SHARED_BLKDEV(mmc)
#define BOOTENV_DEV_MMC BOOTENV_DEV_BLKDEV
@@ -167,6 +179,7 @@
#define BOOTENV_DEV(devtypeu, devtypel, instance) \
BOOTENV_DEV_##devtypeu(devtypeu, devtypel, instance)
#define BOOTENV \
+ BOOTENV_SHARED_HOST \
BOOTENV_SHARED_MMC \
BOOTENV_SHARED_USB \
BOOTENV_SHARED_SATA \
diff --git a/include/config_distro_defaults.h b/include/config_distro_defaults.h
index 8237239c00..5eea5cf900 100644
--- a/include/config_distro_defaults.h
+++ b/include/config_distro_defaults.h
@@ -29,6 +29,10 @@
#else
#define CONFIG_BOOTP_VCI_STRING "U-boot.arm"
#endif
+#elif defined(__i386__)
+#define CONFIG_BOOTP_PXE_CLIENTARCH 0x0
+#elif defined(__x86_64__)
+#define CONFIG_BOOTP_PXE_CLIENTARCH 0x9
#endif
#define CONFIG_OF_LIBFDT
diff --git a/include/configs/axs101.h b/include/configs/axs101.h
index 8a7095c5b2..389f75bca8 100644
--- a/include/configs/axs101.h
+++ b/include/configs/axs101.h
@@ -116,7 +116,6 @@
/*
* Ethernet configuration
*/
-#define CONFIG_DESIGNWARE_ETH
#define CONFIG_DW_AUTONEG
#define CONFIG_NET_MULTI
diff --git a/include/configs/bf609-ezkit.h b/include/configs/bf609-ezkit.h
index 878009ff66..7507d57527 100644
--- a/include/configs/bf609-ezkit.h
+++ b/include/configs/bf609-ezkit.h
@@ -71,7 +71,6 @@
#define CONFIG_NETCONSOLE
#define CONFIG_NET_MULTI
#define CONFIG_HOSTNAME "bf609-ezkit"
-#define CONFIG_DESIGNWARE_ETH
#define CONFIG_PHY_ADDR 1
#define CONFIG_DW_PORTS 1
#define CONFIG_DW_ALTDESCRIPTOR
diff --git a/include/configs/chromebook_link.h b/include/configs/chromebook_link.h
index 7b460e83c4..52657878c6 100644
--- a/include/configs/chromebook_link.h
+++ b/include/configs/chromebook_link.h
@@ -14,65 +14,6 @@
#define __CONFIG_H
#include <configs/x86-common.h>
-
-
-#define CONFIG_SYS_MONITOR_LEN (1 << 20)
-
-#define CONFIG_DCACHE_RAM_MRC_VAR_SIZE 0x4000
-#define CONFIG_BOARD_EARLY_INIT_F
-#define CONFIG_MISC_INIT_R
-
-#define CONFIG_NR_DRAM_BANKS 8
-#define CONFIG_X86_MRC_ADDR 0xfffa0000
-#define CONFIG_CACHE_MRC_SIZE_KB 512
-
-#define CONFIG_X86_SERIAL
-
-#define CONFIG_SCSI_DEV_LIST {PCI_VENDOR_ID_INTEL, \
- PCI_DEVICE_ID_INTEL_NM10_AHCI}, \
- {PCI_VENDOR_ID_INTEL, \
- PCI_DEVICE_ID_INTEL_COUGARPOINT_AHCI_MOBILE}, \
- {PCI_VENDOR_ID_INTEL, \
- PCI_DEVICE_ID_INTEL_COUGARPOINT_AHCI_SERIES6}, \
- {PCI_VENDOR_ID_INTEL, \
- PCI_DEVICE_ID_INTEL_PANTHERPOINT_AHCI_MOBILE}
-
-#define CONFIG_X86_OPTION_ROM_FILE pci8086,0166.bin
-#define CONFIG_X86_OPTION_ROM_ADDR 0xfff90000
-
-#define CONFIG_PCI_MEM_BUS 0xe0000000
-#define CONFIG_PCI_MEM_PHYS CONFIG_PCI_MEM_BUS
-#define CONFIG_PCI_MEM_SIZE 0x10000000
-
-#define CONFIG_PCI_PREF_BUS 0xd0000000
-#define CONFIG_PCI_PREF_PHYS CONFIG_PCI_PREF_BUS
-#define CONFIG_PCI_PREF_SIZE 0x10000000
-
-#define CONFIG_PCI_IO_BUS 0x1000
-#define CONFIG_PCI_IO_PHYS CONFIG_PCI_IO_BUS
-#define CONFIG_PCI_IO_SIZE 0xefff
-
-#define CONFIG_SYS_EARLY_PCI_INIT
-#define CONFIG_PCI_PNP
-
-#define CONFIG_BIOSEMU
-#define VIDEO_IO_OFFSET 0
-#define CONFIG_X86EMU_RAW_IO
-
-#define CONFIG_CROS_EC
-#define CONFIG_CROS_EC_LPC
-#define CONFIG_CMD_CROS_EC
-#define CONFIG_ARCH_EARLY_INIT_R
-
-#undef CONFIG_ENV_IS_NOWHERE
-#undef CONFIG_ENV_SIZE
-#define CONFIG_ENV_SIZE 0x1000
-#define CONFIG_ENV_SECT_SIZE 0x1000
-#define CONFIG_ENV_IS_IN_SPI_FLASH
-#define CONFIG_ENV_OFFSET 0x003f8000
-
-#define CONFIG_STD_DEVICES_SETTINGS "stdin=usbkbd,vga,serial\0" \
- "stdout=vga,serial\0" \
- "stderr=vga,serial\0"
+#include <configs/x86-chromebook.h>
#endif /* __CONFIG_H */
diff --git a/include/configs/chromebox_panther.h b/include/configs/chromebox_panther.h
new file mode 100644
index 0000000000..00fe26da29
--- /dev/null
+++ b/include/configs/chromebox_panther.h
@@ -0,0 +1,17 @@
+/*
+ * Copyright (c) 2011 The Chromium OS Authors.
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef __CONFIG_H
+#define __CONFIG_H
+
+#include <configs/x86-common.h>
+#include <configs/x86-chromebook.h>
+
+#define CONFIG_RTL8169
+/* Avoid a warning in the Realtek Ethernet driver */
+#define CONFIG_SYS_CACHELINE_SIZE 16
+
+#endif /* __CONFIG_H */
diff --git a/include/configs/exynos5250-common.h b/include/configs/exynos5250-common.h
index ae0e5ff47b..95e96ecde4 100644
--- a/include/configs/exynos5250-common.h
+++ b/include/configs/exynos5250-common.h
@@ -28,16 +28,6 @@
#define CONFIG_SYS_INIT_SP_ADDR CONFIG_IRAM_STACK
-/* Sound */
-#define CONFIG_CMD_SOUND
-#ifdef CONFIG_CMD_SOUND
-#define CONFIG_SOUND
-#define CONFIG_I2S_SAMSUNG
-#define CONFIG_I2S
-#define CONFIG_SOUND_MAX98095
-#define CONFIG_SOUND_WM8994
-#endif
-
/* I2C */
#define CONFIG_MAX_I2C_NUM 8
diff --git a/include/configs/exynos5420-common.h b/include/configs/exynos5420-common.h
index b42dab7a7f..3b1ac2cecd 100644
--- a/include/configs/exynos5420-common.h
+++ b/include/configs/exynos5420-common.h
@@ -15,8 +15,6 @@
#include <configs/exynos5-common.h>
-#define CONFIG_ARCH_EARLY_INIT_R
-
#define MACH_TYPE_SMDK5420 8002
#define CONFIG_MACH_TYPE MACH_TYPE_SMDK5420
diff --git a/include/configs/sandbox.h b/include/configs/sandbox.h
index febbfb69f6..3bf45a224d 100644
--- a/include/configs/sandbox.h
+++ b/include/configs/sandbox.h
@@ -21,9 +21,6 @@
#define CONFIG_SYS_TIMER_RATE 1000000
-#define CONFIG_BOOTSTAGE
-#define CONFIG_BOOTSTAGE_REPORT
-
#define CONFIG_SYS_STDIO_DEREGISTER
/* Number of bits in a C 'long' on this architecture */
@@ -34,6 +31,10 @@
#define CONFIG_CMD_FDT
#define CONFIG_ANDROID_BOOT_IMAGE
+#define CONFIG_CMD_PCI
+#define CONFIG_PCI_PNP
+#define CONFIG_CMD_IO
+
#define CONFIG_FS_FAT
#define CONFIG_FAT_WRITE
#define CONFIG_FS_EXT4
@@ -47,15 +48,12 @@
#define CONFIG_CMD_FS_GENERIC
#define CONFIG_CMD_MD5SUM
-#define CONFIG_SYS_VSNPRINTF
-
#define CONFIG_CMD_GPIO
-#define CONFIG_SANDBOX_GPIO
-#define CONFIG_SANDBOX_GPIO_COUNT 128
#define CONFIG_CMD_GPT
#define CONFIG_PARTITION_UUIDS
#define CONFIG_EFI_PARTITION
+#define CONFIG_DOS_PARTITION
/*
* Size of malloc() pool, before and after relocation
@@ -75,13 +73,11 @@
#define CONFIG_CMDLINE_EDITING
#define CONFIG_COMMAND_HISTORY
#define CONFIG_AUTO_COMPLETE
-#define CONFIG_BOOTDELAY 3
#define CONFIG_ENV_SIZE 8192
#define CONFIG_ENV_IS_NOWHERE
/* SPI - enable all SPI flash types for testing purposes */
-#define CONFIG_SANDBOX_SPI
#define CONFIG_CMD_SF
#define CONFIG_CMD_SF_TEST
#define CONFIG_CMD_SPI
@@ -90,14 +86,12 @@
#define CONFIG_SPI_FLASH_EON
#define CONFIG_SPI_FLASH_GIGADEVICE
#define CONFIG_SPI_FLASH_MACRONIX
-#define CONFIG_SPI_FLASH_SANDBOX
#define CONFIG_SPI_FLASH_SPANSION
#define CONFIG_SPI_FLASH_SST
#define CONFIG_SPI_FLASH_STMICRO
#define CONFIG_SPI_FLASH_WINBOND
#define CONFIG_CMD_I2C
-#define CONFIG_SYS_I2C_SANDBOX
#define CONFIG_I2C_EDID
#define CONFIG_I2C_EEPROM
@@ -125,29 +119,42 @@
/* include default commands */
#include <config_cmd_default.h>
-
-/* We don't have networking support yet */
-#undef CONFIG_CMD_NET
-#undef CONFIG_CMD_NFS
+#include <config_distro_defaults.h>
+
+#define BOOT_TARGET_DEVICES(func) \
+ func(HOST, host, 1) \
+ func(HOST, host, 0)
+
+#include <config_distro_bootcmd.h>
+
+#define CONFIG_KEEP_SERVERADDR
+#define CONFIG_UDP_CHECKSUM
+#define CONFIG_CMD_LINK_LOCAL
+#define CONFIG_CMD_CDP
+#define CONFIG_CMD_DNS
+#define CONFIG_CMD_SNTP
+#define CONFIG_TIMESTAMP
+#define CONFIG_CMD_RARP
+#define CONFIG_BOOTP_DNS
+#define CONFIG_BOOTP_DNS2
+#define CONFIG_BOOTP_SEND_HOSTNAME
+#define CONFIG_BOOTP_SERVERIP
+#define CONFIG_IP_DEFRAG
+
+/* Can't boot elf images */
+#undef CONFIG_CMD_ELF
#define CONFIG_CMD_HASH
#define CONFIG_HASH_VERIFY
#define CONFIG_SHA1
#define CONFIG_SHA256
-#define CONFIG_TPM_TIS_SANDBOX
-
#define CONFIG_CMD_SANDBOX
#define CONFIG_BOOTARGS ""
-#define CONFIG_ARCH_EARLY_INIT_R
#define CONFIG_BOARD_LATE_INIT
-#define CONFIG_SOUND
-#define CONFIG_SOUND_SANDBOX
-#define CONFIG_CMD_SOUND
-
#ifndef SANDBOX_NO_SDL
#define CONFIG_SANDBOX_SDL
#endif
@@ -165,23 +172,40 @@
#define CONFIG_KEYBOARD
-#define CONFIG_EXTRA_ENV_SETTINGS "stdin=serial,cros-ec-keyb\0" \
+#define SANDBOX_SERIAL_SETTINGS "stdin=serial,cros-ec-keyb\0" \
"stdout=serial,lcd\0" \
"stderr=serial,lcd\0"
#else
-
-#define CONFIG_EXTRA_ENV_SETTINGS "stdin=serial\0" \
+#define SANDBOX_SERIAL_SETTINGS "stdin=serial\0" \
"stdout=serial,lcd\0" \
"stderr=serial,lcd\0"
#endif
+#define SANDBOX_ETH_SETTINGS "ethaddr=00:00:11:22:33:44\0" \
+ "eth1addr=00:00:11:22:33:45\0" \
+ "eth5addr=00:00:11:22:33:46\0" \
+ "ipaddr=1.2.3.4\0"
+
+#define MEM_LAYOUT_ENV_SETTINGS \
+ "bootm_size=0x10000000\0" \
+ "kernel_addr_r=0x1000000\0" \
+ "fdt_addr_r=0xc00000\0" \
+ "ramdisk_addr_r=0x2000000\0" \
+ "scriptaddr=0x1000\0" \
+ "pxefile_addr_r=0x2000\0"
+
+#define CONFIG_EXTRA_ENV_SETTINGS \
+ SANDBOX_SERIAL_SETTINGS \
+ SANDBOX_ETH_SETTINGS \
+ BOOTENV \
+ MEM_LAYOUT_ENV_SETTINGS
+
#define CONFIG_GZIP_COMPRESSED
#define CONFIG_BZIP2
#define CONFIG_LZO
#define CONFIG_LZMA
-#define CONFIG_TPM_TIS_SANDBOX
-
#define CONFIG_CMD_LZMADEC
+#define CONFIG_CMD_USB
#endif
diff --git a/include/configs/smdk5250.h b/include/configs/smdk5250.h
index 3b06d305db..08381e3418 100644
--- a/include/configs/smdk5250.h
+++ b/include/configs/smdk5250.h
@@ -22,7 +22,6 @@
#define CONFIG_POWER_MAX77686
#define CONFIG_BOARD_COMMON
-#define CONFIG_ARCH_EARLY_INIT_R
#define CONFIG_USB_XHCI
#define CONFIG_USB_XHCI_EXYNOS
diff --git a/include/configs/snow.h b/include/configs/snow.h
index fe802f253c..a2fb3f9808 100644
--- a/include/configs/snow.h
+++ b/include/configs/snow.h
@@ -23,10 +23,11 @@
#define CONFIG_POWER_TPS65090_I2C
#define CONFIG_BOARD_COMMON
-#define CONFIG_ARCH_EARLY_INIT_R
#define CONFIG_USB_XHCI
+#define CONFIG_USB_EHCI
#define CONFIG_USB_XHCI_EXYNOS
+#define CONFIG_USB_EHCI_EXYNOS
#define CONFIG_SYS_PROMPT "snow # "
#define CONFIG_IDENT_STRING " for snow"
diff --git a/include/configs/socfpga_common.h b/include/configs/socfpga_common.h
index 6d9347204b..1ecd56f42a 100644
--- a/include/configs/socfpga_common.h
+++ b/include/configs/socfpga_common.h
@@ -99,7 +99,6 @@
* Ethernet on SoC (EMAC)
*/
#if defined(CONFIG_CMD_NET) && !defined(CONFIG_SOCFPGA_VIRTUAL_TARGET)
-#define CONFIG_DESIGNWARE_ETH
#define CONFIG_NET_MULTI
#define CONFIG_DW_ALTDESCRIPTOR
#define CONFIG_MII
diff --git a/include/configs/spear-common.h b/include/configs/spear-common.h
index 16281f5ba8..409cf54172 100644
--- a/include/configs/spear-common.h
+++ b/include/configs/spear-common.h
@@ -18,7 +18,6 @@
/* Ethernet driver configuration */
#define CONFIG_MII
-#define CONFIG_DESIGNWARE_ETH
#define CONFIG_NET_MULTI
#define CONFIG_PHYLIB
#define CONFIG_PHY_RESET_DELAY 10000 /* in usec */
diff --git a/include/configs/stv0991.h b/include/configs/stv0991.h
index 156e0fa8e1..ab1e61cf89 100644
--- a/include/configs/stv0991.h
+++ b/include/configs/stv0991.h
@@ -55,7 +55,6 @@
#define CONFIG_MII
#define CONFIG_PHYLIB
#define CONFIG_CMD_NET
-#define CONFIG_DESIGNWARE_ETH
#define CONFIG_DW_ALTDESCRIPTOR
#define CONFIG_PHY_MICREL
diff --git a/include/configs/sunxi-common.h b/include/configs/sunxi-common.h
index 438272cbda..365d9a50b5 100644
--- a/include/configs/sunxi-common.h
+++ b/include/configs/sunxi-common.h
@@ -288,7 +288,6 @@ extern int soft_i2c_gpio_scl;
#endif
#ifdef CONFIG_SUNXI_GMAC
-#define CONFIG_DESIGNWARE_ETH /* GMAC can use designware driver */
#define CONFIG_DW_AUTONEG
#define CONFIG_PHY_GIGE /* GMAC can use gigabit PHY */
#define CONFIG_PHY_ADDR 1
diff --git a/include/configs/tb100.h b/include/configs/tb100.h
index 501449a581..b2b4b1037f 100644
--- a/include/configs/tb100.h
+++ b/include/configs/tb100.h
@@ -62,7 +62,6 @@
/*
* Ethernet configuration
*/
-#define CONFIG_DESIGNWARE_ETH
#define ETH0_BASE_ADDRESS 0xFE100000
#define ETH1_BASE_ADDRESS 0xFE110000
diff --git a/include/configs/x600.h b/include/configs/x600.h
index 241bf65f30..27a66a53e8 100644
--- a/include/configs/x600.h
+++ b/include/configs/x600.h
@@ -74,7 +74,6 @@
/* Ethernet config options */
#define CONFIG_MII
-#define CONFIG_DESIGNWARE_ETH
#define CONFIG_NET_MULTI
#define CONFIG_PHYLIB
#define CONFIG_PHY_RESET_DELAY 10000 /* in usec */
diff --git a/include/configs/x86-chromebook.h b/include/configs/x86-chromebook.h
new file mode 100644
index 0000000000..b6a76fe075
--- /dev/null
+++ b/include/configs/x86-chromebook.h
@@ -0,0 +1,68 @@
+/*
+ *
+ * Copyright (c) 2015 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _X86_CHROMEBOOK_H
+#define _X86_CHROMEBOOK_H
+
+#define CONFIG_SYS_MONITOR_LEN (1 << 20)
+
+#define CONFIG_DCACHE_RAM_MRC_VAR_SIZE 0x4000
+#define CONFIG_BOARD_EARLY_INIT_F
+#define CONFIG_MISC_INIT_R
+
+#define CONFIG_NR_DRAM_BANKS 8
+#define CONFIG_X86_MRC_ADDR 0xfffa0000
+#define CONFIG_CACHE_MRC_SIZE_KB 512
+
+#define CONFIG_X86_SERIAL
+
+#define CONFIG_SCSI_DEV_LIST \
+ {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_NM10_AHCI}, \
+ {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_COUGARPOINT_AHCI_MOBILE}, \
+ {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_COUGARPOINT_AHCI_SERIES6}, \
+ {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_PANTHERPOINT_AHCI_MOBILE}, \
+ {PCI_VENDOR_ID_INTEL, PCI_DEVICE_ID_INTEL_LYNXPOINT_AHCI}
+
+#define CONFIG_X86_OPTION_ROM_FILE pci8086,0166.bin
+#define CONFIG_X86_OPTION_ROM_ADDR 0xfff90000
+
+#define CONFIG_PCI_MEM_BUS 0xe0000000
+#define CONFIG_PCI_MEM_PHYS CONFIG_PCI_MEM_BUS
+#define CONFIG_PCI_MEM_SIZE 0x10000000
+
+#define CONFIG_PCI_PREF_BUS 0xd0000000
+#define CONFIG_PCI_PREF_PHYS CONFIG_PCI_PREF_BUS
+#define CONFIG_PCI_PREF_SIZE 0x10000000
+
+#define CONFIG_PCI_IO_BUS 0x1000
+#define CONFIG_PCI_IO_PHYS CONFIG_PCI_IO_BUS
+#define CONFIG_PCI_IO_SIZE 0xefff
+
+#define CONFIG_SYS_EARLY_PCI_INIT
+#define CONFIG_PCI_PNP
+
+#define CONFIG_BIOSEMU
+#define VIDEO_IO_OFFSET 0
+#define CONFIG_X86EMU_RAW_IO
+
+#define CONFIG_CROS_EC
+#define CONFIG_CROS_EC_LPC
+#define CONFIG_CMD_CROS_EC
+#define CONFIG_ARCH_EARLY_INIT_R
+
+#undef CONFIG_ENV_IS_NOWHERE
+#undef CONFIG_ENV_SIZE
+#define CONFIG_ENV_SIZE 0x1000
+#define CONFIG_ENV_SECT_SIZE 0x1000
+#define CONFIG_ENV_IS_IN_SPI_FLASH
+#define CONFIG_ENV_OFFSET 0x003f8000
+
+#define CONFIG_STD_DEVICES_SETTINGS "stdin=usbkbd,vga,serial\0" \
+ "stdout=vga,serial\0" \
+ "stderr=vga,serial\0"
+
+#endif
diff --git a/include/configs/x86-common.h b/include/configs/x86-common.h
index b7dd63e060..9571c656be 100644
--- a/include/configs/x86-common.h
+++ b/include/configs/x86-common.h
@@ -16,7 +16,6 @@
* (easy to change)
*/
#define CONFIG_SHOW_BOOT_PROGRESS
-#define CONFIG_SYS_VSNPRINTF
#define CONFIG_ZBOOT_32
#define CONFIG_PHYSMEM
#define CONFIG_DISPLAY_BOARDINFO_LATE
@@ -204,7 +203,6 @@
#define CONFIG_CMD_SF_TEST
#define CONFIG_CMD_SPI
#define CONFIG_SPI
-#define CONFIG_OF_SPI_FLASH
/*-----------------------------------------------------------------------
* Environment configuration
@@ -238,9 +236,6 @@
#define CONFIG_BOOTP_GATEWAY
#define CONFIG_BOOTP_HOSTNAME
-#define CONFIG_BOOTSTAGE
-#define CONFIG_CMD_BOOTSTAGE
-
#define CONFIG_CMD_USB
/* Default environment */
diff --git a/include/cros_ec.h b/include/cros_ec.h
index 8457c80c5e..3b2be2c2fa 100644
--- a/include/cros_ec.h
+++ b/include/cros_ec.h
@@ -15,31 +15,9 @@
#include <cros_ec_message.h>
#include <asm/gpio.h>
-#ifndef CONFIG_DM_CROS_EC
-/* Which interface is the device on? */
-enum cros_ec_interface_t {
- CROS_EC_IF_NONE,
- CROS_EC_IF_SPI,
- CROS_EC_IF_I2C,
- CROS_EC_IF_LPC, /* Intel Low Pin Count interface */
- CROS_EC_IF_SANDBOX,
-};
-#endif
-
/* Our configuration information */
struct cros_ec_dev {
-#ifdef CONFIG_DM_CROS_EC
struct udevice *dev; /* Transport device */
-#else
- enum cros_ec_interface_t interface;
- struct spi_slave *spi; /* Our SPI slave, if using SPI */
- int node; /* Our node */
- int parent_node; /* Our parent node (interface) */
- unsigned int cs; /* Our chip select */
- unsigned int addr; /* Device address (for I2C) */
- unsigned int bus_num; /* Bus number (for I2C) */
- unsigned int max_frequency; /* Maximum interface frequency */
-#endif
struct gpio_desc ec_int; /* GPIO used as EC interrupt line */
int protocol_version; /* Protocol version to use */
int optimise_flash_write; /* Don't write erased flash blocks */
@@ -240,8 +218,6 @@ int cros_ec_flash_update_rw(struct cros_ec_dev *dev,
*/
struct cros_ec_dev *board_get_cros_ec_dev(void);
-#ifdef CONFIG_DM_CROS_EC
-
struct dm_cros_ec_ops {
int (*check_version)(struct udevice *dev);
int (*command)(struct udevice *dev, uint8_t cmd, int cmd_version,
@@ -255,112 +231,6 @@ struct dm_cros_ec_ops {
int cros_ec_register(struct udevice *dev);
-#else /* !CONFIG_DM_CROS_EC */
-
-/* Internal interfaces */
-int cros_ec_i2c_init(struct cros_ec_dev *dev, const void *blob);
-int cros_ec_spi_init(struct cros_ec_dev *dev, const void *blob);
-int cros_ec_lpc_init(struct cros_ec_dev *dev, const void *blob);
-int cros_ec_sandbox_init(struct cros_ec_dev *dev, const void *blob);
-
-/**
- * Read information from the fdt for the i2c cros_ec interface
- *
- * @param dev CROS-EC device
- * @param blob Device tree blob
- * @return 0 if ok, -1 if we failed to read all required information
- */
-int cros_ec_i2c_decode_fdt(struct cros_ec_dev *dev, const void *blob);
-
-/**
- * Read information from the fdt for the spi cros_ec interface
- *
- * @param dev CROS-EC device
- * @param blob Device tree blob
- * @return 0 if ok, -1 if we failed to read all required information
- */
-int cros_ec_spi_decode_fdt(struct cros_ec_dev *dev, const void *blob);
-
-/**
- * Read information from the fdt for the sandbox cros_ec interface
- *
- * @param dev CROS-EC device
- * @param blob Device tree blob
- * @return 0 if ok, -1 if we failed to read all required information
- */
-int cros_ec_sandbox_decode_fdt(struct cros_ec_dev *dev, const void *blob);
-
-/**
- * Check whether the LPC interface supports new-style commands.
- *
- * LPC has its own way of doing this, which involves checking LPC values
- * visible to the host. Do this, and update dev->protocol_version accordingly.
- *
- * @param dev CROS-EC device to check
- */
-int cros_ec_lpc_check_version(struct cros_ec_dev *dev);
-
-/**
- * Send a command to an I2C CROS-EC device and return the reply.
- *
- * This rather complicated function deals with sending both old-style and
- * new-style commands. The old ones have just a command byte and arguments.
- * The new ones have version, command, arg-len, [args], chksum so are 3 bytes
- * longer.
- *
- * The device's internal input/output buffers are used.
- *
- * @param dev CROS-EC device
- * @param cmd Command to send (EC_CMD_...)
- * @param cmd_version Version of command to send (EC_VER_...)
- * @param dout Output data (may be NULL If dout_len=0)
- * @param dout_len Size of output data in bytes
- * @param dinp Returns pointer to response data
- * @param din_len Maximum size of response in bytes
- * @return number of bytes in response, or -1 on error
- */
-int cros_ec_i2c_command(struct cros_ec_dev *dev, uint8_t cmd, int cmd_version,
- const uint8_t *dout, int dout_len,
- uint8_t **dinp, int din_len);
-
-/**
- * Send a command to a LPC CROS-EC device and return the reply.
- *
- * The device's internal input/output buffers are used.
- *
- * @param dev CROS-EC device
- * @param cmd Command to send (EC_CMD_...)
- * @param cmd_version Version of command to send (EC_VER_...)
- * @param dout Output data (may be NULL If dout_len=0)
- * @param dout_len Size of output data in bytes
- * @param dinp Returns pointer to response data
- * @param din_len Maximum size of response in bytes
- * @return number of bytes in response, or -1 on error
- */
-int cros_ec_lpc_command(struct cros_ec_dev *dev, uint8_t cmd, int cmd_version,
- const uint8_t *dout, int dout_len,
- uint8_t **dinp, int din_len);
-
-int cros_ec_spi_command(struct cros_ec_dev *dev, uint8_t cmd, int cmd_version,
- const uint8_t *dout, int dout_len,
- uint8_t **dinp, int din_len);
-
-/**
- * Send a packet to a CROS-EC device and return the response packet.
- *
- * Expects the request packet to be stored in dev->dout. Stores the response
- * packet in dev->din.
- *
- * @param dev CROS-EC device
- * @param out_bytes Size of request packet to output
- * @param in_bytes Maximum size of response packet to receive
- * @return number of bytes in response packet, or <0 on error
- */
-int cros_ec_spi_packet(struct cros_ec_dev *dev, int out_bytes, int in_bytes);
-int cros_ec_sandbox_packet(struct cros_ec_dev *dev, int out_bytes,
- int in_bytes);
-#endif
-
/**
* Dump a block of data for a command.
*
@@ -493,13 +363,6 @@ int cros_ec_set_ldo(struct cros_ec_dev *dev, uint8_t index, uint8_t state);
int cros_ec_get_ldo(struct cros_ec_dev *dev, uint8_t index, uint8_t *state);
/**
- * Initialize the Chrome OS EC at board initialization time.
- *
- * @return 0 if ok, -ve on error
- */
-int cros_ec_board_init(void);
-
-/**
* Get access to the error reported when cros_ec_board_init() was called
*
* This permits delayed reporting of the EC error if it failed during
diff --git a/include/dm/device-internal.h b/include/dm/device-internal.h
index e2418fedb9..687462b093 100644
--- a/include/dm/device-internal.h
+++ b/include/dm/device-internal.h
@@ -34,7 +34,7 @@ struct udevice;
* @devp: Returns a pointer to the bound device
* @return 0 if OK, -ve on error
*/
-int device_bind(struct udevice *parent, struct driver *drv,
+int device_bind(struct udevice *parent, const struct driver *drv,
const char *name, void *platdata, int of_offset,
struct udevice **devp);
diff --git a/include/dm/device.h b/include/dm/device.h
index 7a48eb88b8..c11342c33b 100644
--- a/include/dm/device.h
+++ b/include/dm/device.h
@@ -30,6 +30,9 @@ struct driver_info;
/* DM is responsible for allocating and freeing parent_platdata */
#define DM_FLAG_ALLOC_PARENT_PDATA (1 << 3)
+/* Allocate driver private data on a DMA boundary */
+#define DM_FLAG_ALLOC_PRIV_DMA (1 << 4)
+
/**
* struct udevice - An instance of a driver
*
@@ -52,7 +55,8 @@ struct driver_info;
* @platdata: Configuration data for this device
* @parent_platdata: The parent bus's configuration data for this device
* @of_offset: Device tree node offset for this device (- for none)
- * @of_id: Pointer to the udevice_id structure which created the device
+ * @driver_data: Driver data word for the entry that matched this device with
+ * its driver
* @parent: Parent of this device, or NULL for the top level device
* @priv: Private data for this device
* @uclass: Pointer to uclass for this device
@@ -67,12 +71,12 @@ struct driver_info;
* when the device is probed and will be unique within the device's uclass.
*/
struct udevice {
- struct driver *driver;
+ const struct driver *driver;
const char *name;
void *platdata;
void *parent_platdata;
int of_offset;
- const struct udevice_id *of_id;
+ ulong driver_data;
struct udevice *parent;
void *priv;
struct uclass *uclass;
@@ -238,13 +242,28 @@ void *dev_get_priv(struct udevice *dev);
struct udevice *dev_get_parent(struct udevice *child);
/**
- * dev_get_of_data() - get the device tree data used to bind a device
+ * dev_get_uclass_priv() - Get the private uclass data for a device
+ *
+ * This checks that dev is not NULL, but no other checks for now
+ *
+ * @dev Device to check
+ * @return private uclass data for this device, or NULL if none
+ */
+void *dev_get_uclass_priv(struct udevice *dev);
+
+/**
+ * dev_get_driver_data() - get the driver data used to bind a device
*
* When a device is bound using a device tree node, it matches a
* particular compatible string as in struct udevice_id. This function
- * returns the associated data value for that compatible string
+ * returns the associated data value for that compatible string. This is
+ * the 'data' field in struct udevice_id.
+ *
+ * For USB devices, this is the driver_info field in struct usb_device_id.
+ *
+ * @dev: Device to check
*/
-ulong dev_get_of_data(struct udevice *dev);
+ulong dev_get_driver_data(struct udevice *dev);
/*
* device_get_uclass_id() - return the uclass ID of a device
@@ -361,4 +380,34 @@ int device_find_next_child(struct udevice **devp);
*/
fdt_addr_t dev_get_addr(struct udevice *dev);
+/**
+ * device_has_children() - check if a device has any children
+ *
+ * @dev: Device to check
+ * @return true if the device has one or more children
+ */
+bool device_has_children(struct udevice *dev);
+
+/**
+ * device_has_active_children() - check if a device has any active children
+ *
+ * @dev: Device to check
+ * @return true if the device has one or more children and at least one of
+ * them is active (probed).
+ */
+bool device_has_active_children(struct udevice *dev);
+
+/**
+ * device_is_last_sibling() - check if a device is the last sibling
+ *
+ * This function can be useful for display purposes, when special action needs
+ * to be taken when displaying the last sibling. This can happen when a tree
+ * view of devices is being displayed.
+ *
+ * @dev: Device to check
+ * @return true if there are no more siblings after this one - i.e. is it
+ * last in the list.
+ */
+bool device_is_last_sibling(struct udevice *dev);
+
#endif
diff --git a/include/dm/test.h b/include/dm/test.h
index 707c69e07f..9c4b8d3e57 100644
--- a/include/dm/test.h
+++ b/include/dm/test.h
@@ -44,6 +44,7 @@ enum {
/* For uclass */
DM_TEST_OP_POST_BIND,
DM_TEST_OP_PRE_UNBIND,
+ DM_TEST_OP_PRE_PROBE,
DM_TEST_OP_POST_PROBE,
DM_TEST_OP_PRE_REMOVE,
DM_TEST_OP_INIT,
@@ -204,12 +205,13 @@ void dm_leak_check_start(struct dm_test_state *dms);
/**
- * dm_test_main() - Run all the tests
+ * dm_test_main() - Run all or one of the tests
*
- * This runs all available driver model tests
+ * This runs all available driver model tests, or a selected one
*
+ * @test_name: Name of test to run, or NULL for all
* @return 0 if OK, -ve on error
*/
-int dm_test_main(void);
+int dm_test_main(const char *test_name);
#endif
diff --git a/include/dm/uclass-id.h b/include/dm/uclass-id.h
index 91bb90dcfb..fddfd35f1f 100644
--- a/include/dm/uclass-id.h
+++ b/include/dm/uclass-id.h
@@ -20,6 +20,8 @@ enum uclass_id {
UCLASS_TEST_BUS,
UCLASS_SPI_EMUL, /* sandbox SPI device emulator */
UCLASS_I2C_EMUL, /* sandbox I2C device emulator */
+ UCLASS_PCI_EMUL, /* sandbox PCI device emulator */
+ UCLASS_USB_EMUL, /* sandbox USB bus device emulator */
UCLASS_SIMPLE_BUS,
/* U-Boot uclasses start here */
@@ -34,6 +36,15 @@ enum uclass_id {
UCLASS_I2C_GENERIC, /* Generic I2C device */
UCLASS_I2C_EEPROM, /* I2C EEPROM device */
UCLASS_MOD_EXP, /* RSA Mod Exp device */
+ UCLASS_PCI, /* PCI bus */
+ UCLASS_PCI_GENERIC, /* Generic PCI bus device */
+ UCLASS_PCH, /* x86 platform controller hub */
+ UCLASS_ETH, /* Ethernet device */
+ UCLASS_LPC, /* x86 'low pin count' interface */
+ UCLASS_USB, /* USB bus */
+ UCLASS_USB_HUB, /* USB hub */
+ UCLASS_USB_DEV_GENERIC, /* USB generic device */
+ UCLASS_MASS_STORAGE, /* Mass storage device */
UCLASS_COUNT,
UCLASS_INVALID = -1,
diff --git a/include/dm/uclass-internal.h b/include/dm/uclass-internal.h
index f2f254a825..ae2a93d7d4 100644
--- a/include/dm/uclass-internal.h
+++ b/include/dm/uclass-internal.h
@@ -44,15 +44,16 @@ int uclass_bind_device(struct udevice *dev);
int uclass_unbind_device(struct udevice *dev);
/**
- * uclass_pre_probe_child() - Deal with a child that is about to be probed
+ * uclass_pre_probe_device() - Deal with a device that is about to be probed
*
* Perform any pre-processing that is needed by the uclass before it can be
- * probed.
+ * probed. This includes the uclass' pre-probe() method and the parent
+ * uclass' child_pre_probe() method.
*
* @dev: Pointer to the device
* #return 0 on success, -ve on error
*/
-int uclass_pre_probe_child(struct udevice *dev);
+int uclass_pre_probe_device(struct udevice *dev);
/**
* uclass_post_probe_device() - Deal with a device that has just been probed
diff --git a/include/dm/uclass.h b/include/dm/uclass.h
index d6c40c60dd..d57d804259 100644
--- a/include/dm/uclass.h
+++ b/include/dm/uclass.h
@@ -53,6 +53,7 @@ struct udevice;
* @id: ID number of this uclass
* @post_bind: Called after a new device is bound to this uclass
* @pre_unbind: Called before a device is unbound from this uclass
+ * @pre_probe: Called before a new device is probed
* @post_probe: Called after a new device is probed
* @pre_remove: Called before a device is removed
* @child_post_bind: Called after a child is bound to a device in this uclass
@@ -80,6 +81,7 @@ struct uclass_driver {
enum uclass_id id;
int (*post_bind)(struct udevice *dev);
int (*pre_unbind)(struct udevice *dev);
+ int (*pre_probe)(struct udevice *dev);
int (*post_probe)(struct udevice *dev);
int (*pre_remove)(struct udevice *dev);
int (*child_post_bind)(struct udevice *dev);
diff --git a/include/fdtdec.h b/include/fdtdec.h
index 11a7b86007..d14e06abab 100644
--- a/include/fdtdec.h
+++ b/include/fdtdec.h
@@ -134,7 +134,6 @@ enum fdt_compat_id {
COMPAT_SAMSUNG_S3C2440_I2C, /* Exynos I2C Controller */
COMPAT_SAMSUNG_EXYNOS5_SOUND, /* Exynos Sound */
COMPAT_WOLFSON_WM8994_CODEC, /* Wolfson WM8994 Sound Codec */
- COMPAT_GOOGLE_CROS_EC, /* Google CROS_EC Protocol */
COMPAT_GOOGLE_CROS_EC_KEYB, /* Google CROS_EC Keyboard */
COMPAT_SAMSUNG_EXYNOS_EHCI, /* Exynos EHCI controller */
COMPAT_SAMSUNG_EXYNOS5_XHCI, /* Exynos5 XHCI controller */
@@ -153,13 +152,11 @@ enum fdt_compat_id {
COMPAT_INFINEON_SLB9635_TPM, /* Infineon SLB9635 TPM */
COMPAT_INFINEON_SLB9645_TPM, /* Infineon SLB9645 TPM */
COMPAT_SAMSUNG_EXYNOS5_I2C, /* Exynos5 High Speed I2C Controller */
- COMPAT_SANDBOX_HOST_EMULATION, /* Sandbox emulation of a function */
COMPAT_SANDBOX_LCD_SDL, /* Sandbox LCD emulation with SDL */
COMPAT_TI_TPS65090, /* Texas Instrument TPS65090 */
COMPAT_NXP_PTN3460, /* NXP PTN3460 DP/LVDS bridge */
COMPAT_SAMSUNG_EXYNOS_SYSMMU, /* Exynos sysmmu */
COMPAT_PARADE_PS8625, /* Parade PS8622 EDP->LVDS bridge */
- COMPAT_INTEL_LPC, /* Intel Low Pin Count I/F */
COMPAT_INTEL_MICROCODE, /* Intel microcode update */
COMPAT_MEMORY_SPD, /* Memory SPD information */
COMPAT_INTEL_PANTHERPOINT_AHCI, /* Intel Pantherpoint AHCI */
@@ -169,6 +166,7 @@ enum fdt_compat_id {
COMPAT_INTEL_ICH_SPI, /* Intel ICH7/9 SPI controller */
COMPAT_INTEL_QRK_MRC, /* Intel Quark MRC */
COMPAT_SOCIONEXT_XHCI, /* Socionext UniPhier xHCI */
+ COMPAT_INTEL_PCH, /* Intel PCH */
COMPAT_COUNT,
};
@@ -327,7 +325,9 @@ fdt_addr_t fdtdec_get_addr_size(const void *blob, int node,
* @param type pci address type (FDT_PCI_SPACE_xxx)
* @param prop_name name of property to find
* @param addr returns pci address in the form of fdt_pci_addr
- * @return 0 if ok, negative on error
+ * @return 0 if ok, -ENOENT if the property did not exist, -EINVAL if the
+ * format of the property was invalid, -ENXIO if the requested
+ * address type was not found
*/
int fdtdec_get_pci_addr(const void *blob, int node, enum fdt_pci_space type,
const char *prop_name, struct fdt_pci_addr *addr);
@@ -389,6 +389,17 @@ s32 fdtdec_get_int(const void *blob, int node, const char *prop_name,
s32 default_val);
/**
+ * Get a variable-sized number from a property
+ *
+ * This reads a number from one or more cells.
+ *
+ * @param ptr Pointer to property
+ * @param cells Number of cells containing the number
+ * @return the value in the cells
+ */
+u64 fdtdec_get_number(const fdt32_t *ptr, unsigned int cells);
+
+/**
* Look up a 64-bit integer property in a node and return it. The property
* must have at least 8 bytes of data (2 cells). The first two cells are
* concatenated to form a 8 bytes value, where the first cell is top half and
diff --git a/include/fsl_dspi.h b/include/fsl_dspi.h
new file mode 100644
index 0000000000..b569b4d2b6
--- /dev/null
+++ b/include/fsl_dspi.h
@@ -0,0 +1,150 @@
+/*
+ * Freescale DSPI Module Defines
+ *
+ * Copyright (C) 2004-2007, 2015 Freescale Semiconductor, Inc.
+ * TsiChung Liew (Tsi-Chung.Liew@freescale.com)
+ * Chao Fu (B44548@freesacle.com)
+ * Haikun Wang (B53464@freescale.com)
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#ifndef _FSL_DSPI_H_
+#define _FSL_DSPI_H_
+
+/* DMA Serial Peripheral Interface (DSPI) */
+struct dspi {
+ u32 mcr; /* 0x00 */
+ u32 resv0; /* 0x04 */
+ u32 tcr; /* 0x08 */
+ u32 ctar[8]; /* 0x0C - 0x28 */
+ u32 sr; /* 0x2C */
+ u32 irsr; /* 0x30 */
+ u32 tfr; /* 0x34 - PUSHR */
+ u32 rfr; /* 0x38 - POPR */
+#ifdef CONFIG_MCF547x_8x
+ u32 tfdr[4]; /* 0x3C */
+ u8 resv2[0x30]; /* 0x40 */
+ u32 rfdr[4]; /* 0x7C */
+#else
+ u32 tfdr[16]; /* 0x3C */
+ u32 rfdr[16]; /* 0x7C */
+#endif
+};
+
+/* Module configuration */
+#define DSPI_MCR_MSTR 0x80000000
+#define DSPI_MCR_CSCK 0x40000000
+#define DSPI_MCR_DCONF(x) (((x) & 0x03) << 28)
+#define DSPI_MCR_FRZ 0x08000000
+#define DSPI_MCR_MTFE 0x04000000
+#define DSPI_MCR_PCSSE 0x02000000
+#define DSPI_MCR_ROOE 0x01000000
+#define DSPI_MCR_PCSIS(x) (1 << (16 + (x)))
+#define DSPI_MCR_PCSIS_MASK (0xff << 16)
+#define DSPI_MCR_CSIS7 0x00800000
+#define DSPI_MCR_CSIS6 0x00400000
+#define DSPI_MCR_CSIS5 0x00200000
+#define DSPI_MCR_CSIS4 0x00100000
+#define DSPI_MCR_CSIS3 0x00080000
+#define DSPI_MCR_CSIS2 0x00040000
+#define DSPI_MCR_CSIS1 0x00020000
+#define DSPI_MCR_CSIS0 0x00010000
+#define DSPI_MCR_DOZE 0x00008000
+#define DSPI_MCR_MDIS 0x00004000
+#define DSPI_MCR_DTXF 0x00002000
+#define DSPI_MCR_DRXF 0x00001000
+#define DSPI_MCR_CTXF 0x00000800
+#define DSPI_MCR_CRXF 0x00000400
+#define DSPI_MCR_SMPL_PT(x) (((x) & 0x03) << 8)
+#define DSPI_MCR_FCPCS 0x00000001
+#define DSPI_MCR_PES 0x00000001
+#define DSPI_MCR_HALT 0x00000001
+
+/* Transfer count */
+#define DSPI_TCR_SPI_TCNT(x) (((x) & 0x0000FFFF) << 16)
+
+/* Clock and transfer attributes */
+#define DSPI_CTAR(x) (0x0c + (x * 4))
+#define DSPI_CTAR_DBR 0x80000000
+#define DSPI_CTAR_TRSZ(x) (((x) & 0x0F) << 27)
+#define DSPI_CTAR_CPOL 0x04000000
+#define DSPI_CTAR_CPHA 0x02000000
+#define DSPI_CTAR_LSBFE 0x01000000
+#define DSPI_CTAR_PCSSCK(x) (((x) & 0x03) << 22)
+#define DSPI_CTAR_PCSSCK_7CLK 0x00A00000
+#define DSPI_CTAR_PCSSCK_5CLK 0x00800000
+#define DSPI_CTAR_PCSSCK_3CLK 0x00400000
+#define DSPI_CTAR_PCSSCK_1CLK 0x00000000
+#define DSPI_CTAR_PASC(x) (((x) & 0x03) << 20)
+#define DSPI_CTAR_PASC_7CLK 0x00300000
+#define DSPI_CTAR_PASC_5CLK 0x00200000
+#define DSPI_CTAR_PASC_3CLK 0x00100000
+#define DSPI_CTAR_PASC_1CLK 0x00000000
+#define DSPI_CTAR_PDT(x) (((x) & 0x03) << 18)
+#define DSPI_CTAR_PDT_7CLK 0x000A0000
+#define DSPI_CTAR_PDT_5CLK 0x00080000
+#define DSPI_CTAR_PDT_3CLK 0x00040000
+#define DSPI_CTAR_PDT_1CLK 0x00000000
+#define DSPI_CTAR_PBR(x) (((x) & 0x03) << 16)
+#define DSPI_CTAR_PBR_7CLK 0x00030000
+#define DSPI_CTAR_PBR_5CLK 0x00020000
+#define DSPI_CTAR_PBR_3CLK 0x00010000
+#define DSPI_CTAR_PBR_1CLK 0x00000000
+#define DSPI_CTAR_CSSCK(x) (((x) & 0x0F) << 12)
+#define DSPI_CTAR_ASC(x) (((x) & 0x0F) << 8)
+#define DSPI_CTAR_DT(x) (((x) & 0x0F) << 4)
+#define DSPI_CTAR_BR(x) ((x) & 0x0F)
+
+/* Status */
+#define DSPI_SR_TCF 0x80000000
+#define DSPI_SR_TXRXS 0x40000000
+#define DSPI_SR_EOQF 0x10000000
+#define DSPI_SR_TFUF 0x08000000
+#define DSPI_SR_TFFF 0x02000000
+#define DSPI_SR_RFOF 0x00080000
+#define DSPI_SR_RFDF 0x00020000
+#define DSPI_SR_TXCTR(x) (((x) & 0x0000F000) >> 12)
+#define DSPI_SR_TXPTR(x) (((x) & 0x00000F00) >> 8)
+#define DSPI_SR_RXCTR(x) (((x) & 0x000000F0) >> 4)
+#define DSPI_SR_RXPTR(x) ((x) & 0x0000000F)
+
+/* DMA/interrupt request selct and enable */
+#define DSPI_IRSR_TCFE 0x80000000
+#define DSPI_IRSR_EOQFE 0x10000000
+#define DSPI_IRSR_TFUFE 0x08000000
+#define DSPI_IRSR_TFFFE 0x02000000
+#define DSPI_IRSR_TFFFS 0x01000000
+#define DSPI_IRSR_RFOFE 0x00080000
+#define DSPI_IRSR_RFDFE 0x00020000
+#define DSPI_IRSR_RFDFS 0x00010000
+
+/* Transfer control - 32-bit access */
+#define DSPI_TFR_PCS(x) (((1 << x) & 0x0000003f) << 16)
+#define DSPI_TFR_CONT 0x80000000
+#define DSPI_TFR_CTAS(x) (((x) & 0x07) << 28)
+#define DSPI_TFR_EOQ 0x08000000
+#define DSPI_TFR_CTCNT 0x04000000
+#define DSPI_TFR_CS7 0x00800000
+#define DSPI_TFR_CS6 0x00400000
+#define DSPI_TFR_CS5 0x00200000
+#define DSPI_TFR_CS4 0x00100000
+#define DSPI_TFR_CS3 0x00080000
+#define DSPI_TFR_CS2 0x00040000
+#define DSPI_TFR_CS1 0x00020000
+#define DSPI_TFR_CS0 0x00010000
+
+/* Transfer Fifo */
+#define DSPI_TFR_TXDATA(x) ((x) & 0x0000FFFF)
+
+/* Bit definitions and macros for DRFR */
+#define DSPI_RFR_RXDATA(x) ((x) & 0x0000FFFF)
+
+/* Bit definitions and macros for DTFDR group */
+#define DSPI_TFDR_TXDATA(x) ((x) & 0x0000FFFF)
+#define DSPI_TFDR_TXCMD(x) (((x) & 0x0000FFFF) << 16)
+
+/* Bit definitions and macros for DRFDR group */
+#define DSPI_RFDR_RXDATA(x) ((x) & 0x0000FFFF)
+
+#endif /* _FSL_DSPI_H_ */
diff --git a/include/i2c.h b/include/i2c.h
index 31b038991e..6fd73fae4c 100644
--- a/include/i2c.h
+++ b/include/i2c.h
@@ -64,8 +64,8 @@ struct dm_i2c_chip {
* bus can operate at different speeds (measured in Hz, typically 100KHz
* or 400KHz).
*
- * To obtain this structure, use bus->uclass_priv where bus is the I2C
- * bus udevice.
+ * To obtain this structure, use dev_get_uclass_priv(bus) where bus is the
+ * I2C bus udevice.
*
* @speed_hz: Bus speed in hertz (typically 100000)
*/
@@ -340,7 +340,7 @@ struct dm_i2c_ops {
* The bus speed value will be updated by the uclass if this function
* does not return an error. This method is optional - if it is not
* provided then the driver can read the speed from
- * bus->uclass_priv->speed_hz
+ * dev_get_uclass_priv(bus)->speed_hz
*
* @bus: Bus to adjust
* @speed: Requested speed in Hz
@@ -354,7 +354,7 @@ struct dm_i2c_ops {
* Normally this can be provided by the uclass, but if you want your
* driver to check the bus speed by looking at the hardware, you can
* implement that here. This method is optional. This method would
- * normally be expected to return bus->uclass_priv->speed_hz.
+ * normally be expected to return dev_get_uclass_priv(bus)->speed_hz.
*
* @bus: Bus to check
* @return speed of selected I2C bus in Hz, -ve on error
diff --git a/include/linker_lists.h b/include/linker_lists.h
index 940c871281..b22d169d97 100644
--- a/include/linker_lists.h
+++ b/include/linker_lists.h
@@ -103,6 +103,16 @@
*/
/**
+ * ll_sym() - Access a linker-generated array entry
+ * @_type: Data type of the entry
+ * @_name: Name of the entry
+ * @_list: name of the list. Should contain only characters allowed
+ * in a C variable name!
+ */
+#define llsym(_type, _name, _list) \
+ ((_type *)&_u_boot_list_2_##_list##_2_##_name)
+
+/**
* ll_entry_declare() - Declare linker-generated array entry
* @_type: Data type of the entry
* @_name: Name of the entry
diff --git a/include/linux/usb/ch9.h b/include/linux/usb/ch9.h
index bd48704c87..822fca0357 100644
--- a/include/linux/usb/ch9.h
+++ b/include/linux/usb/ch9.h
@@ -379,6 +379,11 @@ struct usb_endpoint_descriptor {
#define USB_DT_ENDPOINT_SIZE 7
#define USB_DT_ENDPOINT_AUDIO_SIZE 9 /* Audio extension */
+/* Used to access common fields */
+struct usb_generic_descriptor {
+ __u8 bLength;
+ __u8 bDescriptorType;
+};
/*
* Endpoints
@@ -1002,4 +1007,17 @@ struct usb_set_sel_req {
*/
#define USB_SELF_POWER_VBUS_MAX_DRAW 100
+/**
+ * struct usb_string - wraps a C string and its USB id
+ * @id:the (nonzero) ID for this string
+ * @s:the string, in UTF-8 encoding
+ *
+ * If you're using usb_gadget_get_string(), use this to wrap a string
+ * together with its ID.
+ */
+struct usb_string {
+ u8 id;
+ const char *s;
+};
+
#endif /* __LINUX_USB_CH9_H */
diff --git a/include/linux/usb/gadget.h b/include/linux/usb/gadget.h
index 230f47d67e..4adf35e3ae 100644
--- a/include/linux/usb/gadget.h
+++ b/include/linux/usb/gadget.h
@@ -859,19 +859,6 @@ void usb_del_gadget_udc(struct usb_gadget *gadget);
/* utility to simplify dealing with string descriptors */
/**
- * struct usb_string - wraps a C string and its USB id
- * @id:the (nonzero) ID for this string
- * @s:the string, in UTF-8 encoding
- *
- * If you're using usb_gadget_get_string(), use this to wrap a string
- * together with its ID.
- */
-struct usb_string {
- u8 id;
- const char *s;
-};
-
-/**
* struct usb_gadget_strings - a set of USB strings in a given language
* @language:identifies the strings' language (0x0409 for en-us)
* @strings:array of strings with their ids
diff --git a/include/mapmem.h b/include/mapmem.h
new file mode 100644
index 0000000000..42ef3e8c2a
--- /dev/null
+++ b/include/mapmem.h
@@ -0,0 +1,32 @@
+/*
+ * Copyright (c) 2015 National Instruments
+ *
+ * (C) Copyright 2015
+ * Joe Hershberger <joe.hershberger@ni.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#ifndef __MAPMEM_H
+#define __MAPMEM_H
+
+/* Define a null map_sysmem() if the architecture doesn't use it */
+# ifdef CONFIG_ARCH_MAP_SYSMEM
+#include <asm/io.h>
+# else
+static inline void *map_sysmem(phys_addr_t paddr, unsigned long len)
+{
+ return (void *)(uintptr_t)paddr;
+}
+
+static inline void unmap_sysmem(const void *vaddr)
+{
+}
+
+static inline phys_addr_t map_to_sysmem(const void *ptr)
+{
+ return (phys_addr_t)(uintptr_t)ptr;
+}
+# endif
+
+#endif /* __MAPMEM_H */
diff --git a/include/net.h b/include/net.h
index 237c932be3..d17173d818 100644
--- a/include/net.h
+++ b/include/net.h
@@ -39,8 +39,9 @@
#define PKTALIGN ARCH_DMA_MINALIGN
/* IPv4 addresses are always 32 bits in size */
-typedef __be32 IPaddr_t;
-
+struct in_addr {
+ __be32 s_addr;
+};
/**
* An incoming packet handler.
@@ -51,7 +52,7 @@ typedef __be32 IPaddr_t;
* @param len packet length
*/
typedef void rxhand_f(uchar *pkt, unsigned dport,
- IPaddr_t sip, unsigned sport,
+ struct in_addr sip, unsigned sport,
unsigned len);
/**
@@ -65,7 +66,7 @@ typedef void rxhand_f(uchar *pkt, unsigned dport,
* @param len packet length
*/
typedef void rxhand_icmp_f(unsigned type, unsigned code, unsigned dport,
- IPaddr_t sip, unsigned sport, uchar *pkt, unsigned len);
+ struct in_addr sip, unsigned sport, uchar *pkt, unsigned len);
/*
* A timeout handler. Called after time interval has expired.
@@ -78,32 +79,94 @@ enum eth_state_t {
ETH_STATE_ACTIVE
};
+#ifdef CONFIG_DM_ETH
+/**
+ * struct eth_pdata - Platform data for Ethernet MAC controllers
+ *
+ * @iobase: The base address of the hardware registers
+ * @enetaddr: The Ethernet MAC address that is loaded from EEPROM or env
+ * @phy_interface: PHY interface to use - see PHY_INTERFACE_MODE_...
+ */
+struct eth_pdata {
+ phys_addr_t iobase;
+ unsigned char enetaddr[6];
+ int phy_interface;
+};
+
+/**
+ * struct eth_ops - functions of Ethernet MAC controllers
+ *
+ * start: Prepare the hardware to send and receive packets
+ * send: Send the bytes passed in "packet" as a packet on the wire
+ * recv: Check if the hardware received a packet. If so, set the pointer to the
+ * packet buffer in the packetp parameter. If not, return an error or 0 to
+ * indicate that the hardware receive FIFO is empty. If 0 is returned, the
+ * network stack will not process the empty packet, but free_pkt() will be
+ * called if supplied
+ * free_pkt: Give the driver an opportunity to manage its packet buffer memory
+ * when the network stack is finished processing it. This will only be
+ * called when no error was returned from recv - optional
+ * stop: Stop the hardware from looking for packets - may be called even if
+ * state == PASSIVE
+ * mcast: Join or leave a multicast group (for TFTP) - optional
+ * write_hwaddr: Write a MAC address to the hardware (used to pass it to Linux
+ * on some platforms like ARM). This function expects the
+ * eth_pdata::enetaddr field to be populated - optional
+ * read_rom_hwaddr: Some devices have a backup of the MAC address stored in a
+ * ROM on the board. This is how the driver should expose it
+ * to the network stack. This function should fill in the
+ * eth_pdata::enetaddr field - optional
+ */
+struct eth_ops {
+ int (*start)(struct udevice *dev);
+ int (*send)(struct udevice *dev, void *packet, int length);
+ int (*recv)(struct udevice *dev, uchar **packetp);
+ int (*free_pkt)(struct udevice *dev, uchar *packet, int length);
+ void (*stop)(struct udevice *dev);
+#ifdef CONFIG_MCAST_TFTP
+ int (*mcast)(struct udevice *dev, const u8 *enetaddr, int join);
+#endif
+ int (*write_hwaddr)(struct udevice *dev);
+ int (*read_rom_hwaddr)(struct udevice *dev);
+};
+
+#define eth_get_ops(dev) ((struct eth_ops *)(dev)->driver->ops)
+
+struct udevice *eth_get_dev(void); /* get the current device */
+/*
+ * The devname can be either an exact name given by the driver or device tree
+ * or it can be an alias of the form "eth%d"
+ */
+struct udevice *eth_get_dev_by_name(const char *devname);
+unsigned char *eth_get_ethaddr(void); /* get the current device MAC */
+/* Used only when NetConsole is enabled */
+int eth_init_state_only(void); /* Set active state */
+void eth_halt_state_only(void); /* Set passive state */
+#endif
+
+#ifndef CONFIG_DM_ETH
struct eth_device {
char name[16];
unsigned char enetaddr[6];
phys_addr_t iobase;
int state;
- int (*init) (struct eth_device *, bd_t *);
- int (*send) (struct eth_device *, void *packet, int length);
- int (*recv) (struct eth_device *);
- void (*halt) (struct eth_device *);
+ int (*init)(struct eth_device *, bd_t *);
+ int (*send)(struct eth_device *, void *packet, int length);
+ int (*recv)(struct eth_device *);
+ void (*halt)(struct eth_device *);
#ifdef CONFIG_MCAST_TFTP
- int (*mcast) (struct eth_device *, const u8 *enetaddr, u8 set);
+ int (*mcast)(struct eth_device *, const u8 *enetaddr, u8 set);
#endif
- int (*write_hwaddr) (struct eth_device *);
+ int (*write_hwaddr)(struct eth_device *);
struct eth_device *next;
int index;
void *priv;
};
-extern int eth_initialize(bd_t *bis); /* Initialize network subsystem */
-extern int eth_register(struct eth_device* dev);/* Register network device */
-extern int eth_unregister(struct eth_device *dev);/* Remove network device */
-extern void eth_try_another(int first_restart); /* Change the device */
-extern void eth_set_current(void); /* set nterface to ethcur var */
+int eth_register(struct eth_device *dev);/* Register network device */
+int eth_unregister(struct eth_device *dev);/* Remove network device */
-/* get the current device MAC */
extern struct eth_device *eth_current;
static inline __attribute__((always_inline))
@@ -111,39 +174,19 @@ struct eth_device *eth_get_dev(void)
{
return eth_current;
}
-extern struct eth_device *eth_get_dev_by_name(const char *devname);
-extern struct eth_device *eth_get_dev_by_index(int index); /* get dev @ index */
-extern int eth_get_dev_index(void); /* get the device index */
-extern void eth_parse_enetaddr(const char *addr, uchar *enetaddr);
-extern int eth_getenv_enetaddr(char *name, uchar *enetaddr);
-extern int eth_setenv_enetaddr(char *name, const uchar *enetaddr);
+struct eth_device *eth_get_dev_by_name(const char *devname);
+struct eth_device *eth_get_dev_by_index(int index); /* get dev @ index */
-/*
- * Get the hardware address for an ethernet interface .
- * Args:
- * base_name - base name for device (normally "eth")
- * index - device index number (0 for first)
- * enetaddr - returns 6 byte hardware address
- * Returns:
- * Return true if the address is valid.
- */
-extern int eth_getenv_enetaddr_by_index(const char *base_name, int index,
- uchar *enetaddr);
-
-extern int usb_eth_initialize(bd_t *bi);
-extern int eth_init(bd_t *bis); /* Initialize the device */
-extern int eth_send(void *packet, int length); /* Send a packet */
-
-#ifdef CONFIG_API
-extern int eth_receive(void *packet, int length); /* Receive a packet*/
-extern void (*push_packet)(void *packet, int length);
-#endif
-extern int eth_rx(void); /* Check for received packets */
-extern void eth_halt(void); /* stop SCC */
-extern char *eth_get_name(void); /* get name of current device */
+/* get the current device MAC */
+static inline unsigned char *eth_get_ethaddr(void)
+{
+ if (eth_current)
+ return eth_current->enetaddr;
+ return NULL;
+}
/* Set active state */
-static inline __attribute__((always_inline)) int eth_init_state_only(bd_t *bis)
+static inline __attribute__((always_inline)) int eth_init_state_only(void)
{
eth_get_dev()->state = ETH_STATE_ACTIVE;
@@ -167,8 +210,43 @@ static inline __attribute__((always_inline)) void eth_halt_state_only(void)
int eth_write_hwaddr(struct eth_device *dev, const char *base_name,
int eth_number);
+int usb_eth_initialize(bd_t *bi);
+#endif
+
+int eth_initialize(void); /* Initialize network subsystem */
+void eth_try_another(int first_restart); /* Change the device */
+void eth_set_current(void); /* set nterface to ethcur var */
+
+int eth_get_dev_index(void); /* get the device index */
+void eth_parse_enetaddr(const char *addr, uchar *enetaddr);
+int eth_getenv_enetaddr(char *name, uchar *enetaddr);
+int eth_setenv_enetaddr(char *name, const uchar *enetaddr);
+
+/*
+ * Get the hardware address for an ethernet interface .
+ * Args:
+ * base_name - base name for device (normally "eth")
+ * index - device index number (0 for first)
+ * enetaddr - returns 6 byte hardware address
+ * Returns:
+ * Return true if the address is valid.
+ */
+int eth_getenv_enetaddr_by_index(const char *base_name, int index,
+ uchar *enetaddr);
+
+int eth_init(void); /* Initialize the device */
+int eth_send(void *packet, int length); /* Send a packet */
+
+#ifdef CONFIG_API
+int eth_receive(void *packet, int length); /* Receive a packet*/
+extern void (*push_packet)(void *packet, int length);
+#endif
+int eth_rx(void); /* Check for received packets */
+void eth_halt(void); /* stop SCC */
+const char *eth_get_name(void); /* get name of current device */
+
#ifdef CONFIG_MCAST_TFTP
-int eth_mcast_join(IPaddr_t mcast_addr, u8 join);
+int eth_mcast_join(struct in_addr mcast_addr, int join);
u32 ether_crc(size_t len, unsigned char const *p);
#endif
@@ -183,9 +261,9 @@ u32 ether_crc(size_t len, unsigned char const *p);
*/
struct ethernet_hdr {
- uchar et_dest[6]; /* Destination node */
- uchar et_src[6]; /* Source node */
- ushort et_protlen; /* Protocol or length */
+ u8 et_dest[6]; /* Destination node */
+ u8 et_src[6]; /* Source node */
+ u16 et_protlen; /* Protocol or length */
};
/* Ethernet header size */
@@ -194,16 +272,16 @@ struct ethernet_hdr {
#define ETH_FCS_LEN 4 /* Octets in the FCS */
struct e802_hdr {
- uchar et_dest[6]; /* Destination node */
- uchar et_src[6]; /* Source node */
- ushort et_protlen; /* Protocol or length */
- uchar et_dsap; /* 802 DSAP */
- uchar et_ssap; /* 802 SSAP */
- uchar et_ctl; /* 802 control */
- uchar et_snap1; /* SNAP */
- uchar et_snap2;
- uchar et_snap3;
- ushort et_prot; /* 802 protocol */
+ u8 et_dest[6]; /* Destination node */
+ u8 et_src[6]; /* Source node */
+ u16 et_protlen; /* Protocol or length */
+ u8 et_dsap; /* 802 DSAP */
+ u8 et_ssap; /* 802 SSAP */
+ u8 et_ctl; /* 802 control */
+ u8 et_snap1; /* SNAP */
+ u8 et_snap2;
+ u8 et_snap3;
+ u16 et_prot; /* 802 protocol */
};
/* 802 + SNAP + ethernet header size */
@@ -213,11 +291,11 @@ struct e802_hdr {
* Virtual LAN Ethernet header
*/
struct vlan_ethernet_hdr {
- uchar vet_dest[6]; /* Destination node */
- uchar vet_src[6]; /* Source node */
- ushort vet_vlan_type; /* PROT_VLAN */
- ushort vet_tag; /* TAG of VLAN */
- ushort vet_type; /* protocol type */
+ u8 vet_dest[6]; /* Destination node */
+ u8 vet_src[6]; /* Source node */
+ u16 vet_vlan_type; /* PROT_VLAN */
+ u16 vet_tag; /* TAG of VLAN */
+ u16 vet_type; /* protocol type */
};
/* VLAN Ethernet header size */
@@ -235,16 +313,16 @@ struct vlan_ethernet_hdr {
* Internet Protocol (IP) header.
*/
struct ip_hdr {
- uchar ip_hl_v; /* header length and version */
- uchar ip_tos; /* type of service */
- ushort ip_len; /* total length */
- ushort ip_id; /* identification */
- ushort ip_off; /* fragment offset field */
- uchar ip_ttl; /* time to live */
- uchar ip_p; /* protocol */
- ushort ip_sum; /* checksum */
- IPaddr_t ip_src; /* Source IP address */
- IPaddr_t ip_dst; /* Destination IP address */
+ u8 ip_hl_v; /* header length and version */
+ u8 ip_tos; /* type of service */
+ u16 ip_len; /* total length */
+ u16 ip_id; /* identification */
+ u16 ip_off; /* fragment offset field */
+ u8 ip_ttl; /* time to live */
+ u8 ip_p; /* protocol */
+ u16 ip_sum; /* checksum */
+ struct in_addr ip_src; /* Source IP address */
+ struct in_addr ip_dst; /* Destination IP address */
};
#define IP_OFFS 0x1fff /* ip offset *= 8 */
@@ -259,20 +337,20 @@ struct ip_hdr {
* Internet Protocol (IP) + UDP header.
*/
struct ip_udp_hdr {
- uchar ip_hl_v; /* header length and version */
- uchar ip_tos; /* type of service */
- ushort ip_len; /* total length */
- ushort ip_id; /* identification */
- ushort ip_off; /* fragment offset field */
- uchar ip_ttl; /* time to live */
- uchar ip_p; /* protocol */
- ushort ip_sum; /* checksum */
- IPaddr_t ip_src; /* Source IP address */
- IPaddr_t ip_dst; /* Destination IP address */
- ushort udp_src; /* UDP source port */
- ushort udp_dst; /* UDP destination port */
- ushort udp_len; /* Length of UDP packet */
- ushort udp_xsum; /* Checksum */
+ u8 ip_hl_v; /* header length and version */
+ u8 ip_tos; /* type of service */
+ u16 ip_len; /* total length */
+ u16 ip_id; /* identification */
+ u16 ip_off; /* fragment offset field */
+ u8 ip_ttl; /* time to live */
+ u8 ip_p; /* protocol */
+ u16 ip_sum; /* checksum */
+ struct in_addr ip_src; /* Source IP address */
+ struct in_addr ip_dst; /* Destination IP address */
+ u16 udp_src; /* UDP source port */
+ u16 udp_dst; /* UDP destination port */
+ u16 udp_len; /* Length of UDP packet */
+ u16 udp_xsum; /* Checksum */
};
#define IP_UDP_HDR_SIZE (sizeof(struct ip_udp_hdr))
@@ -282,14 +360,14 @@ struct ip_udp_hdr {
* Address Resolution Protocol (ARP) header.
*/
struct arp_hdr {
- ushort ar_hrd; /* Format of hardware address */
+ u16 ar_hrd; /* Format of hardware address */
# define ARP_ETHER 1 /* Ethernet hardware address */
- ushort ar_pro; /* Format of protocol address */
- uchar ar_hln; /* Length of hardware address */
+ u16 ar_pro; /* Format of protocol address */
+ u8 ar_hln; /* Length of hardware address */
# define ARP_HLEN 6
- uchar ar_pln; /* Length of protocol address */
+ u8 ar_pln; /* Length of protocol address */
# define ARP_PLEN 4
- ushort ar_op; /* Operation */
+ u16 ar_op; /* Operation */
# define ARPOP_REQUEST 1 /* Request to resolve address */
# define ARPOP_REPLY 2 /* Response to previous request */
@@ -301,16 +379,16 @@ struct arp_hdr {
* the sizes above, and are defined as appropriate for
* specific hardware/protocol combinations.
*/
- uchar ar_data[0];
+ u8 ar_data[0];
#define ar_sha ar_data[0]
#define ar_spa ar_data[ARP_HLEN]
#define ar_tha ar_data[ARP_HLEN + ARP_PLEN]
#define ar_tpa ar_data[ARP_HLEN + ARP_PLEN + ARP_HLEN]
#if 0
- uchar ar_sha[]; /* Sender hardware address */
- uchar ar_spa[]; /* Sender protocol address */
- uchar ar_tha[]; /* Target hardware address */
- uchar ar_tpa[]; /* Target protocol address */
+ u8 ar_sha[]; /* Sender hardware address */
+ u8 ar_spa[]; /* Sender protocol address */
+ u8 ar_tha[]; /* Target hardware address */
+ u8 ar_tpa[]; /* Target protocol address */
#endif /* 0 */
};
@@ -332,20 +410,20 @@ struct arp_hdr {
#define ICMP_NOT_REACH_PORT 3 /* Port unreachable */
struct icmp_hdr {
- uchar type;
- uchar code;
- ushort checksum;
+ u8 type;
+ u8 code;
+ u16 checksum;
union {
struct {
- ushort id;
- ushort sequence;
+ u16 id;
+ u16 sequence;
} echo;
- ulong gateway;
+ u32 gateway;
struct {
- ushort unused;
- ushort mtu;
+ u16 unused;
+ u16 mtu;
} frag;
- uchar data[0];
+ u8 data[0];
} un;
};
@@ -383,105 +461,104 @@ struct icmp_hdr {
*
* Note:
*
- * All variables of type IPaddr_t are stored in NETWORK byte order
+ * All variables of type struct in_addr are stored in NETWORK byte order
* (big endian).
*/
/* net.c */
/** BOOTP EXTENTIONS **/
-extern IPaddr_t NetOurGatewayIP; /* Our gateway IP address */
-extern IPaddr_t NetOurSubnetMask; /* Our subnet mask (0 = unknown) */
-extern IPaddr_t NetOurDNSIP; /* Our Domain Name Server (0 = unknown) */
+extern struct in_addr net_gateway; /* Our gateway IP address */
+extern struct in_addr net_netmask; /* Our subnet mask (0 = unknown) */
+/* Our Domain Name Server (0 = unknown) */
+extern struct in_addr net_dns_server;
#if defined(CONFIG_BOOTP_DNS2)
-extern IPaddr_t NetOurDNS2IP; /* Our 2nd Domain Name Server (0 = unknown) */
+/* Our 2nd Domain Name Server (0 = unknown) */
+extern struct in_addr net_dns_server2;
#endif
-extern char NetOurNISDomain[32]; /* Our NIS domain */
-extern char NetOurHostName[32]; /* Our hostname */
-extern char NetOurRootPath[64]; /* Our root path */
-extern ushort NetBootFileSize; /* Our boot file size in blocks */
+extern char net_nis_domain[32]; /* Our IS domain */
+extern char net_hostname[32]; /* Our hostname */
+extern char net_root_path[64]; /* Our root path */
/** END OF BOOTP EXTENTIONS **/
-extern ulong NetBootFileXferSize; /* size of bootfile in bytes */
-extern uchar NetOurEther[6]; /* Our ethernet address */
-extern uchar NetServerEther[6]; /* Boot server enet address */
-extern IPaddr_t NetOurIP; /* Our IP addr (0 = unknown) */
-extern IPaddr_t NetServerIP; /* Server IP addr (0 = unknown) */
-extern uchar *NetTxPacket; /* THE transmit packet */
-extern uchar *NetRxPackets[PKTBUFSRX]; /* Receive packets */
-extern uchar *NetRxPacket; /* Current receive packet */
-extern int NetRxPacketLen; /* Current rx packet length */
-extern unsigned NetIPID; /* IP ID (counting) */
-extern uchar NetBcastAddr[6]; /* Ethernet boardcast address */
-extern uchar NetEtherNullAddr[6];
+extern u8 net_ethaddr[6]; /* Our ethernet address */
+extern u8 net_server_ethaddr[6]; /* Boot server enet address */
+extern struct in_addr net_ip; /* Our IP addr (0 = unknown) */
+extern struct in_addr net_server_ip; /* Server IP addr (0 = unknown) */
+extern uchar *net_tx_packet; /* THE transmit packet */
+extern uchar *net_rx_packets[PKTBUFSRX]; /* Receive packets */
+extern uchar *net_rx_packet; /* Current receive packet */
+extern int net_rx_packet_len; /* Current rx packet length */
+extern const u8 net_bcast_ethaddr[6]; /* Ethernet broadcast address */
+extern const u8 net_null_ethaddr[6];
#define VLAN_NONE 4095 /* untagged */
#define VLAN_IDMASK 0x0fff /* mask of valid vlan id */
-extern ushort NetOurVLAN; /* Our VLAN */
-extern ushort NetOurNativeVLAN; /* Our Native VLAN */
+extern ushort net_our_vlan; /* Our VLAN */
+extern ushort net_native_vlan; /* Our Native VLAN */
-extern int NetRestartWrap; /* Tried all network devices */
+extern int net_restart_wrap; /* Tried all network devices */
enum proto_t {
BOOTP, RARP, ARP, TFTPGET, DHCP, PING, DNS, NFS, CDP, NETCONS, SNTP,
TFTPSRV, TFTPPUT, LINKLOCAL
};
-/* from net/net.c */
-extern char BootFile[128]; /* Boot File name */
+extern char net_boot_file_name[128];/* Boot File name */
+/* The actual transferred size of the bootfile (in bytes) */
+extern u32 net_boot_file_size;
+/* Boot file size in blocks as reported by the DHCP server */
+extern u32 net_boot_file_expected_size_in_blocks;
#if defined(CONFIG_CMD_DNS)
-extern char *NetDNSResolve; /* The host to resolve */
-extern char *NetDNSenvvar; /* the env var to put the ip into */
+extern char *net_dns_resolve; /* The host to resolve */
+extern char *net_dns_env_var; /* the env var to put the ip into */
#endif
#if defined(CONFIG_CMD_PING)
-extern IPaddr_t NetPingIP; /* the ip address to ping */
+extern struct in_addr net_ping_ip; /* the ip address to ping */
#endif
#if defined(CONFIG_CMD_CDP)
/* when CDP completes these hold the return values */
-extern ushort CDPNativeVLAN; /* CDP returned native VLAN */
-extern ushort CDPApplianceVLAN; /* CDP returned appliance VLAN */
+extern ushort cdp_native_vlan; /* CDP returned native VLAN */
+extern ushort cdp_appliance_vlan; /* CDP returned appliance VLAN */
/*
* Check for a CDP packet by examining the received MAC address field
*/
-static inline int is_cdp_packet(const uchar *et_addr)
+static inline int is_cdp_packet(const uchar *ethaddr)
{
- extern const uchar NetCDPAddr[6];
+ extern const u8 net_cdp_ethaddr[6];
- return memcmp(et_addr, NetCDPAddr, 6) == 0;
+ return memcmp(ethaddr, net_cdp_ethaddr, 6) == 0;
}
#endif
#if defined(CONFIG_CMD_SNTP)
-extern IPaddr_t NetNtpServerIP; /* the ip address to NTP */
-extern int NetTimeOffset; /* offset time from UTC */
+extern struct in_addr net_ntp_server; /* the ip address to NTP */
+extern int net_ntp_time_offset; /* offset time from UTC */
#endif
#if defined(CONFIG_MCAST_TFTP)
-extern IPaddr_t Mcast_addr;
+extern struct in_addr net_mcast_addr;
#endif
/* Initialize the network adapter */
-extern void net_init(void);
-extern int NetLoop(enum proto_t);
-
-/* Shutdown adapters and cleanup */
-extern void NetStop(void);
+void net_init(void);
+int net_loop(enum proto_t);
/* Load failed. Start again. */
-extern void NetStartAgain(void);
+int net_start_again(void);
/* Get size of the ethernet header when we send */
-extern int NetEthHdrSize(void);
+int net_eth_hdr_size(void);
/* Set ethernet header; returns the size of the header */
-extern int NetSetEther(uchar *, uchar *, uint);
-extern int net_update_ether(struct ethernet_hdr *et, uchar *addr, uint prot);
+int net_set_ether(uchar *xet, const uchar *dest_ethaddr, uint prot);
+int net_update_ether(struct ethernet_hdr *et, uchar *addr, uint prot);
/* Set IP header */
-extern void net_set_ip_header(uchar *pkt, IPaddr_t dest, IPaddr_t source);
-extern void net_set_udp_header(uchar *pkt, IPaddr_t dest, int dport,
+void net_set_ip_header(uchar *pkt, struct in_addr dest, struct in_addr source);
+void net_set_udp_header(uchar *pkt, struct in_addr dest, int dport,
int sport, int len);
/**
@@ -515,12 +592,12 @@ unsigned add_ip_checksums(unsigned offset, unsigned sum, unsigned new_sum);
int ip_checksum_ok(const void *addr, unsigned nbytes);
/* Callbacks */
-extern rxhand_f *net_get_udp_handler(void); /* Get UDP RX packet handler */
-extern void net_set_udp_handler(rxhand_f *); /* Set UDP RX packet handler */
-extern rxhand_f *net_get_arp_handler(void); /* Get ARP RX packet handler */
-extern void net_set_arp_handler(rxhand_f *); /* Set ARP RX packet handler */
-extern void net_set_icmp_handler(rxhand_icmp_f *f); /* Set ICMP RX handler */
-extern void NetSetTimeout(ulong, thand_f *);/* Set timeout handler */
+rxhand_f *net_get_udp_handler(void); /* Get UDP RX packet handler */
+void net_set_udp_handler(rxhand_f *); /* Set UDP RX packet handler */
+rxhand_f *net_get_arp_handler(void); /* Get ARP RX packet handler */
+void net_set_arp_handler(rxhand_f *); /* Set ARP RX packet handler */
+void net_set_icmp_handler(rxhand_icmp_f *f); /* Set ICMP RX handler */
+void net_set_timeout_handler(ulong, thand_f *);/* Set timeout handler */
/* Network loop state */
enum net_loop_state {
@@ -538,13 +615,14 @@ static inline void net_set_state(enum net_loop_state state)
}
/* Transmit a packet */
-static inline void NetSendPacket(uchar *pkt, int len)
+static inline void net_send_packet(uchar *pkt, int len)
{
+ /* Currently no way to return errors from eth_send() */
(void) eth_send(pkt, len);
}
/*
- * Transmit "NetTxPacket" as UDP packet, performing ARP request if needed
+ * Transmit "net_tx_packet" as UDP packet, performing ARP request if needed
* (ether will be populated)
*
* @param ether Raw packet buffer
@@ -553,15 +631,15 @@ static inline void NetSendPacket(uchar *pkt, int len)
* @param sport Source UDP port
* @param payload_len Length of data after the UDP header
*/
-extern int NetSendUDPPacket(uchar *ether, IPaddr_t dest, int dport,
+int net_send_udp_packet(uchar *ether, struct in_addr dest, int dport,
int sport, int payload_len);
/* Processes a received packet */
-extern void NetReceive(uchar *, int);
+void net_process_received_packet(uchar *in_packet, int len);
#ifdef CONFIG_NETCONSOLE
-void NcStart(void);
-int nc_input_packet(uchar *pkt, IPaddr_t src_ip, unsigned dest_port,
+void nc_start(void);
+int nc_input_packet(uchar *pkt, struct in_addr src_ip, unsigned dest_port,
unsigned src_port, unsigned len);
#endif
@@ -599,78 +677,78 @@ void net_auto_load(void);
* footprint in our tests.
*/
/* return IP *in network byteorder* */
-static inline IPaddr_t NetReadIP(void *from)
+static inline struct in_addr net_read_ip(void *from)
{
- IPaddr_t ip;
+ struct in_addr ip;
memcpy((void *)&ip, (void *)from, sizeof(ip));
return ip;
}
/* return ulong *in network byteorder* */
-static inline ulong NetReadLong(ulong *from)
+static inline u32 net_read_u32(u32 *from)
{
- ulong l;
+ u32 l;
memcpy((void *)&l, (void *)from, sizeof(l));
return l;
}
/* write IP *in network byteorder* */
-static inline void NetWriteIP(void *to, IPaddr_t ip)
+static inline void net_write_ip(void *to, struct in_addr ip)
{
memcpy(to, (void *)&ip, sizeof(ip));
}
/* copy IP */
-static inline void NetCopyIP(void *to, void *from)
+static inline void net_copy_ip(void *to, void *from)
{
- memcpy((void *)to, from, sizeof(IPaddr_t));
+ memcpy((void *)to, from, sizeof(struct in_addr));
}
/* copy ulong */
-static inline void NetCopyLong(ulong *to, ulong *from)
+static inline void net_copy_u32(u32 *to, u32 *from)
{
- memcpy((void *)to, (void *)from, sizeof(ulong));
+ memcpy((void *)to, (void *)from, sizeof(u32));
}
/**
- * is_zero_ether_addr - Determine if give Ethernet address is all zeros.
+ * is_zero_ethaddr - Determine if give Ethernet address is all zeros.
* @addr: Pointer to a six-byte array containing the Ethernet address
*
* Return true if the address is all zeroes.
*/
-static inline int is_zero_ether_addr(const u8 *addr)
+static inline int is_zero_ethaddr(const u8 *addr)
{
return !(addr[0] | addr[1] | addr[2] | addr[3] | addr[4] | addr[5]);
}
/**
- * is_multicast_ether_addr - Determine if the Ethernet address is a multicast.
+ * is_multicast_ethaddr - Determine if the Ethernet address is a multicast.
* @addr: Pointer to a six-byte array containing the Ethernet address
*
* Return true if the address is a multicast address.
* By definition the broadcast address is also a multicast address.
*/
-static inline int is_multicast_ether_addr(const u8 *addr)
+static inline int is_multicast_ethaddr(const u8 *addr)
{
return 0x01 & addr[0];
}
/*
- * is_broadcast_ether_addr - Determine if the Ethernet address is broadcast
+ * is_broadcast_ethaddr - Determine if the Ethernet address is broadcast
* @addr: Pointer to a six-byte array containing the Ethernet address
*
* Return true if the address is the broadcast address.
*/
-static inline int is_broadcast_ether_addr(const u8 *addr)
+static inline int is_broadcast_ethaddr(const u8 *addr)
{
return (addr[0] & addr[1] & addr[2] & addr[3] & addr[4] & addr[5]) ==
0xff;
}
/*
- * is_valid_ether_addr - Determine if the given Ethernet address is valid
+ * is_valid_ethaddr - Determine if the given Ethernet address is valid
* @addr: Pointer to a six-byte array containing the Ethernet address
*
* Check that the Ethernet address (MAC) is not 00:00:00:00:00:00, is not
@@ -678,21 +756,21 @@ static inline int is_broadcast_ether_addr(const u8 *addr)
*
* Return true if the address is valid.
*/
-static inline int is_valid_ether_addr(const u8 *addr)
+static inline int is_valid_ethaddr(const u8 *addr)
{
/* FF:FF:FF:FF:FF:FF is a multicast address so we don't need to
* explicitly check for it here. */
- return !is_multicast_ether_addr(addr) && !is_zero_ether_addr(addr);
+ return !is_multicast_ethaddr(addr) && !is_zero_ethaddr(addr);
}
/**
- * eth_random_addr - Generate software assigned random Ethernet address
+ * net_random_ethaddr - Generate software assigned random Ethernet address
* @addr: Pointer to a six-byte array containing the Ethernet address
*
* Generate a random Ethernet address (MAC) that is not multicast
* and has the local assigned bit set.
*/
-static inline void eth_random_addr(uchar *addr)
+static inline void net_random_ethaddr(uchar *addr)
{
int i;
unsigned int seed = get_timer(0);
@@ -705,28 +783,28 @@ static inline void eth_random_addr(uchar *addr)
}
/* Convert an IP address to a string */
-extern void ip_to_string(IPaddr_t x, char *s);
+void ip_to_string(struct in_addr x, char *s);
/* Convert a string to ip address */
-extern IPaddr_t string_to_ip(const char *s);
+struct in_addr string_to_ip(const char *s);
/* Convert a VLAN id to a string */
-extern void VLAN_to_string(ushort x, char *s);
+void vlan_to_string(ushort x, char *s);
/* Convert a string to a vlan id */
-extern ushort string_to_VLAN(const char *s);
+ushort string_to_vlan(const char *s);
/* read a VLAN id from an environment variable */
-extern ushort getenv_VLAN(char *);
+ushort getenv_vlan(char *);
/* copy a filename (allow for "..." notation, limit length) */
-extern void copy_filename(char *dst, const char *src, int size);
+void copy_filename(char *dst, const char *src, int size);
/* get a random source port */
-extern unsigned int random_port(void);
+unsigned int random_port(void);
/* Update U-Boot over TFTP */
-extern int update_tftp(ulong addr);
+int update_tftp(ulong addr);
/**********************************************************************/
diff --git a/include/os.h b/include/os.h
index e3645e0116..a758f099aa 100644
--- a/include/os.h
+++ b/include/os.h
@@ -64,7 +64,7 @@ off_t os_lseek(int fd, off_t offset, int whence);
* Access to the OS open() system call
*
* \param pathname Pathname of file to open
- * \param flags Flags, like O_RDONLY, O_RDWR
+ * \param flags Flags, like OS_O_RDONLY, OS_O_RDWR
* \return file descriptor, or -1 on error
*/
int os_open(const char *pathname, int flags);
diff --git a/include/pci.h b/include/pci.h
index 004a048d2f..07b1e9a4f5 100644
--- a/include/pci.h
+++ b/include/pci.h
@@ -457,12 +457,15 @@ static inline void pci_set_region(struct pci_region *reg,
typedef int pci_dev_t;
-#define PCI_BUS(d) (((d) >> 16) & 0xff)
-#define PCI_DEV(d) (((d) >> 11) & 0x1f)
-#define PCI_FUNC(d) (((d) >> 8) & 0x7)
-#define PCI_BDF(b,d,f) ((b) << 16 | (d) << 11 | (f) << 8)
-
-#define PCI_ANY_ID (~0)
+#define PCI_BUS(d) (((d) >> 16) & 0xff)
+#define PCI_DEV(d) (((d) >> 11) & 0x1f)
+#define PCI_FUNC(d) (((d) >> 8) & 0x7)
+#define PCI_DEVFN(d, f) ((d) << 11 | (f) << 8)
+#define PCI_MASK_BUS(bdf) ((bdf) & 0xffff)
+#define PCI_ADD_BUS(bus, devfn) (((bus) << 16) | (devfn))
+#define PCI_BDF(b, d, f) ((b) << 16 | PCI_DEVFN(d, f))
+#define PCI_VENDEV(v, d) (((v) << 16) | (d))
+#define PCI_ANY_ID (~0)
struct pci_device_id {
unsigned int vendor, device; /* Vendor and device ID or PCI_ANY_ID */
@@ -495,7 +498,12 @@ extern void pci_cfgfunc_config_device(struct pci_controller* hose, pci_dev_t dev
* Structure of a PCI controller (host bridge)
*/
struct pci_controller {
+#ifdef CONFIG_DM_PCI
+ struct udevice *bus;
+ struct udevice *ctlr;
+#else
struct pci_controller *next;
+#endif
int first_busno;
int last_busno;
@@ -511,7 +519,7 @@ struct pci_controller {
struct pci_config_table *config_table;
void (*fixup_irq)(struct pci_controller *, pci_dev_t);
-
+#ifndef CONFIG_DM_PCI
/* Low-level architecture-dependent routines */
int (*read_byte)(struct pci_controller*, pci_dev_t, int where, u8 *);
int (*read_word)(struct pci_controller*, pci_dev_t, int where, u16 *);
@@ -519,17 +527,21 @@ struct pci_controller {
int (*write_byte)(struct pci_controller*, pci_dev_t, int where, u8);
int (*write_word)(struct pci_controller*, pci_dev_t, int where, u16);
int (*write_dword)(struct pci_controller*, pci_dev_t, int where, u32);
+#endif
/* Used by auto config */
struct pci_region *pci_mem, *pci_io, *pci_prefetch;
/* Used by ppc405 autoconfig*/
struct pci_region *pci_fb;
+#ifndef CONFIG_DM_PCI
int current_busno;
void *priv_data;
+#endif
};
+#ifndef CONFIG_DM_PCI
static inline void pci_set_ops(struct pci_controller *hose,
int (*read_byte)(struct pci_controller*,
pci_dev_t, int where, u8 *),
@@ -550,6 +562,7 @@ static inline void pci_set_ops(struct pci_controller *hose,
hose->write_word = write_word;
hose->write_dword = write_dword;
}
+#endif
#ifdef CONFIG_PCI_INDIRECT_BRIDGE
extern void pci_setup_indirect(struct pci_controller* hose, u32 cfg_addr, u32 cfg_data);
@@ -602,12 +615,14 @@ extern int pci_hose_write_config_word(struct pci_controller *hose,
extern int pci_hose_write_config_dword(struct pci_controller *hose,
pci_dev_t dev, int where, u32 val);
+#ifndef CONFIG_DM_PCI
extern int pci_read_config_byte(pci_dev_t dev, int where, u8 *val);
extern int pci_read_config_word(pci_dev_t dev, int where, u16 *val);
extern int pci_read_config_dword(pci_dev_t dev, int where, u32 *val);
extern int pci_write_config_byte(pci_dev_t dev, int where, u8 val);
extern int pci_write_config_word(pci_dev_t dev, int where, u16 val);
extern int pci_write_config_dword(pci_dev_t dev, int where, u32 val);
+#endif
extern int pci_hose_read_config_byte_via_dword(struct pci_controller *hose,
pci_dev_t dev, int where, u8 *val);
@@ -705,5 +720,387 @@ u32 pci_read_bar32(struct pci_controller *hose, pci_dev_t dev, int barnum);
*/
int pciauto_setup_rom(struct pci_controller *hose, pci_dev_t dev);
+/**
+ * pci_hose_find_devices() - Find devices by vendor/device ID
+ *
+ * @hose: PCI hose to search
+ * @busnum: Bus number to search
+ * @ids: PCI vendor/device IDs to look for, terminated by 0, 0 record
+ * @indexp: Pointer to device index to find. To find the first matching
+ * device, pass 0; to find the second, pass 1, etc. This
+ * parameter is decremented for each non-matching device so
+ * can be called repeatedly.
+ */
+pci_dev_t pci_hose_find_devices(struct pci_controller *hose, int busnum,
+ struct pci_device_id *ids, int *indexp);
+
+/* Access sizes for PCI reads and writes */
+enum pci_size_t {
+ PCI_SIZE_8,
+ PCI_SIZE_16,
+ PCI_SIZE_32,
+};
+
+struct udevice;
+
+#ifdef CONFIG_DM_PCI
+/**
+ * struct pci_child_platdata - information stored about each PCI device
+ *
+ * Every device on a PCI bus has this per-child data.
+ *
+ * It can be accessed using dev_get_parentdata(dev) if dev->parent is a
+ * PCI bus (i.e. UCLASS_PCI)
+ *
+ * @devfn: Encoded device and function index - see PCI_DEVFN()
+ * @vendor: PCI vendor ID (see pci_ids.h)
+ * @device: PCI device ID (see pci_ids.h)
+ * @class: PCI class, 3 bytes: (base, sub, prog-if)
+ */
+struct pci_child_platdata {
+ int devfn;
+ unsigned short vendor;
+ unsigned short device;
+ unsigned int class;
+};
+
+/* PCI bus operations */
+struct dm_pci_ops {
+ /**
+ * read_config() - Read a PCI configuration value
+ *
+ * PCI buses must support reading and writing configuration values
+ * so that the bus can be scanned and its devices configured.
+ *
+ * Normally PCI_BUS(@bdf) is the same as @bus->seq, but not always.
+ * If bridges exist it is possible to use the top-level bus to
+ * access a sub-bus. In that case @bus will be the top-level bus
+ * and PCI_BUS(bdf) will be a different (higher) value
+ *
+ * @bus: Bus to read from
+ * @bdf: Bus, device and function to read
+ * @offset: Byte offset within the device's configuration space
+ * @valuep: Place to put the returned value
+ * @size: Access size
+ * @return 0 if OK, -ve on error
+ */
+ int (*read_config)(struct udevice *bus, pci_dev_t bdf, uint offset,
+ ulong *valuep, enum pci_size_t size);
+ /**
+ * write_config() - Write a PCI configuration value
+ *
+ * @bus: Bus to write to
+ * @bdf: Bus, device and function to write
+ * @offset: Byte offset within the device's configuration space
+ * @value: Value to write
+ * @size: Access size
+ * @return 0 if OK, -ve on error
+ */
+ int (*write_config)(struct udevice *bus, pci_dev_t bdf, uint offset,
+ ulong value, enum pci_size_t size);
+};
+
+/* Get access to a PCI bus' operations */
+#define pci_get_ops(dev) ((struct dm_pci_ops *)(dev)->driver->ops)
+
+/**
+ * pci_bind_bus_devices() - scan a PCI bus and bind devices
+ *
+ * Scan a PCI bus looking for devices. Bind each one that is found. If
+ * devices are already bound that match the scanned devices, just update the
+ * child data so that the device can be used correctly (this happens when
+ * the device tree describes devices we expect to see on the bus).
+ *
+ * Devices that are bound in this way will use a generic PCI driver which
+ * does nothing. The device can still be accessed but will not provide any
+ * driver interface.
+ *
+ * @bus: Bus containing devices to bind
+ * @return 0 if OK, -ve on error
+ */
+int pci_bind_bus_devices(struct udevice *bus);
+
+/**
+ * pci_auto_config_devices() - configure bus devices ready for use
+ *
+ * This works through all devices on a bus by scanning the driver model
+ * data structures (normally these have been set up by pci_bind_bus_devices()
+ * earlier).
+ *
+ * Space is allocated for each PCI base address register (BAR) so that the
+ * devices are mapped into memory and I/O space ready for use.
+ *
+ * @bus: Bus containing devices to bind
+ * @return 0 if OK, -ve on error
+ */
+int pci_auto_config_devices(struct udevice *bus);
+
+/**
+ * pci_bus_find_bdf() - Find a device given its PCI bus address
+ *
+ * @bdf: PCI device address: bus, device and function -see PCI_BDF()
+ * @devp: Returns the device for this address, if found
+ * @return 0 if OK, -ENODEV if not found
+ */
+int pci_bus_find_bdf(pci_dev_t bdf, struct udevice **devp);
+
+/**
+ * pci_bus_find_devfn() - Find a device on a bus
+ *
+ * @find_devfn: PCI device address (device and function only)
+ * @devp: Returns the device for this address, if found
+ * @return 0 if OK, -ENODEV if not found
+ */
+int pci_bus_find_devfn(struct udevice *bus, pci_dev_t find_devfn,
+ struct udevice **devp);
+
+/**
+ * pci_get_ff() - Returns a mask for the given access size
+ *
+ * @size: Access size
+ * @return 0xff for PCI_SIZE_8, 0xffff for PCI_SIZE_16, 0xffffffff for
+ * PCI_SIZE_32
+ */
+int pci_get_ff(enum pci_size_t size);
+
+/**
+ * pci_bus_find_devices () - Find devices on a bus
+ *
+ * @bus: Bus to search
+ * @ids: PCI vendor/device IDs to look for, terminated by 0, 0 record
+ * @indexp: Pointer to device index to find. To find the first matching
+ * device, pass 0; to find the second, pass 1, etc. This
+ * parameter is decremented for each non-matching device so
+ * can be called repeatedly.
+ * @devp: Returns matching device if found
+ * @return 0 if found, -ENODEV if not
+ */
+int pci_bus_find_devices(struct udevice *bus, struct pci_device_id *ids,
+ int *indexp, struct udevice **devp);
+
+/**
+ * pci_find_device_id() - Find a device on any bus
+ *
+ * @ids: PCI vendor/device IDs to look for, terminated by 0, 0 record
+ * @index: Index number of device to find, 0 for the first match, 1 for
+ * the second, etc.
+ * @devp: Returns matching device if found
+ * @return 0 if found, -ENODEV if not
+ */
+int pci_find_device_id(struct pci_device_id *ids, int index,
+ struct udevice **devp);
+
+/**
+ * dm_pci_hose_probe_bus() - probe a subordinate bus, scanning it for devices
+ *
+ * This probes the given bus which causes it to be scanned for devices. The
+ * devices will be bound but not probed.
+ *
+ * @hose specifies the PCI hose that will be used for the scan. This is
+ * always a top-level bus with uclass UCLASS_PCI. The bus to scan is
+ * in @bdf, and is a subordinate bus reachable from @hose.
+ *
+ * @hose: PCI hose to scan
+ * @bdf: PCI bus address to scan (PCI_BUS(bdf) is the bus number)
+ * @return 0 if OK, -ve on error
+ */
+int dm_pci_hose_probe_bus(struct pci_controller *hose, pci_dev_t bdf);
+
+/**
+ * pci_bus_read_config() - Read a configuration value from a device
+ *
+ * TODO(sjg@chromium.org): We should be able to pass just a device and have
+ * it do the right thing. It would be good to have that function also.
+ *
+ * @bus: Bus to read from
+ * @bdf: PCI device address: bus, device and function -see PCI_BDF()
+ * @valuep: Place to put the returned value
+ * @size: Access size
+ * @return 0 if OK, -ve on error
+ */
+int pci_bus_read_config(struct udevice *bus, pci_dev_t bdf, int offset,
+ unsigned long *valuep, enum pci_size_t size);
+
+/**
+ * pci_bus_write_config() - Write a configuration value to a device
+ *
+ * @bus: Bus to write from
+ * @bdf: PCI device address: bus, device and function -see PCI_BDF()
+ * @value: Value to write
+ * @size: Access size
+ * @return 0 if OK, -ve on error
+ */
+int pci_bus_write_config(struct udevice *bus, pci_dev_t bdf, int offset,
+ unsigned long value, enum pci_size_t size);
+
+/*
+ * The following functions provide access to the above without needing the
+ * size parameter. We are trying to encourage the use of the 8/16/32-style
+ * functions, rather than byte/word/dword. But both are supported.
+ */
+int pci_write_config32(pci_dev_t pcidev, int offset, u32 value);
+
+/* Compatibility with old naming */
+static inline int pci_write_config_dword(pci_dev_t pcidev, int offset,
+ u32 value)
+{
+ return pci_write_config32(pcidev, offset, value);
+}
+
+int pci_write_config16(pci_dev_t pcidev, int offset, u16 value);
+
+/* Compatibility with old naming */
+static inline int pci_write_config_word(pci_dev_t pcidev, int offset,
+ u16 value)
+{
+ return pci_write_config16(pcidev, offset, value);
+}
+
+int pci_write_config8(pci_dev_t pcidev, int offset, u8 value);
+
+/* Compatibility with old naming */
+static inline int pci_write_config_byte(pci_dev_t pcidev, int offset,
+ u8 value)
+{
+ return pci_write_config8(pcidev, offset, value);
+}
+
+int pci_read_config32(pci_dev_t pcidev, int offset, u32 *valuep);
+
+/* Compatibility with old naming */
+static inline int pci_read_config_dword(pci_dev_t pcidev, int offset,
+ u32 *valuep)
+{
+ return pci_read_config32(pcidev, offset, valuep);
+}
+
+int pci_read_config16(pci_dev_t pcidev, int offset, u16 *valuep);
+
+/* Compatibility with old naming */
+static inline int pci_read_config_word(pci_dev_t pcidev, int offset,
+ u16 *valuep)
+{
+ return pci_read_config16(pcidev, offset, valuep);
+}
+
+int pci_read_config8(pci_dev_t pcidev, int offset, u8 *valuep);
+
+/* Compatibility with old naming */
+static inline int pci_read_config_byte(pci_dev_t pcidev, int offset,
+ u8 *valuep)
+{
+ return pci_read_config8(pcidev, offset, valuep);
+}
+
+/**
+ * struct dm_pci_emul_ops - PCI device emulator operations
+ */
+struct dm_pci_emul_ops {
+ /**
+ * get_devfn(): Check which device and function this emulators
+ *
+ * @dev: device to check
+ * @return the device and function this emulates, or -ve on error
+ */
+ int (*get_devfn)(struct udevice *dev);
+ /**
+ * read_config() - Read a PCI configuration value
+ *
+ * @dev: Emulated device to read from
+ * @offset: Byte offset within the device's configuration space
+ * @valuep: Place to put the returned value
+ * @size: Access size
+ * @return 0 if OK, -ve on error
+ */
+ int (*read_config)(struct udevice *dev, uint offset, ulong *valuep,
+ enum pci_size_t size);
+ /**
+ * write_config() - Write a PCI configuration value
+ *
+ * @dev: Emulated device to write to
+ * @offset: Byte offset within the device's configuration space
+ * @value: Value to write
+ * @size: Access size
+ * @return 0 if OK, -ve on error
+ */
+ int (*write_config)(struct udevice *dev, uint offset, ulong value,
+ enum pci_size_t size);
+ /**
+ * read_io() - Read a PCI I/O value
+ *
+ * @dev: Emulated device to read from
+ * @addr: I/O address to read
+ * @valuep: Place to put the returned value
+ * @size: Access size
+ * @return 0 if OK, -ENOENT if @addr is not mapped by this device,
+ * other -ve value on error
+ */
+ int (*read_io)(struct udevice *dev, unsigned int addr, ulong *valuep,
+ enum pci_size_t size);
+ /**
+ * write_io() - Write a PCI I/O value
+ *
+ * @dev: Emulated device to write from
+ * @addr: I/O address to write
+ * @value: Value to write
+ * @size: Access size
+ * @return 0 if OK, -ENOENT if @addr is not mapped by this device,
+ * other -ve value on error
+ */
+ int (*write_io)(struct udevice *dev, unsigned int addr,
+ ulong value, enum pci_size_t size);
+ /**
+ * map_physmem() - Map a device into sandbox memory
+ *
+ * @dev: Emulated device to map
+ * @addr: Memory address, normally corresponding to a PCI BAR.
+ * The device should have been configured to have a BAR
+ * at this address.
+ * @lenp: On entry, the size of the area to map, On exit it is
+ * updated to the size actually mapped, which may be less
+ * if the device has less space
+ * @ptrp: Returns a pointer to the mapped address. The device's
+ * space can be accessed as @lenp bytes starting here
+ * @return 0 if OK, -ENOENT if @addr is not mapped by this device,
+ * other -ve value on error
+ */
+ int (*map_physmem)(struct udevice *dev, phys_addr_t addr,
+ unsigned long *lenp, void **ptrp);
+ /**
+ * unmap_physmem() - undo a memory mapping
+ *
+ * This must be called after map_physmem() to undo the mapping.
+ * Some devices can use this to check what has been written into
+ * their mapped memory and perform an operations they require on it.
+ * In this way, map/unmap can be used as a sort of handshake between
+ * the emulated device and its users.
+ *
+ * @dev: Emuated device to unmap
+ * @vaddr: Mapped memory address, as passed to map_physmem()
+ * @len: Size of area mapped, as returned by map_physmem()
+ * @return 0 if OK, -ve on error
+ */
+ int (*unmap_physmem)(struct udevice *dev, const void *vaddr,
+ unsigned long len);
+};
+
+/* Get access to a PCI device emulator's operations */
+#define pci_get_emul_ops(dev) ((struct dm_pci_emul_ops *)(dev)->driver->ops)
+
+/**
+ * sandbox_pci_get_emul() - Get the emulation device for a PCI device
+ *
+ * Searches for a suitable emulator for the given PCI bus device
+ *
+ * @bus: PCI bus to search
+ * @find_devfn: PCI device and function address (PCI_DEVFN())
+ * @emulp: Returns emulated device if found
+ * @return 0 if found, -ENODEV if not found
+ */
+int sandbox_pci_get_emul(struct udevice *bus, pci_dev_t find_devfn,
+ struct udevice **emulp);
+
+#endif
+
#endif /* __ASSEMBLY__ */
#endif /* _PCI_H */
diff --git a/include/pci_ids.h b/include/pci_ids.h
index dc2ca218a6..2e6685112b 100644
--- a/include/pci_ids.h
+++ b/include/pci_ids.h
@@ -3016,6 +3016,8 @@
#define PCI_DEVICE_ID_INTEL_TCF_UART_2 0x8813
#define PCI_DEVICE_ID_INTEL_TCF_UART_3 0x8814
#define PCI_DEVICE_ID_INTEL_IXP2800 0x9004
+#define PCI_DEVICE_ID_INTEL_LYNXPOINT_AHCI 0x9c03
+#define PCI_DEVICE_ID_INTEL_LYNXPOINT_LPC 0x9c45
#define PCI_DEVICE_ID_INTEL_S21152BB 0xb152
#define PCI_VENDOR_ID_SCALEMP 0x8686
diff --git a/include/phy.h b/include/phy.h
index d117fc1634..384dc2321e 100644
--- a/include/phy.h
+++ b/include/phy.h
@@ -51,7 +51,9 @@ typedef enum {
PHY_INTERFACE_MODE_RGMII_TXID,
PHY_INTERFACE_MODE_RTBI,
PHY_INTERFACE_MODE_XGMII,
- PHY_INTERFACE_MODE_NONE /* Must be last */
+ PHY_INTERFACE_MODE_NONE, /* Must be last */
+
+ PHY_INTERFACE_MODE_COUNT,
} phy_interface_t;
static const char *phy_interface_strings[] = {
@@ -142,7 +144,11 @@ struct phy_device {
struct phy_driver *drv;
void *priv;
+#ifdef CONFIG_DM_ETH
+ struct udevice *dev;
+#else
struct eth_device *dev;
+#endif
/* forced speed & duplex (no autoneg)
* partner speed & duplex & pause (autoneg)
@@ -205,10 +211,17 @@ int phy_init(void);
int phy_reset(struct phy_device *phydev);
struct phy_device *phy_find_by_mask(struct mii_dev *bus, unsigned phy_mask,
phy_interface_t interface);
+#ifdef CONFIG_DM_ETH
+void phy_connect_dev(struct phy_device *phydev, struct udevice *dev);
+struct phy_device *phy_connect(struct mii_dev *bus, int addr,
+ struct udevice *dev,
+ phy_interface_t interface);
+#else
void phy_connect_dev(struct phy_device *phydev, struct eth_device *dev);
struct phy_device *phy_connect(struct mii_dev *bus, int addr,
struct eth_device *dev,
phy_interface_t interface);
+#endif
int phy_startup(struct phy_device *phydev);
int phy_config(struct phy_device *phydev);
int phy_shutdown(struct phy_device *phydev);
@@ -242,6 +255,14 @@ int phy_vitesse_init(void);
int board_phy_config(struct phy_device *phydev);
+/**
+ * phy_get_interface_by_name() - Look up a PHY interface name
+ *
+ * @str: PHY interface name, e.g. "mii"
+ * @return PHY_INTERFACE_MODE_... value, or -1 if not found
+ */
+int phy_get_interface_by_name(const char *str);
+
/* PHY UIDs for various PHYs that are referenced in external code */
#define PHY_UID_CS4340 0x13e51002
#define PHY_UID_TN2020 0x00a19410
diff --git a/include/spi_flash.h b/include/spi_flash.h
index 5913b39e26..218283fc98 100644
--- a/include/spi_flash.h
+++ b/include/spi_flash.h
@@ -118,6 +118,41 @@ struct dm_spi_flash_ops {
#define sf_get_ops(dev) ((struct dm_spi_flash_ops *)(dev)->driver->ops)
#ifdef CONFIG_DM_SPI_FLASH
+/**
+ * spi_flash_read_dm() - Read data from SPI flash
+ *
+ * @dev: SPI flash device
+ * @offset: Offset into device in bytes to read from
+ * @len: Number of bytes to read
+ * @buf: Buffer to put the data that is read
+ * @return 0 if OK, -ve on error
+ */
+int spi_flash_read_dm(struct udevice *dev, u32 offset, size_t len, void *buf);
+
+/**
+ * spi_flash_write_dm() - Write data to SPI flash
+ *
+ * @dev: SPI flash device
+ * @offset: Offset into device in bytes to write to
+ * @len: Number of bytes to write
+ * @buf: Buffer containing bytes to write
+ * @return 0 if OK, -ve on error
+ */
+int spi_flash_write_dm(struct udevice *dev, u32 offset, size_t len,
+ const void *buf);
+
+/**
+ * spi_flash_erase_dm() - Erase blocks of the SPI flash
+ *
+ * Note that @len must be a muiltiple of the flash sector size.
+ *
+ * @dev: SPI flash device
+ * @offset: Offset into device in bytes to start erasing
+ * @len: Number of bytes to erase
+ * @return 0 if OK, -ve on error
+ */
+int spi_flash_erase_dm(struct udevice *dev, u32 offset, size_t len);
+
int spi_flash_probe_bus_cs(unsigned int busnum, unsigned int cs,
unsigned int max_hz, unsigned int spi_mode,
struct udevice **devp);
@@ -132,21 +167,21 @@ void spi_flash_free(struct spi_flash *flash);
int spi_flash_remove(struct udevice *flash);
static inline int spi_flash_read(struct spi_flash *flash, u32 offset,
- size_t len, void *buf)
+ size_t len, void *buf)
{
- return sf_get_ops(flash->dev)->read(flash->dev, offset, len, buf);
+ return spi_flash_read_dm(flash->dev, offset, len, buf);
}
static inline int spi_flash_write(struct spi_flash *flash, u32 offset,
- size_t len, const void *buf)
+ size_t len, const void *buf)
{
- return sf_get_ops(flash->dev)->write(flash->dev, offset, len, buf);
+ return spi_flash_write_dm(flash->dev, offset, len, buf);
}
static inline int spi_flash_erase(struct spi_flash *flash, u32 offset,
- size_t len)
+ size_t len)
{
- return sf_get_ops(flash->dev)->erase(flash->dev, offset, len);
+ return spi_flash_erase_dm(flash->dev, offset, len);
}
struct sandbox_state;
diff --git a/include/usb.h b/include/usb.h
index 2c3d506345..1984e8f590 100644
--- a/include/usb.h
+++ b/include/usb.h
@@ -2,6 +2,9 @@
* (C) Copyright 2001
* Denis Peter, MPL AG Switzerland
*
+ * Adapted for U-Boot driver model
+ * (C) Copyright 2015 Google, Inc
+ *
* SPDX-License-Identifier: GPL-2.0+
* Note: Part of this code has been derived from linux
*
@@ -9,6 +12,7 @@
#ifndef _USB_H_
#define _USB_H_
+#include <fdtdec.h>
#include <usb_defs.h>
#include <linux/usb/ch9.h>
#include <asm/cache.h>
@@ -85,6 +89,19 @@ enum {
PACKET_SIZE_64 = 3,
};
+/**
+ * struct usb_device - information about a USB device
+ *
+ * With driver model both UCLASS_USB (the USB controllers) and UCLASS_USB_HUB
+ * (the hubs) have this as parent data. Hubs are children of controllers or
+ * other hubs and there is always a single root hub for each controller.
+ * Therefore struct usb_device can always be accessed with
+ * dev_get_parentdata(dev), where dev is a USB device.
+ *
+ * Pointers exist for obtaining both the device (could be any uclass) and
+ * controller (UCLASS_USB) from this structure. The controller does not have
+ * a struct usb_device since it is not a device.
+ */
struct usb_device {
int devnum; /* Device number on USB bus */
int speed; /* full/low/high */
@@ -123,13 +140,19 @@ struct usb_device {
unsigned long int_pending; /* 1 bit per ep, used by int_queue */
int act_len; /* transfered bytes */
int maxchild; /* Number of ports if hub */
- int portnr;
+ int portnr; /* Port number, 1=first */
+#ifndef CONFIG_DM_USB
+ /* parent hub, or NULL if this is the root hub */
struct usb_device *parent;
struct usb_device *children[USB_MAXCHILDREN];
-
void *controller; /* hardware controller private data */
+#endif
/* slot_id - for xHCI enabled devices */
unsigned int slot_id;
+#ifdef CONFIG_DM_USB
+ struct udevice *dev; /* Pointer to associated device */
+ struct udevice *controller_dev; /* Pointer to associated controller */
+#endif
};
struct int_queue;
@@ -156,12 +179,14 @@ enum usb_init_type {
defined(CONFIG_USB_BLACKFIN) || defined(CONFIG_USB_AM35X) || \
defined(CONFIG_USB_MUSB_DSPS) || defined(CONFIG_USB_MUSB_AM35X) || \
defined(CONFIG_USB_MUSB_OMAP2PLUS) || defined(CONFIG_USB_MUSB_SUNXI) || \
- defined(CONFIG_USB_XHCI) || defined(CONFIG_USB_DWC2)
+ defined(CONFIG_USB_XHCI) || defined(CONFIG_USB_DWC2) || \
+ defined(CONFIG_USB_EMUL)
int usb_lowlevel_init(int index, enum usb_init_type init, void **controller);
int usb_lowlevel_stop(int index);
-#ifdef CONFIG_MUSB_HOST
-void usb_reset_root_port(void);
+
+#if defined(CONFIG_MUSB_HOST) || defined(CONFIG_DM_USB)
+int usb_reset_root_port(void);
#else
#define usb_reset_root_port()
#endif
@@ -245,7 +270,6 @@ int usb_stop(void); /* stop the USB Controller */
int usb_set_protocol(struct usb_device *dev, int ifnum, int protocol);
int usb_set_idle(struct usb_device *dev, int ifnum, int duration,
int report_id);
-struct usb_device *usb_get_dev_index(int index);
int usb_control_msg(struct usb_device *dev, unsigned int pipe,
unsigned char request, unsigned char requesttype,
unsigned short value, unsigned short index,
@@ -389,6 +413,113 @@ int usb_set_interface(struct usb_device *dev, int interface, int alternate);
((usb_pipeendpoint(pipe) * 2) - \
(usb_pipein(pipe) ? 0 : 1))
+/**
+ * struct usb_device_id - identifies USB devices for probing and hotplugging
+ * @match_flags: Bit mask controlling which of the other fields are used to
+ * match against new devices. Any field except for driver_info may be
+ * used, although some only make sense in conjunction with other fields.
+ * This is usually set by a USB_DEVICE_*() macro, which sets all
+ * other fields in this structure except for driver_info.
+ * @idVendor: USB vendor ID for a device; numbers are assigned
+ * by the USB forum to its members.
+ * @idProduct: Vendor-assigned product ID.
+ * @bcdDevice_lo: Low end of range of vendor-assigned product version numbers.
+ * This is also used to identify individual product versions, for
+ * a range consisting of a single device.
+ * @bcdDevice_hi: High end of version number range. The range of product
+ * versions is inclusive.
+ * @bDeviceClass: Class of device; numbers are assigned
+ * by the USB forum. Products may choose to implement classes,
+ * or be vendor-specific. Device classes specify behavior of all
+ * the interfaces on a device.
+ * @bDeviceSubClass: Subclass of device; associated with bDeviceClass.
+ * @bDeviceProtocol: Protocol of device; associated with bDeviceClass.
+ * @bInterfaceClass: Class of interface; numbers are assigned
+ * by the USB forum. Products may choose to implement classes,
+ * or be vendor-specific. Interface classes specify behavior only
+ * of a given interface; other interfaces may support other classes.
+ * @bInterfaceSubClass: Subclass of interface; associated with bInterfaceClass.
+ * @bInterfaceProtocol: Protocol of interface; associated with bInterfaceClass.
+ * @bInterfaceNumber: Number of interface; composite devices may use
+ * fixed interface numbers to differentiate between vendor-specific
+ * interfaces.
+ * @driver_info: Holds information used by the driver. Usually it holds
+ * a pointer to a descriptor understood by the driver, or perhaps
+ * device flags.
+ *
+ * In most cases, drivers will create a table of device IDs by using
+ * USB_DEVICE(), or similar macros designed for that purpose.
+ * They will then export it to userspace using MODULE_DEVICE_TABLE(),
+ * and provide it to the USB core through their usb_driver structure.
+ *
+ * See the usb_match_id() function for information about how matches are
+ * performed. Briefly, you will normally use one of several macros to help
+ * construct these entries. Each entry you provide will either identify
+ * one or more specific products, or will identify a class of products
+ * which have agreed to behave the same. You should put the more specific
+ * matches towards the beginning of your table, so that driver_info can
+ * record quirks of specific products.
+ */
+struct usb_device_id {
+ /* which fields to match against? */
+ u16 match_flags;
+
+ /* Used for product specific matches; range is inclusive */
+ u16 idVendor;
+ u16 idProduct;
+ u16 bcdDevice_lo;
+ u16 bcdDevice_hi;
+
+ /* Used for device class matches */
+ u8 bDeviceClass;
+ u8 bDeviceSubClass;
+ u8 bDeviceProtocol;
+
+ /* Used for interface class matches */
+ u8 bInterfaceClass;
+ u8 bInterfaceSubClass;
+ u8 bInterfaceProtocol;
+
+ /* Used for vendor-specific interface matches */
+ u8 bInterfaceNumber;
+
+ /* not matched against */
+ ulong driver_info;
+};
+
+/* Some useful macros to use to create struct usb_device_id */
+#define USB_DEVICE_ID_MATCH_VENDOR 0x0001
+#define USB_DEVICE_ID_MATCH_PRODUCT 0x0002
+#define USB_DEVICE_ID_MATCH_DEV_LO 0x0004
+#define USB_DEVICE_ID_MATCH_DEV_HI 0x0008
+#define USB_DEVICE_ID_MATCH_DEV_CLASS 0x0010
+#define USB_DEVICE_ID_MATCH_DEV_SUBCLASS 0x0020
+#define USB_DEVICE_ID_MATCH_DEV_PROTOCOL 0x0040
+#define USB_DEVICE_ID_MATCH_INT_CLASS 0x0080
+#define USB_DEVICE_ID_MATCH_INT_SUBCLASS 0x0100
+#define USB_DEVICE_ID_MATCH_INT_PROTOCOL 0x0200
+#define USB_DEVICE_ID_MATCH_INT_NUMBER 0x0400
+
+/* Match anything, indicates this is a valid entry even if everything is 0 */
+#define USB_DEVICE_ID_MATCH_NONE 0x0800
+#define USB_DEVICE_ID_MATCH_ALL 0x07ff
+
+/**
+ * struct usb_driver_entry - Matches a driver to its usb_device_ids
+ * @compatible: Compatible string
+ * @data: Data for this compatible string
+ */
+struct usb_driver_entry {
+ struct driver *driver;
+ const struct usb_device_id *match;
+};
+
+#define USB_DEVICE(__name, __match) \
+ ll_entry_declare(struct usb_driver_entry, __name, usb_driver_entry) = {\
+ .driver = llsym(struct driver, __name, driver), \
+ .match = __match, \
+ }
+
/*************************************************************************
* Hub Stuff
*/
@@ -423,15 +554,360 @@ struct usb_hub_device {
struct usb_hub_descriptor desc;
};
+#ifdef CONFIG_DM_USB
+/**
+ * struct usb_platdata - Platform data about a USB controller
+ *
+ * Given a USB controller (UCLASS_USB) dev this is dev_get_platdata(dev)
+ */
+struct usb_platdata {
+ enum usb_init_type init_type;
+};
+
+/**
+ * struct usb_dev_platdata - Platform data about a USB device
+ *
+ * Given a USB device dev this structure is dev_get_parent_platdata(dev).
+ * This is used by sandbox to provide emulation data also.
+ *
+ * @id: ID used to match this device
+ * @speed: Stores the speed associated with a USB device
+ * @devnum: Device address on the USB bus
+ * @slot_id: USB3 slot ID, which is separate from the device address
+ * @portnr: Port number of this device on its parent hub, numbered from 1
+ * (0 mean this device is the root hub)
+ * @strings: List of descriptor strings (for sandbox emulation purposes)
+ * @desc_list: List of descriptors (for sandbox emulation purposes)
+ */
+struct usb_dev_platdata {
+ struct usb_device_id id;
+ enum usb_device_speed speed;
+ int devnum;
+ int slot_id;
+ int portnr; /* Hub port number, 1..n */
+#ifdef CONFIG_SANDBOX
+ struct usb_string *strings;
+ /* NULL-terminated list of descriptor pointers */
+ struct usb_generic_descriptor **desc_list;
+#endif
+ int configno;
+};
+
+/**
+ * struct usb_bus_priv - information about the USB controller
+ *
+ * Given a USB controller (UCLASS_USB) 'dev', this is
+ * dev_get_uclass_priv(dev).
+ *
+ * @next_addr: Next device address to allocate minus 1. Incremented by 1
+ * each time a new device address is set, so this holds the
+ * number of devices on the bus
+ * @desc_before_addr: true if we can read a device descriptor before it
+ * has been assigned an address. For XHCI this is not possible
+ * so this will be false.
+ */
+struct usb_bus_priv {
+ int next_addr;
+ bool desc_before_addr;
+};
+
+/**
+ * struct dm_usb_ops - USB controller operations
+ *
+ * This defines the operations supoorted on a USB controller. Common
+ * arguments are:
+ *
+ * @bus: USB bus (i.e. controller), which is in UCLASS_USB.
+ * @udev: USB device parent data. Controllers are not expected to need
+ * this, since the device address on the bus is encoded in @pipe.
+ * It is used for sandbox, and can be handy for debugging and
+ * logging.
+ * @pipe: An assortment of bitfields which provide address and packet
+ * type information. See create_pipe() above for encoding
+ * details
+ * @buffer: A buffer to use for sending/receiving. This should be
+ * DMA-aligned.
+ * @length: Buffer length in bytes
+ */
+struct dm_usb_ops {
+ /**
+ * control() - Send a control message
+ *
+ * Most parameters are as above.
+ *
+ * @setup: Additional setup information required by the message
+ */
+ int (*control)(struct udevice *bus, struct usb_device *udev,
+ unsigned long pipe, void *buffer, int length,
+ struct devrequest *setup);
+ /**
+ * bulk() - Send a bulk message
+ *
+ * Parameters are as above.
+ */
+ int (*bulk)(struct udevice *bus, struct usb_device *udev,
+ unsigned long pipe, void *buffer, int length);
+ /**
+ * interrupt() - Send an interrupt message
+ *
+ * Most parameters are as above.
+ *
+ * @interval: Interrupt interval
+ */
+ int (*interrupt)(struct udevice *bus, struct usb_device *udev,
+ unsigned long pipe, void *buffer, int length,
+ int interval);
+ /**
+ * alloc_device() - Allocate a new device context (XHCI)
+ *
+ * Before sending packets to a new device on an XHCI bus, a device
+ * context must be created. If this method is not NULL it will be
+ * called before the device is enumerated (even before its descriptor
+ * is read). This should be NULL for EHCI, which does not need this.
+ */
+ int (*alloc_device)(struct udevice *bus, struct usb_device *udev);
+};
+
+#define usb_get_ops(dev) ((struct dm_usb_ops *)(dev)->driver->ops)
+#define usb_get_emul_ops(dev) ((struct dm_usb_ops *)(dev)->driver->ops)
+
+#ifdef CONFIG_MUSB_HOST
+int usb_reset_root_port(void);
+#endif
+
+/**
+ * usb_get_dev_index() - look up a device index number
+ *
+ * Look up devices using their index number (starting at 0). This works since
+ * in U-Boot device addresses are allocated starting at 1 with no gaps.
+ *
+ * TODO(sjg@chromium.org): Remove this function when usb_ether.c is modified
+ * to work better with driver model.
+ *
+ * @bus: USB bus to check
+ * @index: Index number of device to find (0=first). This is just the
+ * device address less 1.
+ */
+struct usb_device *usb_get_dev_index(struct udevice *bus, int index);
+
+/**
+ * usb_legacy_port_reset() - Legacy function to reset a hub port
+ *
+ * @hub: Hub device
+ * @portnr: Port number (1=first)
+ */
+int usb_legacy_port_reset(struct usb_device *hub, int portnr);
+
+/**
+ * usb_setup_device() - set up a device ready for use
+ *
+ * @dev: USB device pointer. This need not be a real device - it is
+ * common for it to just be a local variable with its ->dev
+ * member (i.e. @dev->dev) set to the parent device
+ * @do_read: true to read the device descriptor before an address is set
+ * (should be false for XHCI buses, true otherwise)
+ * @parent: Parent device (either UCLASS_USB or UCLASS_USB_HUB)
+ * @portnr: Port number on hub (1=first) or 0 for none
+ * @return 0 if OK, -ve on error */
+int usb_setup_device(struct usb_device *dev, bool do_read,
+ struct usb_device *parent, int portnr);
+
+/**
+ * usb_hub_scan() - Scan a hub and find its devices
+ *
+ * @hub: Hub device to scan
+ */
+int usb_hub_scan(struct udevice *hub);
+
+/**
+ * usb_scan_device() - Scan a device on a bus
+ *
+ * Scan a device on a bus. It has already been detected and is ready to
+ * be enumerated. This may be either the root hub (@parent is a bus) or a
+ * normal device (@parent is a hub)
+ *
+ * @parent: Parent device
+ * @port: Hub port number (numbered from 1)
+ * @speed: USB speed to use for this device
+ * @devp: Returns pointer to device if all is well
+ * @return 0 if OK, -ve on error
+ */
+int usb_scan_device(struct udevice *parent, int port,
+ enum usb_device_speed speed, struct udevice **devp);
+
+/**
+ * usb_get_bus() - Find the bus for a device
+ *
+ * Search up through parents to find the bus this device is connected to. This
+ * will be a device with uclass UCLASS_USB.
+ *
+ * @dev: Device to check
+ * @busp: Returns bus, or NULL if not found
+ * @return 0 if OK, -EXDEV is somehow this bus does not have a controller (this
+ * indicates a critical error in the USB stack
+ */
+int usb_get_bus(struct udevice *dev, struct udevice **busp);
+
+/**
+ * usb_select_config() - Set up a device ready for use
+ *
+ * This function assumes that the device already has an address and a driver
+ * bound, and is ready to be set up.
+ *
+ * This re-reads the device and configuration descriptors and sets the
+ * configuration
+ *
+ * @dev: Device to set up
+ */
+int usb_select_config(struct usb_device *dev);
+
+/**
+ * usb_child_pre_probe() - Pre-probe function for USB devices
+ *
+ * This is called on all children of hubs and USB controllers (i.e. UCLASS_USB
+ * and UCLASS_USB_HUB) when a new device is about to be probed. It sets up the
+ * device from the saved platform data and calls usb_select_config() to
+ * finish set up.
+ *
+ * Once this is done, the device's normal driver can take over, knowing the
+ * device is accessible on the USB bus.
+ *
+ * This function is for use only by the internal USB stack.
+ *
+ * @dev: Device to set up
+ */
+int usb_child_pre_probe(struct udevice *dev);
+
+struct ehci_ctrl;
+
+/**
+ * usb_setup_ehci_gadget() - Set up a USB device as a gadget
+ *
+ * TODO(sjg@chromium.org): Tidy this up when USB gadgets can use driver model
+ *
+ * This provides a way to tell a controller to start up as a USB device
+ * instead of as a host. It is untested.
+ */
+int usb_setup_ehci_gadget(struct ehci_ctrl **ctlrp);
+
+/**
+ * usb_stor_reset() - Prepare to scan USB storage devices
+ *
+ * Empty the list of USB storage devices in preparation for scanning them.
+ * This must be called before a USB scan.
+ */
+void usb_stor_reset(void);
+
+#else /* !CONFIG_DM_USB */
+
+struct usb_device *usb_get_dev_index(int index);
+
+#endif
+
+bool usb_device_has_child_on_port(struct usb_device *parent, int port);
+
int usb_hub_probe(struct usb_device *dev, int ifnum);
void usb_hub_reset(void);
-int hub_port_reset(struct usb_device *dev, int port,
+
+/**
+ * legacy_hub_port_reset() - reset a port given its usb_device pointer
+ *
+ * Reset a hub port and see if a device is present on that port, providing
+ * sufficient time for it to show itself. The port status is returned.
+ *
+ * With driver model this moves to hub_port_reset() and is passed a struct
+ * udevice.
+ *
+ * @dev: USB device to reset
+ * @port: Port number to reset (note ports are numbered from 0 here)
+ * @portstat: Returns port status
+ */
+int legacy_hub_port_reset(struct usb_device *dev, int port,
unsigned short *portstat);
-struct usb_device *usb_alloc_new_device(void *controller);
+int hub_port_reset(struct udevice *dev, int port, unsigned short *portstat);
+
+/**
+ * usb_alloc_new_device() - Allocate a new device
+ *
+ * @devp: returns a pointer of a new device structure. With driver model this
+ * is a device pointer, but with legacy USB this pointer is
+ * driver-specific.
+ * @return 0 if OK, -ENOSPC if we have found out of room for new devices
+ */
+int usb_alloc_new_device(struct udevice *controller, struct usb_device **devp);
+
+/**
+ * usb_free_device() - Free a partially-inited device
+ *
+ * This is an internal function. It is used to reverse the action of
+ * usb_alloc_new_device() when we hit a problem during init.
+ */
+void usb_free_device(struct udevice *controller);
int usb_new_device(struct usb_device *dev);
-void usb_free_device(void);
+
int usb_alloc_device(struct usb_device *dev);
+/**
+ * usb_emul_setup_device() - Set up a new USB device emulation
+ *
+ * This is normally called when a new emulation device is bound. It tells
+ * the USB emulation uclass about the features of the emulator.
+ *
+ * @dev: Emulation device
+ * @maxpacketsize: Maximum packet size (e.g. PACKET_SIZE_64)
+ * @strings: List of USB string descriptors, terminated by a NULL
+ * entry
+ * @desc_list: List of points or USB descriptors, terminated by NULL.
+ * The first entry must be struct usb_device_descriptor,
+ * and others follow on after that.
+ * @return 0 if OK, -ve on error
+ */
+int usb_emul_setup_device(struct udevice *dev, int maxpacketsize,
+ struct usb_string *strings, void **desc_list);
+
+/**
+ * usb_emul_control() - Send a control packet to an emulator
+ *
+ * @emul: Emulator device
+ * @udev: USB device (which the emulator is causing to appear)
+ * See struct dm_usb_ops for details on other parameters
+ * @return 0 if OK, -ve on error
+ */
+int usb_emul_control(struct udevice *emul, struct usb_device *udev,
+ unsigned long pipe, void *buffer, int length,
+ struct devrequest *setup);
+
+/**
+ * usb_emul_bulk() - Send a bulk packet to an emulator
+ *
+ * @emul: Emulator device
+ * @udev: USB device (which the emulator is causing to appear)
+ * See struct dm_usb_ops for details on other parameters
+ * @return 0 if OK, -ve on error
+ */
+int usb_emul_bulk(struct udevice *emul, struct usb_device *udev,
+ unsigned long pipe, void *buffer, int length);
+
+/**
+ * usb_emul_find() - Find an emulator for a particular device
+ *
+ * Check @pipe to find a device number on bus @bus and return it.
+ *
+ * @bus: USB bus (controller)
+ * @pipe: Describes pipe being used, and includes the device number
+ * @emulp: Returns pointer to emulator, or NULL if not found
+ * @return 0 if found, -ve on error
+ */
+int usb_emul_find(struct udevice *bus, ulong pipe, struct udevice **emulp);
+
+/**
+ * usb_emul_reset() - Reset all emulators ready for use
+ *
+ * Clear out any address information in the emulators and make then ready for
+ * a new USB scan
+ */
+void usb_emul_reset(struct udevice *dev);
+
#endif /*_USB_H_ */
diff --git a/include/usb_defs.h b/include/usb_defs.h
index 236a5ecdf6..8214ba9bf5 100644
--- a/include/usb_defs.h
+++ b/include/usb_defs.h
@@ -165,12 +165,14 @@
#define USB_TEST_MODE_FORCE_ENABLE 0x05
-/* "pipe" definitions */
-
-#define PIPE_ISOCHRONOUS 0
-#define PIPE_INTERRUPT 1
-#define PIPE_CONTROL 2
-#define PIPE_BULK 3
+/*
+ * "pipe" definitions, use unsigned so we can compare reliably, since this
+ * value is shifted up to bits 30/31.
+ */
+#define PIPE_ISOCHRONOUS 0U
+#define PIPE_INTERRUPT 1U
+#define PIPE_CONTROL 2U
+#define PIPE_BULK 3U
#define PIPE_DEVEP_MASK 0x0007ff00
#define USB_ISOCHRONOUS 0
@@ -178,6 +180,15 @@
#define USB_CONTROL 2
#define USB_BULK 3
+#define USB_PIPE_TYPE_SHIFT 30
+#define USB_PIPE_TYPE_MASK (3 << USB_PIPE_TYPE_SHIFT)
+
+#define USB_PIPE_DEV_SHIFT 8
+#define USB_PIPE_DEV_MASK (0x7f << USB_PIPE_DEV_SHIFT)
+
+#define USB_PIPE_EP_SHIFT 15
+#define USB_PIPE_EP_MASK (0xf << USB_PIPE_EP_SHIFT)
+
/* USB-status codes: */
#define USB_ST_ACTIVE 0x1 /* TD is active */
#define USB_ST_STALLED 0x2 /* TD is stalled */
@@ -286,4 +297,49 @@
#define HUB_CHANGE_LOCAL_POWER 0x0001
#define HUB_CHANGE_OVERCURRENT 0x0002
+/* Mask for wIndex in get/set port feature */
+#define USB_HUB_PORT_MASK 0xf
+
+/*
+ * CBI style
+ */
+
+#define US_CBI_ADSC 0
+
+/* Command Block Wrapper */
+struct umass_bbb_cbw {
+ __u32 dCBWSignature;
+# define CBWSIGNATURE 0x43425355
+ __u32 dCBWTag;
+ __u32 dCBWDataTransferLength;
+ __u8 bCBWFlags;
+# define CBWFLAGS_OUT 0x00
+# define CBWFLAGS_IN 0x80
+# define CBWFLAGS_SBZ 0x7f
+ __u8 bCBWLUN;
+ __u8 bCDBLength;
+# define CBWCDBLENGTH 16
+ __u8 CBWCDB[CBWCDBLENGTH];
+};
+#define UMASS_BBB_CBW_SIZE 31
+
+/* Command Status Wrapper */
+struct umass_bbb_csw {
+ __u32 dCSWSignature;
+# define CSWSIGNATURE 0x53425355
+ __u32 dCSWTag;
+ __u32 dCSWDataResidue;
+ __u8 bCSWStatus;
+# define CSWSTATUS_GOOD 0x0
+# define CSWSTATUS_FAILED 0x1
+# define CSWSTATUS_PHASE 0x2
+};
+#define UMASS_BBB_CSW_SIZE 13
+
+/*
+ * BULK only
+ */
+#define US_BBB_RESET 0xff
+#define US_BBB_GET_MAX_LUN 0xfe
+
#endif /*_USB_DEFS_H_ */
diff --git a/lib/Kconfig b/lib/Kconfig
index c9d2767d1d..d7fd21928d 100644
--- a/lib/Kconfig
+++ b/lib/Kconfig
@@ -27,6 +27,15 @@ config SYS_HZ
get_timer() must operate in milliseconds and this option must be
set to 1000.
+config SYS_VSNPRINTF
+ bool "Enable safe version of sprintf()"
+ help
+ Since sprintf() can overflow its buffer, it is common to use
+ snprintf() instead, which knows the buffer size and can avoid
+ overflow. However, this does increase code size slightly (for
+ Thumb-2, about 420 bytes). Enable this option for safety when
+ using sprintf() with data you do not control.
+
source lib/rsa/Kconfig
menu "Hashing Support"
diff --git a/lib/fdtdec.c b/lib/fdtdec.c
index 1a0268a3f9..331eae2ce1 100644
--- a/lib/fdtdec.c
+++ b/lib/fdtdec.c
@@ -42,7 +42,6 @@ static const char * const compat_names[COMPAT_COUNT] = {
COMPAT(SAMSUNG_S3C2440_I2C, "samsung,s3c2440-i2c"),
COMPAT(SAMSUNG_EXYNOS5_SOUND, "samsung,exynos-sound"),
COMPAT(WOLFSON_WM8994_CODEC, "wolfson,wm8994-codec"),
- COMPAT(GOOGLE_CROS_EC, "google,cros-ec"),
COMPAT(GOOGLE_CROS_EC_KEYB, "google,cros-ec-keyb"),
COMPAT(SAMSUNG_EXYNOS_EHCI, "samsung,exynos-ehci"),
COMPAT(SAMSUNG_EXYNOS5_XHCI, "samsung,exynos5250-xhci"),
@@ -61,13 +60,11 @@ static const char * const compat_names[COMPAT_COUNT] = {
COMPAT(INFINEON_SLB9635_TPM, "infineon,slb9635-tpm"),
COMPAT(INFINEON_SLB9645_TPM, "infineon,slb9645-tpm"),
COMPAT(SAMSUNG_EXYNOS5_I2C, "samsung,exynos5-hsi2c"),
- COMPAT(SANDBOX_HOST_EMULATION, "sandbox,host-emulation"),
COMPAT(SANDBOX_LCD_SDL, "sandbox,lcd-sdl"),
COMPAT(TI_TPS65090, "ti,tps65090"),
COMPAT(COMPAT_NXP_PTN3460, "nxp,ptn3460"),
COMPAT(SAMSUNG_EXYNOS_SYSMMU, "samsung,sysmmu-v3.3"),
COMPAT(PARADE_PS8625, "parade,ps8625"),
- COMPAT(COMPAT_INTEL_LPC, "intel,lpc"),
COMPAT(INTEL_MICROCODE, "intel,microcode"),
COMPAT(MEMORY_SPD, "memory-spd"),
COMPAT(INTEL_PANTHERPOINT_AHCI, "intel,pantherpoint-ahci"),
@@ -77,6 +74,7 @@ static const char * const compat_names[COMPAT_COUNT] = {
COMPAT(INTEL_ICH_SPI, "intel,ich-spi"),
COMPAT(INTEL_QRK_MRC, "intel,quark-mrc"),
COMPAT(SOCIONEXT_XHCI, "socionext,uniphier-xhci"),
+ COMPAT(COMPAT_INTEL_PCH, "intel,bd82x6x"),
};
const char *fdtdec_get_compatible(enum fdt_compat_id id)
@@ -160,8 +158,10 @@ int fdtdec_get_pci_addr(const void *blob, int node, enum fdt_pci_space type,
}
}
- if (i == num)
+ if (i == num) {
+ ret = -ENXIO;
goto fail;
+ }
return 0;
} else {
@@ -918,7 +918,7 @@ int fdtdec_read_fmap_entry(const void *blob, int node, const char *name,
return 0;
}
-static u64 fdtdec_get_number(const fdt32_t *ptr, unsigned int cells)
+u64 fdtdec_get_number(const fdt32_t *ptr, unsigned int cells)
{
u64 number = 0;
diff --git a/lib/net_utils.c b/lib/net_utils.c
index 8d66163159..cfae842752 100644
--- a/lib/net_utils.c
+++ b/lib/net_utils.c
@@ -12,23 +12,25 @@
#include <common.h>
-IPaddr_t string_to_ip(const char *s)
+struct in_addr string_to_ip(const char *s)
{
- IPaddr_t addr;
+ struct in_addr addr;
char *e;
int i;
+ addr.s_addr = 0;
if (s == NULL)
- return(0);
+ return addr;
- for (addr=0, i=0; i<4; ++i) {
+ for (addr.s_addr = 0, i = 0; i < 4; ++i) {
ulong val = s ? simple_strtoul(s, &e, 10) : 0;
- addr <<= 8;
- addr |= (val & 0xFF);
+ addr.s_addr <<= 8;
+ addr.s_addr |= (val & 0xFF);
if (s) {
s = (*e) ? e+1 : e;
}
}
- return (htonl(addr));
+ addr.s_addr = htonl(addr.s_addr);
+ return addr;
}
diff --git a/lib/trace.c b/lib/trace.c
index 711e5b5836..ad5e07bd84 100644
--- a/lib/trace.c
+++ b/lib/trace.c
@@ -5,6 +5,7 @@
*/
#include <common.h>
+#include <mapmem.h>
#include <trace.h>
#include <asm/io.h>
#include <asm/sections.h>
diff --git a/net/arp.c b/net/arp.c
index 21ed31bf74..b8655700a8 100644
--- a/net/arp.c
+++ b/net/arp.c
@@ -27,43 +27,43 @@
# define ARP_TIMEOUT_COUNT CONFIG_NET_RETRY_COUNT
#endif
-IPaddr_t NetArpWaitPacketIP;
-static IPaddr_t NetArpWaitReplyIP;
+struct in_addr net_arp_wait_packet_ip;
+static struct in_addr net_arp_wait_reply_ip;
/* MAC address of waiting packet's destination */
-uchar *NetArpWaitPacketMAC;
-int NetArpWaitTxPacketSize;
-ulong NetArpWaitTimerStart;
-int NetArpWaitTry;
+uchar *arp_wait_packet_ethaddr;
+int arp_wait_tx_packet_size;
+ulong arp_wait_timer_start;
+int arp_wait_try;
-static uchar *NetArpTxPacket; /* THE ARP transmit packet */
-static uchar NetArpPacketBuf[PKTSIZE_ALIGN + PKTALIGN];
+static uchar *arp_tx_packet; /* THE ARP transmit packet */
+static uchar arp_tx_packet_buf[PKTSIZE_ALIGN + PKTALIGN];
-void ArpInit(void)
+void arp_init(void)
{
/* XXX problem with bss workaround */
- NetArpWaitPacketMAC = NULL;
- NetArpWaitPacketIP = 0;
- NetArpWaitReplyIP = 0;
- NetArpWaitTxPacketSize = 0;
- NetArpTxPacket = &NetArpPacketBuf[0] + (PKTALIGN - 1);
- NetArpTxPacket -= (ulong)NetArpTxPacket % PKTALIGN;
+ arp_wait_packet_ethaddr = NULL;
+ net_arp_wait_packet_ip.s_addr = 0;
+ net_arp_wait_reply_ip.s_addr = 0;
+ arp_wait_tx_packet_size = 0;
+ arp_tx_packet = &arp_tx_packet_buf[0] + (PKTALIGN - 1);
+ arp_tx_packet -= (ulong)arp_tx_packet % PKTALIGN;
}
-void arp_raw_request(IPaddr_t sourceIP, const uchar *targetEther,
- IPaddr_t targetIP)
+void arp_raw_request(struct in_addr source_ip, const uchar *target_ethaddr,
+ struct in_addr target_ip)
{
uchar *pkt;
struct arp_hdr *arp;
int eth_hdr_size;
- debug_cond(DEBUG_DEV_PKT, "ARP broadcast %d\n", NetArpWaitTry);
+ debug_cond(DEBUG_DEV_PKT, "ARP broadcast %d\n", arp_wait_try);
- pkt = NetArpTxPacket;
+ pkt = arp_tx_packet;
- eth_hdr_size = NetSetEther(pkt, NetBcastAddr, PROT_ARP);
+ eth_hdr_size = net_set_ether(pkt, net_bcast_ethaddr, PROT_ARP);
pkt += eth_hdr_size;
- arp = (struct arp_hdr *) pkt;
+ arp = (struct arp_hdr *)pkt;
arp->ar_hrd = htons(ARP_ETHER);
arp->ar_pro = htons(PROT_IP);
@@ -71,59 +71,59 @@ void arp_raw_request(IPaddr_t sourceIP, const uchar *targetEther,
arp->ar_pln = ARP_PLEN;
arp->ar_op = htons(ARPOP_REQUEST);
- memcpy(&arp->ar_sha, NetOurEther, ARP_HLEN); /* source ET addr */
- NetWriteIP(&arp->ar_spa, sourceIP); /* source IP addr */
- memcpy(&arp->ar_tha, targetEther, ARP_HLEN); /* target ET addr */
- NetWriteIP(&arp->ar_tpa, targetIP); /* target IP addr */
+ memcpy(&arp->ar_sha, net_ethaddr, ARP_HLEN); /* source ET addr */
+ net_write_ip(&arp->ar_spa, source_ip); /* source IP addr */
+ memcpy(&arp->ar_tha, target_ethaddr, ARP_HLEN); /* target ET addr */
+ net_write_ip(&arp->ar_tpa, target_ip); /* target IP addr */
- NetSendPacket(NetArpTxPacket, eth_hdr_size + ARP_HDR_SIZE);
+ net_send_packet(arp_tx_packet, eth_hdr_size + ARP_HDR_SIZE);
}
-void ArpRequest(void)
+void arp_request(void)
{
- if ((NetArpWaitPacketIP & NetOurSubnetMask) !=
- (NetOurIP & NetOurSubnetMask)) {
- if (NetOurGatewayIP == 0) {
+ if ((net_arp_wait_packet_ip.s_addr & net_netmask.s_addr) !=
+ (net_ip.s_addr & net_netmask.s_addr)) {
+ if (net_gateway.s_addr == 0) {
puts("## Warning: gatewayip needed but not set\n");
- NetArpWaitReplyIP = NetArpWaitPacketIP;
+ net_arp_wait_reply_ip = net_arp_wait_packet_ip;
} else {
- NetArpWaitReplyIP = NetOurGatewayIP;
+ net_arp_wait_reply_ip = net_gateway;
}
} else {
- NetArpWaitReplyIP = NetArpWaitPacketIP;
+ net_arp_wait_reply_ip = net_arp_wait_packet_ip;
}
- arp_raw_request(NetOurIP, NetEtherNullAddr, NetArpWaitReplyIP);
+ arp_raw_request(net_ip, net_null_ethaddr, net_arp_wait_reply_ip);
}
-void ArpTimeoutCheck(void)
+void arp_timeout_check(void)
{
ulong t;
- if (!NetArpWaitPacketIP)
+ if (!net_arp_wait_packet_ip.s_addr)
return;
t = get_timer(0);
/* check for arp timeout */
- if ((t - NetArpWaitTimerStart) > ARP_TIMEOUT) {
- NetArpWaitTry++;
+ if ((t - arp_wait_timer_start) > ARP_TIMEOUT) {
+ arp_wait_try++;
- if (NetArpWaitTry >= ARP_TIMEOUT_COUNT) {
+ if (arp_wait_try >= ARP_TIMEOUT_COUNT) {
puts("\nARP Retry count exceeded; starting again\n");
- NetArpWaitTry = 0;
- NetStartAgain();
+ arp_wait_try = 0;
+ net_start_again();
} else {
- NetArpWaitTimerStart = t;
- ArpRequest();
+ arp_wait_timer_start = t;
+ arp_request();
}
}
}
-void ArpReceive(struct ethernet_hdr *et, struct ip_udp_hdr *ip, int len)
+void arp_receive(struct ethernet_hdr *et, struct ip_udp_hdr *ip, int len)
{
struct arp_hdr *arp;
- IPaddr_t reply_ip_addr;
+ struct in_addr reply_ip_addr;
uchar *pkt;
int eth_hdr_size;
@@ -152,10 +152,10 @@ void ArpReceive(struct ethernet_hdr *et, struct ip_udp_hdr *ip, int len)
if (arp->ar_pln != ARP_PLEN)
return;
- if (NetOurIP == 0)
+ if (net_ip.s_addr == 0)
return;
- if (NetReadIP(&arp->ar_tpa) != NetOurIP)
+ if (net_read_ip(&arp->ar_tpa).s_addr != net_ip.s_addr)
return;
switch (ntohs(arp->ar_op)) {
@@ -167,9 +167,9 @@ void ArpReceive(struct ethernet_hdr *et, struct ip_udp_hdr *ip, int len)
pkt += eth_hdr_size;
arp->ar_op = htons(ARPOP_REPLY);
memcpy(&arp->ar_tha, &arp->ar_sha, ARP_HLEN);
- NetCopyIP(&arp->ar_tpa, &arp->ar_spa);
- memcpy(&arp->ar_sha, NetOurEther, ARP_HLEN);
- NetCopyIP(&arp->ar_spa, &NetOurIP);
+ net_copy_ip(&arp->ar_tpa, &arp->ar_spa);
+ memcpy(&arp->ar_sha, net_ethaddr, ARP_HLEN);
+ net_copy_ip(&arp->ar_spa, &net_ip);
#ifdef CONFIG_CMD_LINK_LOCAL
/*
@@ -180,53 +180,52 @@ void ArpReceive(struct ethernet_hdr *et, struct ip_udp_hdr *ip, int len)
* reply to ARP request so that our reply will overwrite
* the arp-proxy's instead of the other way around.
*/
- if ((NetReadIP(&arp->ar_tpa) & NetOurSubnetMask) !=
- (NetReadIP(&arp->ar_spa) & NetOurSubnetMask))
+ if ((net_read_ip(&arp->ar_tpa).s_addr & net_netmask.s_addr) !=
+ (net_read_ip(&arp->ar_spa).s_addr & net_netmask.s_addr))
udelay(5000);
#endif
- NetSendPacket((uchar *)et, eth_hdr_size + ARP_HDR_SIZE);
+ net_send_packet((uchar *)et, eth_hdr_size + ARP_HDR_SIZE);
return;
case ARPOP_REPLY: /* arp reply */
/* are we waiting for a reply */
- if (!NetArpWaitPacketIP)
+ if (!net_arp_wait_packet_ip.s_addr)
break;
#ifdef CONFIG_KEEP_SERVERADDR
- if (NetServerIP == NetArpWaitPacketIP) {
+ if (net_server_ip.s_addr == net_arp_wait_packet_ip.s_addr) {
char buf[20];
sprintf(buf, "%pM", &arp->ar_sha);
setenv("serveraddr", buf);
}
#endif
- reply_ip_addr = NetReadIP(&arp->ar_spa);
+ reply_ip_addr = net_read_ip(&arp->ar_spa);
/* matched waiting packet's address */
- if (reply_ip_addr == NetArpWaitReplyIP) {
+ if (reply_ip_addr.s_addr == net_arp_wait_reply_ip.s_addr) {
debug_cond(DEBUG_DEV_PKT,
- "Got ARP REPLY, set eth addr (%pM)\n",
- arp->ar_data);
+ "Got ARP REPLY, set eth addr (%pM)\n",
+ arp->ar_data);
/* save address for later use */
- if (NetArpWaitPacketMAC != NULL)
- memcpy(NetArpWaitPacketMAC,
+ if (arp_wait_packet_ethaddr != NULL)
+ memcpy(arp_wait_packet_ethaddr,
&arp->ar_sha, ARP_HLEN);
net_get_arp_handler()((uchar *)arp, 0, reply_ip_addr,
- 0, len);
+ 0, len);
/* set the mac address in the waiting packet's header
and transmit it */
- memcpy(((struct ethernet_hdr *)NetTxPacket)->et_dest,
- &arp->ar_sha, ARP_HLEN);
- NetSendPacket(NetTxPacket, NetArpWaitTxPacketSize);
+ memcpy(((struct ethernet_hdr *)net_tx_packet)->et_dest,
+ &arp->ar_sha, ARP_HLEN);
+ net_send_packet(net_tx_packet, arp_wait_tx_packet_size);
/* no arp request pending now */
- NetArpWaitPacketIP = 0;
- NetArpWaitTxPacketSize = 0;
- NetArpWaitPacketMAC = NULL;
-
+ net_arp_wait_packet_ip.s_addr = 0;
+ arp_wait_tx_packet_size = 0;
+ arp_wait_packet_ethaddr = NULL;
}
return;
default:
diff --git a/net/arp.h b/net/arp.h
index 3a0a13a372..43c6296f7e 100644
--- a/net/arp.h
+++ b/net/arp.h
@@ -14,18 +14,18 @@
#include <common.h>
-extern IPaddr_t NetArpWaitPacketIP;
+extern struct in_addr net_arp_wait_packet_ip;
/* MAC address of waiting packet's destination */
-extern uchar *NetArpWaitPacketMAC;
-extern int NetArpWaitTxPacketSize;
-extern ulong NetArpWaitTimerStart;
-extern int NetArpWaitTry;
+extern uchar *arp_wait_packet_ethaddr;
+extern int arp_wait_tx_packet_size;
+extern ulong arp_wait_timer_start;
+extern int arp_wait_try;
-void ArpInit(void);
-void ArpRequest(void);
-void arp_raw_request(IPaddr_t sourceIP, const uchar *targetEther,
- IPaddr_t targetIP);
-void ArpTimeoutCheck(void);
-void ArpReceive(struct ethernet_hdr *et, struct ip_udp_hdr *ip, int len);
+void arp_init(void);
+void arp_request(void);
+void arp_raw_request(struct in_addr source_ip, const uchar *targetEther,
+ struct in_addr target_ip);
+void arp_timeout_check(void);
+void arp_receive(struct ethernet_hdr *et, struct ip_udp_hdr *ip, int len);
#endif /* __ARP_H__ */
diff --git a/net/bootp.c b/net/bootp.c
index 81066015f1..43466af2f3 100644
--- a/net/bootp.c
+++ b/net/bootp.c
@@ -51,18 +51,21 @@
#define CONFIG_BOOTP_ID_CACHE_SIZE 4
#endif
-ulong bootp_ids[CONFIG_BOOTP_ID_CACHE_SIZE];
+u32 bootp_ids[CONFIG_BOOTP_ID_CACHE_SIZE];
unsigned int bootp_num_ids;
-int BootpTry;
+int bootp_try;
ulong bootp_start;
ulong bootp_timeout;
+char net_nis_domain[32] = {0,}; /* Our NIS domain */
+char net_hostname[32] = {0,}; /* Our hostname */
+char net_root_path[64] = {0,}; /* Our bootpath */
#if defined(CONFIG_CMD_DHCP)
static dhcp_state_t dhcp_state = INIT;
-static unsigned long dhcp_leasetime;
-static IPaddr_t NetDHCPServerIP;
-static void DhcpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src,
- unsigned len);
+static u32 dhcp_leasetime;
+static struct in_addr dhcp_server_ip;
+static void dhcp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
+ unsigned src, unsigned len);
/* For Debug */
#if 0
@@ -106,14 +109,14 @@ static bool bootp_match_id(ulong id)
return false;
}
-static int BootpCheckPkt(uchar *pkt, unsigned dest, unsigned src, unsigned len)
+static int check_packet(uchar *pkt, unsigned dest, unsigned src, unsigned len)
{
- struct Bootp_t *bp = (struct Bootp_t *) pkt;
+ struct bootp_hdr *bp = (struct bootp_hdr *)pkt;
int retval = 0;
if (dest != PORT_BOOTPC || src != PORT_BOOTPS)
retval = -1;
- else if (len < sizeof(struct Bootp_t) - OPT_FIELD_SIZE)
+ else if (len < sizeof(struct bootp_hdr) - OPT_FIELD_SIZE)
retval = -2;
else if (bp->bp_op != OP_BOOTREQUEST &&
bp->bp_op != OP_BOOTREPLY &&
@@ -125,7 +128,7 @@ static int BootpCheckPkt(uchar *pkt, unsigned dest, unsigned src, unsigned len)
retval = -4;
else if (bp->bp_hlen != HWL_ETHER)
retval = -5;
- else if (!bootp_match_id(NetReadLong((ulong *)&bp->bp_id)))
+ else if (!bootp_match_id(net_read_u32(&bp->bp_id)))
retval = -6;
debug("Filtering pkt = %d\n", retval);
@@ -136,28 +139,30 @@ static int BootpCheckPkt(uchar *pkt, unsigned dest, unsigned src, unsigned len)
/*
* Copy parameters of interest from BOOTP_REPLY/DHCP_OFFER packet
*/
-static void BootpCopyNetParams(struct Bootp_t *bp)
+static void store_net_params(struct bootp_hdr *bp)
{
#if !defined(CONFIG_BOOTP_SERVERIP)
- IPaddr_t tmp_ip;
+ struct in_addr tmp_ip;
- NetCopyIP(&tmp_ip, &bp->bp_siaddr);
- if (tmp_ip != 0)
- NetCopyIP(&NetServerIP, &bp->bp_siaddr);
- memcpy(NetServerEther, ((struct ethernet_hdr *)NetRxPacket)->et_src, 6);
+ net_copy_ip(&tmp_ip, &bp->bp_siaddr);
+ if (tmp_ip.s_addr != 0)
+ net_copy_ip(&net_server_ip, &bp->bp_siaddr);
+ memcpy(net_server_ethaddr,
+ ((struct ethernet_hdr *)net_rx_packet)->et_src, 6);
if (strlen(bp->bp_file) > 0)
- copy_filename(BootFile, bp->bp_file, sizeof(BootFile));
+ copy_filename(net_boot_file_name, bp->bp_file,
+ sizeof(net_boot_file_name));
- debug("Bootfile: %s\n", BootFile);
+ debug("net_boot_file_name: %s\n", net_boot_file_name);
/* Propagate to environment:
* don't delete exising entry when BOOTP / DHCP reply does
* not contain a new value
*/
- if (*BootFile)
- setenv("bootfile", BootFile);
+ if (*net_boot_file_name)
+ setenv("bootfile", net_boot_file_name);
#endif
- NetCopyIP(&NetOurIP, &bp->bp_yiaddr);
+ net_copy_ip(&net_ip, &bp->bp_yiaddr);
}
static int truncate_sz(const char *name, int maxlen, int curlen)
@@ -172,38 +177,40 @@ static int truncate_sz(const char *name, int maxlen, int curlen)
#if !defined(CONFIG_CMD_DHCP)
-static void BootpVendorFieldProcess(u8 *ext)
+static void bootp_process_vendor_field(u8 *ext)
{
int size = *(ext + 1);
debug("[BOOTP] Processing extension %d... (%d bytes)\n", *ext,
- *(ext + 1));
+ *(ext + 1));
- NetBootFileSize = 0;
+ net_boot_file_expected_size_in_blocks = 0;
switch (*ext) {
/* Fixed length fields */
case 1: /* Subnet mask */
- if (NetOurSubnetMask == 0)
- NetCopyIP(&NetOurSubnetMask, (IPaddr_t *) (ext + 2));
+ if (net_netmask.s_addr == 0)
+ net_copy_ip(&net_netmask, (struct in_addr *)(ext + 2));
break;
case 2: /* Time offset - Not yet supported */
break;
/* Variable length fields */
case 3: /* Gateways list */
- if (NetOurGatewayIP == 0)
- NetCopyIP(&NetOurGatewayIP, (IPaddr_t *) (ext + 2));
+ if (net_gateway.s_addr == 0)
+ net_copy_ip(&net_gateway, (struct in_addr *)(ext + 2));
break;
case 4: /* Time server - Not yet supported */
break;
case 5: /* IEN-116 name server - Not yet supported */
break;
case 6:
- if (NetOurDNSIP == 0)
- NetCopyIP(&NetOurDNSIP, (IPaddr_t *) (ext + 2));
+ if (net_dns_server.s_addr == 0)
+ net_copy_ip(&net_dns_server,
+ (struct in_addr *)(ext + 2));
#if defined(CONFIG_BOOTP_DNS2)
- if ((NetOurDNS2IP == 0) && (size > 4))
- NetCopyIP(&NetOurDNS2IP, (IPaddr_t *) (ext + 2 + 4));
+ if ((net_dns_server2.s_addr == 0) && (size > 4))
+ net_copy_ip(&net_dns_server2,
+ (struct in_addr *)(ext + 2 + 4));
#endif
break;
case 7: /* Log server - Not yet supported */
@@ -217,18 +224,20 @@ static void BootpVendorFieldProcess(u8 *ext)
case 11: /* RPL server - Not yet supported */
break;
case 12: /* Host name */
- if (NetOurHostName[0] == 0) {
+ if (net_hostname[0] == 0) {
size = truncate_sz("Host Name",
- sizeof(NetOurHostName), size);
- memcpy(&NetOurHostName, ext + 2, size);
- NetOurHostName[size] = 0;
+ sizeof(net_hostname), size);
+ memcpy(&net_hostname, ext + 2, size);
+ net_hostname[size] = 0;
}
break;
case 13: /* Boot file size */
if (size == 2)
- NetBootFileSize = ntohs(*(ushort *) (ext + 2));
+ net_boot_file_expected_size_in_blocks =
+ ntohs(*(ushort *)(ext + 2));
else if (size == 4)
- NetBootFileSize = ntohl(*(ulong *) (ext + 2));
+ net_boot_file_expected_size_in_blocks =
+ ntohl(*(ulong *)(ext + 2));
break;
case 14: /* Merit dump file - Not yet supported */
break;
@@ -237,11 +246,11 @@ static void BootpVendorFieldProcess(u8 *ext)
case 16: /* Swap server - Not yet supported */
break;
case 17: /* Root path */
- if (NetOurRootPath[0] == 0) {
+ if (net_root_path[0] == 0) {
size = truncate_sz("Root Path",
- sizeof(NetOurRootPath), size);
- memcpy(&NetOurRootPath, ext + 2, size);
- NetOurRootPath[size] = 0;
+ sizeof(net_root_path), size);
+ memcpy(&net_root_path, ext + 2, size);
+ net_root_path[size] = 0;
}
break;
case 18: /* Extension path - Not yet supported */
@@ -253,16 +262,16 @@ static void BootpVendorFieldProcess(u8 *ext)
break;
/* IP host layer fields */
case 40: /* NIS Domain name */
- if (NetOurNISDomain[0] == 0) {
+ if (net_nis_domain[0] == 0) {
size = truncate_sz("NIS Domain Name",
- sizeof(NetOurNISDomain), size);
- memcpy(&NetOurNISDomain, ext + 2, size);
- NetOurNISDomain[size] = 0;
+ sizeof(net_nis_domain), size);
+ memcpy(&net_nis_domain, ext + 2, size);
+ net_nis_domain[size] = 0;
}
break;
#if defined(CONFIG_CMD_SNTP) && defined(CONFIG_BOOTP_NTPSERVER)
case 42: /* NTP server IP */
- NetCopyIP(&NetNtpServerIP, (IPaddr_t *) (ext + 2));
+ net_copy_ip(&net_ntp_server, (struct in_addr *)(ext + 2));
break;
#endif
/* Application layer fields */
@@ -276,7 +285,7 @@ static void BootpVendorFieldProcess(u8 *ext)
}
}
-static void BootpVendorProcess(u8 *ext, int size)
+static void bootp_process_vendor(u8 *ext, int size)
{
u8 *end = ext + size;
@@ -290,54 +299,51 @@ static void BootpVendorProcess(u8 *ext, int size)
ext += ext[1] + 2;
if (ext <= end)
- BootpVendorFieldProcess(opt);
+ bootp_process_vendor_field(opt);
}
}
debug("[BOOTP] Received fields:\n");
- if (NetOurSubnetMask)
- debug("NetOurSubnetMask : %pI4\n", &NetOurSubnetMask);
+ if (net_netmask.s_addr)
+ debug("net_netmask : %pI4\n", &net_netmask);
- if (NetOurGatewayIP)
- debug("NetOurGatewayIP : %pI4", &NetOurGatewayIP);
+ if (net_gateway.s_addr)
+ debug("net_gateway : %pI4", &net_gateway);
- if (NetBootFileSize)
- debug("NetBootFileSize : %d\n", NetBootFileSize);
+ if (net_boot_file_expected_size_in_blocks)
+ debug("net_boot_file_expected_size_in_blocks : %d\n",
+ net_boot_file_expected_size_in_blocks);
- if (NetOurHostName[0])
- debug("NetOurHostName : %s\n", NetOurHostName);
+ if (net_hostname[0])
+ debug("net_hostname : %s\n", net_hostname);
- if (NetOurRootPath[0])
- debug("NetOurRootPath : %s\n", NetOurRootPath);
+ if (net_root_path[0])
+ debug("net_root_path : %s\n", net_root_path);
- if (NetOurNISDomain[0])
- debug("NetOurNISDomain : %s\n", NetOurNISDomain);
-
- if (NetBootFileSize)
- debug("NetBootFileSize: %d\n", NetBootFileSize);
+ if (net_nis_domain[0])
+ debug("net_nis_domain : %s\n", net_nis_domain);
#if defined(CONFIG_CMD_SNTP) && defined(CONFIG_BOOTP_NTPSERVER)
- if (NetNtpServerIP)
- debug("NetNtpServerIP : %pI4\n", &NetNtpServerIP);
+ if (net_ntp_server)
+ debug("net_ntp_server : %pI4\n", &net_ntp_server);
#endif
}
/*
* Handle a BOOTP received packet.
*/
-static void
-BootpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src,
- unsigned len)
+static void bootp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
+ unsigned src, unsigned len)
{
- struct Bootp_t *bp;
+ struct bootp_hdr *bp;
debug("got BOOTP packet (src=%d, dst=%d, len=%d want_len=%zu)\n",
- src, dest, len, sizeof(struct Bootp_t));
+ src, dest, len, sizeof(struct bootp_hdr));
- bp = (struct Bootp_t *)pkt;
+ bp = (struct bootp_hdr *)pkt;
/* Filter out pkts we don't want */
- if (BootpCheckPkt(pkt, dest, src, len))
+ if (check_packet(pkt, dest, src, len))
return;
/*
@@ -347,13 +353,13 @@ BootpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src,
status_led_set(STATUS_LED_BOOT, STATUS_LED_OFF);
#endif
- BootpCopyNetParams(bp); /* Store net parameters from reply */
+ store_net_params(bp); /* Store net parameters from reply */
/* Retrieve extended information (we must parse the vendor area) */
- if (NetReadLong((ulong *)&bp->bp_vend[0]) == htonl(BOOTP_VENDOR_MAGIC))
- BootpVendorProcess((uchar *)&bp->bp_vend[4], len);
+ if (net_read_u32((u32 *)&bp->bp_vend[0]) == htonl(BOOTP_VENDOR_MAGIC))
+ bootp_process_vendor((uchar *)&bp->bp_vend[4], len);
- NetSetTimeout(0, (thand_f *)0);
+ net_set_timeout_handler(0, (thand_f *)0);
bootstage_mark_name(BOOTSTAGE_ID_BOOTP_STOP, "bootp_stop");
debug("Got good BOOTP\n");
@@ -365,8 +371,7 @@ BootpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src,
/*
* Timeout on BOOTP/DHCP request.
*/
-static void
-BootpTimeout(void)
+static void bootp_timeout_handler(void)
{
ulong time_taken = get_timer(bootp_start);
@@ -376,14 +381,14 @@ BootpTimeout(void)
net_set_state(NETLOOP_FAIL);
#else
puts("\nRetry time exceeded; starting again\n");
- NetStartAgain();
+ net_start_again();
#endif
} else {
bootp_timeout *= 2;
if (bootp_timeout > 2000)
bootp_timeout = 2000;
- NetSetTimeout(bootp_timeout, BootpTimeout);
- BootpRequest();
+ net_set_timeout_handler(bootp_timeout, bootp_timeout_handler);
+ bootp_request();
}
}
@@ -400,8 +405,8 @@ BootpTimeout(void)
* Initialize BOOTP extension fields in the request.
*/
#if defined(CONFIG_CMD_DHCP)
-static int DhcpExtended(u8 *e, int message_type, IPaddr_t ServerID,
- IPaddr_t RequestedIP)
+static int dhcp_extended(u8 *e, int message_type, struct in_addr server_ip,
+ struct in_addr requested_ip)
{
u8 *start = e;
u8 *cnt;
@@ -431,8 +436,8 @@ static int DhcpExtended(u8 *e, int message_type, IPaddr_t ServerID,
*e++ = (576 - 312 + OPT_FIELD_SIZE) >> 8;
*e++ = (576 - 312 + OPT_FIELD_SIZE) & 0xff;
- if (ServerID) {
- int tmp = ntohl(ServerID);
+ if (server_ip.s_addr) {
+ int tmp = ntohl(server_ip.s_addr);
*e++ = 54; /* ServerID */
*e++ = 4;
@@ -442,8 +447,8 @@ static int DhcpExtended(u8 *e, int message_type, IPaddr_t ServerID,
*e++ = tmp & 0xff;
}
- if (RequestedIP) {
- int tmp = ntohl(RequestedIP);
+ if (requested_ip.s_addr) {
+ int tmp = ntohl(requested_ip.s_addr);
*e++ = 50; /* Requested IP */
*e++ = 4;
@@ -561,7 +566,7 @@ static int DhcpExtended(u8 *e, int message_type, IPaddr_t ServerID,
/*
* Warning: no field size check - change CONFIG_BOOTP_* at your own risk!
*/
-static int BootpExtended(u8 *e)
+static int bootp_extended(u8 *e)
{
u8 *start = e;
@@ -643,25 +648,26 @@ static int BootpExtended(u8 *e)
}
#endif
-void BootpReset(void)
+void bootp_reset(void)
{
bootp_num_ids = 0;
- BootpTry = 0;
+ bootp_try = 0;
bootp_start = get_timer(0);
bootp_timeout = 250;
}
-void
-BootpRequest(void)
+void bootp_request(void)
{
uchar *pkt, *iphdr;
- struct Bootp_t *bp;
+ struct bootp_hdr *bp;
int extlen, pktlen, iplen;
int eth_hdr_size;
#ifdef CONFIG_BOOTP_RANDOM_DELAY
ulong rand_ms;
#endif
- ulong BootpID;
+ u32 bootp_id;
+ struct in_addr zero_ip;
+ struct in_addr bcast_ip;
bootstage_mark_name(BOOTSTAGE_ID_BOOTP_START, "bootp_start");
#if defined(CONFIG_CMD_DHCP)
@@ -669,11 +675,11 @@ BootpRequest(void)
#endif
#ifdef CONFIG_BOOTP_RANDOM_DELAY /* Random BOOTP delay */
- if (BootpTry == 0)
+ if (bootp_try == 0)
srand_mac();
- if (BootpTry <= 2) /* Start with max 1024 * 1ms */
- rand_ms = rand() >> (22 - BootpTry);
+ if (bootp_try <= 2) /* Start with max 1024 * 1ms */
+ rand_ms = rand() >> (22 - bootp_try);
else /* After 3rd BOOTP request max 8192 * 1ms */
rand_ms = rand() >> 19;
@@ -682,11 +688,11 @@ BootpRequest(void)
#endif /* CONFIG_BOOTP_RANDOM_DELAY */
- printf("BOOTP broadcast %d\n", ++BootpTry);
- pkt = NetTxPacket;
+ printf("BOOTP broadcast %d\n", ++bootp_try);
+ pkt = net_tx_packet;
memset((void *)pkt, 0, PKTSIZE);
- eth_hdr_size = NetSetEther(pkt, NetBcastAddr, PROT_IP);
+ eth_hdr_size = net_set_ether(pkt, net_bcast_ethaddr, PROT_IP);
pkt += eth_hdr_size;
/*
@@ -697,42 +703,44 @@ BootpRequest(void)
* C. Hallinan, DS4.COM, Inc.
*/
/* net_set_udp_header(pkt, 0xFFFFFFFFL, PORT_BOOTPS, PORT_BOOTPC,
- sizeof (struct Bootp_t)); */
+ sizeof (struct bootp_hdr)); */
iphdr = pkt; /* We need this later for net_set_udp_header() */
pkt += IP_UDP_HDR_SIZE;
- bp = (struct Bootp_t *)pkt;
+ bp = (struct bootp_hdr *)pkt;
bp->bp_op = OP_BOOTREQUEST;
bp->bp_htype = HWT_ETHER;
bp->bp_hlen = HWL_ETHER;
bp->bp_hops = 0;
bp->bp_secs = htons(get_timer(0) / 1000);
- NetWriteIP(&bp->bp_ciaddr, 0);
- NetWriteIP(&bp->bp_yiaddr, 0);
- NetWriteIP(&bp->bp_siaddr, 0);
- NetWriteIP(&bp->bp_giaddr, 0);
- memcpy(bp->bp_chaddr, NetOurEther, 6);
- copy_filename(bp->bp_file, BootFile, sizeof(bp->bp_file));
+ zero_ip.s_addr = 0;
+ net_write_ip(&bp->bp_ciaddr, zero_ip);
+ net_write_ip(&bp->bp_yiaddr, zero_ip);
+ net_write_ip(&bp->bp_siaddr, zero_ip);
+ net_write_ip(&bp->bp_giaddr, zero_ip);
+ memcpy(bp->bp_chaddr, net_ethaddr, 6);
+ copy_filename(bp->bp_file, net_boot_file_name, sizeof(bp->bp_file));
/* Request additional information from the BOOTP/DHCP server */
#if defined(CONFIG_CMD_DHCP)
- extlen = DhcpExtended((u8 *)bp->bp_vend, DHCP_DISCOVER, 0, 0);
+ extlen = dhcp_extended((u8 *)bp->bp_vend, DHCP_DISCOVER, zero_ip,
+ zero_ip);
#else
- extlen = BootpExtended((u8 *)bp->bp_vend);
+ extlen = bootp_extended((u8 *)bp->bp_vend);
#endif
/*
* Bootp ID is the lower 4 bytes of our ethernet address
* plus the current time in ms.
*/
- BootpID = ((ulong)NetOurEther[2] << 24)
- | ((ulong)NetOurEther[3] << 16)
- | ((ulong)NetOurEther[4] << 8)
- | (ulong)NetOurEther[5];
- BootpID += get_timer(0);
- BootpID = htonl(BootpID);
- bootp_add_id(BootpID);
- NetCopyLong(&bp->bp_id, &BootpID);
+ bootp_id = ((u32)net_ethaddr[2] << 24)
+ | ((u32)net_ethaddr[3] << 16)
+ | ((u32)net_ethaddr[4] << 8)
+ | (u32)net_ethaddr[5];
+ bootp_id += get_timer(0);
+ bootp_id = htonl(bootp_id);
+ bootp_add_id(bootp_id);
+ net_copy_u32(&bp->bp_id, &bootp_id);
/*
* Calculate proper packet lengths taking into account the
@@ -740,20 +748,21 @@ BootpRequest(void)
*/
iplen = BOOTP_HDR_SIZE - OPT_FIELD_SIZE + extlen;
pktlen = eth_hdr_size + IP_UDP_HDR_SIZE + iplen;
- net_set_udp_header(iphdr, 0xFFFFFFFFL, PORT_BOOTPS, PORT_BOOTPC, iplen);
- NetSetTimeout(bootp_timeout, BootpTimeout);
+ bcast_ip.s_addr = 0xFFFFFFFFL;
+ net_set_udp_header(iphdr, bcast_ip, PORT_BOOTPS, PORT_BOOTPC, iplen);
+ net_set_timeout_handler(bootp_timeout, bootp_timeout_handler);
#if defined(CONFIG_CMD_DHCP)
dhcp_state = SELECTING;
- net_set_udp_handler(DhcpHandler);
+ net_set_udp_handler(dhcp_handler);
#else
- net_set_udp_handler(BootpHandler);
+ net_set_udp_handler(bootp_handler);
#endif
- NetSendPacket(NetTxPacket, pktlen);
+ net_send_packet(net_tx_packet, pktlen);
}
#if defined(CONFIG_CMD_DHCP)
-static void DhcpOptionsProcess(uchar *popt, struct Bootp_t *bp)
+static void dhcp_process_options(uchar *popt, struct bootp_hdr *bp)
{
uchar *end = popt + BOOTP_HDR_SIZE;
int oplen, size;
@@ -765,53 +774,53 @@ static void DhcpOptionsProcess(uchar *popt, struct Bootp_t *bp)
oplen = *(popt + 1);
switch (*popt) {
case 1:
- NetCopyIP(&NetOurSubnetMask, (popt + 2));
+ net_copy_ip(&net_netmask, (popt + 2));
break;
#if defined(CONFIG_CMD_SNTP) && defined(CONFIG_BOOTP_TIMEOFFSET)
case 2: /* Time offset */
- to_ptr = &NetTimeOffset;
- NetCopyLong((ulong *)to_ptr, (ulong *)(popt + 2));
- NetTimeOffset = ntohl(NetTimeOffset);
+ to_ptr = &net_ntp_time_offset;
+ net_copy_u32((u32 *)to_ptr, (u32 *)(popt + 2));
+ net_ntp_time_offset = ntohl(net_ntp_time_offset);
break;
#endif
case 3:
- NetCopyIP(&NetOurGatewayIP, (popt + 2));
+ net_copy_ip(&net_gateway, (popt + 2));
break;
case 6:
- NetCopyIP(&NetOurDNSIP, (popt + 2));
+ net_copy_ip(&net_dns_server, (popt + 2));
#if defined(CONFIG_BOOTP_DNS2)
if (*(popt + 1) > 4)
- NetCopyIP(&NetOurDNS2IP, (popt + 2 + 4));
+ net_copy_ip(&net_dns_server2, (popt + 2 + 4));
#endif
break;
case 12:
size = truncate_sz("Host Name",
- sizeof(NetOurHostName), oplen);
- memcpy(&NetOurHostName, popt + 2, size);
- NetOurHostName[size] = 0;
+ sizeof(net_hostname), oplen);
+ memcpy(&net_hostname, popt + 2, size);
+ net_hostname[size] = 0;
break;
case 15: /* Ignore Domain Name Option */
break;
case 17:
size = truncate_sz("Root Path",
- sizeof(NetOurRootPath), oplen);
- memcpy(&NetOurRootPath, popt + 2, size);
- NetOurRootPath[size] = 0;
+ sizeof(net_root_path), oplen);
+ memcpy(&net_root_path, popt + 2, size);
+ net_root_path[size] = 0;
break;
case 28: /* Ignore Broadcast Address Option */
break;
#if defined(CONFIG_CMD_SNTP) && defined(CONFIG_BOOTP_NTPSERVER)
case 42: /* NTP server IP */
- NetCopyIP(&NetNtpServerIP, (popt + 2));
+ net_copy_ip(&net_ntp_server, (popt + 2));
break;
#endif
case 51:
- NetCopyLong(&dhcp_leasetime, (ulong *) (popt + 2));
+ net_copy_u32(&dhcp_leasetime, (u32 *)(popt + 2));
break;
case 53: /* Ignore Message Type Option */
break;
case 54:
- NetCopyIP(&NetDHCPServerIP, (popt + 2));
+ net_copy_ip(&dhcp_server_ip, (popt + 2));
break;
case 58: /* Ignore Renewal Time Option */
break;
@@ -840,7 +849,7 @@ static void DhcpOptionsProcess(uchar *popt, struct Bootp_t *bp)
* to me
*/
printf("*** WARNING: using vendor "
- "optional boot file\n");
+ "optional boot file\n");
memcpy(bp->bp_file, popt + 2, size);
bp->bp_file[size] = '\0';
}
@@ -851,16 +860,16 @@ static void DhcpOptionsProcess(uchar *popt, struct Bootp_t *bp)
break;
#endif
printf("*** Unhandled DHCP Option in OFFER/ACK:"
- " %d\n", *popt);
+ " %d\n", *popt);
break;
}
popt += oplen + 2; /* Process next option */
}
}
-static int DhcpMessageType(unsigned char *popt)
+static int dhcp_message_type(unsigned char *popt)
{
- if (NetReadLong((ulong *)popt) != htonl(BOOTP_VENDOR_MAGIC))
+ if (net_read_u32((u32 *)popt) != htonl(BOOTP_VENDOR_MAGIC))
return -1;
popt += 4;
@@ -872,25 +881,27 @@ static int DhcpMessageType(unsigned char *popt)
return -1;
}
-static void DhcpSendRequestPkt(struct Bootp_t *bp_offer)
+static void dhcp_send_request_packet(struct bootp_hdr *bp_offer)
{
uchar *pkt, *iphdr;
- struct Bootp_t *bp;
+ struct bootp_hdr *bp;
int pktlen, iplen, extlen;
int eth_hdr_size;
- IPaddr_t OfferedIP;
+ struct in_addr offered_ip;
+ struct in_addr zero_ip;
+ struct in_addr bcast_ip;
- debug("DhcpSendRequestPkt: Sending DHCPREQUEST\n");
- pkt = NetTxPacket;
+ debug("dhcp_send_request_packet: Sending DHCPREQUEST\n");
+ pkt = net_tx_packet;
memset((void *)pkt, 0, PKTSIZE);
- eth_hdr_size = NetSetEther(pkt, NetBcastAddr, PROT_IP);
+ eth_hdr_size = net_set_ether(pkt, net_bcast_ethaddr, PROT_IP);
pkt += eth_hdr_size;
iphdr = pkt; /* We'll need this later to set proper pkt size */
pkt += IP_UDP_HDR_SIZE;
- bp = (struct Bootp_t *)pkt;
+ bp = (struct bootp_hdr *)pkt;
bp->bp_op = OP_BOOTREQUEST;
bp->bp_htype = HWT_ETHER;
bp->bp_hlen = HWL_ETHER;
@@ -903,54 +914,55 @@ static void DhcpSendRequestPkt(struct Bootp_t *bp_offer)
* RFC3046 requires Relay Agents to discard packets with
* nonzero and offered giaddr
*/
- NetWriteIP(&bp->bp_giaddr, 0);
+ zero_ip.s_addr = 0;
+ net_write_ip(&bp->bp_giaddr, zero_ip);
- memcpy(bp->bp_chaddr, NetOurEther, 6);
+ memcpy(bp->bp_chaddr, net_ethaddr, 6);
/*
* ID is the id of the OFFER packet
*/
- NetCopyLong(&bp->bp_id, &bp_offer->bp_id);
+ net_copy_u32(&bp->bp_id, &bp_offer->bp_id);
/*
* Copy options from OFFER packet if present
*/
/* Copy offered IP into the parameters request list */
- NetCopyIP(&OfferedIP, &bp_offer->bp_yiaddr);
- extlen = DhcpExtended((u8 *)bp->bp_vend, DHCP_REQUEST,
- NetDHCPServerIP, OfferedIP);
+ net_copy_ip(&offered_ip, &bp_offer->bp_yiaddr);
+ extlen = dhcp_extended((u8 *)bp->bp_vend, DHCP_REQUEST,
+ dhcp_server_ip, offered_ip);
iplen = BOOTP_HDR_SIZE - OPT_FIELD_SIZE + extlen;
pktlen = eth_hdr_size + IP_UDP_HDR_SIZE + iplen;
- net_set_udp_header(iphdr, 0xFFFFFFFFL, PORT_BOOTPS, PORT_BOOTPC, iplen);
+ bcast_ip.s_addr = 0xFFFFFFFFL;
+ net_set_udp_header(iphdr, bcast_ip, PORT_BOOTPS, PORT_BOOTPC, iplen);
#ifdef CONFIG_BOOTP_DHCP_REQUEST_DELAY
udelay(CONFIG_BOOTP_DHCP_REQUEST_DELAY);
#endif /* CONFIG_BOOTP_DHCP_REQUEST_DELAY */
debug("Transmitting DHCPREQUEST packet: len = %d\n", pktlen);
- NetSendPacket(NetTxPacket, pktlen);
+ net_send_packet(net_tx_packet, pktlen);
}
/*
* Handle DHCP received packets.
*/
-static void
-DhcpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src,
- unsigned len)
+static void dhcp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
+ unsigned src, unsigned len)
{
- struct Bootp_t *bp = (struct Bootp_t *)pkt;
+ struct bootp_hdr *bp = (struct bootp_hdr *)pkt;
debug("DHCPHandler: got packet: (src=%d, dst=%d, len=%d) state: %d\n",
- src, dest, len, dhcp_state);
+ src, dest, len, dhcp_state);
/* Filter out pkts we don't want */
- if (BootpCheckPkt(pkt, dest, src, len))
+ if (check_packet(pkt, dest, src, len))
return;
- debug("DHCPHandler: got DHCP packet: (src=%d, dst=%d, len=%d) state:"
- " %d\n", src, dest, len, dhcp_state);
+ debug("DHCPHandler: got DHCP packet: (src=%d, dst=%d, len=%d) state: "
+ "%d\n", src, dest, len, dhcp_state);
switch (dhcp_state) {
case SELECTING:
@@ -970,12 +982,12 @@ DhcpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src,
debug("TRANSITIONING TO REQUESTING STATE\n");
dhcp_state = REQUESTING;
- if (NetReadLong((ulong *)&bp->bp_vend[0]) ==
+ if (net_read_u32((u32 *)&bp->bp_vend[0]) ==
htonl(BOOTP_VENDOR_MAGIC))
- DhcpOptionsProcess((u8 *)&bp->bp_vend[4], bp);
+ dhcp_process_options((u8 *)&bp->bp_vend[4], bp);
- NetSetTimeout(5000, BootpTimeout);
- DhcpSendRequestPkt(bp);
+ net_set_timeout_handler(5000, bootp_timeout_handler);
+ dhcp_send_request_packet(bp);
#ifdef CONFIG_SYS_BOOTFILE_PREFIX
}
#endif /* CONFIG_SYS_BOOTFILE_PREFIX */
@@ -985,17 +997,17 @@ DhcpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src,
case REQUESTING:
debug("DHCP State: REQUESTING\n");
- if (DhcpMessageType((u8 *)bp->bp_vend) == DHCP_ACK) {
- if (NetReadLong((ulong *)&bp->bp_vend[0]) ==
+ if (dhcp_message_type((u8 *)bp->bp_vend) == DHCP_ACK) {
+ if (net_read_u32((u32 *)&bp->bp_vend[0]) ==
htonl(BOOTP_VENDOR_MAGIC))
- DhcpOptionsProcess((u8 *)&bp->bp_vend[4], bp);
+ dhcp_process_options((u8 *)&bp->bp_vend[4], bp);
/* Store net params from reply */
- BootpCopyNetParams(bp);
+ store_net_params(bp);
dhcp_state = BOUND;
printf("DHCP client bound to address %pI4 (%lu ms)\n",
- &NetOurIP, get_timer(bootp_start));
+ &net_ip, get_timer(bootp_start));
bootstage_mark_name(BOOTSTAGE_ID_BOOTP_STOP,
- "bootp_stop");
+ "bootp_stop");
net_auto_load();
return;
@@ -1008,11 +1020,10 @@ DhcpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src,
puts("DHCP: INVALID STATE\n");
break;
}
-
}
-void DhcpRequest(void)
+void dhcp_request(void)
{
- BootpRequest();
+ bootp_request();
}
#endif /* CONFIG_CMD_DHCP */
diff --git a/net/bootp.h b/net/bootp.h
index 3b95a0a2de..fcb0a64e61 100644
--- a/net/bootp.h
+++ b/net/bootp.h
@@ -29,29 +29,29 @@ extern u8 *dhcp_vendorex_proc(u8 *e); /*rtn next e if mine,else NULL */
#define OPT_FIELD_SIZE 64
#endif
-struct Bootp_t {
- uchar bp_op; /* Operation */
+struct bootp_hdr {
+ u8 bp_op; /* Operation */
# define OP_BOOTREQUEST 1
# define OP_BOOTREPLY 2
- uchar bp_htype; /* Hardware type */
+ u8 bp_htype; /* Hardware type */
# define HWT_ETHER 1
- uchar bp_hlen; /* Hardware address length */
+ u8 bp_hlen; /* Hardware address length */
# define HWL_ETHER 6
- uchar bp_hops; /* Hop count (gateway thing) */
- ulong bp_id; /* Transaction ID */
- ushort bp_secs; /* Seconds since boot */
- ushort bp_spare1; /* Alignment */
- IPaddr_t bp_ciaddr; /* Client IP address */
- IPaddr_t bp_yiaddr; /* Your (client) IP address */
- IPaddr_t bp_siaddr; /* Server IP address */
- IPaddr_t bp_giaddr; /* Gateway IP address */
- uchar bp_chaddr[16]; /* Client hardware address */
+ u8 bp_hops; /* Hop count (gateway thing) */
+ u32 bp_id; /* Transaction ID */
+ u16 bp_secs; /* Seconds since boot */
+ u16 bp_spare1; /* Alignment */
+ struct in_addr bp_ciaddr; /* Client IP address */
+ struct in_addr bp_yiaddr; /* Your (client) IP address */
+ struct in_addr bp_siaddr; /* Server IP address */
+ struct in_addr bp_giaddr; /* Gateway IP address */
+ u8 bp_chaddr[16]; /* Client hardware address */
char bp_sname[64]; /* Server host name */
char bp_file[128]; /* Boot file name */
char bp_vend[OPT_FIELD_SIZE]; /* Vendor information */
};
-#define BOOTP_HDR_SIZE sizeof(struct Bootp_t)
+#define BOOTP_HDR_SIZE sizeof(struct bootp_hdr)
/**********************************************************************/
/*
@@ -59,17 +59,16 @@ struct Bootp_t {
*/
/* bootp.c */
-extern ulong BootpID; /* ID of cur BOOTP request */
-extern char BootFile[128]; /* Boot file name */
-extern int BootpTry;
+extern u32 bootp_id; /* ID of cur BOOTP request */
+extern int bootp_try;
/* Send a BOOTP request */
-extern void BootpReset(void);
-extern void BootpRequest(void);
+void bootp_reset(void);
+void bootp_request(void);
/****************** DHCP Support *********************/
-extern void DhcpRequest(void);
+void dhcp_request(void);
/* DHCP States */
typedef enum { INIT,
diff --git a/net/cdp.c b/net/cdp.c
index 2d8fa03a7e..f9ccf53231 100644
--- a/net/cdp.c
+++ b/net/cdp.c
@@ -18,7 +18,7 @@
#include "cdp.h"
/* Ethernet bcast address */
-const uchar NetCDPAddr[6] = { 0x01, 0x00, 0x0c, 0xcc, 0xcc, 0xcc };
+const u8 net_cdp_ethaddr[6] = { 0x01, 0x00, 0x0c, 0xcc, 0xcc, 0xcc };
#define CDP_DEVICE_ID_TLV 0x0001
#define CDP_ADDRESS_TLV 0x0002
@@ -36,17 +36,16 @@ const uchar NetCDPAddr[6] = { 0x01, 0x00, 0x0c, 0xcc, 0xcc, 0xcc };
#define CDP_TIMEOUT 250UL /* one packet every 250ms */
-static int CDPSeq;
-static int CDPOK;
+static int cdp_seq;
+static int cdp_ok;
-ushort CDPNativeVLAN;
-ushort CDPApplianceVLAN;
+ushort cdp_native_vlan;
+ushort cdp_appliance_vlan;
-static const uchar CDP_SNAP_hdr[8] = {
+static const uchar cdp_snap_hdr[8] = {
0xAA, 0xAA, 0x03, 0x00, 0x00, 0x0C, 0x20, 0x00 };
-static ushort
-CDP_compute_csum(const uchar *buff, ushort len)
+static ushort cdp_compute_csum(const uchar *buff, ushort len)
{
ushort csum;
int odd;
@@ -104,8 +103,7 @@ CDP_compute_csum(const uchar *buff, ushort len)
return csum;
}
-static int
-CDPSendTrigger(void)
+static int cdp_send_trigger(void)
{
uchar *pkt;
ushort *s;
@@ -118,20 +116,20 @@ CDPSendTrigger(void)
char buf[32];
#endif
- pkt = NetTxPacket;
+ pkt = net_tx_packet;
et = (struct ethernet_hdr *)pkt;
/* NOTE: trigger sent not on any VLAN */
/* form ethernet header */
- memcpy(et->et_dest, NetCDPAddr, 6);
- memcpy(et->et_src, NetOurEther, 6);
+ memcpy(et->et_dest, net_cdp_ethaddr, 6);
+ memcpy(et->et_src, net_ethaddr, 6);
pkt += ETHER_HDR_SIZE;
/* SNAP header */
- memcpy((uchar *)pkt, CDP_SNAP_hdr, sizeof(CDP_SNAP_hdr));
- pkt += sizeof(CDP_SNAP_hdr);
+ memcpy((uchar *)pkt, cdp_snap_hdr, sizeof(cdp_snap_hdr));
+ pkt += sizeof(cdp_snap_hdr);
/* CDP header */
*pkt++ = 0x02; /* CDP version 2 */
@@ -145,7 +143,7 @@ CDPSendTrigger(void)
#ifdef CONFIG_CDP_DEVICE_ID
*s++ = htons(CDP_DEVICE_ID_TLV);
*s++ = htons(CONFIG_CDP_DEVICE_ID);
- sprintf(buf, CONFIG_CDP_DEVICE_ID_PREFIX "%pm", NetOurEther);
+ sprintf(buf, CONFIG_CDP_DEVICE_ID_PREFIX "%pm", net_ethaddr);
memcpy((uchar *)s, buf, 16);
s += 16 / 2;
#endif
@@ -207,34 +205,33 @@ CDPSendTrigger(void)
#endif
/* length of ethernet packet */
- len = (uchar *)s - ((uchar *)NetTxPacket + ETHER_HDR_SIZE);
+ len = (uchar *)s - ((uchar *)net_tx_packet + ETHER_HDR_SIZE);
et->et_protlen = htons(len);
- len = ETHER_HDR_SIZE + sizeof(CDP_SNAP_hdr);
- chksum = CDP_compute_csum((uchar *)NetTxPacket + len,
- (uchar *)s - (NetTxPacket + len));
+ len = ETHER_HDR_SIZE + sizeof(cdp_snap_hdr);
+ chksum = cdp_compute_csum((uchar *)net_tx_packet + len,
+ (uchar *)s - (net_tx_packet + len));
if (chksum == 0)
chksum = 0xFFFF;
*cp = htons(chksum);
- NetSendPacket(NetTxPacket, (uchar *)s - NetTxPacket);
+ net_send_packet(net_tx_packet, (uchar *)s - net_tx_packet);
return 0;
}
-static void
-CDPTimeout(void)
+static void cdp_timeout_handler(void)
{
- CDPSeq++;
+ cdp_seq++;
- if (CDPSeq < 3) {
- NetSetTimeout(CDP_TIMEOUT, CDPTimeout);
- CDPSendTrigger();
+ if (cdp_seq < 3) {
+ net_set_timeout_handler(CDP_TIMEOUT, cdp_timeout_handler);
+ cdp_send_trigger();
return;
}
/* if not OK try again */
- if (!CDPOK)
- NetStartAgain();
+ if (!cdp_ok)
+ net_start_again();
else
net_set_state(NETLOOP_SUCCESS);
}
@@ -247,15 +244,15 @@ void cdp_receive(const uchar *pkt, unsigned len)
ushort vlan, nvlan;
/* minimum size? */
- if (len < sizeof(CDP_SNAP_hdr) + 4)
+ if (len < sizeof(cdp_snap_hdr) + 4)
goto pkt_short;
/* check for valid CDP SNAP header */
- if (memcmp(pkt, CDP_SNAP_hdr, sizeof(CDP_SNAP_hdr)) != 0)
+ if (memcmp(pkt, cdp_snap_hdr, sizeof(cdp_snap_hdr)) != 0)
return;
- pkt += sizeof(CDP_SNAP_hdr);
- len -= sizeof(CDP_SNAP_hdr);
+ pkt += sizeof(cdp_snap_hdr);
+ len -= sizeof(cdp_snap_hdr);
/* Version of CDP protocol must be >= 2 and TTL != 0 */
if (pkt[0] < 0x02 || pkt[1] == 0)
@@ -269,7 +266,7 @@ void cdp_receive(const uchar *pkt, unsigned len)
printf("**WARNING: CDP packet received with a protocol version "
"%d > 2\n", pkt[0] & 0xff);
- if (CDP_compute_csum(pkt, len) != 0)
+ if (cdp_compute_csum(pkt, len) != 0)
return;
pkt += 4;
@@ -340,28 +337,27 @@ void cdp_receive(const uchar *pkt, unsigned len)
}
}
- CDPApplianceVLAN = vlan;
- CDPNativeVLAN = nvlan;
+ cdp_appliance_vlan = vlan;
+ cdp_native_vlan = nvlan;
- CDPOK = 1;
+ cdp_ok = 1;
return;
- pkt_short:
+pkt_short:
printf("** CDP packet is too short\n");
return;
}
-void
-CDPStart(void)
+void cdp_start(void)
{
printf("Using %s device\n", eth_get_name());
- CDPSeq = 0;
- CDPOK = 0;
+ cdp_seq = 0;
+ cdp_ok = 0;
- CDPNativeVLAN = htons(-1);
- CDPApplianceVLAN = htons(-1);
+ cdp_native_vlan = htons(-1);
+ cdp_appliance_vlan = htons(-1);
- NetSetTimeout(CDP_TIMEOUT, CDPTimeout);
+ net_set_timeout_handler(CDP_TIMEOUT, cdp_timeout_handler);
- CDPSendTrigger();
+ cdp_send_trigger();
}
diff --git a/net/cdp.h b/net/cdp.h
index 95e4ce025d..83475c992d 100644
--- a/net/cdp.h
+++ b/net/cdp.h
@@ -14,7 +14,7 @@
#ifndef __CDP_H__
#define __CDP_H__
-void CDPStart(void);
+void cdp_start(void);
/* Process a received CDP packet */
void cdp_receive(const uchar *pkt, unsigned len);
diff --git a/net/dns.c b/net/dns.c
index dd45320150..7017bac75a 100644
--- a/net/dns.c
+++ b/net/dns.c
@@ -5,7 +5,7 @@
* Copyright (c) 2009 Robin Getz <rgetz@blackfin.uclinux.org>
*
* This is a simple DNS implementation for U-Boot. It will use the first IP
- * in the DNS response as NetServerIP. This can then be used for any other
+ * in the DNS response as net_server_ip. This can then be used for any other
* network related activities.
*
* The packet handling is partly based on TADNS, original copyrights
@@ -29,13 +29,12 @@
#include "dns.h"
-char *NetDNSResolve; /* The host to resolve */
-char *NetDNSenvvar; /* The envvar to store the answer in */
+char *net_dns_resolve; /* The host to resolve */
+char *net_dns_env_var; /* The envvar to store the answer in */
-static int DnsOurPort;
+static int dns_our_port;
-static void
-DnsSend(void)
+static void dns_send(void)
{
struct header *header;
int n, name_len;
@@ -44,11 +43,12 @@ DnsSend(void)
const char *name;
enum dns_query_type qtype = DNS_A_RECORD;
- name = NetDNSResolve;
- pkt = p = (uchar *)(NetTxPacket + NetEthHdrSize() + IP_UDP_HDR_SIZE);
+ name = net_dns_resolve;
+ pkt = (uchar *)(net_tx_packet + net_eth_hdr_size() + IP_UDP_HDR_SIZE);
+ p = pkt;
/* Prepare DNS packet header */
- header = (struct header *) pkt;
+ header = (struct header *)pkt;
header->tid = 1;
header->flags = htons(0x100); /* standard query */
header->nqueries = htons(1); /* Just one query */
@@ -58,7 +58,7 @@ DnsSend(void)
/* Encode DNS name */
name_len = strlen(name);
- p = (uchar *) &header->data; /* For encoding host name into packet */
+ p = (uchar *)&header->data; /* For encoding host name into packet */
do {
s = strchr(name, '.');
@@ -87,41 +87,40 @@ DnsSend(void)
n = p - pkt; /* Total packet length */
debug("Packet size %d\n", n);
- DnsOurPort = random_port();
+ dns_our_port = random_port();
- NetSendUDPPacket(NetServerEther, NetOurDNSIP, DNS_SERVICE_PORT,
- DnsOurPort, n);
+ net_send_udp_packet(net_server_ethaddr, net_dns_server,
+ DNS_SERVICE_PORT, dns_our_port, n);
debug("DNS packet sent\n");
}
-static void
-DnsTimeout(void)
+static void dns_timeout_handler(void)
{
puts("Timeout\n");
net_set_state(NETLOOP_FAIL);
}
-static void
-DnsHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, unsigned len)
+static void dns_handler(uchar *pkt, unsigned dest, struct in_addr sip,
+ unsigned src, unsigned len)
{
struct header *header;
const unsigned char *p, *e, *s;
u16 type, i;
int found, stop, dlen;
- char IPStr[22];
- IPaddr_t IPAddress;
+ char ip_str[22];
+ struct in_addr ip_addr;
debug("%s\n", __func__);
- if (dest != DnsOurPort)
+ if (dest != dns_our_port)
return;
for (i = 0; i < len; i += 4)
debug("0x%p - 0x%.2x 0x%.2x 0x%.2x 0x%.2x\n",
- pkt+i, pkt[i], pkt[i+1], pkt[i+2], pkt[i+3]);
+ pkt+i, pkt[i], pkt[i+1], pkt[i+2], pkt[i+3]);
/* We sent one query. We want to have a single answer: */
- header = (struct header *) pkt;
+ header = (struct header *)pkt;
if (ntohs(header->nqueries) != 1)
return;
@@ -150,7 +149,6 @@ DnsHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, unsigned len)
/* Loop through the answers, we want A type answer */
for (found = stop = 0; !stop && &p[12] < e; ) {
-
/* Skip possible name in CNAME answer */
if (*p != 0xc0) {
while (*p && &p[12] < e)
@@ -169,7 +167,8 @@ DnsHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, unsigned len)
p += 12 + dlen;
} else if (type == DNS_A_RECORD) {
debug("Found A-record\n");
- found = stop = 1;
+ found = 1;
+ stop = 1;
} else {
debug("Unknown type\n");
stop = 1;
@@ -177,33 +176,32 @@ DnsHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, unsigned len)
}
if (found && &p[12] < e) {
-
dlen = get_unaligned_be16(p+10);
p += 12;
- memcpy(&IPAddress, p, 4);
+ memcpy(&ip_addr, p, 4);
if (p + dlen <= e) {
- ip_to_string(IPAddress, IPStr);
- printf("%s\n", IPStr);
- if (NetDNSenvvar)
- setenv(NetDNSenvvar, IPStr);
- } else
+ ip_to_string(ip_addr, ip_str);
+ printf("%s\n", ip_str);
+ if (net_dns_env_var)
+ setenv(net_dns_env_var, ip_str);
+ } else {
puts("server responded with invalid IP number\n");
+ }
}
net_set_state(NETLOOP_SUCCESS);
}
-void
-DnsStart(void)
+void dns_start(void)
{
debug("%s\n", __func__);
- NetSetTimeout(DNS_TIMEOUT, DnsTimeout);
- net_set_udp_handler(DnsHandler);
+ net_set_timeout_handler(DNS_TIMEOUT, dns_timeout_handler);
+ net_set_udp_handler(dns_handler);
/* Clear a previous MAC address, the server IP might have changed. */
- memset(NetServerEther, 0, sizeof(NetServerEther));
+ memset(net_server_ethaddr, 0, sizeof(net_server_ethaddr));
- DnsSend();
+ dns_send();
}
diff --git a/net/dns.h b/net/dns.h
index dbc3890df9..c4e96afa06 100644
--- a/net/dns.h
+++ b/net/dns.h
@@ -31,6 +31,6 @@ struct header {
unsigned char data[1]; /* Data, variable length */
};
-extern void DnsStart(void); /* Begin DNS */
+void dns_start(void); /* Begin DNS */
#endif
diff --git a/net/eth.c b/net/eth.c
index eac4f7b3d0..8e6acfef89 100644
--- a/net/eth.c
+++ b/net/eth.c
@@ -1,16 +1,21 @@
/*
- * (C) Copyright 2001-2010
+ * (C) Copyright 2001-2015
* Wolfgang Denk, DENX Software Engineering, wd@denx.de.
+ * Joe Hershberger, National Instruments
*
* SPDX-License-Identifier: GPL-2.0+
*/
#include <common.h>
#include <command.h>
+#include <dm.h>
#include <net.h>
#include <miiphy.h>
#include <phy.h>
#include <asm/errno.h>
+#include <dm/device-internal.h>
+
+DECLARE_GLOBAL_DATA_PTR;
void eth_parse_enetaddr(const char *addr, uchar *enetaddr)
{
@@ -27,7 +32,7 @@ void eth_parse_enetaddr(const char *addr, uchar *enetaddr)
int eth_getenv_enetaddr(char *name, uchar *enetaddr)
{
eth_parse_enetaddr(getenv(name), enetaddr);
- return is_valid_ether_addr(enetaddr);
+ return is_valid_ethaddr(enetaddr);
}
int eth_setenv_enetaddr(char *name, const uchar *enetaddr)
@@ -55,15 +60,28 @@ static inline int eth_setenv_enetaddr_by_index(const char *base_name, int index,
return eth_setenv_enetaddr(enetvar, enetaddr);
}
+static void eth_env_init(void)
+{
+ const char *s;
+
+ s = getenv("bootfile");
+ if (s != NULL)
+ copy_filename(net_boot_file_name, s,
+ sizeof(net_boot_file_name));
+}
static int eth_mac_skip(int index)
{
char enetvar[15];
char *skip_state;
+
sprintf(enetvar, index ? "eth%dmacskip" : "ethmacskip", index);
- return ((skip_state = getenv(enetvar)) != NULL);
+ skip_state = getenv(enetvar);
+ return skip_state != NULL;
}
+static void eth_current_changed(void);
+
/*
* CPU and board-specific Ethernet initializations. Aliased function
* signals caller to move on
@@ -75,6 +93,472 @@ static int __def_eth_init(bd_t *bis)
int cpu_eth_init(bd_t *bis) __attribute__((weak, alias("__def_eth_init")));
int board_eth_init(bd_t *bis) __attribute__((weak, alias("__def_eth_init")));
+static void eth_common_init(void)
+{
+ bootstage_mark(BOOTSTAGE_ID_NET_ETH_START);
+#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) || defined(CONFIG_PHYLIB)
+ miiphy_init();
+#endif
+
+#ifdef CONFIG_PHYLIB
+ phy_init();
+#endif
+
+ eth_env_init();
+
+ /*
+ * If board-specific initialization exists, call it.
+ * If not, call a CPU-specific one
+ */
+ if (board_eth_init != __def_eth_init) {
+ if (board_eth_init(gd->bd) < 0)
+ printf("Board Net Initialization Failed\n");
+ } else if (cpu_eth_init != __def_eth_init) {
+ if (cpu_eth_init(gd->bd) < 0)
+ printf("CPU Net Initialization Failed\n");
+ } else {
+ printf("Net Initialization Skipped\n");
+ }
+}
+
+#ifdef CONFIG_DM_ETH
+/**
+ * struct eth_device_priv - private structure for each Ethernet device
+ *
+ * @state: The state of the Ethernet MAC driver (defined by enum eth_state_t)
+ */
+struct eth_device_priv {
+ enum eth_state_t state;
+};
+
+/**
+ * struct eth_uclass_priv - The structure attached to the uclass itself
+ *
+ * @current: The Ethernet device that the network functions are using
+ */
+struct eth_uclass_priv {
+ struct udevice *current;
+};
+
+/* eth_errno - This stores the most recent failure code from DM functions */
+static int eth_errno;
+
+static struct eth_uclass_priv *eth_get_uclass_priv(void)
+{
+ struct uclass *uc;
+
+ uclass_get(UCLASS_ETH, &uc);
+ assert(uc);
+ return uc->priv;
+}
+
+static void eth_set_current_to_next(void)
+{
+ struct eth_uclass_priv *uc_priv;
+
+ uc_priv = eth_get_uclass_priv();
+ if (uc_priv->current)
+ uclass_next_device(&uc_priv->current);
+ if (!uc_priv->current)
+ uclass_first_device(UCLASS_ETH, &uc_priv->current);
+}
+
+/*
+ * Typically this will simply return the active device.
+ * In the case where the most recent active device was unset, this will attempt
+ * to return the first device. If that device doesn't exist or fails to probe,
+ * this function will return NULL.
+ */
+struct udevice *eth_get_dev(void)
+{
+ struct eth_uclass_priv *uc_priv;
+
+ uc_priv = eth_get_uclass_priv();
+ if (!uc_priv->current)
+ eth_errno = uclass_first_device(UCLASS_ETH,
+ &uc_priv->current);
+ return uc_priv->current;
+}
+
+/*
+ * Typically this will just store a device pointer.
+ * In case it was not probed, we will attempt to do so.
+ * dev may be NULL to unset the active device.
+ */
+static void eth_set_dev(struct udevice *dev)
+{
+ if (dev && !device_active(dev))
+ eth_errno = device_probe(dev);
+ eth_get_uclass_priv()->current = dev;
+}
+
+/*
+ * Find the udevice that either has the name passed in as devname or has an
+ * alias named devname.
+ */
+struct udevice *eth_get_dev_by_name(const char *devname)
+{
+ int seq = -1;
+ char *endp = NULL;
+ const char *startp = NULL;
+ struct udevice *it;
+ struct uclass *uc;
+
+ /* Must be longer than 3 to be an alias */
+ if (strlen(devname) > strlen("eth")) {
+ startp = devname + strlen("eth");
+ seq = simple_strtoul(startp, &endp, 10);
+ }
+
+ uclass_get(UCLASS_ETH, &uc);
+ uclass_foreach_dev(it, uc) {
+ /*
+ * We need the seq to be valid, so try to probe it.
+ * If the probe fails, the seq will not match since it will be
+ * -1 instead of what we are looking for.
+ * We don't care about errors from probe here. Either they won't
+ * match an alias or it will match a literal name and we'll pick
+ * up the error when we try to probe again in eth_set_dev().
+ */
+ device_probe(it);
+ /*
+ * Check for the name or the sequence number to match
+ */
+ if (strcmp(it->name, devname) == 0 ||
+ (endp > startp && it->seq == seq))
+ return it;
+ }
+
+ return NULL;
+}
+
+unsigned char *eth_get_ethaddr(void)
+{
+ struct eth_pdata *pdata;
+
+ if (eth_get_dev()) {
+ pdata = eth_get_dev()->platdata;
+ return pdata->enetaddr;
+ }
+
+ return NULL;
+}
+
+/* Set active state without calling start on the driver */
+int eth_init_state_only(void)
+{
+ struct udevice *current;
+ struct eth_device_priv *priv;
+
+ current = eth_get_dev();
+ if (!current || !device_active(current))
+ return -EINVAL;
+
+ priv = current->uclass_priv;
+ priv->state = ETH_STATE_ACTIVE;
+
+ return 0;
+}
+
+/* Set passive state without calling stop on the driver */
+void eth_halt_state_only(void)
+{
+ struct udevice *current;
+ struct eth_device_priv *priv;
+
+ current = eth_get_dev();
+ if (!current || !device_active(current))
+ return;
+
+ priv = current->uclass_priv;
+ priv->state = ETH_STATE_PASSIVE;
+}
+
+int eth_get_dev_index(void)
+{
+ if (eth_get_dev())
+ return eth_get_dev()->seq;
+ return -1;
+}
+
+int eth_init(void)
+{
+ struct udevice *current;
+ struct udevice *old_current;
+ int ret = -ENODEV;
+
+ current = eth_get_dev();
+ if (!current) {
+ printf("No ethernet found.\n");
+ return -ENODEV;
+ }
+
+ old_current = current;
+ do {
+ debug("Trying %s\n", current->name);
+
+ if (device_active(current)) {
+ uchar env_enetaddr[6];
+ struct eth_pdata *pdata = current->platdata;
+
+ /* Sync environment with network device */
+ if (eth_getenv_enetaddr_by_index("eth", current->seq,
+ env_enetaddr))
+ memcpy(pdata->enetaddr, env_enetaddr, 6);
+ else
+ memset(pdata->enetaddr, 0, 6);
+
+ ret = eth_get_ops(current)->start(current);
+ if (ret >= 0) {
+ struct eth_device_priv *priv =
+ current->uclass_priv;
+
+ priv->state = ETH_STATE_ACTIVE;
+ return 0;
+ }
+ } else {
+ ret = eth_errno;
+ }
+
+ debug("FAIL\n");
+
+ /*
+ * If ethrotate is enabled, this will change "current",
+ * otherwise we will drop out of this while loop immediately
+ */
+ eth_try_another(0);
+ /* This will ensure the new "current" attempted to probe */
+ current = eth_get_dev();
+ } while (old_current != current);
+
+ return ret;
+}
+
+void eth_halt(void)
+{
+ struct udevice *current;
+ struct eth_device_priv *priv;
+
+ current = eth_get_dev();
+ if (!current || !device_active(current))
+ return;
+
+ eth_get_ops(current)->stop(current);
+ priv = current->uclass_priv;
+ priv->state = ETH_STATE_PASSIVE;
+}
+
+int eth_send(void *packet, int length)
+{
+ struct udevice *current;
+ int ret;
+
+ current = eth_get_dev();
+ if (!current)
+ return -ENODEV;
+
+ if (!device_active(current))
+ return -EINVAL;
+
+ ret = eth_get_ops(current)->send(current, packet, length);
+ if (ret < 0) {
+ /* We cannot completely return the error at present */
+ debug("%s: send() returned error %d\n", __func__, ret);
+ }
+ return ret;
+}
+
+int eth_rx(void)
+{
+ struct udevice *current;
+ uchar *packet;
+ int ret;
+ int i;
+
+ current = eth_get_dev();
+ if (!current)
+ return -ENODEV;
+
+ if (!device_active(current))
+ return -EINVAL;
+
+ /* Process up to 32 packets at one time */
+ for (i = 0; i < 32; i++) {
+ ret = eth_get_ops(current)->recv(current, &packet);
+ if (ret > 0)
+ net_process_received_packet(packet, ret);
+ if (ret >= 0 && eth_get_ops(current)->free_pkt)
+ eth_get_ops(current)->free_pkt(current, packet, ret);
+ if (ret <= 0)
+ break;
+ }
+ if (ret == -EAGAIN)
+ ret = 0;
+ if (ret < 0) {
+ /* We cannot completely return the error at present */
+ debug("%s: recv() returned error %d\n", __func__, ret);
+ }
+ return ret;
+}
+
+static int eth_write_hwaddr(struct udevice *dev)
+{
+ struct eth_pdata *pdata = dev->platdata;
+ int ret = 0;
+
+ if (!dev || !device_active(dev))
+ return -EINVAL;
+
+ /* seq is valid since the device is active */
+ if (eth_get_ops(dev)->write_hwaddr && !eth_mac_skip(dev->seq)) {
+ if (!is_valid_ethaddr(pdata->enetaddr)) {
+ printf("\nError: %s address %pM illegal value\n",
+ dev->name, pdata->enetaddr);
+ return -EINVAL;
+ }
+
+ ret = eth_get_ops(dev)->write_hwaddr(dev);
+ if (ret)
+ printf("\nWarning: %s failed to set MAC address\n",
+ dev->name);
+ }
+
+ return ret;
+}
+
+int eth_initialize(void)
+{
+ int num_devices = 0;
+ struct udevice *dev;
+
+ eth_common_init();
+
+ /*
+ * Devices need to write the hwaddr even if not started so that Linux
+ * will have access to the hwaddr that u-boot stored for the device.
+ * This is accomplished by attempting to probe each device and calling
+ * their write_hwaddr() operation.
+ */
+ uclass_first_device(UCLASS_ETH, &dev);
+ if (!dev) {
+ printf("No ethernet found.\n");
+ bootstage_error(BOOTSTAGE_ID_NET_ETH_START);
+ } else {
+ char *ethprime = getenv("ethprime");
+ struct udevice *prime_dev = NULL;
+
+ if (ethprime)
+ prime_dev = eth_get_dev_by_name(ethprime);
+ if (prime_dev) {
+ eth_set_dev(prime_dev);
+ eth_current_changed();
+ } else {
+ eth_set_dev(NULL);
+ }
+
+ bootstage_mark(BOOTSTAGE_ID_NET_ETH_INIT);
+ do {
+ if (num_devices)
+ printf(", ");
+
+ printf("eth%d: %s", dev->seq, dev->name);
+
+ if (ethprime && dev == prime_dev)
+ printf(" [PRIME]");
+
+ eth_write_hwaddr(dev);
+
+ uclass_next_device(&dev);
+ num_devices++;
+ } while (dev);
+
+ putc('\n');
+ }
+
+ return num_devices;
+}
+
+static int eth_post_bind(struct udevice *dev)
+{
+ if (strchr(dev->name, ' ')) {
+ printf("\nError: eth device name \"%s\" has a space!\n",
+ dev->name);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int eth_pre_unbind(struct udevice *dev)
+{
+ /* Don't hang onto a pointer that is going away */
+ if (dev == eth_get_uclass_priv()->current)
+ eth_set_dev(NULL);
+
+ return 0;
+}
+
+static int eth_post_probe(struct udevice *dev)
+{
+ struct eth_device_priv *priv = dev->uclass_priv;
+ struct eth_pdata *pdata = dev->platdata;
+ unsigned char env_enetaddr[6];
+
+ priv->state = ETH_STATE_INIT;
+
+ /* Check if the device has a MAC address in ROM */
+ if (eth_get_ops(dev)->read_rom_hwaddr)
+ eth_get_ops(dev)->read_rom_hwaddr(dev);
+
+ eth_getenv_enetaddr_by_index("eth", dev->seq, env_enetaddr);
+ if (!is_zero_ethaddr(env_enetaddr)) {
+ if (!is_zero_ethaddr(pdata->enetaddr) &&
+ memcmp(pdata->enetaddr, env_enetaddr, 6)) {
+ printf("\nWarning: %s MAC addresses don't match:\n",
+ dev->name);
+ printf("Address in SROM is %pM\n",
+ pdata->enetaddr);
+ printf("Address in environment is %pM\n",
+ env_enetaddr);
+ }
+
+ /* Override the ROM MAC address */
+ memcpy(pdata->enetaddr, env_enetaddr, 6);
+ } else if (is_valid_ethaddr(pdata->enetaddr)) {
+ eth_setenv_enetaddr_by_index("eth", dev->seq, pdata->enetaddr);
+ printf("\nWarning: %s using MAC address from ROM\n",
+ dev->name);
+ } else if (is_zero_ethaddr(pdata->enetaddr)) {
+ printf("\nError: %s address not set.\n",
+ dev->name);
+ return -EINVAL;
+ }
+
+ return 0;
+}
+
+static int eth_pre_remove(struct udevice *dev)
+{
+ eth_get_ops(dev)->stop(dev);
+
+ return 0;
+}
+
+UCLASS_DRIVER(eth) = {
+ .name = "eth",
+ .id = UCLASS_ETH,
+ .post_bind = eth_post_bind,
+ .pre_unbind = eth_pre_unbind,
+ .post_probe = eth_post_probe,
+ .pre_remove = eth_pre_remove,
+ .priv_auto_alloc_size = sizeof(struct eth_uclass_priv),
+ .per_device_auto_alloc_size = sizeof(struct eth_device_priv),
+ .flags = DM_UC_FLAG_SEQ_ALIAS,
+};
+#endif
+
+#ifndef CONFIG_DM_ETH
+
#ifdef CONFIG_API
static struct {
uchar data[PKTSIZE];
@@ -87,6 +571,16 @@ static unsigned int eth_rcv_current, eth_rcv_last;
static struct eth_device *eth_devices;
struct eth_device *eth_current;
+static void eth_set_current_to_next(void)
+{
+ eth_current = eth_current->next;
+}
+
+static void eth_set_dev(struct eth_device *dev)
+{
+ eth_current = dev;
+}
+
struct eth_device *eth_get_dev_by_name(const char *devname)
{
struct eth_device *dev, *target_dev;
@@ -137,27 +631,6 @@ int eth_get_dev_index(void)
return eth_current->index;
}
-static void eth_current_changed(void)
-{
- char *act = getenv("ethact");
- /* update current ethernet name */
- if (eth_current) {
- if (act == NULL || strcmp(act, eth_current->name) != 0)
- setenv("ethact", eth_current->name);
- }
- /*
- * remove the variable completely if there is no active
- * interface
- */
- else if (act != NULL)
- setenv("ethact", NULL);
-}
-
-static int eth_address_set(unsigned char *addr)
-{
- return memcmp(addr, "\0\0\0\0\0\0", 6);
-}
-
int eth_write_hwaddr(struct eth_device *dev, const char *base_name,
int eth_number)
{
@@ -166,39 +639,40 @@ int eth_write_hwaddr(struct eth_device *dev, const char *base_name,
eth_getenv_enetaddr_by_index(base_name, eth_number, env_enetaddr);
- if (eth_address_set(env_enetaddr)) {
- if (eth_address_set(dev->enetaddr) &&
- memcmp(dev->enetaddr, env_enetaddr, 6)) {
+ if (!is_zero_ethaddr(env_enetaddr)) {
+ if (!is_zero_ethaddr(dev->enetaddr) &&
+ memcmp(dev->enetaddr, env_enetaddr, 6)) {
printf("\nWarning: %s MAC addresses don't match:\n",
- dev->name);
+ dev->name);
printf("Address in SROM is %pM\n",
- dev->enetaddr);
+ dev->enetaddr);
printf("Address in environment is %pM\n",
- env_enetaddr);
+ env_enetaddr);
}
memcpy(dev->enetaddr, env_enetaddr, 6);
- } else if (is_valid_ether_addr(dev->enetaddr)) {
+ } else if (is_valid_ethaddr(dev->enetaddr)) {
eth_setenv_enetaddr_by_index(base_name, eth_number,
dev->enetaddr);
printf("\nWarning: %s using MAC address from net device\n",
- dev->name);
- } else if (!(eth_address_set(dev->enetaddr))) {
+ dev->name);
+ } else if (is_zero_ethaddr(dev->enetaddr)) {
printf("\nError: %s address not set.\n",
dev->name);
return -EINVAL;
}
if (dev->write_hwaddr && !eth_mac_skip(eth_number)) {
- if (!is_valid_ether_addr(dev->enetaddr)) {
+ if (!is_valid_ethaddr(dev->enetaddr)) {
printf("\nError: %s address %pM illegal value\n",
- dev->name, dev->enetaddr);
+ dev->name, dev->enetaddr);
return -EINVAL;
}
ret = dev->write_hwaddr(dev);
if (ret)
- printf("\nWarning: %s failed to set MAC address\n", dev->name);
+ printf("\nWarning: %s failed to set MAC address\n",
+ dev->name);
}
return ret;
@@ -212,7 +686,8 @@ int eth_register(struct eth_device *dev)
assert(strlen(dev->name) < sizeof(dev->name));
if (!eth_devices) {
- eth_current = eth_devices = dev;
+ eth_devices = dev;
+ eth_current = dev;
eth_current_changed();
} else {
for (d = eth_devices; d->next != eth_devices; d = d->next)
@@ -233,7 +708,7 @@ int eth_unregister(struct eth_device *dev)
/* No device */
if (!eth_devices)
- return -1;
+ return -ENODEV;
for (cur = eth_devices; cur->next != eth_devices && cur->next != dev;
cur = cur->next)
@@ -241,7 +716,7 @@ int eth_unregister(struct eth_device *dev)
/* Device not found */
if (cur->next != dev)
- return -1;
+ return -ENODEV;
cur->next = dev->next;
@@ -256,43 +731,13 @@ int eth_unregister(struct eth_device *dev)
return 0;
}
-static void eth_env_init(bd_t *bis)
-{
- const char *s;
-
- if ((s = getenv("bootfile")) != NULL)
- copy_filename(BootFile, s, sizeof(BootFile));
-}
-
-int eth_initialize(bd_t *bis)
+int eth_initialize(void)
{
int num_devices = 0;
+
eth_devices = NULL;
eth_current = NULL;
-
- bootstage_mark(BOOTSTAGE_ID_NET_ETH_START);
-#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII) || defined(CONFIG_PHYLIB)
- miiphy_init();
-#endif
-
-#ifdef CONFIG_PHYLIB
- phy_init();
-#endif
-
- eth_env_init(bis);
-
- /*
- * If board-specific initialization exists, call it.
- * If not, call a CPU-specific one
- */
- if (board_eth_init != __def_eth_init) {
- if (board_eth_init(bis) < 0)
- printf("Board Net Initialization Failed\n");
- } else if (cpu_eth_init != __def_eth_init) {
- if (cpu_eth_init(bis) < 0)
- printf("CPU Net Initialization Failed\n");
- } else
- printf("Net Initialization Skipped\n");
+ eth_common_init();
if (!eth_devices) {
puts("No ethernet found.\n");
@@ -335,14 +780,14 @@ int eth_initialize(bd_t *bis)
* mcast_addr: multicast ipaddr from which multicast Mac is made
* join: 1=join, 0=leave.
*/
-int eth_mcast_join(IPaddr_t mcast_ip, u8 join)
+int eth_mcast_join(struct in_addr mcast_ip, int join)
{
u8 mcast_mac[6];
if (!eth_current || !eth_current->mcast)
return -1;
- mcast_mac[5] = htonl(mcast_ip) & 0xff;
- mcast_mac[4] = (htonl(mcast_ip)>>8) & 0xff;
- mcast_mac[3] = (htonl(mcast_ip)>>16) & 0x7f;
+ mcast_mac[5] = htonl(mcast_ip.s_addr) & 0xff;
+ mcast_mac[4] = (htonl(mcast_ip.s_addr)>>8) & 0xff;
+ mcast_mac[3] = (htonl(mcast_ip.s_addr)>>16) & 0x7f;
mcast_mac[2] = 0x5e;
mcast_mac[1] = 0x0;
mcast_mac[0] = 0x1;
@@ -376,13 +821,13 @@ u32 ether_crc(size_t len, unsigned char const *p)
#endif
-int eth_init(bd_t *bis)
+int eth_init(void)
{
struct eth_device *old_current, *dev;
if (!eth_current) {
puts("No ethernet found.\n");
- return -1;
+ return -ENODEV;
}
/* Sync environment with network devices */
@@ -401,7 +846,7 @@ int eth_init(bd_t *bis)
do {
debug("Trying %s\n", eth_current->name);
- if (eth_current->init(eth_current, bis) >= 0) {
+ if (eth_current->init(eth_current, gd->bd) >= 0) {
eth_current->state = ETH_STATE_ACTIVE;
return 0;
@@ -411,7 +856,7 @@ int eth_init(bd_t *bis)
eth_try_another(0);
} while (old_current != eth_current);
- return -1;
+ return -ETIMEDOUT;
}
void eth_halt(void)
@@ -427,7 +872,7 @@ void eth_halt(void)
int eth_send(void *packet, int length)
{
if (!eth_current)
- return -1;
+ return -ENODEV;
return eth_current->send(eth_current, packet, length);
}
@@ -435,10 +880,11 @@ int eth_send(void *packet, int length)
int eth_rx(void)
{
if (!eth_current)
- return -1;
+ return -ENODEV;
return eth_current->recv(eth_current);
}
+#endif /* ifndef CONFIG_DM_ETH */
#ifdef CONFIG_API
static void eth_save_packet(void *packet, int length)
@@ -484,9 +930,25 @@ int eth_receive(void *packet, int length)
}
#endif /* CONFIG_API */
+static void eth_current_changed(void)
+{
+ char *act = getenv("ethact");
+ /* update current ethernet name */
+ if (eth_get_dev()) {
+ if (act == NULL || strcmp(act, eth_get_name()) != 0)
+ setenv("ethact", eth_get_name());
+ }
+ /*
+ * remove the variable completely if there is no active
+ * interface
+ */
+ else if (act != NULL)
+ setenv("ethact", NULL);
+}
+
void eth_try_another(int first_restart)
{
- static struct eth_device *first_failed;
+ static void *first_failed;
char *ethrotate;
/*
@@ -497,48 +959,50 @@ void eth_try_another(int first_restart)
if ((ethrotate != NULL) && (strcmp(ethrotate, "no") == 0))
return;
- if (!eth_current)
+ if (!eth_get_dev())
return;
if (first_restart)
- first_failed = eth_current;
+ first_failed = eth_get_dev();
- eth_current = eth_current->next;
+ eth_set_current_to_next();
eth_current_changed();
- if (first_failed == eth_current)
- NetRestartWrap = 1;
+ if (first_failed == eth_get_dev())
+ net_restart_wrap = 1;
}
void eth_set_current(void)
{
static char *act;
static int env_changed_id;
- struct eth_device *old_current;
int env_id;
- if (!eth_current) /* XXX no current */
- return;
-
env_id = get_env_id();
if ((act == NULL) || (env_changed_id != env_id)) {
act = getenv("ethact");
env_changed_id = env_id;
}
- if (act != NULL) {
- old_current = eth_current;
- do {
- if (strcmp(eth_current->name, act) == 0)
- return;
- eth_current = eth_current->next;
- } while (old_current != eth_current);
+
+ if (act == NULL) {
+ char *ethprime = getenv("ethprime");
+ void *dev = NULL;
+
+ if (ethprime)
+ dev = eth_get_dev_by_name(ethprime);
+ if (dev)
+ eth_set_dev(dev);
+ else
+ eth_set_dev(NULL);
+ } else {
+ eth_set_dev(eth_get_dev_by_name(act));
}
eth_current_changed();
}
-char *eth_get_name(void)
+const char *eth_get_name(void)
{
- return eth_current ? eth_current->name : "unknown";
+ return eth_get_dev() ? eth_get_dev()->name : "unknown";
}
diff --git a/net/link_local.c b/net/link_local.c
index 4152fae5ba..27851b6b81 100644
--- a/net/link_local.c
+++ b/net/link_local.c
@@ -49,7 +49,7 @@ static enum ll_state_t {
DISABLED
} state = DISABLED;
-static IPaddr_t ip;
+static struct in_addr ip;
static int timeout_ms = -1;
static unsigned deadline_ms;
static unsigned conflicts;
@@ -64,14 +64,16 @@ static void link_local_timeout(void);
* Pick a random link local IP address on 169.254/16, except that
* the first and last 256 addresses are reserved.
*/
-static IPaddr_t pick(void)
+static struct in_addr pick(void)
{
unsigned tmp;
+ struct in_addr ip;
do {
tmp = rand_r(&seed) & IN_CLASSB_HOST;
} while (tmp > (IN_CLASSB_HOST - 0x0200));
- return (IPaddr_t) htonl((LINKLOCAL_ADDR + 0x0100) + tmp);
+ ip.s_addr = htonl((LINKLOCAL_ADDR + 0x0100) + tmp);
+ return ip;
}
/**
@@ -95,23 +97,24 @@ static void configure_wait(void)
deadline_ms = MONOTONIC_MS() + timeout_ms;
debug_cond(DEBUG_DEV_PKT, "...wait %d %s nprobes=%u, nclaims=%u\n",
- timeout_ms, eth_get_name(), nprobes, nclaims);
+ timeout_ms, eth_get_name(), nprobes, nclaims);
- NetSetTimeout(timeout_ms, link_local_timeout);
+ net_set_timeout_handler(timeout_ms, link_local_timeout);
}
void link_local_start(void)
{
- ip = getenv_IPaddr("llipaddr");
- if (ip != 0 && (ntohl(ip) & IN_CLASSB_NET) != LINKLOCAL_ADDR) {
+ ip = getenv_ip("llipaddr");
+ if (ip.s_addr != 0 &&
+ (ntohl(ip.s_addr) & IN_CLASSB_NET) != LINKLOCAL_ADDR) {
puts("invalid link address");
net_set_state(NETLOOP_FAIL);
return;
}
- NetOurSubnetMask = IN_CLASSB_NET;
+ net_netmask.s_addr = IN_CLASSB_NET;
seed = seed_mac();
- if (ip == 0)
+ if (ip.s_addr == 0)
ip = pick();
state = PROBE;
@@ -131,10 +134,12 @@ static void link_local_timeout(void)
/* timeouts in the PROBE state mean no conflicting ARP packets
have been received, so we can progress through the states */
if (nprobes < PROBE_NUM) {
+ struct in_addr zero_ip = {.s_addr = 0};
+
nprobes++;
debug_cond(DEBUG_LL_STATE, "probe/%u %s@%pI4\n",
- nprobes, eth_get_name(), &ip);
- arp_raw_request(0, NetEtherNullAddr, ip);
+ nprobes, eth_get_name(), &ip);
+ arp_raw_request(zero_ip, net_null_ethaddr, ip);
timeout_ms = PROBE_MIN * 1000;
timeout_ms += random_delay_ms(PROBE_MAX - PROBE_MIN);
} else {
@@ -142,8 +147,8 @@ static void link_local_timeout(void)
state = ANNOUNCE;
nclaims = 0;
debug_cond(DEBUG_LL_STATE, "announce/%u %s@%pI4\n",
- nclaims, eth_get_name(), &ip);
- arp_raw_request(ip, NetOurEther, ip);
+ nclaims, eth_get_name(), &ip);
+ arp_raw_request(ip, net_ethaddr, ip);
timeout_ms = ANNOUNCE_INTERVAL * 1000;
}
break;
@@ -154,8 +159,8 @@ static void link_local_timeout(void)
state = ANNOUNCE;
nclaims = 0;
debug_cond(DEBUG_LL_STATE, "announce/%u %s@%pI4\n",
- nclaims, eth_get_name(), &ip);
- arp_raw_request(ip, NetOurEther, ip);
+ nclaims, eth_get_name(), &ip);
+ arp_raw_request(ip, net_ethaddr, ip);
timeout_ms = ANNOUNCE_INTERVAL * 1000;
break;
case ANNOUNCE:
@@ -165,19 +170,19 @@ static void link_local_timeout(void)
if (nclaims < ANNOUNCE_NUM) {
nclaims++;
debug_cond(DEBUG_LL_STATE, "announce/%u %s@%pI4\n",
- nclaims, eth_get_name(), &ip);
- arp_raw_request(ip, NetOurEther, ip);
+ nclaims, eth_get_name(), &ip);
+ arp_raw_request(ip, net_ethaddr, ip);
timeout_ms = ANNOUNCE_INTERVAL * 1000;
} else {
/* Switch to monitor state */
state = MONITOR;
printf("Successfully assigned %pI4\n", &ip);
- NetCopyIP(&NetOurIP, &ip);
+ net_copy_ip(&net_ip, &ip);
ready = 1;
conflicts = 0;
timeout_ms = -1;
/* Never timeout in the monitor state */
- NetSetTimeout(0, NULL);
+ net_set_timeout_handler(0, NULL);
/* NOTE: all other exit paths should deconfig ... */
net_set_state(NETLOOP_SUCCESS);
@@ -206,7 +211,7 @@ void link_local_receive_arp(struct arp_hdr *arp, int len)
{
int source_ip_conflict;
int target_ip_conflict;
- IPaddr_t null_ip = 0;
+ struct in_addr null_ip = {.s_addr = 0};
if (state == DISABLED)
return;
@@ -219,7 +224,7 @@ void link_local_receive_arp(struct arp_hdr *arp, int len)
/* Current time is greater than the expected timeout
time. This should never happen */
debug_cond(DEBUG_LL_STATE,
- "missed an expected timeout\n");
+ "missed an expected timeout\n");
timeout_ms = 0;
} else {
debug_cond(DEBUG_INT_STATE, "adjusting timeout\n");
@@ -234,9 +239,8 @@ void link_local_receive_arp(struct arp_hdr *arp, int len)
* FIXME: links routinely go down;
*/
bb_error_msg("iface %s is down", eth_get_name());
- if (ready) {
+ if (ready)
run(argv, "deconfig", &ip);
- }
return EXIT_FAILURE;
}
continue;
@@ -244,18 +248,17 @@ void link_local_receive_arp(struct arp_hdr *arp, int len)
#endif
debug_cond(DEBUG_INT_STATE, "%s recv arp type=%d, op=%d,\n",
- eth_get_name(), ntohs(arp->ar_pro),
- ntohs(arp->ar_op));
+ eth_get_name(), ntohs(arp->ar_pro),
+ ntohs(arp->ar_op));
debug_cond(DEBUG_INT_STATE, "\tsource=%pM %pI4\n",
- &arp->ar_sha,
- &arp->ar_spa);
+ &arp->ar_sha,
+ &arp->ar_spa);
debug_cond(DEBUG_INT_STATE, "\ttarget=%pM %pI4\n",
- &arp->ar_tha,
- &arp->ar_tpa);
+ &arp->ar_tha,
+ &arp->ar_tpa);
- if (arp->ar_op != htons(ARPOP_REQUEST)
- && arp->ar_op != htons(ARPOP_REPLY)
- ) {
+ if (arp->ar_op != htons(ARPOP_REQUEST) &&
+ arp->ar_op != htons(ARPOP_REPLY)) {
configure_wait();
return;
}
@@ -263,11 +266,9 @@ void link_local_receive_arp(struct arp_hdr *arp, int len)
source_ip_conflict = 0;
target_ip_conflict = 0;
- if (memcmp(&arp->ar_spa, &ip, ARP_PLEN) == 0
- && memcmp(&arp->ar_sha, NetOurEther, ARP_HLEN) != 0
- ) {
+ if (memcmp(&arp->ar_spa, &ip, ARP_PLEN) == 0 &&
+ memcmp(&arp->ar_sha, net_ethaddr, ARP_HLEN) != 0)
source_ip_conflict = 1;
- }
/*
* According to RFC 3927, section 2.2.1:
@@ -279,13 +280,13 @@ void link_local_receive_arp(struct arp_hdr *arp, int len)
if (arp->ar_op == htons(ARPOP_REQUEST) &&
memcmp(&arp->ar_spa, &null_ip, ARP_PLEN) == 0 &&
memcmp(&arp->ar_tpa, &ip, ARP_PLEN) == 0 &&
- memcmp(&arp->ar_sha, NetOurEther, ARP_HLEN) != 0) {
+ memcmp(&arp->ar_sha, net_ethaddr, ARP_HLEN) != 0) {
target_ip_conflict = 1;
}
debug_cond(DEBUG_NET_PKT,
- "state = %d, source ip conflict = %d, target ip conflict = "
- "%d\n", state, source_ip_conflict, target_ip_conflict);
+ "state = %d, source ip conflict = %d, target ip conflict = "
+ "%d\n", state, source_ip_conflict, target_ip_conflict);
switch (state) {
case PROBE:
case ANNOUNCE:
@@ -313,7 +314,7 @@ void link_local_receive_arp(struct arp_hdr *arp, int len)
debug("monitor conflict -- defending\n");
state = DEFEND;
timeout_ms = DEFEND_INTERVAL * 1000;
- arp_raw_request(ip, NetOurEther, ip);
+ arp_raw_request(ip, net_ethaddr, ip);
}
break;
case DEFEND:
@@ -322,7 +323,7 @@ void link_local_receive_arp(struct arp_hdr *arp, int len)
state = PROBE;
debug("defend conflict -- starting over\n");
ready = 0;
- NetOurIP = 0;
+ net_ip.s_addr = 0;
/* restart the whole protocol */
ip = pick();
diff --git a/net/net.c b/net/net.c
index b60ce6242c..a365df0586 100644
--- a/net/net.c
+++ b/net/net.c
@@ -84,6 +84,7 @@
#include <common.h>
#include <command.h>
#include <environment.h>
+#include <errno.h>
#include <net.h>
#if defined(CONFIG_STATUS_LED)
#include <miiphy.h>
@@ -111,82 +112,74 @@ DECLARE_GLOBAL_DATA_PTR;
/** BOOTP EXTENTIONS **/
/* Our subnet mask (0=unknown) */
-IPaddr_t NetOurSubnetMask;
+struct in_addr net_netmask;
/* Our gateways IP address */
-IPaddr_t NetOurGatewayIP;
+struct in_addr net_gateway;
/* Our DNS IP address */
-IPaddr_t NetOurDNSIP;
+struct in_addr net_dns_server;
#if defined(CONFIG_BOOTP_DNS2)
/* Our 2nd DNS IP address */
-IPaddr_t NetOurDNS2IP;
+struct in_addr net_dns_server2;
#endif
-/* Our NIS domain */
-char NetOurNISDomain[32] = {0,};
-/* Our hostname */
-char NetOurHostName[32] = {0,};
-/* Our bootpath */
-char NetOurRootPath[64] = {0,};
-/* Our bootfile size in blocks */
-ushort NetBootFileSize;
#ifdef CONFIG_MCAST_TFTP /* Multicast TFTP */
-IPaddr_t Mcast_addr;
+struct in_addr net_mcast_addr;
#endif
/** END OF BOOTP EXTENTIONS **/
-/* The actual transferred size of the bootfile (in bytes) */
-ulong NetBootFileXferSize;
/* Our ethernet address */
-uchar NetOurEther[6];
+u8 net_ethaddr[6];
/* Boot server enet address */
-uchar NetServerEther[6];
+u8 net_server_ethaddr[6];
/* Our IP addr (0 = unknown) */
-IPaddr_t NetOurIP;
+struct in_addr net_ip;
/* Server IP addr (0 = unknown) */
-IPaddr_t NetServerIP;
+struct in_addr net_server_ip;
/* Current receive packet */
-uchar *NetRxPacket;
+uchar *net_rx_packet;
/* Current rx packet length */
-int NetRxPacketLen;
+int net_rx_packet_len;
/* IP packet ID */
-unsigned NetIPID;
+static unsigned net_ip_id;
/* Ethernet bcast address */
-uchar NetBcastAddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
-uchar NetEtherNullAddr[6];
+const u8 net_bcast_ethaddr[6] = { 0xff, 0xff, 0xff, 0xff, 0xff, 0xff };
+const u8 net_null_ethaddr[6];
#ifdef CONFIG_API
-void (*push_packet)(void *, int len) = 0;
+void (*push_packet)(void *, int len) = 0;
#endif
/* Network loop state */
enum net_loop_state net_state;
/* Tried all network devices */
-int NetRestartWrap;
+int net_restart_wrap;
/* Network loop restarted */
-static int NetRestarted;
+static int net_restarted;
/* At least one device configured */
-static int NetDevExists;
+static int net_dev_exists;
/* XXX in both little & big endian machines 0xFFFF == ntohs(-1) */
/* default is without VLAN */
-ushort NetOurVLAN = 0xFFFF;
+ushort net_our_vlan = 0xFFFF;
/* ditto */
-ushort NetOurNativeVLAN = 0xFFFF;
+ushort net_native_vlan = 0xFFFF;
/* Boot File name */
-char BootFile[128];
+char net_boot_file_name[128];
+/* The actual transferred size of the bootfile (in bytes) */
+u32 net_boot_file_size;
+/* Boot file size in blocks as reported by the DHCP server */
+u32 net_boot_file_expected_size_in_blocks;
#if defined(CONFIG_CMD_SNTP)
/* NTP server IP address */
-IPaddr_t NetNtpServerIP;
+struct in_addr net_ntp_server;
/* offset time from UTC */
-int NetTimeOffset;
+int net_ntp_time_offset;
#endif
-static uchar PktBuf[(PKTBUFSRX+1) * PKTSIZE_ALIGN + PKTALIGN];
-
-/* Receive packet */
-uchar *NetRxPackets[PKTBUFSRX];
-
+static uchar net_pkt_buf[(PKTBUFSRX+1) * PKTSIZE_ALIGN + PKTALIGN];
+/* Receive packets */
+uchar *net_rx_packets[PKTBUFSRX];
/* Current UDP RX packet handler */
static rxhand_f *udp_packet_handler;
/* Current ARP RX packet handler */
@@ -196,17 +189,17 @@ static rxhand_f *arp_packet_handler;
static rxhand_icmp_f *packet_icmp_handler;
#endif
/* Current timeout handler */
-static thand_f *timeHandler;
+static thand_f *time_handler;
/* Time base value */
-static ulong timeStart;
+static ulong time_start;
/* Current timeout value */
-static ulong timeDelta;
+static ulong time_delta;
/* THE transmit packet */
-uchar *NetTxPacket;
+uchar *net_tx_packet;
static int net_check_prereq(enum proto_t protocol);
-static int NetTryCount;
+static int net_try_count;
int __maybe_unused net_busy_flag;
@@ -218,7 +211,8 @@ static int on_bootfile(const char *name, const char *value, enum env_op op,
switch (op) {
case env_op_create:
case env_op_overwrite:
- copy_filename(BootFile, value, sizeof(BootFile));
+ copy_filename(net_boot_file_name, value,
+ sizeof(net_boot_file_name));
break;
default:
break;
@@ -241,7 +235,7 @@ void net_auto_load(void)
/*
* Use NFS to load the bootfile.
*/
- NfsStart();
+ nfs_start();
return;
}
#endif
@@ -253,29 +247,29 @@ void net_auto_load(void)
net_set_state(NETLOOP_SUCCESS);
return;
}
- TftpStart(TFTPGET);
+ tftp_start(TFTPGET);
}
-static void NetInitLoop(void)
+static void net_init_loop(void)
{
static int env_changed_id;
int env_id = get_env_id();
/* update only when the environment has changed */
if (env_changed_id != env_id) {
- NetOurIP = getenv_IPaddr("ipaddr");
- NetOurGatewayIP = getenv_IPaddr("gatewayip");
- NetOurSubnetMask = getenv_IPaddr("netmask");
- NetServerIP = getenv_IPaddr("serverip");
- NetOurNativeVLAN = getenv_VLAN("nvlan");
- NetOurVLAN = getenv_VLAN("vlan");
+ net_ip = getenv_ip("ipaddr");
+ net_gateway = getenv_ip("gatewayip");
+ net_netmask = getenv_ip("netmask");
+ net_server_ip = getenv_ip("serverip");
+ net_native_vlan = getenv_vlan("nvlan");
+ net_our_vlan = getenv_vlan("vlan");
#if defined(CONFIG_CMD_DNS)
- NetOurDNSIP = getenv_IPaddr("dnsip");
+ net_dns_server = getenv_ip("dnsip");
#endif
env_changed_id = env_id;
}
if (eth_get_dev())
- memcpy(NetOurEther, eth_get_dev()->enetaddr, 6);
+ memcpy(net_ethaddr, eth_get_ethaddr(), 6);
return;
}
@@ -284,7 +278,7 @@ static void net_clear_handlers(void)
{
net_set_udp_handler(NULL);
net_set_arp_handler(NULL);
- NetSetTimeout(0, NULL);
+ net_set_timeout_handler(0, NULL);
}
static void net_cleanup_loop(void)
@@ -302,19 +296,20 @@ void net_init(void)
*/
int i;
- NetTxPacket = &PktBuf[0] + (PKTALIGN - 1);
- NetTxPacket -= (ulong)NetTxPacket % PKTALIGN;
- for (i = 0; i < PKTBUFSRX; i++)
- NetRxPackets[i] = NetTxPacket + (i + 1) * PKTSIZE_ALIGN;
-
- ArpInit();
+ net_tx_packet = &net_pkt_buf[0] + (PKTALIGN - 1);
+ net_tx_packet -= (ulong)net_tx_packet % PKTALIGN;
+ for (i = 0; i < PKTBUFSRX; i++) {
+ net_rx_packets[i] = net_tx_packet +
+ (i + 1) * PKTSIZE_ALIGN;
+ }
+ arp_init();
net_clear_handlers();
/* Only need to setup buffer pointers once. */
first_call = 0;
}
- NetInitLoop();
+ net_init_loop();
}
/**********************************************************************/
@@ -322,28 +317,28 @@ void net_init(void)
* Main network processing loop.
*/
-int NetLoop(enum proto_t protocol)
+int net_loop(enum proto_t protocol)
{
- bd_t *bd = gd->bd;
- int ret = -1;
+ int ret = -EINVAL;
- NetRestarted = 0;
- NetDevExists = 0;
- NetTryCount = 1;
- debug_cond(DEBUG_INT_STATE, "--- NetLoop Entry\n");
+ net_restarted = 0;
+ net_dev_exists = 0;
+ net_try_count = 1;
+ debug_cond(DEBUG_INT_STATE, "--- net_loop Entry\n");
bootstage_mark_name(BOOTSTAGE_ID_ETH_START, "eth_start");
net_init();
if (eth_is_on_demand_init() || protocol != NETCONS) {
eth_halt();
eth_set_current();
- if (eth_init(bd) < 0) {
+ ret = eth_init();
+ if (ret < 0) {
eth_halt();
- return -1;
+ return ret;
}
- } else
- eth_init_state_only(bd);
-
+ } else {
+ eth_init_state_only();
+ }
restart:
#ifdef CONFIG_USB_KEYBOARD
net_busy_flag = 0;
@@ -355,54 +350,54 @@ restart:
* here on, this code is a state machine driven by received
* packets and timer events.
*/
- debug_cond(DEBUG_INT_STATE, "--- NetLoop Init\n");
- NetInitLoop();
+ debug_cond(DEBUG_INT_STATE, "--- net_loop Init\n");
+ net_init_loop();
switch (net_check_prereq(protocol)) {
case 1:
/* network not configured */
eth_halt();
- return -1;
+ return -ENODEV;
case 2:
/* network device not configured */
break;
case 0:
- NetDevExists = 1;
- NetBootFileXferSize = 0;
+ net_dev_exists = 1;
+ net_boot_file_size = 0;
switch (protocol) {
case TFTPGET:
#ifdef CONFIG_CMD_TFTPPUT
case TFTPPUT:
#endif
/* always use ARP to get server ethernet address */
- TftpStart(protocol);
+ tftp_start(protocol);
break;
#ifdef CONFIG_CMD_TFTPSRV
case TFTPSRV:
- TftpStartServer();
+ tftp_start_server();
break;
#endif
#if defined(CONFIG_CMD_DHCP)
case DHCP:
- BootpReset();
- NetOurIP = 0;
- DhcpRequest(); /* Basically same as BOOTP */
+ bootp_reset();
+ net_ip.s_addr = 0;
+ dhcp_request(); /* Basically same as BOOTP */
break;
#endif
case BOOTP:
- BootpReset();
- NetOurIP = 0;
- BootpRequest();
+ bootp_reset();
+ net_ip.s_addr = 0;
+ bootp_request();
break;
#if defined(CONFIG_CMD_RARP)
case RARP:
- RarpTry = 0;
- NetOurIP = 0;
- RarpRequest();
+ rarp_try = 0;
+ net_ip.s_addr = 0;
+ rarp_request();
break;
#endif
#if defined(CONFIG_CMD_PING)
@@ -412,27 +407,27 @@ restart:
#endif
#if defined(CONFIG_CMD_NFS)
case NFS:
- NfsStart();
+ nfs_start();
break;
#endif
#if defined(CONFIG_CMD_CDP)
case CDP:
- CDPStart();
+ cdp_start();
break;
#endif
-#if defined (CONFIG_NETCONSOLE) && !(CONFIG_SPL_BUILD)
+#if defined(CONFIG_NETCONSOLE) && !(CONFIG_SPL_BUILD)
case NETCONS:
- NcStart();
+ nc_start();
break;
#endif
#if defined(CONFIG_CMD_SNTP)
case SNTP:
- SntpStart();
+ sntp_start();
break;
#endif
#if defined(CONFIG_CMD_DNS)
case DNS:
- DnsStart();
+ dns_start();
break;
#endif
#if defined(CONFIG_CMD_LINK_LOCAL)
@@ -476,6 +471,8 @@ restart:
/*
* Check the ethernet for a new packet. The ethernet
* receive routine will process it.
+ * Most drivers return the most recent packet size, but not
+ * errors that may have happened.
*/
eth_rx();
@@ -484,7 +481,7 @@ restart:
*/
if (ctrlc()) {
/* cancel any ARP that may not have completed */
- NetArpWaitPacketIP = 0;
+ net_arp_wait_packet_ip.s_addr = 0;
net_cleanup_loop();
eth_halt();
@@ -494,17 +491,18 @@ restart:
puts("\nAbort\n");
/* include a debug print as well incase the debug
messages are directed to stderr */
- debug_cond(DEBUG_INT_STATE, "--- NetLoop Abort!\n");
+ debug_cond(DEBUG_INT_STATE, "--- net_loop Abort!\n");
goto done;
}
- ArpTimeoutCheck();
+ arp_timeout_check();
/*
* Check for a timeout, and run the timeout handler
* if we have one.
*/
- if (timeHandler && ((get_timer(0) - timeStart) > timeDelta)) {
+ if (time_handler &&
+ ((get_timer(0) - time_start) > time_delta)) {
thand_f *x;
#if defined(CONFIG_MII) || defined(CONFIG_CMD_MII)
@@ -515,33 +513,32 @@ restart:
* Echo the inverted link state to the fault LED.
*/
if (miiphy_link(eth_get_dev()->name,
- CONFIG_SYS_FAULT_MII_ADDR)) {
+ CONFIG_SYS_FAULT_MII_ADDR))
status_led_set(STATUS_LED_RED, STATUS_LED_OFF);
- } else {
+ else
status_led_set(STATUS_LED_RED, STATUS_LED_ON);
- }
#endif /* CONFIG_SYS_FAULT_ECHO_LINK_DOWN, ... */
#endif /* CONFIG_MII, ... */
- debug_cond(DEBUG_INT_STATE, "--- NetLoop timeout\n");
- x = timeHandler;
- timeHandler = (thand_f *)0;
+ debug_cond(DEBUG_INT_STATE, "--- net_loop timeout\n");
+ x = time_handler;
+ time_handler = (thand_f *)0;
(*x)();
}
+ if (net_state == NETLOOP_FAIL)
+ ret = net_start_again();
switch (net_state) {
-
case NETLOOP_RESTART:
- NetRestarted = 1;
+ net_restarted = 1;
goto restart;
case NETLOOP_SUCCESS:
net_cleanup_loop();
- if (NetBootFileXferSize > 0) {
- printf("Bytes transferred = %ld (%lx hex)\n",
- NetBootFileXferSize,
- NetBootFileXferSize);
- setenv_hex("filesize", NetBootFileXferSize);
+ if (net_boot_file_size > 0) {
+ printf("Bytes transferred = %d (%x hex)\n",
+ net_boot_file_size, net_boot_file_size);
+ setenv_hex("filesize", net_boot_file_size);
setenv_hex("fileaddr", load_addr);
}
if (protocol != NETCONS)
@@ -551,15 +548,15 @@ restart:
eth_set_last_protocol(protocol);
- ret = NetBootFileXferSize;
- debug_cond(DEBUG_INT_STATE, "--- NetLoop Success!\n");
+ ret = net_boot_file_size;
+ debug_cond(DEBUG_INT_STATE, "--- net_loop Success!\n");
goto done;
case NETLOOP_FAIL:
net_cleanup_loop();
/* Invalidate the last protocol */
eth_set_last_protocol(BOOTP);
- debug_cond(DEBUG_INT_STATE, "--- NetLoop Fail!\n");
+ debug_cond(DEBUG_INT_STATE, "--- net_loop Fail!\n");
goto done;
case NETLOOP_CONTINUE:
@@ -581,17 +578,17 @@ done:
/**********************************************************************/
-static void
-startAgainTimeout(void)
+static void start_again_timeout_handler(void)
{
net_set_state(NETLOOP_RESTART);
}
-void NetStartAgain(void)
+int net_start_again(void)
{
char *nretry;
int retry_forever = 0;
unsigned long retrycnt = 0;
+ int ret;
nretry = getenv("netretry");
if (nretry) {
@@ -603,26 +600,33 @@ void NetStartAgain(void)
retrycnt = 1;
else
retrycnt = simple_strtoul(nretry, NULL, 0);
- } else
- retry_forever = 1;
+ } else {
+ retrycnt = 0;
+ retry_forever = 0;
+ }
- if ((!retry_forever) && (NetTryCount >= retrycnt)) {
+ if ((!retry_forever) && (net_try_count >= retrycnt)) {
eth_halt();
net_set_state(NETLOOP_FAIL);
- return;
+ /*
+ * We don't provide a way for the protocol to return an error,
+ * but this is almost always the reason.
+ */
+ return -ETIMEDOUT;
}
- NetTryCount++;
+ net_try_count++;
eth_halt();
#if !defined(CONFIG_NET_DO_NOT_TRY_ANOTHER)
- eth_try_another(!NetRestarted);
+ eth_try_another(!net_restarted);
#endif
- eth_init(gd->bd);
- if (NetRestartWrap) {
- NetRestartWrap = 0;
- if (NetDevExists) {
- NetSetTimeout(10000UL, startAgainTimeout);
+ ret = eth_init();
+ if (net_restart_wrap) {
+ net_restart_wrap = 0;
+ if (net_dev_exists) {
+ net_set_timeout_handler(10000UL,
+ start_again_timeout_handler);
net_set_udp_handler(NULL);
} else {
net_set_state(NETLOOP_FAIL);
@@ -630,6 +634,7 @@ void NetStartAgain(void)
} else {
net_set_state(NETLOOP_RESTART);
}
+ return ret;
}
/**********************************************************************/
@@ -638,7 +643,7 @@ void NetStartAgain(void)
*/
static void dummy_handler(uchar *pkt, unsigned dport,
- IPaddr_t sip, unsigned sport,
+ struct in_addr sip, unsigned sport,
unsigned len)
{
}
@@ -650,7 +655,7 @@ rxhand_f *net_get_udp_handler(void)
void net_set_udp_handler(rxhand_f *f)
{
- debug_cond(DEBUG_INT_STATE, "--- NetLoop UDP handler set (%p)\n", f);
+ debug_cond(DEBUG_INT_STATE, "--- net_loop UDP handler set (%p)\n", f);
if (f == NULL)
udp_packet_handler = dummy_handler;
else
@@ -664,7 +669,7 @@ rxhand_f *net_get_arp_handler(void)
void net_set_arp_handler(rxhand_f *f)
{
- debug_cond(DEBUG_INT_STATE, "--- NetLoop ARP handler set (%p)\n", f);
+ debug_cond(DEBUG_INT_STATE, "--- net_loop ARP handler set (%p)\n", f);
if (f == NULL)
arp_packet_handler = dummy_handler;
else
@@ -678,69 +683,68 @@ void net_set_icmp_handler(rxhand_icmp_f *f)
}
#endif
-void
-NetSetTimeout(ulong iv, thand_f *f)
+void net_set_timeout_handler(ulong iv, thand_f *f)
{
if (iv == 0) {
debug_cond(DEBUG_INT_STATE,
- "--- NetLoop timeout handler cancelled\n");
- timeHandler = (thand_f *)0;
+ "--- net_loop timeout handler cancelled\n");
+ time_handler = (thand_f *)0;
} else {
debug_cond(DEBUG_INT_STATE,
- "--- NetLoop timeout handler set (%p)\n", f);
- timeHandler = f;
- timeStart = get_timer(0);
- timeDelta = iv * CONFIG_SYS_HZ / 1000;
+ "--- net_loop timeout handler set (%p)\n", f);
+ time_handler = f;
+ time_start = get_timer(0);
+ time_delta = iv * CONFIG_SYS_HZ / 1000;
}
}
-int NetSendUDPPacket(uchar *ether, IPaddr_t dest, int dport, int sport,
+int net_send_udp_packet(uchar *ether, struct in_addr dest, int dport, int sport,
int payload_len)
{
uchar *pkt;
int eth_hdr_size;
int pkt_hdr_size;
- /* make sure the NetTxPacket is initialized (NetInit() was called) */
- assert(NetTxPacket != NULL);
- if (NetTxPacket == NULL)
+ /* make sure the net_tx_packet is initialized (net_init() was called) */
+ assert(net_tx_packet != NULL);
+ if (net_tx_packet == NULL)
return -1;
/* convert to new style broadcast */
- if (dest == 0)
- dest = 0xFFFFFFFF;
+ if (dest.s_addr == 0)
+ dest.s_addr = 0xFFFFFFFF;
/* if broadcast, make the ether address a broadcast and don't do ARP */
- if (dest == 0xFFFFFFFF)
- ether = NetBcastAddr;
+ if (dest.s_addr == 0xFFFFFFFF)
+ ether = (uchar *)net_bcast_ethaddr;
- pkt = (uchar *)NetTxPacket;
+ pkt = (uchar *)net_tx_packet;
- eth_hdr_size = NetSetEther(pkt, ether, PROT_IP);
+ eth_hdr_size = net_set_ether(pkt, ether, PROT_IP);
pkt += eth_hdr_size;
net_set_udp_header(pkt, dest, dport, sport, payload_len);
pkt_hdr_size = eth_hdr_size + IP_UDP_HDR_SIZE;
/* if MAC address was not discovered yet, do an ARP request */
- if (memcmp(ether, NetEtherNullAddr, 6) == 0) {
+ if (memcmp(ether, net_null_ethaddr, 6) == 0) {
debug_cond(DEBUG_DEV_PKT, "sending ARP for %pI4\n", &dest);
/* save the ip and eth addr for the packet to send after arp */
- NetArpWaitPacketIP = dest;
- NetArpWaitPacketMAC = ether;
+ net_arp_wait_packet_ip = dest;
+ arp_wait_packet_ethaddr = ether;
/* size of the waiting packet */
- NetArpWaitTxPacketSize = pkt_hdr_size + payload_len;
+ arp_wait_tx_packet_size = pkt_hdr_size + payload_len;
/* and do the ARP request */
- NetArpWaitTry = 1;
- NetArpWaitTimerStart = get_timer(0);
- ArpRequest();
+ arp_wait_try = 1;
+ arp_wait_timer_start = get_timer(0);
+ arp_request();
return 1; /* waiting */
} else {
debug_cond(DEBUG_DEV_PKT, "sending UDP to %pI4/%pM\n",
- &dest, ether);
- NetSendPacket(NetTxPacket, pkt_hdr_size + payload_len);
+ &dest, ether);
+ net_send_packet(net_tx_packet, pkt_hdr_size + payload_len);
return 0; /* transmitted */
}
}
@@ -778,7 +782,7 @@ struct hole {
u16 unused;
};
-static struct ip_udp_hdr *__NetDefragment(struct ip_udp_hdr *ip, int *lenp)
+static struct ip_udp_hdr *__net_defragment(struct ip_udp_hdr *ip, int *lenp)
{
static uchar pkt_buff[IP_PKTSIZE] __aligned(PKTALIGN);
static u16 first_hole, total_len;
@@ -898,17 +902,19 @@ static struct ip_udp_hdr *__NetDefragment(struct ip_udp_hdr *ip, int *lenp)
return localip;
}
-static inline struct ip_udp_hdr *NetDefragment(struct ip_udp_hdr *ip, int *lenp)
+static inline struct ip_udp_hdr *net_defragment(struct ip_udp_hdr *ip,
+ int *lenp)
{
u16 ip_off = ntohs(ip->ip_off);
if (!(ip_off & (IP_OFFS | IP_FLAGS_MFRAG)))
return ip; /* not a fragment */
- return __NetDefragment(ip, lenp);
+ return __net_defragment(ip, lenp);
}
#else /* !CONFIG_IP_DEFRAG */
-static inline struct ip_udp_hdr *NetDefragment(struct ip_udp_hdr *ip, int *lenp)
+static inline struct ip_udp_hdr *net_defragment(struct ip_udp_hdr *ip,
+ int *lenp)
{
u16 ip_off = ntohs(ip->ip_off);
if (!(ip_off & (IP_OFFS | IP_FLAGS_MFRAG)))
@@ -924,7 +930,7 @@ static inline struct ip_udp_hdr *NetDefragment(struct ip_udp_hdr *ip, int *lenp)
* @parma ip IP packet containing the ICMP
*/
static void receive_icmp(struct ip_udp_hdr *ip, int len,
- IPaddr_t src_ip, struct ethernet_hdr *et)
+ struct in_addr src_ip, struct ethernet_hdr *et)
{
struct icmp_hdr *icmph = (struct icmp_hdr *)&ip->udp_src;
@@ -933,7 +939,7 @@ static void receive_icmp(struct ip_udp_hdr *ip, int len,
if (icmph->code != ICMP_REDIR_HOST)
return;
printf(" ICMP Host Redirect to %pI4 ",
- &icmph->un.gateway);
+ &icmph->un.gateway);
break;
default:
#if defined(CONFIG_CMD_PING)
@@ -942,20 +948,20 @@ static void receive_icmp(struct ip_udp_hdr *ip, int len,
#ifdef CONFIG_CMD_TFTPPUT
if (packet_icmp_handler)
packet_icmp_handler(icmph->type, icmph->code,
- ntohs(ip->udp_dst), src_ip, ntohs(ip->udp_src),
- icmph->un.data, ntohs(ip->udp_len));
+ ntohs(ip->udp_dst), src_ip,
+ ntohs(ip->udp_src), icmph->un.data,
+ ntohs(ip->udp_len));
#endif
break;
}
}
-void
-NetReceive(uchar *inpkt, int len)
+void net_process_received_packet(uchar *in_packet, int len)
{
struct ethernet_hdr *et;
struct ip_udp_hdr *ip;
- IPaddr_t dst_ip;
- IPaddr_t src_ip;
+ struct in_addr dst_ip;
+ struct in_addr src_ip;
int eth_proto;
#if defined(CONFIG_CMD_CDP)
int iscdp;
@@ -964,9 +970,9 @@ NetReceive(uchar *inpkt, int len)
debug_cond(DEBUG_NET_PKT, "packet received\n");
- NetRxPacket = inpkt;
- NetRxPacketLen = len;
- et = (struct ethernet_hdr *)inpkt;
+ net_rx_packet = in_packet;
+ net_rx_packet_len = len;
+ et = (struct ethernet_hdr *)in_packet;
/* too small packet? */
if (len < ETHER_HDR_SIZE)
@@ -974,7 +980,7 @@ NetReceive(uchar *inpkt, int len)
#ifdef CONFIG_API
if (push_packet) {
- (*push_packet)(inpkt, len);
+ (*push_packet)(in_packet, len);
return;
}
#endif
@@ -984,10 +990,10 @@ NetReceive(uchar *inpkt, int len)
iscdp = is_cdp_packet(et->et_dest);
#endif
- myvlanid = ntohs(NetOurVLAN);
+ myvlanid = ntohs(net_our_vlan);
if (myvlanid == (ushort)-1)
myvlanid = VLAN_NONE;
- mynvlanid = ntohs(NetOurNativeVLAN);
+ mynvlanid = ntohs(net_native_vlan);
if (mynvlanid == (ushort)-1)
mynvlanid = VLAN_NONE;
@@ -1001,11 +1007,11 @@ NetReceive(uchar *inpkt, int len)
*/
eth_proto = ntohs(et802->et_prot);
- ip = (struct ip_udp_hdr *)(inpkt + E802_HDR_SIZE);
+ ip = (struct ip_udp_hdr *)(in_packet + E802_HDR_SIZE);
len -= E802_HDR_SIZE;
} else if (eth_proto != PROT_VLAN) { /* normal packet */
- ip = (struct ip_udp_hdr *)(inpkt + ETHER_HDR_SIZE);
+ ip = (struct ip_udp_hdr *)(in_packet + ETHER_HDR_SIZE);
len -= ETHER_HDR_SIZE;
} else { /* VLAN packet */
@@ -1019,7 +1025,7 @@ NetReceive(uchar *inpkt, int len)
return;
/* if no VLAN active */
- if ((ntohs(NetOurVLAN) & VLAN_IDMASK) == VLAN_NONE
+ if ((ntohs(net_our_vlan) & VLAN_IDMASK) == VLAN_NONE
#if defined(CONFIG_CMD_CDP)
&& iscdp == 0
#endif
@@ -1030,7 +1036,7 @@ NetReceive(uchar *inpkt, int len)
vlanid = cti & VLAN_IDMASK;
eth_proto = ntohs(vet->vet_type);
- ip = (struct ip_udp_hdr *)(inpkt + VLAN_ETHER_HDR_SIZE);
+ ip = (struct ip_udp_hdr *)(in_packet + VLAN_ETHER_HDR_SIZE);
len -= VLAN_ETHER_HDR_SIZE;
}
@@ -1052,9 +1058,8 @@ NetReceive(uchar *inpkt, int len)
}
switch (eth_proto) {
-
case PROT_ARP:
- ArpReceive(et, ip, len);
+ arp_receive(et, ip, len);
break;
#ifdef CONFIG_CMD_RARP
@@ -1067,7 +1072,7 @@ NetReceive(uchar *inpkt, int len)
/* Before we start poking the header, make sure it is there */
if (len < IP_UDP_HDR_SIZE) {
debug("len bad %d < %lu\n", len,
- (ulong)IP_UDP_HDR_SIZE);
+ (ulong)IP_UDP_HDR_SIZE);
return;
}
/* Check the packet length */
@@ -1077,7 +1082,7 @@ NetReceive(uchar *inpkt, int len)
}
len = ntohs(ip->ip_len);
debug_cond(DEBUG_NET_PKT, "len=%d, v=%02x\n",
- len, ip->ip_hl_v & 0xff);
+ len, ip->ip_hl_v & 0xff);
/* Can't deal with anything except IPv4 */
if ((ip->ip_hl_v & 0xf0) != 0x40)
@@ -1091,21 +1096,22 @@ NetReceive(uchar *inpkt, int len)
return;
}
/* If it is not for us, ignore it */
- dst_ip = NetReadIP(&ip->ip_dst);
- if (NetOurIP && dst_ip != NetOurIP && dst_ip != 0xFFFFFFFF) {
+ dst_ip = net_read_ip(&ip->ip_dst);
+ if (net_ip.s_addr && dst_ip.s_addr != net_ip.s_addr &&
+ dst_ip.s_addr != 0xFFFFFFFF) {
#ifdef CONFIG_MCAST_TFTP
- if (Mcast_addr != dst_ip)
+ if (net_mcast_addr != dst_ip)
#endif
return;
}
/* Read source IP address for later use */
- src_ip = NetReadIP(&ip->ip_src);
+ src_ip = net_read_ip(&ip->ip_src);
/*
* The function returns the unchanged packet if it's not
* a fragment, and either the complete packet or NULL if
* it is a fragment (if !CONFIG_IP_DEFRAG, it returns NULL)
*/
- ip = NetDefragment(ip, &len);
+ ip = net_defragment(ip, &len);
if (!ip)
return;
/*
@@ -1137,8 +1143,8 @@ NetReceive(uchar *inpkt, int len)
}
debug_cond(DEBUG_DEV_PKT,
- "received UDP (to=%pI4, from=%pI4, len=%d)\n",
- &dst_ip, &src_ip, len);
+ "received UDP (to=%pI4, from=%pI4, len=%d)\n",
+ &dst_ip, &src_ip, len);
#ifdef CONFIG_UDP_CHECKSUM
if (ip->udp_xsum != 0) {
@@ -1148,13 +1154,13 @@ NetReceive(uchar *inpkt, int len)
xsum = ip->ip_p;
xsum += (ntohs(ip->udp_len));
- xsum += (ntohl(ip->ip_src) >> 16) & 0x0000ffff;
- xsum += (ntohl(ip->ip_src) >> 0) & 0x0000ffff;
- xsum += (ntohl(ip->ip_dst) >> 16) & 0x0000ffff;
- xsum += (ntohl(ip->ip_dst) >> 0) & 0x0000ffff;
+ xsum += (ntohl(ip->ip_src.s_addr) >> 16) & 0x0000ffff;
+ xsum += (ntohl(ip->ip_src.s_addr) >> 0) & 0x0000ffff;
+ xsum += (ntohl(ip->ip_dst.s_addr) >> 16) & 0x0000ffff;
+ xsum += (ntohl(ip->ip_dst.s_addr) >> 0) & 0x0000ffff;
sumlen = ntohs(ip->udp_len);
- sumptr = (ushort *) &(ip->udp_src);
+ sumptr = (ushort *)&(ip->udp_src);
while (sumlen > 1) {
ushort sumdata;
@@ -1166,7 +1172,7 @@ NetReceive(uchar *inpkt, int len)
if (sumlen > 0) {
ushort sumdata;
- sumdata = *(unsigned char *) sumptr;
+ sumdata = *(unsigned char *)sumptr;
sumdata = (sumdata << 8) & 0xff00;
xsum += sumdata;
}
@@ -1176,33 +1182,31 @@ NetReceive(uchar *inpkt, int len)
}
if ((xsum != 0x00000000) && (xsum != 0x0000ffff)) {
printf(" UDP wrong checksum %08lx %08x\n",
- xsum, ntohs(ip->udp_xsum));
+ xsum, ntohs(ip->udp_xsum));
return;
}
}
#endif
-
-#if defined (CONFIG_NETCONSOLE) && !(CONFIG_SPL_BUILD)
+#if defined(CONFIG_NETCONSOLE) && !(CONFIG_SPL_BUILD)
nc_input_packet((uchar *)ip + IP_UDP_HDR_SIZE,
- src_ip,
- ntohs(ip->udp_dst),
- ntohs(ip->udp_src),
- ntohs(ip->udp_len) - UDP_HDR_SIZE);
+ src_ip,
+ ntohs(ip->udp_dst),
+ ntohs(ip->udp_src),
+ ntohs(ip->udp_len) - UDP_HDR_SIZE);
#endif
/*
- * IP header OK. Pass the packet to the current handler.
+ * IP header OK. Pass the packet to the current handler.
*/
(*udp_packet_handler)((uchar *)ip + IP_UDP_HDR_SIZE,
- ntohs(ip->udp_dst),
- src_ip,
- ntohs(ip->udp_src),
- ntohs(ip->udp_len) - UDP_HDR_SIZE);
+ ntohs(ip->udp_dst),
+ src_ip,
+ ntohs(ip->udp_src),
+ ntohs(ip->udp_len) - UDP_HDR_SIZE);
break;
}
}
-
/**********************************************************************/
static int net_check_prereq(enum proto_t protocol)
@@ -1211,7 +1215,7 @@ static int net_check_prereq(enum proto_t protocol)
/* Fall through */
#if defined(CONFIG_CMD_PING)
case PING:
- if (NetPingIP == 0) {
+ if (net_ping_ip.s_addr == 0) {
puts("*** ERROR: ping address not given\n");
return 1;
}
@@ -1219,7 +1223,7 @@ static int net_check_prereq(enum proto_t protocol)
#endif
#if defined(CONFIG_CMD_SNTP)
case SNTP:
- if (NetNtpServerIP == 0) {
+ if (net_ntp_server.s_addr == 0) {
puts("*** ERROR: NTP server address not given\n");
return 1;
}
@@ -1227,7 +1231,7 @@ static int net_check_prereq(enum proto_t protocol)
#endif
#if defined(CONFIG_CMD_DNS)
case DNS:
- if (NetOurDNSIP == 0) {
+ if (net_dns_server.s_addr == 0) {
puts("*** ERROR: DNS server address not given\n");
return 1;
}
@@ -1236,9 +1240,10 @@ static int net_check_prereq(enum proto_t protocol)
#if defined(CONFIG_CMD_NFS)
case NFS:
#endif
+ /* Fall through */
case TFTPGET:
case TFTPPUT:
- if (NetServerIP == 0) {
+ if (net_server_ip.s_addr == 0) {
puts("*** ERROR: `serverip' not set\n");
return 1;
}
@@ -1250,7 +1255,7 @@ common:
case NETCONS:
case TFTPSRV:
- if (NetOurIP == 0) {
+ if (net_ip.s_addr == 0) {
puts("*** ERROR: `ipaddr' not set\n");
return 1;
}
@@ -1263,7 +1268,7 @@ common:
case CDP:
case DHCP:
case LINKLOCAL:
- if (memcmp(NetOurEther, "\0\0\0\0\0\0", 6) == 0) {
+ if (memcmp(net_ethaddr, "\0\0\0\0\0\0", 6) == 0) {
int num = eth_get_dev_index();
switch (num) {
@@ -1275,11 +1280,11 @@ common:
break;
default:
printf("*** ERROR: `eth%daddr' not set\n",
- num);
+ num);
break;
}
- NetStartAgain();
+ net_start_again();
return 2;
}
/* Fall through */
@@ -1291,11 +1296,11 @@ common:
/**********************************************************************/
int
-NetEthHdrSize(void)
+net_eth_hdr_size(void)
{
ushort myvlanid;
- myvlanid = ntohs(NetOurVLAN);
+ myvlanid = ntohs(net_our_vlan);
if (myvlanid == (ushort)-1)
myvlanid = VLAN_NONE;
@@ -1303,18 +1308,17 @@ NetEthHdrSize(void)
VLAN_ETHER_HDR_SIZE;
}
-int
-NetSetEther(uchar *xet, uchar * addr, uint prot)
+int net_set_ether(uchar *xet, const uchar *dest_ethaddr, uint prot)
{
struct ethernet_hdr *et = (struct ethernet_hdr *)xet;
ushort myvlanid;
- myvlanid = ntohs(NetOurVLAN);
+ myvlanid = ntohs(net_our_vlan);
if (myvlanid == (ushort)-1)
myvlanid = VLAN_NONE;
- memcpy(et->et_dest, addr, 6);
- memcpy(et->et_src, NetOurEther, 6);
+ memcpy(et->et_dest, dest_ethaddr, 6);
+ memcpy(et->et_src, net_ethaddr, 6);
if ((myvlanid & VLAN_IDMASK) == VLAN_NONE) {
et->et_protlen = htons(prot);
return ETHER_HDR_SIZE;
@@ -1334,7 +1338,7 @@ int net_update_ether(struct ethernet_hdr *et, uchar *addr, uint prot)
ushort protlen;
memcpy(et->et_dest, addr, 6);
- memcpy(et->et_src, NetOurEther, 6);
+ memcpy(et->et_src, net_ethaddr, 6);
protlen = ntohs(et->et_protlen);
if (protlen == PROT_VLAN) {
struct vlan_ethernet_hdr *vet =
@@ -1352,7 +1356,7 @@ int net_update_ether(struct ethernet_hdr *et, uchar *addr, uint prot)
}
}
-void net_set_ip_header(uchar *pkt, IPaddr_t dest, IPaddr_t source)
+void net_set_ip_header(uchar *pkt, struct in_addr dest, struct in_addr source)
{
struct ip_udp_hdr *ip = (struct ip_udp_hdr *)pkt;
@@ -1363,17 +1367,17 @@ void net_set_ip_header(uchar *pkt, IPaddr_t dest, IPaddr_t source)
ip->ip_hl_v = 0x45;
ip->ip_tos = 0;
ip->ip_len = htons(IP_HDR_SIZE);
- ip->ip_id = htons(NetIPID++);
+ ip->ip_id = htons(net_ip_id++);
ip->ip_off = htons(IP_FLAGS_DFRAG); /* Don't fragment */
ip->ip_ttl = 255;
ip->ip_sum = 0;
/* already in network byte order */
- NetCopyIP((void *)&ip->ip_src, &source);
+ net_copy_ip((void *)&ip->ip_src, &source);
/* already in network byte order */
- NetCopyIP((void *)&ip->ip_dst, &dest);
+ net_copy_ip((void *)&ip->ip_dst, &dest);
}
-void net_set_udp_header(uchar *pkt, IPaddr_t dest, int dport, int sport,
+void net_set_udp_header(uchar *pkt, struct in_addr dest, int dport, int sport,
int len)
{
struct ip_udp_hdr *ip = (struct ip_udp_hdr *)pkt;
@@ -1386,7 +1390,7 @@ void net_set_udp_header(uchar *pkt, IPaddr_t dest, int dport, int sport,
if (len & 1)
pkt[IP_UDP_HDR_SIZE + len] = 0;
- net_set_ip_header(pkt, dest, NetOurIP);
+ net_set_ip_header(pkt, dest, net_ip);
ip->ip_len = htons(IP_UDP_HDR_SIZE + len);
ip->ip_p = IPPROTO_UDP;
ip->ip_sum = compute_ip_checksum(ip, IP_HDR_SIZE);
@@ -1423,17 +1427,18 @@ unsigned int random_port(void)
}
#endif
-void ip_to_string(IPaddr_t x, char *s)
+void ip_to_string(struct in_addr x, char *s)
{
- x = ntohl(x);
+ x.s_addr = ntohl(x.s_addr);
sprintf(s, "%d.%d.%d.%d",
- (int) ((x >> 24) & 0xff),
- (int) ((x >> 16) & 0xff),
- (int) ((x >> 8) & 0xff), (int) ((x >> 0) & 0xff)
+ (int) ((x.s_addr >> 24) & 0xff),
+ (int) ((x.s_addr >> 16) & 0xff),
+ (int) ((x.s_addr >> 8) & 0xff),
+ (int) ((x.s_addr >> 0) & 0xff)
);
}
-void VLAN_to_string(ushort x, char *s)
+void vlan_to_string(ushort x, char *s)
{
x = ntohs(x);
@@ -1446,7 +1451,7 @@ void VLAN_to_string(ushort x, char *s)
sprintf(s, "%d", x & VLAN_IDMASK);
}
-ushort string_to_VLAN(const char *s)
+ushort string_to_vlan(const char *s)
{
ushort id;
@@ -1461,7 +1466,7 @@ ushort string_to_VLAN(const char *s)
return htons(id);
}
-ushort getenv_VLAN(char *var)
+ushort getenv_vlan(char *var)
{
- return string_to_VLAN(getenv(var));
+ return string_to_vlan(getenv(var));
}
diff --git a/net/nfs.c b/net/nfs.c
index 381b75f1c5..78968d82e9 100644
--- a/net/nfs.c
+++ b/net/nfs.c
@@ -26,6 +26,7 @@
#include <command.h>
#include <net.h>
#include <malloc.h>
+#include <mapmem.h>
#include "nfs.h"
#include "bootp.h"
@@ -50,12 +51,12 @@ static char dirfh[NFS_FHSIZE]; /* file handle of directory */
static char filefh[NFS_FHSIZE]; /* file handle of kernel image */
static enum net_loop_state nfs_download_state;
-static IPaddr_t NfsServerIP;
-static int NfsSrvMountPort;
-static int NfsSrvNfsPort;
-static int NfsOurPort;
-static int NfsTimeoutCount;
-static int NfsState;
+static struct in_addr nfs_server_ip;
+static int nfs_server_mount_port;
+static int nfs_server_port;
+static int nfs_our_port;
+static int nfs_timeout_count;
+static int nfs_state;
#define STATE_PRCLOOKUP_PROG_MOUNT_REQ 1
#define STATE_PRCLOOKUP_PROG_NFS_REQ 2
#define STATE_MOUNT_REQ 3
@@ -69,8 +70,7 @@ static char *nfs_filename;
static char *nfs_path;
static char nfs_path_buff[2048];
-static inline int
-store_block(uchar *src, unsigned offset, unsigned len)
+static inline int store_block(uchar *src, unsigned offset, unsigned len)
{
ulong newsize = offset + len;
#ifdef CONFIG_SYS_DIRECT_FLASH_NFS
@@ -93,16 +93,18 @@ store_block(uchar *src, unsigned offset, unsigned len)
} else
#endif /* CONFIG_SYS_DIRECT_FLASH_NFS */
{
- (void)memcpy((void *)(load_addr + offset), src, len);
+ void *ptr = map_sysmem(load_addr + offset, len);
+
+ memcpy(ptr, src, len);
+ unmap_sysmem(ptr);
}
- if (NetBootFileXferSize < (offset+len))
- NetBootFileXferSize = newsize;
+ if (net_boot_file_size < (offset + len))
+ net_boot_file_size = newsize;
return 0;
}
-static char*
-basename(char *path)
+static char *basename(char *path)
{
char *fname;
@@ -117,8 +119,7 @@ basename(char *path)
return fname;
}
-static char*
-dirname(char *path)
+static char *dirname(char *path)
{
char *fname;
@@ -174,8 +175,7 @@ static long *rpc_add_credentials(long *p)
/**************************************************************************
RPC_LOOKUP - Lookup RPC Port numbers
**************************************************************************/
-static void
-rpc_req(int rpc_prog, int rpc_proc, uint32_t *data, int datalen)
+static void rpc_req(int rpc_prog, int rpc_proc, uint32_t *data, int datalen)
{
struct rpc_t pkt;
unsigned long id;
@@ -197,25 +197,24 @@ rpc_req(int rpc_prog, int rpc_proc, uint32_t *data, int datalen)
pktlen = (char *)p + datalen*sizeof(uint32_t) - (char *)&pkt;
- memcpy((char *)NetTxPacket + NetEthHdrSize() + IP_UDP_HDR_SIZE,
- (char *)&pkt, pktlen);
+ memcpy((char *)net_tx_packet + net_eth_hdr_size() + IP_UDP_HDR_SIZE,
+ (char *)&pkt, pktlen);
if (rpc_prog == PROG_PORTMAP)
sport = SUNRPC_PORT;
else if (rpc_prog == PROG_MOUNT)
- sport = NfsSrvMountPort;
+ sport = nfs_server_mount_port;
else
- sport = NfsSrvNfsPort;
+ sport = nfs_server_port;
- NetSendUDPPacket(NetServerEther, NfsServerIP, sport, NfsOurPort,
- pktlen);
+ net_send_udp_packet(net_server_ethaddr, nfs_server_ip, sport,
+ nfs_our_port, pktlen);
}
/**************************************************************************
RPC_LOOKUP - Lookup RPC Port numbers
**************************************************************************/
-static void
-rpc_lookup_req(int prog, int ver)
+static void rpc_lookup_req(int prog, int ver)
{
uint32_t data[16];
@@ -232,8 +231,7 @@ rpc_lookup_req(int prog, int ver)
/**************************************************************************
NFS_MOUNT - Mount an NFS Filesystem
**************************************************************************/
-static void
-nfs_mount_req(char *path)
+static void nfs_mount_req(char *path)
{
uint32_t data[1024];
uint32_t *p;
@@ -259,14 +257,13 @@ nfs_mount_req(char *path)
/**************************************************************************
NFS_UMOUNTALL - Unmount all our NFS Filesystems on the Server
**************************************************************************/
-static void
-nfs_umountall_req(void)
+static void nfs_umountall_req(void)
{
uint32_t data[1024];
uint32_t *p;
int len;
- if ((NfsSrvMountPort == -1) || (!fs_mounted))
+ if ((nfs_server_mount_port == -1) || (!fs_mounted))
/* Nothing mounted, nothing to umount */
return;
@@ -285,8 +282,7 @@ nfs_umountall_req(void)
* In case of successful readlink(), the dirname is manipulated,
* so that inside the nfs() function a recursion can be done.
**************************************************************************/
-static void
-nfs_readlink_req(void)
+static void nfs_readlink_req(void)
{
uint32_t data[1024];
uint32_t *p;
@@ -306,8 +302,7 @@ nfs_readlink_req(void)
/**************************************************************************
NFS_LOOKUP - Lookup Pathname
**************************************************************************/
-static void
-nfs_lookup_req(char *fname)
+static void nfs_lookup_req(char *fname)
{
uint32_t data[1024];
uint32_t *p;
@@ -335,8 +330,7 @@ nfs_lookup_req(char *fname)
/**************************************************************************
NFS_READ - Read File on NFS Server
**************************************************************************/
-static void
-nfs_read_req(int offset, int readlen)
+static void nfs_read_req(int offset, int readlen)
{
uint32_t data[1024];
uint32_t *p;
@@ -359,13 +353,11 @@ nfs_read_req(int offset, int readlen)
/**************************************************************************
RPC request dispatcher
**************************************************************************/
-
-static void
-NfsSend(void)
+static void nfs_send(void)
{
debug("%s\n", __func__);
- switch (NfsState) {
+ switch (nfs_state) {
case STATE_PRCLOOKUP_PROG_MOUNT_REQ:
rpc_lookup_req(PROG_MOUNT, 1);
break;
@@ -394,8 +386,7 @@ NfsSend(void)
Handlers for the reply from server
**************************************************************************/
-static int
-rpc_lookup_reply(int prog, uchar *pkt, unsigned len)
+static int rpc_lookup_reply(int prog, uchar *pkt, unsigned len)
{
struct rpc_t rpc_pkt;
@@ -415,18 +406,17 @@ rpc_lookup_reply(int prog, uchar *pkt, unsigned len)
switch (prog) {
case PROG_MOUNT:
- NfsSrvMountPort = ntohl(rpc_pkt.u.reply.data[0]);
+ nfs_server_mount_port = ntohl(rpc_pkt.u.reply.data[0]);
break;
case PROG_NFS:
- NfsSrvNfsPort = ntohl(rpc_pkt.u.reply.data[0]);
+ nfs_server_port = ntohl(rpc_pkt.u.reply.data[0]);
break;
}
return 0;
}
-static int
-nfs_mount_reply(uchar *pkt, unsigned len)
+static int nfs_mount_reply(uchar *pkt, unsigned len)
{
struct rpc_t rpc_pkt;
@@ -451,8 +441,7 @@ nfs_mount_reply(uchar *pkt, unsigned len)
return 0;
}
-static int
-nfs_umountall_reply(uchar *pkt, unsigned len)
+static int nfs_umountall_reply(uchar *pkt, unsigned len)
{
struct rpc_t rpc_pkt;
@@ -476,8 +465,7 @@ nfs_umountall_reply(uchar *pkt, unsigned len)
return 0;
}
-static int
-nfs_lookup_reply(uchar *pkt, unsigned len)
+static int nfs_lookup_reply(uchar *pkt, unsigned len)
{
struct rpc_t rpc_pkt;
@@ -501,8 +489,7 @@ nfs_lookup_reply(uchar *pkt, unsigned len)
return 0;
}
-static int
-nfs_readlink_reply(uchar *pkt, unsigned len)
+static int nfs_readlink_reply(uchar *pkt, unsigned len)
{
struct rpc_t rpc_pkt;
int rlen;
@@ -529,7 +516,7 @@ nfs_readlink_reply(uchar *pkt, unsigned len)
strcat(nfs_path, "/");
pathlen = strlen(nfs_path);
memcpy(nfs_path + pathlen, (uchar *)&(rpc_pkt.u.reply.data[2]),
- rlen);
+ rlen);
nfs_path[pathlen + rlen] = 0;
} else {
memcpy(nfs_path, (uchar *)&(rpc_pkt.u.reply.data[2]), rlen);
@@ -538,8 +525,7 @@ nfs_readlink_reply(uchar *pkt, unsigned len)
return 0;
}
-static int
-nfs_read_reply(uchar *pkt, unsigned len)
+static int nfs_read_reply(uchar *pkt, unsigned len)
{
struct rpc_t rpc_pkt;
int rlen;
@@ -581,67 +567,66 @@ nfs_read_reply(uchar *pkt, unsigned len)
/**************************************************************************
Interfaces of U-BOOT
**************************************************************************/
-
-static void
-NfsTimeout(void)
+static void nfs_timeout_handler(void)
{
- if (++NfsTimeoutCount > NFS_RETRY_COUNT) {
+ if (++nfs_timeout_count > NFS_RETRY_COUNT) {
puts("\nRetry count exceeded; starting again\n");
- NetStartAgain();
+ net_start_again();
} else {
puts("T ");
- NetSetTimeout(nfs_timeout + NFS_TIMEOUT * NfsTimeoutCount,
- NfsTimeout);
- NfsSend();
+ net_set_timeout_handler(nfs_timeout +
+ NFS_TIMEOUT * nfs_timeout_count,
+ nfs_timeout_handler);
+ nfs_send();
}
}
-static void
-NfsHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, unsigned len)
+static void nfs_handler(uchar *pkt, unsigned dest, struct in_addr sip,
+ unsigned src, unsigned len)
{
int rlen;
int reply;
debug("%s\n", __func__);
- if (dest != NfsOurPort)
+ if (dest != nfs_our_port)
return;
- switch (NfsState) {
+ switch (nfs_state) {
case STATE_PRCLOOKUP_PROG_MOUNT_REQ:
if (rpc_lookup_reply(PROG_MOUNT, pkt, len) == -NFS_RPC_DROP)
break;
- NfsState = STATE_PRCLOOKUP_PROG_NFS_REQ;
- NfsSend();
+ nfs_state = STATE_PRCLOOKUP_PROG_NFS_REQ;
+ nfs_send();
break;
case STATE_PRCLOOKUP_PROG_NFS_REQ:
if (rpc_lookup_reply(PROG_NFS, pkt, len) == -NFS_RPC_DROP)
break;
- NfsState = STATE_MOUNT_REQ;
- NfsSend();
+ nfs_state = STATE_MOUNT_REQ;
+ nfs_send();
break;
case STATE_MOUNT_REQ:
reply = nfs_mount_reply(pkt, len);
- if (reply == -NFS_RPC_DROP)
+ if (reply == -NFS_RPC_DROP) {
break;
- else if (reply == -NFS_RPC_ERR) {
+ } else if (reply == -NFS_RPC_ERR) {
puts("*** ERROR: Cannot mount\n");
/* just to be sure... */
- NfsState = STATE_UMOUNT_REQ;
- NfsSend();
+ nfs_state = STATE_UMOUNT_REQ;
+ nfs_send();
} else {
- NfsState = STATE_LOOKUP_REQ;
- NfsSend();
+ nfs_state = STATE_LOOKUP_REQ;
+ nfs_send();
}
break;
case STATE_UMOUNT_REQ:
reply = nfs_umountall_reply(pkt, len);
- if (reply == -NFS_RPC_DROP)
+ if (reply == -NFS_RPC_DROP) {
break;
- else if (reply == -NFS_RPC_ERR) {
+ } else if (reply == -NFS_RPC_ERR) {
puts("*** ERROR: Cannot umount\n");
net_set_state(NETLOOP_FAIL);
} else {
@@ -652,66 +637,65 @@ NfsHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src, unsigned len)
case STATE_LOOKUP_REQ:
reply = nfs_lookup_reply(pkt, len);
- if (reply == -NFS_RPC_DROP)
+ if (reply == -NFS_RPC_DROP) {
break;
- else if (reply == -NFS_RPC_ERR) {
+ } else if (reply == -NFS_RPC_ERR) {
puts("*** ERROR: File lookup fail\n");
- NfsState = STATE_UMOUNT_REQ;
- NfsSend();
+ nfs_state = STATE_UMOUNT_REQ;
+ nfs_send();
} else {
- NfsState = STATE_READ_REQ;
+ nfs_state = STATE_READ_REQ;
nfs_offset = 0;
nfs_len = NFS_READ_SIZE;
- NfsSend();
+ nfs_send();
}
break;
case STATE_READLINK_REQ:
reply = nfs_readlink_reply(pkt, len);
- if (reply == -NFS_RPC_DROP)
+ if (reply == -NFS_RPC_DROP) {
break;
- else if (reply == -NFS_RPC_ERR) {
+ } else if (reply == -NFS_RPC_ERR) {
puts("*** ERROR: Symlink fail\n");
- NfsState = STATE_UMOUNT_REQ;
- NfsSend();
+ nfs_state = STATE_UMOUNT_REQ;
+ nfs_send();
} else {
debug("Symlink --> %s\n", nfs_path);
nfs_filename = basename(nfs_path);
nfs_path = dirname(nfs_path);
- NfsState = STATE_MOUNT_REQ;
- NfsSend();
+ nfs_state = STATE_MOUNT_REQ;
+ nfs_send();
}
break;
case STATE_READ_REQ:
rlen = nfs_read_reply(pkt, len);
- NetSetTimeout(nfs_timeout, NfsTimeout);
+ net_set_timeout_handler(nfs_timeout, nfs_timeout_handler);
if (rlen > 0) {
nfs_offset += rlen;
- NfsSend();
+ nfs_send();
} else if ((rlen == -NFSERR_ISDIR) || (rlen == -NFSERR_INVAL)) {
/* symbolic link */
- NfsState = STATE_READLINK_REQ;
- NfsSend();
+ nfs_state = STATE_READLINK_REQ;
+ nfs_send();
} else {
if (!rlen)
nfs_download_state = NETLOOP_SUCCESS;
- NfsState = STATE_UMOUNT_REQ;
- NfsSend();
+ nfs_state = STATE_UMOUNT_REQ;
+ nfs_send();
}
break;
}
}
-void
-NfsStart(void)
+void nfs_start(void)
{
debug("%s\n", __func__);
nfs_download_state = NETLOOP_FAIL;
- NfsServerIP = NetServerIP;
+ nfs_server_ip = net_server_ip;
nfs_path = (char *)nfs_path_buff;
if (nfs_path == NULL) {
@@ -720,27 +704,27 @@ NfsStart(void)
return;
}
- if (BootFile[0] == '\0') {
+ if (net_boot_file_name[0] == '\0') {
sprintf(default_filename, "/nfsroot/%02X%02X%02X%02X.img",
- NetOurIP & 0xFF,
- (NetOurIP >> 8) & 0xFF,
- (NetOurIP >> 16) & 0xFF,
- (NetOurIP >> 24) & 0xFF);
+ net_ip.s_addr & 0xFF,
+ (net_ip.s_addr >> 8) & 0xFF,
+ (net_ip.s_addr >> 16) & 0xFF,
+ (net_ip.s_addr >> 24) & 0xFF);
strcpy(nfs_path, default_filename);
printf("*** Warning: no boot file name; using '%s'\n",
- nfs_path);
+ nfs_path);
} else {
- char *p = BootFile;
+ char *p = net_boot_file_name;
p = strchr(p, ':');
if (p != NULL) {
- NfsServerIP = string_to_ip(BootFile);
+ nfs_server_ip = string_to_ip(net_boot_file_name);
++p;
strcpy(nfs_path, p);
} else {
- strcpy(nfs_path, BootFile);
+ strcpy(nfs_path, net_boot_file_name);
}
}
@@ -749,39 +733,42 @@ NfsStart(void)
printf("Using %s device\n", eth_get_name());
- printf("File transfer via NFS from server %pI4"
- "; our IP address is %pI4", &NfsServerIP, &NetOurIP);
+ printf("File transfer via NFS from server %pI4; our IP address is %pI4",
+ &nfs_server_ip, &net_ip);
/* Check if we need to send across this subnet */
- if (NetOurGatewayIP && NetOurSubnetMask) {
- IPaddr_t OurNet = NetOurIP & NetOurSubnetMask;
- IPaddr_t ServerNet = NetServerIP & NetOurSubnetMask;
+ if (net_gateway.s_addr && net_netmask.s_addr) {
+ struct in_addr our_net;
+ struct in_addr server_net;
- if (OurNet != ServerNet)
+ our_net.s_addr = net_ip.s_addr & net_netmask.s_addr;
+ server_net.s_addr = net_server_ip.s_addr & net_netmask.s_addr;
+ if (our_net.s_addr != server_net.s_addr)
printf("; sending through gateway %pI4",
- &NetOurGatewayIP);
+ &net_gateway);
}
printf("\nFilename '%s/%s'.", nfs_path, nfs_filename);
- if (NetBootFileSize) {
- printf(" Size is 0x%x Bytes = ", NetBootFileSize<<9);
- print_size(NetBootFileSize<<9, "");
+ if (net_boot_file_expected_size_in_blocks) {
+ printf(" Size is 0x%x Bytes = ",
+ net_boot_file_expected_size_in_blocks << 9);
+ print_size(net_boot_file_expected_size_in_blocks << 9, "");
}
printf("\nLoad address: 0x%lx\n"
"Loading: *\b", load_addr);
- NetSetTimeout(nfs_timeout, NfsTimeout);
- net_set_udp_handler(NfsHandler);
+ net_set_timeout_handler(nfs_timeout, nfs_timeout_handler);
+ net_set_udp_handler(nfs_handler);
- NfsTimeoutCount = 0;
- NfsState = STATE_PRCLOOKUP_PROG_MOUNT_REQ;
+ nfs_timeout_count = 0;
+ nfs_state = STATE_PRCLOOKUP_PROG_MOUNT_REQ;
- /*NfsOurPort = 4096 + (get_ticks() % 3072);*/
+ /*nfs_our_port = 4096 + (get_ticks() % 3072);*/
/*FIX ME !!!*/
- NfsOurPort = 1000;
+ nfs_our_port = 1000;
/* zero out server ether in case the server ip has changed */
- memset(NetServerEther, 0, 6);
+ memset(net_server_ethaddr, 0, 6);
- NfsSend();
+ nfs_send();
}
diff --git a/net/nfs.h b/net/nfs.h
index 53451dbd17..d69b422f52 100644
--- a/net/nfs.h
+++ b/net/nfs.h
@@ -69,7 +69,7 @@ struct rpc_t {
} reply;
} u;
};
-extern void NfsStart(void); /* Begin NFS */
+void nfs_start(void); /* Begin NFS */
/**********************************************************************/
diff --git a/net/ping.c b/net/ping.c
index 366f51825f..9508cf1160 100644
--- a/net/ping.c
+++ b/net/ping.c
@@ -12,12 +12,12 @@
#include "ping.h"
#include "arp.h"
-static ushort PingSeqNo;
+static ushort ping_seq_number;
/* The ip address to ping */
-IPaddr_t NetPingIP;
+struct in_addr net_ping_ip;
-static void set_icmp_header(uchar *pkt, IPaddr_t dest)
+static void set_icmp_header(uchar *pkt, struct in_addr dest)
{
/*
* Construct an IP and ICMP header.
@@ -25,7 +25,7 @@ static void set_icmp_header(uchar *pkt, IPaddr_t dest)
struct ip_hdr *ip = (struct ip_hdr *)pkt;
struct icmp_hdr *icmp = (struct icmp_hdr *)(pkt + IP_HDR_SIZE);
- net_set_ip_header(pkt, dest, NetOurIP);
+ net_set_ip_header(pkt, dest, net_ip);
ip->ip_len = htons(IP_ICMP_HDR_SIZE);
ip->ip_p = IPPROTO_ICMP;
@@ -35,7 +35,7 @@ static void set_icmp_header(uchar *pkt, IPaddr_t dest)
icmp->code = 0;
icmp->checksum = 0;
icmp->un.echo.id = 0;
- icmp->un.echo.sequence = htons(PingSeqNo++);
+ icmp->un.echo.sequence = htons(ping_seq_number++);
icmp->checksum = compute_ip_checksum(icmp, ICMP_HDR_SIZE);
}
@@ -46,26 +46,26 @@ static int ping_send(void)
/* XXX always send arp request */
- debug_cond(DEBUG_DEV_PKT, "sending ARP for %pI4\n", &NetPingIP);
+ debug_cond(DEBUG_DEV_PKT, "sending ARP for %pI4\n", &net_ping_ip);
- NetArpWaitPacketIP = NetPingIP;
+ net_arp_wait_packet_ip = net_ping_ip;
- eth_hdr_size = NetSetEther(NetTxPacket, NetEtherNullAddr, PROT_IP);
- pkt = (uchar *)NetTxPacket + eth_hdr_size;
+ eth_hdr_size = net_set_ether(net_tx_packet, net_null_ethaddr, PROT_IP);
+ pkt = (uchar *)net_tx_packet + eth_hdr_size;
- set_icmp_header(pkt, NetPingIP);
+ set_icmp_header(pkt, net_ping_ip);
/* size of the waiting packet */
- NetArpWaitTxPacketSize = eth_hdr_size + IP_ICMP_HDR_SIZE;
+ arp_wait_tx_packet_size = eth_hdr_size + IP_ICMP_HDR_SIZE;
/* and do the ARP request */
- NetArpWaitTry = 1;
- NetArpWaitTimerStart = get_timer(0);
- ArpRequest();
+ arp_wait_try = 1;
+ arp_wait_timer_start = get_timer(0);
+ arp_request();
return 1; /* waiting */
}
-static void ping_timeout(void)
+static void ping_timeout_handler(void)
{
eth_halt();
net_set_state(NETLOOP_FAIL); /* we did not get the reply */
@@ -74,7 +74,7 @@ static void ping_timeout(void)
void ping_start(void)
{
printf("Using %s device\n", eth_get_name());
- NetSetTimeout(10000UL, ping_timeout);
+ net_set_timeout_handler(10000UL, ping_timeout_handler);
ping_send();
}
@@ -82,31 +82,32 @@ void ping_start(void)
void ping_receive(struct ethernet_hdr *et, struct ip_udp_hdr *ip, int len)
{
struct icmp_hdr *icmph = (struct icmp_hdr *)&ip->udp_src;
- IPaddr_t src_ip;
+ struct in_addr src_ip;
int eth_hdr_size;
switch (icmph->type) {
case ICMP_ECHO_REPLY:
- src_ip = NetReadIP((void *)&ip->ip_src);
- if (src_ip == NetPingIP)
+ src_ip = net_read_ip((void *)&ip->ip_src);
+ if (src_ip.s_addr == net_ping_ip.s_addr)
net_set_state(NETLOOP_SUCCESS);
return;
case ICMP_ECHO_REQUEST:
eth_hdr_size = net_update_ether(et, et->et_src, PROT_IP);
- debug_cond(DEBUG_DEV_PKT, "Got ICMP ECHO REQUEST, return "
- "%d bytes\n", eth_hdr_size + len);
+ debug_cond(DEBUG_DEV_PKT,
+ "Got ICMP ECHO REQUEST, return %d bytes\n",
+ eth_hdr_size + len);
ip->ip_sum = 0;
ip->ip_off = 0;
- NetCopyIP((void *)&ip->ip_dst, &ip->ip_src);
- NetCopyIP((void *)&ip->ip_src, &NetOurIP);
+ net_copy_ip((void *)&ip->ip_dst, &ip->ip_src);
+ net_copy_ip((void *)&ip->ip_src, &net_ip);
ip->ip_sum = compute_ip_checksum(ip, IP_HDR_SIZE);
icmph->type = ICMP_ECHO_REPLY;
icmph->checksum = 0;
icmph->checksum = compute_ip_checksum(icmph, len - IP_HDR_SIZE);
- NetSendPacket((uchar *)et, eth_hdr_size + len);
+ net_send_packet((uchar *)et, eth_hdr_size + len);
return;
/* default:
return;*/
diff --git a/net/rarp.c b/net/rarp.c
index a8e085126d..4ce2f37a8a 100644
--- a/net/rarp.c
+++ b/net/rarp.c
@@ -20,7 +20,7 @@
#define TIMEOUT_COUNT (CONFIG_NET_RETRY_COUNT)
#endif
-int RarpTry;
+int rarp_try;
/*
* Handle a RARP received packet.
@@ -37,16 +37,15 @@ void rarp_receive(struct ip_udp_hdr *ip, unsigned len)
}
if ((ntohs(arp->ar_op) != RARPOP_REPLY) ||
- (ntohs(arp->ar_hrd) != ARP_ETHER) ||
- (ntohs(arp->ar_pro) != PROT_IP) ||
- (arp->ar_hln != 6) || (arp->ar_pln != 4)) {
-
+ (ntohs(arp->ar_hrd) != ARP_ETHER) ||
+ (ntohs(arp->ar_pro) != PROT_IP) ||
+ (arp->ar_hln != 6) || (arp->ar_pln != 4)) {
puts("invalid RARP header\n");
} else {
- NetCopyIP(&NetOurIP, &arp->ar_data[16]);
- if (NetServerIP == 0)
- NetCopyIP(&NetServerIP, &arp->ar_data[6]);
- memcpy(NetServerEther, &arp->ar_data[0], 6);
+ net_copy_ip(&net_ip, &arp->ar_data[16]);
+ if (net_server_ip.s_addr == 0)
+ net_copy_ip(&net_server_ip, &arp->ar_data[6]);
+ memcpy(net_server_ethaddr, &arp->ar_data[0], 6);
debug_cond(DEBUG_DEV_PKT, "Got good RARP\n");
net_auto_load();
}
@@ -56,28 +55,28 @@ void rarp_receive(struct ip_udp_hdr *ip, unsigned len)
/*
* Timeout on BOOTP request.
*/
-static void RarpTimeout(void)
+static void rarp_timeout_handler(void)
{
- if (RarpTry >= TIMEOUT_COUNT) {
+ if (rarp_try >= TIMEOUT_COUNT) {
puts("\nRetry count exceeded; starting again\n");
- NetStartAgain();
+ net_start_again();
} else {
- NetSetTimeout(TIMEOUT, RarpTimeout);
- RarpRequest();
+ net_set_timeout_handler(TIMEOUT, rarp_timeout_handler);
+ rarp_request();
}
}
-void RarpRequest(void)
+void rarp_request(void)
{
uchar *pkt;
struct arp_hdr *rarp;
int eth_hdr_size;
- printf("RARP broadcast %d\n", ++RarpTry);
- pkt = NetTxPacket;
+ printf("RARP broadcast %d\n", ++rarp_try);
+ pkt = net_tx_packet;
- eth_hdr_size = NetSetEther(pkt, NetBcastAddr, PROT_RARP);
+ eth_hdr_size = net_set_ether(pkt, net_bcast_ethaddr, PROT_RARP);
pkt += eth_hdr_size;
rarp = (struct arp_hdr *)pkt;
@@ -87,14 +86,14 @@ void RarpRequest(void)
rarp->ar_hln = 6;
rarp->ar_pln = 4;
rarp->ar_op = htons(RARPOP_REQUEST);
- memcpy(&rarp->ar_data[0], NetOurEther, 6); /* source ET addr */
- memcpy(&rarp->ar_data[6], &NetOurIP, 4); /* source IP addr */
+ memcpy(&rarp->ar_data[0], net_ethaddr, 6); /* source ET addr */
+ memcpy(&rarp->ar_data[6], &net_ip, 4); /* source IP addr */
/* dest ET addr = source ET addr ??*/
- memcpy(&rarp->ar_data[10], NetOurEther, 6);
+ memcpy(&rarp->ar_data[10], net_ethaddr, 6);
/* dest IP addr set to broadcast */
memset(&rarp->ar_data[16], 0xff, 4);
- NetSendPacket(NetTxPacket, eth_hdr_size + ARP_HDR_SIZE);
+ net_send_packet(net_tx_packet, eth_hdr_size + ARP_HDR_SIZE);
- NetSetTimeout(TIMEOUT, RarpTimeout);
+ net_set_timeout_handler(TIMEOUT, rarp_timeout_handler);
}
diff --git a/net/rarp.h b/net/rarp.h
index 93e18899c3..1ca8833ce5 100644
--- a/net/rarp.h
+++ b/net/rarp.h
@@ -17,11 +17,11 @@
* Global functions and variables.
*/
-extern int RarpTry;
+extern int rarp_try;
/* Process the receipt of a RARP packet */
-extern void rarp_receive(struct ip_udp_hdr *ip, unsigned len);
-extern void RarpRequest(void); /* Send a RARP request */
+void rarp_receive(struct ip_udp_hdr *ip, unsigned len);
+void rarp_request(void); /* Send a RARP request */
/**********************************************************************/
diff --git a/net/sntp.c b/net/sntp.c
index 5de19526e6..6422eef72e 100644
--- a/net/sntp.c
+++ b/net/sntp.c
@@ -14,10 +14,9 @@
#define SNTP_TIMEOUT 10000UL
-static int SntpOurPort;
+static int sntp_our_port;
-static void
-SntpSend(void)
+static void sntp_send(void)
{
struct sntp_pkt_t pkt;
int pktlen = SNTP_PACKET_LEN;
@@ -31,62 +30,63 @@ SntpSend(void)
pkt.vn = NTP_VERSION;
pkt.mode = NTP_MODE_CLIENT;
- memcpy((char *)NetTxPacket + NetEthHdrSize() + IP_UDP_HDR_SIZE,
- (char *)&pkt, pktlen);
+ memcpy((char *)net_tx_packet + net_eth_hdr_size() + IP_UDP_HDR_SIZE,
+ (char *)&pkt, pktlen);
- SntpOurPort = 10000 + (get_timer(0) % 4096);
+ sntp_our_port = 10000 + (get_timer(0) % 4096);
sport = NTP_SERVICE_PORT;
- NetSendUDPPacket(NetServerEther, NetNtpServerIP, sport, SntpOurPort,
- pktlen);
+ net_send_udp_packet(net_server_ethaddr, net_ntp_server, sport,
+ sntp_our_port, pktlen);
}
-static void
-SntpTimeout(void)
+static void sntp_timeout_handler(void)
{
puts("Timeout\n");
net_set_state(NETLOOP_FAIL);
return;
}
-static void
-SntpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src,
- unsigned len)
+static void sntp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
+ unsigned src, unsigned len)
{
+#ifdef CONFIG_TIMESTAMP
struct sntp_pkt_t *rpktp = (struct sntp_pkt_t *)pkt;
struct rtc_time tm;
ulong seconds;
+#endif
debug("%s\n", __func__);
- if (dest != SntpOurPort)
+ if (dest != sntp_our_port)
return;
+#ifdef CONFIG_TIMESTAMP
/*
- * As the RTC's used in U-Boot sepport second resolution only
+ * As the RTC's used in U-Boot support second resolution only
* we simply ignore the sub-second field.
*/
memcpy(&seconds, &rpktp->transmit_timestamp, sizeof(ulong));
- to_tm(ntohl(seconds) - 2208988800UL + NetTimeOffset, &tm);
+ to_tm(ntohl(seconds) - 2208988800UL + net_ntp_time_offset, &tm);
#if defined(CONFIG_CMD_DATE)
rtc_set(&tm);
#endif
printf("Date: %4d-%02d-%02d Time: %2d:%02d:%02d\n",
- tm.tm_year, tm.tm_mon, tm.tm_mday,
- tm.tm_hour, tm.tm_min, tm.tm_sec);
+ tm.tm_year, tm.tm_mon, tm.tm_mday,
+ tm.tm_hour, tm.tm_min, tm.tm_sec);
+#endif
net_set_state(NETLOOP_SUCCESS);
}
-void
-SntpStart(void)
+void sntp_start(void)
{
debug("%s\n", __func__);
- NetSetTimeout(SNTP_TIMEOUT, SntpTimeout);
- net_set_udp_handler(SntpHandler);
- memset(NetServerEther, 0, sizeof(NetServerEther));
+ net_set_timeout_handler(SNTP_TIMEOUT, sntp_timeout_handler);
+ net_set_udp_handler(sntp_handler);
+ memset(net_server_ethaddr, 0, sizeof(net_server_ethaddr));
- SntpSend();
+ sntp_send();
}
diff --git a/net/sntp.h b/net/sntp.h
index bf5bf0bb01..6a9c6bb82f 100644
--- a/net/sntp.h
+++ b/net/sntp.h
@@ -53,6 +53,6 @@ struct sntp_pkt_t {
unsigned long long transmit_timestamp;
};
-extern void SntpStart(void); /* Begin SNTP */
+void sntp_start(void); /* Begin SNTP */
#endif /* __SNTP_H__ */
diff --git a/net/tftp.c b/net/tftp.c
index 0a2c53302c..3e99e73091 100644
--- a/net/tftp.c
+++ b/net/tftp.c
@@ -8,6 +8,7 @@
#include <common.h>
#include <command.h>
+#include <mapmem.h>
#include <net.h>
#include "tftp.h"
#include "bootp.h"
@@ -38,21 +39,21 @@
#define TFTP_ERROR 5
#define TFTP_OACK 6
-static ulong TftpTimeoutMSecs = TIMEOUT;
-static int TftpTimeoutCountMax = TIMEOUT_COUNT;
+static ulong timeout_ms = TIMEOUT;
+static int timeout_count_max = TIMEOUT_COUNT;
static ulong time_start; /* Record time we started tftp */
/*
* These globals govern the timeout behavior when attempting a connection to a
- * TFTP server. TftpRRQTimeoutMSecs specifies the number of milliseconds to
+ * TFTP server. tftp_timeout_ms specifies the number of milliseconds to
* wait for the server to respond to initial connection. Second global,
- * TftpRRQTimeoutCountMax, gives the number of such connection retries.
- * TftpRRQTimeoutCountMax must be non-negative and TftpRRQTimeoutMSecs must be
+ * tftp_timeout_count_max, gives the number of such connection retries.
+ * tftp_timeout_count_max must be non-negative and tftp_timeout_ms must be
* positive. The globals are meant to be set (and restored) by code needing
* non-standard timeout behavior when initiating a TFTP transfer.
*/
-ulong TftpRRQTimeoutMSecs = TIMEOUT;
-int TftpRRQTimeoutCountMax = TIMEOUT_COUNT;
+ulong tftp_timeout_ms = TIMEOUT;
+int tftp_timeout_count_max = TIMEOUT_COUNT;
enum {
TFTP_ERR_UNDEFINED = 0,
@@ -64,32 +65,34 @@ enum {
TFTP_ERR_FILE_ALREADY_EXISTS = 6,
};
-static IPaddr_t TftpRemoteIP;
+static struct in_addr tftp_remote_ip;
/* The UDP port at their end */
-static int TftpRemotePort;
+static int tftp_remote_port;
/* The UDP port at our end */
-static int TftpOurPort;
-static int TftpTimeoutCount;
+static int tftp_our_port;
+static int timeout_count;
/* packet sequence number */
-static ulong TftpBlock;
+static ulong tftp_cur_block;
/* last packet sequence number received */
-static ulong TftpLastBlock;
+static ulong tftp_prev_block;
/* count of sequence number wraparounds */
-static ulong TftpBlockWrap;
+static ulong tftp_block_wrap;
/* memory offset due to wrapping */
-static ulong TftpBlockWrapOffset;
-static int TftpState;
+static ulong tftp_block_wrap_offset;
+static int tftp_state;
#ifdef CONFIG_TFTP_TSIZE
/* The file size reported by the server */
-static int TftpTsize;
+static int tftp_tsize;
/* The number of hashes we printed */
-static short TftpNumchars;
+static short tftp_tsize_num_hash;
#endif
#ifdef CONFIG_CMD_TFTPPUT
-static int TftpWriting; /* 1 if writing, else 0 */
-static int TftpFinalBlock; /* 1 if we have sent the last block */
+/* 1 if writing, else 0 */
+static int tftp_put_active;
+/* 1 if we have sent the last block */
+static int tftp_put_final_block_sent;
#else
-#define TftpWriting 0
+#define tftp_put_active 0
#endif
#define STATE_SEND_RRQ 1
@@ -127,39 +130,42 @@ static char tftp_filename[MAX_LEN];
#define TFTP_MTU_BLOCKSIZE 1468
#endif
-static unsigned short TftpBlkSize = TFTP_BLOCK_SIZE;
-static unsigned short TftpBlkSizeOption = TFTP_MTU_BLOCKSIZE;
+static unsigned short tftp_block_size = TFTP_BLOCK_SIZE;
+static unsigned short tftp_block_size_option = TFTP_MTU_BLOCKSIZE;
#ifdef CONFIG_MCAST_TFTP
#include <malloc.h>
#define MTFTP_BITMAPSIZE 0x1000
-static unsigned *Bitmap;
-static int PrevBitmapHole, Mapsize = MTFTP_BITMAPSIZE;
-static uchar ProhibitMcast, MasterClient;
-static uchar Multicast;
-static int Mcast_port;
-static ulong TftpEndingBlock; /* can get 'last' block before done..*/
+static unsigned *tftp_mcast_bitmap;
+static int tftp_mcast_prev_hole;
+static int tftp_mcast_bitmap_size = MTFTP_BITMAPSIZE;
+static int tftp_mcast_disabled;
+static int tftp_mcast_master_client;
+static int tftp_mcast_active;
+static int tftp_mcast_port;
+/* can get 'last' block before done..*/
+static ulong tftp_mcast_ending_block;
static void parse_multicast_oack(char *pkt, int len);
-static void
-mcast_cleanup(void)
+static void mcast_cleanup(void)
{
- if (Mcast_addr)
- eth_mcast_join(Mcast_addr, 0);
- if (Bitmap)
- free(Bitmap);
- Bitmap = NULL;
- Mcast_addr = Multicast = Mcast_port = 0;
- TftpEndingBlock = -1;
+ if (net_mcast_addr)
+ eth_mcast_join(net_mcast_addr, 0);
+ if (tftp_mcast_bitmap)
+ free(tftp_mcast_bitmap);
+ tftp_mcast_bitmap = NULL;
+ net_mcast_addr.s_addr = 0;
+ tftp_mcast_active = 0;
+ tftp_mcast_port = 0;
+ tftp_mcast_ending_block = -1;
}
#endif /* CONFIG_MCAST_TFTP */
-static inline void
-store_block(int block, uchar *src, unsigned len)
+static inline void store_block(int block, uchar *src, unsigned len)
{
- ulong offset = block * TftpBlkSize + TftpBlockWrapOffset;
+ ulong offset = block * tftp_block_size + tftp_block_wrap_offset;
ulong newsize = offset + len;
#ifdef CONFIG_SYS_DIRECT_FLASH_TFTP
int i, rc = 0;
@@ -184,25 +190,28 @@ store_block(int block, uchar *src, unsigned len)
} else
#endif /* CONFIG_SYS_DIRECT_FLASH_TFTP */
{
- (void)memcpy((void *)(load_addr + offset), src, len);
+ void *ptr = map_sysmem(load_addr + offset, len);
+
+ memcpy(ptr, src, len);
+ unmap_sysmem(ptr);
}
#ifdef CONFIG_MCAST_TFTP
- if (Multicast)
- ext2_set_bit(block, Bitmap);
+ if (tftp_mcast_active)
+ ext2_set_bit(block, tftp_mcast_bitmap);
#endif
- if (NetBootFileXferSize < newsize)
- NetBootFileXferSize = newsize;
+ if (net_boot_file_size < newsize)
+ net_boot_file_size = newsize;
}
/* Clear our state ready for a new transfer */
static void new_transfer(void)
{
- TftpLastBlock = 0;
- TftpBlockWrap = 0;
- TftpBlockWrapOffset = 0;
+ tftp_prev_block = 0;
+ tftp_block_wrap = 0;
+ tftp_block_wrap_offset = 0;
#ifdef CONFIG_CMD_TFTPPUT
- TftpFinalBlock = 0;
+ tftp_put_final_block_sent = 0;
#endif
}
@@ -218,38 +227,39 @@ static void new_transfer(void)
static int load_block(unsigned block, uchar *dst, unsigned len)
{
/* We may want to get the final block from the previous set */
- ulong offset = ((int)block - 1) * len + TftpBlockWrapOffset;
+ ulong offset = ((int)block - 1) * len + tftp_block_wrap_offset;
ulong tosend = len;
- tosend = min(NetBootFileXferSize - offset, tosend);
+ tosend = min(net_boot_file_size - offset, tosend);
(void)memcpy(dst, (void *)(save_addr + offset), tosend);
debug("%s: block=%d, offset=%ld, len=%d, tosend=%ld\n", __func__,
- block, offset, len, tosend);
+ block, offset, len, tosend);
return tosend;
}
#endif
-static void TftpSend(void);
-static void TftpTimeout(void);
+static void tftp_send(void);
+static void tftp_timeout_handler(void);
/**********************************************************************/
static void show_block_marker(void)
{
#ifdef CONFIG_TFTP_TSIZE
- if (TftpTsize) {
- ulong pos = TftpBlock * TftpBlkSize + TftpBlockWrapOffset;
+ if (tftp_tsize) {
+ ulong pos = tftp_cur_block * tftp_block_size +
+ tftp_block_wrap_offset;
- while (TftpNumchars < pos * 50 / TftpTsize) {
+ while (tftp_tsize_num_hash < pos * 50 / tftp_tsize) {
putc('#');
- TftpNumchars++;
+ tftp_tsize_num_hash++;
}
} else
#endif
{
- if (((TftpBlock - 1) % 10) == 0)
+ if (((tftp_cur_block - 1) % 10) == 0)
putc('#');
- else if ((TftpBlock % (10 * HASHES_PER_LINE)) == 0)
+ else if ((tftp_cur_block % (10 * HASHES_PER_LINE)) == 0)
puts("\n\t ");
}
}
@@ -265,7 +275,7 @@ static void restart(const char *msg)
#ifdef CONFIG_MCAST_TFTP
mcast_cleanup();
#endif
- NetStartAgain();
+ net_start_again();
}
/*
@@ -281,10 +291,10 @@ static void update_block_number(void)
* number of 0 this means that there was a wrap
* around of the (16 bit) counter.
*/
- if (TftpBlock == 0 && TftpLastBlock != 0) {
- TftpBlockWrap++;
- TftpBlockWrapOffset += TftpBlkSize * TFTP_SEQUENCE_SIZE;
- TftpTimeoutCount = 0; /* we've done well, reset thhe timeout */
+ if (tftp_cur_block == 0 && tftp_prev_block != 0) {
+ tftp_block_wrap++;
+ tftp_block_wrap_offset += tftp_block_size * TFTP_SEQUENCE_SIZE;
+ timeout_count = 0; /* we've done well, reset the timeout */
} else {
show_block_marker();
}
@@ -295,25 +305,24 @@ static void tftp_complete(void)
{
#ifdef CONFIG_TFTP_TSIZE
/* Print hash marks for the last packet received */
- while (TftpTsize && TftpNumchars < 49) {
+ while (tftp_tsize && tftp_tsize_num_hash < 49) {
putc('#');
- TftpNumchars++;
+ tftp_tsize_num_hash++;
}
puts(" ");
- print_size(TftpTsize, "");
+ print_size(tftp_tsize, "");
#endif
time_start = get_timer(time_start);
if (time_start > 0) {
puts("\n\t "); /* Line up with "Loading: " */
- print_size(NetBootFileXferSize /
+ print_size(net_boot_file_size /
time_start * 1000, "/s");
}
puts("\ndone\n");
net_set_state(NETLOOP_SUCCESS);
}
-static void
-TftpSend(void)
+static void tftp_send(void)
{
uchar *pkt;
uchar *xp;
@@ -322,24 +331,23 @@ TftpSend(void)
#ifdef CONFIG_MCAST_TFTP
/* Multicast TFTP.. non-MasterClients do not ACK data. */
- if (Multicast
- && (TftpState == STATE_DATA)
- && (MasterClient == 0))
+ if (tftp_mcast_active && tftp_state == STATE_DATA &&
+ tftp_mcast_master_client == 0)
return;
#endif
/*
* We will always be sending some sort of packet, so
* cobble together the packet headers now.
*/
- pkt = NetTxPacket + NetEthHdrSize() + IP_UDP_HDR_SIZE;
+ pkt = net_tx_packet + net_eth_hdr_size() + IP_UDP_HDR_SIZE;
- switch (TftpState) {
+ switch (tftp_state) {
case STATE_SEND_RRQ:
case STATE_SEND_WRQ:
xp = pkt;
s = (ushort *)pkt;
#ifdef CONFIG_CMD_TFTPPUT
- *s++ = htons(TftpState == STATE_SEND_RRQ ? TFTP_RRQ :
+ *s++ = htons(tftp_state == STATE_SEND_RRQ ? TFTP_RRQ :
TFTP_WRQ);
#else
*s++ = htons(TFTP_RRQ);
@@ -351,23 +359,23 @@ TftpSend(void)
pkt += 5 /*strlen("octet")*/ + 1;
strcpy((char *)pkt, "timeout");
pkt += 7 /*strlen("timeout")*/ + 1;
- sprintf((char *)pkt, "%lu", TftpTimeoutMSecs / 1000);
+ sprintf((char *)pkt, "%lu", timeout_ms / 1000);
debug("send option \"timeout %s\"\n", (char *)pkt);
pkt += strlen((char *)pkt) + 1;
#ifdef CONFIG_TFTP_TSIZE
- pkt += sprintf((char *)pkt, "tsize%c%lu%c",
- 0, NetBootFileXferSize, 0);
+ pkt += sprintf((char *)pkt, "tsize%c%u%c",
+ 0, net_boot_file_size, 0);
#endif
/* try for more effic. blk size */
pkt += sprintf((char *)pkt, "blksize%c%d%c",
- 0, TftpBlkSizeOption, 0);
+ 0, tftp_block_size_option, 0);
#ifdef CONFIG_MCAST_TFTP
/* Check all preconditions before even trying the option */
- if (!ProhibitMcast) {
- Bitmap = malloc(Mapsize);
- if (Bitmap && eth_get_dev()->mcast) {
- free(Bitmap);
- Bitmap = NULL;
+ if (!tftp_mcast_disabled) {
+ tftp_mcast_bitmap = malloc(tftp_mcast_bitmap_size);
+ if (tftp_mcast_bitmap && eth_get_dev()->mcast) {
+ free(tftp_mcast_bitmap);
+ tftp_mcast_bitmap = NULL;
pkt += sprintf((char *)pkt, "multicast%c%c",
0, 0);
}
@@ -378,11 +386,12 @@ TftpSend(void)
case STATE_OACK:
#ifdef CONFIG_MCAST_TFTP
- /* My turn! Start at where I need blocks I missed.*/
- if (Multicast)
- TftpBlock = ext2_find_next_zero_bit(Bitmap,
- (Mapsize*8), 0);
- /*..falling..*/
+ /* My turn! Start at where I need blocks I missed. */
+ if (tftp_mcast_active)
+ tftp_cur_block = ext2_find_next_zero_bit(
+ tftp_mcast_bitmap,
+ tftp_mcast_bitmap_size * 8, 0);
+ /* fall through */
#endif
case STATE_RECV_WRQ:
@@ -390,16 +399,16 @@ TftpSend(void)
xp = pkt;
s = (ushort *)pkt;
s[0] = htons(TFTP_ACK);
- s[1] = htons(TftpBlock);
+ s[1] = htons(tftp_cur_block);
pkt = (uchar *)(s + 2);
#ifdef CONFIG_CMD_TFTPPUT
- if (TftpWriting) {
- int toload = TftpBlkSize;
- int loaded = load_block(TftpBlock, pkt, toload);
+ if (tftp_put_active) {
+ int toload = tftp_block_size;
+ int loaded = load_block(tftp_cur_block, pkt, toload);
s[0] = htons(TFTP_DATA);
pkt += loaded;
- TftpFinalBlock = (loaded < toload);
+ tftp_put_final_block_sent = (loaded < toload);
}
#endif
len = pkt - xp;
@@ -429,13 +438,14 @@ TftpSend(void)
break;
}
- NetSendUDPPacket(NetServerEther, TftpRemoteIP, TftpRemotePort,
- TftpOurPort, len);
+ net_send_udp_packet(net_server_ethaddr, tftp_remote_ip,
+ tftp_remote_port, tftp_our_port, len);
}
#ifdef CONFIG_CMD_TFTPPUT
static void icmp_handler(unsigned type, unsigned code, unsigned dest,
- IPaddr_t sip, unsigned src, uchar *pkt, unsigned len)
+ struct in_addr sip, unsigned src, uchar *pkt,
+ unsigned len)
{
if (type == ICMP_NOT_REACH && code == ICMP_NOT_REACH_PORT) {
/* Oh dear the other end has gone away */
@@ -444,23 +454,22 @@ static void icmp_handler(unsigned type, unsigned code, unsigned dest,
}
#endif
-static void
-TftpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src,
- unsigned len)
+static void tftp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
+ unsigned src, unsigned len)
{
__be16 proto;
__be16 *s;
int i;
- if (dest != TftpOurPort) {
+ if (dest != tftp_our_port) {
#ifdef CONFIG_MCAST_TFTP
- if (Multicast
- && (!Mcast_port || (dest != Mcast_port)))
+ if (tftp_mcast_active &&
+ (!tftp_mcast_port || dest != tftp_mcast_port))
#endif
return;
}
- if (TftpState != STATE_SEND_RRQ && src != TftpRemotePort &&
- TftpState != STATE_RECV_WRQ && TftpState != STATE_SEND_WRQ)
+ if (tftp_state != STATE_SEND_RRQ && src != tftp_remote_port &&
+ tftp_state != STATE_RECV_WRQ && tftp_state != STATE_SEND_WRQ)
return;
if (len < 2)
@@ -471,14 +480,13 @@ TftpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src,
proto = *s++;
pkt = (uchar *)s;
switch (ntohs(proto)) {
-
case TFTP_RRQ:
break;
case TFTP_ACK:
#ifdef CONFIG_CMD_TFTPPUT
- if (TftpWriting) {
- if (TftpFinalBlock) {
+ if (tftp_put_active) {
+ if (tftp_put_final_block_sent) {
tftp_complete();
} else {
/*
@@ -486,12 +494,12 @@ TftpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src,
* count to wrap just like the other end!
*/
int block = ntohs(*s);
- int ack_ok = (TftpBlock == block);
+ int ack_ok = (tftp_cur_block == block);
- TftpBlock = (unsigned short)(block + 1);
+ tftp_cur_block = (unsigned short)(block + 1);
update_block_number();
if (ack_ok)
- TftpSend(); /* Send next data block */
+ tftp_send(); /* Send next data block */
}
}
#endif
@@ -503,102 +511,99 @@ TftpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src,
#ifdef CONFIG_CMD_TFTPSRV
case TFTP_WRQ:
debug("Got WRQ\n");
- TftpRemoteIP = sip;
- TftpRemotePort = src;
- TftpOurPort = 1024 + (get_timer(0) % 3072);
+ tftp_remote_ip = sip;
+ tftp_remote_port = src;
+ tftp_our_port = 1024 + (get_timer(0) % 3072);
new_transfer();
- TftpSend(); /* Send ACK(0) */
+ tftp_send(); /* Send ACK(0) */
break;
#endif
case TFTP_OACK:
debug("Got OACK: %s %s\n",
- pkt,
- pkt + strlen((char *)pkt) + 1);
- TftpState = STATE_OACK;
- TftpRemotePort = src;
+ pkt, pkt + strlen((char *)pkt) + 1);
+ tftp_state = STATE_OACK;
+ tftp_remote_port = src;
/*
* Check for 'blksize' option.
* Careful: "i" is signed, "len" is unsigned, thus
* something like "len-8" may give a *huge* number
*/
for (i = 0; i+8 < len; i++) {
- if (strcmp((char *)pkt+i, "blksize") == 0) {
- TftpBlkSize = (unsigned short)
- simple_strtoul((char *)pkt+i+8, NULL,
- 10);
+ if (strcmp((char *)pkt + i, "blksize") == 0) {
+ tftp_block_size = (unsigned short)
+ simple_strtoul((char *)pkt + i + 8,
+ NULL, 10);
debug("Blocksize ack: %s, %d\n",
- (char *)pkt+i+8, TftpBlkSize);
+ (char *)pkt + i + 8, tftp_block_size);
}
#ifdef CONFIG_TFTP_TSIZE
if (strcmp((char *)pkt+i, "tsize") == 0) {
- TftpTsize = simple_strtoul((char *)pkt+i+6,
+ tftp_tsize = simple_strtoul((char *)pkt + i + 6,
NULL, 10);
debug("size = %s, %d\n",
- (char *)pkt+i+6, TftpTsize);
+ (char *)pkt + i + 6, tftp_tsize);
}
#endif
}
#ifdef CONFIG_MCAST_TFTP
- parse_multicast_oack((char *)pkt, len-1);
- if ((Multicast) && (!MasterClient))
- TftpState = STATE_DATA; /* passive.. */
+ parse_multicast_oack((char *)pkt, len - 1);
+ if ((tftp_mcast_active) && (!tftp_mcast_master_client))
+ tftp_state = STATE_DATA; /* passive.. */
else
#endif
#ifdef CONFIG_CMD_TFTPPUT
- if (TftpWriting) {
+ if (tftp_put_active) {
/* Get ready to send the first block */
- TftpState = STATE_DATA;
- TftpBlock++;
+ tftp_state = STATE_DATA;
+ tftp_cur_block++;
}
#endif
- TftpSend(); /* Send ACK or first data block */
+ tftp_send(); /* Send ACK or first data block */
break;
case TFTP_DATA:
if (len < 2)
return;
len -= 2;
- TftpBlock = ntohs(*(__be16 *)pkt);
+ tftp_cur_block = ntohs(*(__be16 *)pkt);
update_block_number();
- if (TftpState == STATE_SEND_RRQ)
+ if (tftp_state == STATE_SEND_RRQ)
debug("Server did not acknowledge timeout option!\n");
- if (TftpState == STATE_SEND_RRQ || TftpState == STATE_OACK ||
- TftpState == STATE_RECV_WRQ) {
+ if (tftp_state == STATE_SEND_RRQ || tftp_state == STATE_OACK ||
+ tftp_state == STATE_RECV_WRQ) {
/* first block received */
- TftpState = STATE_DATA;
- TftpRemotePort = src;
+ tftp_state = STATE_DATA;
+ tftp_remote_port = src;
new_transfer();
#ifdef CONFIG_MCAST_TFTP
- if (Multicast) { /* start!=1 common if mcast */
- TftpLastBlock = TftpBlock - 1;
+ if (tftp_mcast_active) { /* start!=1 common if mcast */
+ tftp_prev_block = tftp_cur_block - 1;
} else
#endif
- if (TftpBlock != 1) { /* Assertion */
- printf("\nTFTP error: "
- "First block is not block 1 (%ld)\n"
- "Starting again\n\n",
- TftpBlock);
- NetStartAgain();
+ if (tftp_cur_block != 1) { /* Assertion */
+ puts("\nTFTP error: ");
+ printf("First block is not block 1 (%ld)\n",
+ tftp_cur_block);
+ puts("Starting again\n\n");
+ net_start_again();
break;
}
}
- if (TftpBlock == TftpLastBlock) {
- /*
- * Same block again; ignore it.
- */
+ if (tftp_cur_block == tftp_prev_block) {
+ /* Same block again; ignore it. */
break;
}
- TftpLastBlock = TftpBlock;
- TftpTimeoutCountMax = TIMEOUT_COUNT;
- NetSetTimeout(TftpTimeoutMSecs, TftpTimeout);
+ tftp_prev_block = tftp_cur_block;
+ timeout_count_max = TIMEOUT_COUNT;
+ net_set_timeout_handler(timeout_ms, tftp_timeout_handler);
- store_block(TftpBlock - 1, pkt + 2, len);
+ store_block(tftp_cur_block - 1, pkt + 2, len);
/*
* Acknowledge the block just received, which will prompt
@@ -608,39 +613,41 @@ TftpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src,
/* if I am the MasterClient, actively calculate what my next
* needed block is; else I'm passive; not ACKING
*/
- if (Multicast) {
- if (len < TftpBlkSize) {
- TftpEndingBlock = TftpBlock;
- } else if (MasterClient) {
- TftpBlock = PrevBitmapHole =
- ext2_find_next_zero_bit(
- Bitmap,
- (Mapsize*8),
- PrevBitmapHole);
- if (TftpBlock > ((Mapsize*8) - 1)) {
- printf("tftpfile too big\n");
+ if (tftp_mcast_active) {
+ if (len < tftp_block_size) {
+ tftp_mcast_ending_block = tftp_cur_block;
+ } else if (tftp_mcast_master_client) {
+ tftp_mcast_prev_hole = ext2_find_next_zero_bit(
+ tftp_mcast_bitmap,
+ tftp_mcast_bitmap_size * 8,
+ tftp_mcast_prev_hole);
+ tftp_cur_block = tftp_mcast_prev_hole;
+ if (tftp_cur_block >
+ ((tftp_mcast_bitmap_size * 8) - 1)) {
+ debug("tftpfile too big\n");
/* try to double it and retry */
- Mapsize <<= 1;
+ tftp_mcast_bitmap_size <<= 1;
mcast_cleanup();
- NetStartAgain();
+ net_start_again();
return;
}
- TftpLastBlock = TftpBlock;
+ tftp_prev_block = tftp_cur_block;
}
}
#endif
- TftpSend();
+ tftp_send();
#ifdef CONFIG_MCAST_TFTP
- if (Multicast) {
- if (MasterClient && (TftpBlock >= TftpEndingBlock)) {
+ if (tftp_mcast_active) {
+ if (tftp_mcast_master_client &&
+ (tftp_cur_block >= tftp_mcast_ending_block)) {
puts("\nMulticast tftp done\n");
mcast_cleanup();
net_set_state(NETLOOP_SUCCESS);
}
} else
#endif
- if (len < TftpBlkSize)
+ if (len < tftp_block_size)
tftp_complete();
break;
@@ -665,7 +672,7 @@ TftpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src,
#ifdef CONFIG_MCAST_TFTP
mcast_cleanup();
#endif
- NetStartAgain();
+ net_start_again();
break;
}
break;
@@ -673,21 +680,20 @@ TftpHandler(uchar *pkt, unsigned dest, IPaddr_t sip, unsigned src,
}
-static void
-TftpTimeout(void)
+static void tftp_timeout_handler(void)
{
- if (++TftpTimeoutCount > TftpTimeoutCountMax) {
+ if (++timeout_count > timeout_count_max) {
restart("Retry count exceeded");
} else {
puts("T ");
- NetSetTimeout(TftpTimeoutMSecs, TftpTimeout);
- if (TftpState != STATE_RECV_WRQ)
- TftpSend();
+ net_set_timeout_handler(timeout_ms, tftp_timeout_handler);
+ if (tftp_state != STATE_RECV_WRQ)
+ tftp_send();
}
}
-void TftpStart(enum proto_t protocol)
+void tftp_start(enum proto_t protocol)
{
char *ep; /* Environment pointer */
@@ -697,45 +703,44 @@ void TftpStart(enum proto_t protocol)
*/
ep = getenv("tftpblocksize");
if (ep != NULL)
- TftpBlkSizeOption = simple_strtol(ep, NULL, 10);
+ tftp_block_size_option = simple_strtol(ep, NULL, 10);
ep = getenv("tftptimeout");
if (ep != NULL)
- TftpTimeoutMSecs = simple_strtol(ep, NULL, 10);
+ timeout_ms = simple_strtol(ep, NULL, 10);
- if (TftpTimeoutMSecs < 1000) {
- printf("TFTP timeout (%ld ms) too low, "
- "set minimum = 1000 ms\n",
- TftpTimeoutMSecs);
- TftpTimeoutMSecs = 1000;
+ if (timeout_ms < 1000) {
+ printf("TFTP timeout (%ld ms) too low, set min = 1000 ms\n",
+ timeout_ms);
+ timeout_ms = 1000;
}
debug("TFTP blocksize = %i, timeout = %ld ms\n",
- TftpBlkSizeOption, TftpTimeoutMSecs);
+ tftp_block_size_option, timeout_ms);
- TftpRemoteIP = NetServerIP;
- if (BootFile[0] == '\0') {
+ tftp_remote_ip = net_server_ip;
+ if (net_boot_file_name[0] == '\0') {
sprintf(default_filename, "%02X%02X%02X%02X.img",
- NetOurIP & 0xFF,
- (NetOurIP >> 8) & 0xFF,
- (NetOurIP >> 16) & 0xFF,
- (NetOurIP >> 24) & 0xFF);
+ net_ip.s_addr & 0xFF,
+ (net_ip.s_addr >> 8) & 0xFF,
+ (net_ip.s_addr >> 16) & 0xFF,
+ (net_ip.s_addr >> 24) & 0xFF);
strncpy(tftp_filename, default_filename, MAX_LEN);
- tftp_filename[MAX_LEN-1] = 0;
+ tftp_filename[MAX_LEN - 1] = 0;
printf("*** Warning: no boot file name; using '%s'\n",
- tftp_filename);
+ tftp_filename);
} else {
- char *p = strchr(BootFile, ':');
+ char *p = strchr(net_boot_file_name, ':');
if (p == NULL) {
- strncpy(tftp_filename, BootFile, MAX_LEN);
- tftp_filename[MAX_LEN-1] = 0;
+ strncpy(tftp_filename, net_boot_file_name, MAX_LEN);
+ tftp_filename[MAX_LEN - 1] = 0;
} else {
- TftpRemoteIP = string_to_ip(BootFile);
+ tftp_remote_ip = string_to_ip(net_boot_file_name);
strncpy(tftp_filename, p + 1, MAX_LEN);
- tftp_filename[MAX_LEN-1] = 0;
+ tftp_filename[MAX_LEN - 1] = 0;
}
}
@@ -744,124 +749,127 @@ void TftpStart(enum proto_t protocol)
#ifdef CONFIG_CMD_TFTPPUT
protocol == TFTPPUT ? "to" : "from",
#else
- "from",
+ "from",
#endif
- &TftpRemoteIP, &NetOurIP);
+ &tftp_remote_ip, &net_ip);
/* Check if we need to send across this subnet */
- if (NetOurGatewayIP && NetOurSubnetMask) {
- IPaddr_t OurNet = NetOurIP & NetOurSubnetMask;
- IPaddr_t RemoteNet = TftpRemoteIP & NetOurSubnetMask;
-
- if (OurNet != RemoteNet)
- printf("; sending through gateway %pI4",
- &NetOurGatewayIP);
+ if (net_gateway.s_addr && net_netmask.s_addr) {
+ struct in_addr our_net;
+ struct in_addr remote_net;
+
+ our_net.s_addr = net_ip.s_addr & net_netmask.s_addr;
+ remote_net.s_addr = tftp_remote_ip.s_addr & net_netmask.s_addr;
+ if (our_net.s_addr != remote_net.s_addr)
+ printf("; sending through gateway %pI4", &net_gateway);
}
putc('\n');
printf("Filename '%s'.", tftp_filename);
- if (NetBootFileSize) {
- printf(" Size is 0x%x Bytes = ", NetBootFileSize<<9);
- print_size(NetBootFileSize<<9, "");
+ if (net_boot_file_expected_size_in_blocks) {
+ printf(" Size is 0x%x Bytes = ",
+ net_boot_file_expected_size_in_blocks << 9);
+ print_size(net_boot_file_expected_size_in_blocks << 9, "");
}
putc('\n');
#ifdef CONFIG_CMD_TFTPPUT
- TftpWriting = (protocol == TFTPPUT);
- if (TftpWriting) {
+ tftp_put_active = (protocol == TFTPPUT);
+ if (tftp_put_active) {
printf("Save address: 0x%lx\n", save_addr);
printf("Save size: 0x%lx\n", save_size);
- NetBootFileXferSize = save_size;
+ net_boot_file_size = save_size;
puts("Saving: *\b");
- TftpState = STATE_SEND_WRQ;
+ tftp_state = STATE_SEND_WRQ;
new_transfer();
} else
#endif
{
printf("Load address: 0x%lx\n", load_addr);
puts("Loading: *\b");
- TftpState = STATE_SEND_RRQ;
+ tftp_state = STATE_SEND_RRQ;
}
time_start = get_timer(0);
- TftpTimeoutCountMax = TftpRRQTimeoutCountMax;
+ timeout_count_max = tftp_timeout_count_max;
- NetSetTimeout(TftpTimeoutMSecs, TftpTimeout);
- net_set_udp_handler(TftpHandler);
+ net_set_timeout_handler(timeout_ms, tftp_timeout_handler);
+ net_set_udp_handler(tftp_handler);
#ifdef CONFIG_CMD_TFTPPUT
net_set_icmp_handler(icmp_handler);
#endif
- TftpRemotePort = WELL_KNOWN_PORT;
- TftpTimeoutCount = 0;
+ tftp_remote_port = WELL_KNOWN_PORT;
+ timeout_count = 0;
/* Use a pseudo-random port unless a specific port is set */
- TftpOurPort = 1024 + (get_timer(0) % 3072);
+ tftp_our_port = 1024 + (get_timer(0) % 3072);
#ifdef CONFIG_TFTP_PORT
ep = getenv("tftpdstp");
if (ep != NULL)
- TftpRemotePort = simple_strtol(ep, NULL, 10);
+ tftp_remote_port = simple_strtol(ep, NULL, 10);
ep = getenv("tftpsrcp");
if (ep != NULL)
- TftpOurPort = simple_strtol(ep, NULL, 10);
+ tftp_our_port = simple_strtol(ep, NULL, 10);
#endif
- TftpBlock = 0;
+ tftp_cur_block = 0;
/* zero out server ether in case the server ip has changed */
- memset(NetServerEther, 0, 6);
- /* Revert TftpBlkSize to dflt */
- TftpBlkSize = TFTP_BLOCK_SIZE;
+ memset(net_server_ethaddr, 0, 6);
+ /* Revert tftp_block_size to dflt */
+ tftp_block_size = TFTP_BLOCK_SIZE;
#ifdef CONFIG_MCAST_TFTP
mcast_cleanup();
#endif
#ifdef CONFIG_TFTP_TSIZE
- TftpTsize = 0;
- TftpNumchars = 0;
+ tftp_tsize = 0;
+ tftp_tsize_num_hash = 0;
#endif
- TftpSend();
+ tftp_send();
}
#ifdef CONFIG_CMD_TFTPSRV
-void
-TftpStartServer(void)
+void tftp_start_server(void)
{
tftp_filename[0] = 0;
printf("Using %s device\n", eth_get_name());
- printf("Listening for TFTP transfer on %pI4\n", &NetOurIP);
+ printf("Listening for TFTP transfer on %pI4\n", &net_ip);
printf("Load address: 0x%lx\n", load_addr);
puts("Loading: *\b");
- TftpTimeoutCountMax = TIMEOUT_COUNT;
- TftpTimeoutCount = 0;
- TftpTimeoutMSecs = TIMEOUT;
- NetSetTimeout(TftpTimeoutMSecs, TftpTimeout);
+ timeout_count_max = TIMEOUT_COUNT;
+ timeout_count = 0;
+ timeout_ms = TIMEOUT;
+ net_set_timeout_handler(timeout_ms, tftp_timeout_handler);
- /* Revert TftpBlkSize to dflt */
- TftpBlkSize = TFTP_BLOCK_SIZE;
- TftpBlock = 0;
- TftpOurPort = WELL_KNOWN_PORT;
+ /* Revert tftp_block_size to dflt */
+ tftp_block_size = TFTP_BLOCK_SIZE;
+ tftp_cur_block = 0;
+ tftp_our_port = WELL_KNOWN_PORT;
#ifdef CONFIG_TFTP_TSIZE
- TftpTsize = 0;
- TftpNumchars = 0;
+ tftp_tsize = 0;
+ tftp_tsize_num_hash = 0;
#endif
- TftpState = STATE_RECV_WRQ;
- net_set_udp_handler(TftpHandler);
+ tftp_state = STATE_RECV_WRQ;
+ net_set_udp_handler(tftp_handler);
/* zero out server ether in case the server ip has changed */
- memset(NetServerEther, 0, 6);
+ memset(net_server_ethaddr, 0, 6);
}
#endif /* CONFIG_CMD_TFTPSRV */
#ifdef CONFIG_MCAST_TFTP
-/* Credits: atftp project.
+/*
+ * Credits: atftp project.
*/
-/* pick up BcastAddr, Port, and whether I am [now] the master-client. *
+/*
+ * Pick up BcastAddr, Port, and whether I am [now] the master-client.
* Frame:
* +-------+-----------+---+-------~~-------+---+
* | opc | multicast | 0 | addr, port, mc | 0 |
@@ -876,75 +884,80 @@ TftpStartServer(void)
static void parse_multicast_oack(char *pkt, int len)
{
int i;
- IPaddr_t addr;
- char *mc_adr, *port, *mc;
-
- mc_adr = port = mc = NULL;
+ struct in_addr addr;
+ char *mc_adr;
+ char *port;
+ char *mc;
+
+ mc_adr = NULL;
+ port = NULL;
+ mc = NULL;
/* march along looking for 'multicast\0', which has to start at least
* 14 bytes back from the end.
*/
- for (i = 0; i < len-14; i++)
- if (strcmp(pkt+i, "multicast") == 0)
+ for (i = 0; i < len - 14; i++)
+ if (strcmp(pkt + i, "multicast") == 0)
break;
- if (i >= (len-14)) /* non-Multicast OACK, ign. */
+ if (i >= (len - 14)) /* non-Multicast OACK, ign. */
return;
i += 10; /* strlen multicast */
- mc_adr = pkt+i;
+ mc_adr = pkt + i;
for (; i < len; i++) {
- if (*(pkt+i) == ',') {
- *(pkt+i) = '\0';
+ if (*(pkt + i) == ',') {
+ *(pkt + i) = '\0';
if (port) {
- mc = pkt+i+1;
+ mc = pkt + i + 1;
break;
} else {
- port = pkt+i+1;
+ port = pkt + i + 1;
}
}
}
if (!port || !mc_adr || !mc)
return;
- if (Multicast && MasterClient) {
+ if (tftp_mcast_active && tftp_mcast_master_client) {
printf("I got a OACK as master Client, WRONG!\n");
return;
}
/* ..I now accept packets destined for this MCAST addr, port */
- if (!Multicast) {
- if (Bitmap) {
+ if (!tftp_mcast_active) {
+ if (tftp_mcast_bitmap) {
printf("Internal failure! no mcast.\n");
- free(Bitmap);
- Bitmap = NULL;
- ProhibitMcast = 1;
- return ;
+ free(tftp_mcast_bitmap);
+ tftp_mcast_bitmap = NULL;
+ tftp_mcast_disabled = 1;
+ return;
}
/* I malloc instead of pre-declare; so that if the file ends
* up being too big for this bitmap I can retry
*/
- Bitmap = malloc(Mapsize);
- if (!Bitmap) {
- printf("No Bitmap, no multicast. Sorry.\n");
- ProhibitMcast = 1;
+ tftp_mcast_bitmap = malloc(tftp_mcast_bitmap_size);
+ if (!tftp_mcast_bitmap) {
+ printf("No bitmap, no multicast. Sorry.\n");
+ tftp_mcast_disabled = 1;
return;
}
- memset(Bitmap, 0, Mapsize);
- PrevBitmapHole = 0;
- Multicast = 1;
+ memset(tftp_mcast_bitmap, 0, tftp_mcast_bitmap_size);
+ tftp_mcast_prev_hole = 0;
+ tftp_mcast_active = 1;
}
addr = string_to_ip(mc_adr);
- if (Mcast_addr != addr) {
- if (Mcast_addr)
- eth_mcast_join(Mcast_addr, 0);
- Mcast_addr = addr;
- if (eth_mcast_join(Mcast_addr, 1)) {
+ if (net_mcast_addr.s_addr != addr.s_addr) {
+ if (net_mcast_addr.s_addr)
+ eth_mcast_join(net_mcast_addr, 0);
+ net_mcast_addr = addr;
+ if (eth_mcast_join(net_mcast_addr, 1)) {
printf("Fail to set mcast, revert to TFTP\n");
- ProhibitMcast = 1;
+ tftp_mcast_disabled = 1;
mcast_cleanup();
- NetStartAgain();
+ net_start_again();
}
}
- MasterClient = (unsigned char)simple_strtoul((char *)mc, NULL, 10);
- Mcast_port = (unsigned short)simple_strtoul(port, NULL, 10);
- printf("Multicast: %s:%d [%d]\n", mc_adr, Mcast_port, MasterClient);
+ tftp_mcast_master_client = simple_strtoul((char *)mc, NULL, 10);
+ tftp_mcast_port = (unsigned short)simple_strtoul(port, NULL, 10);
+ printf("Multicast: %s:%d [%d]\n", mc_adr, tftp_mcast_port,
+ tftp_mcast_master_client);
return;
}
diff --git a/net/tftp.h b/net/tftp.h
index 2b686e3ca6..c411c9b2e6 100644
--- a/net/tftp.h
+++ b/net/tftp.h
@@ -16,14 +16,14 @@
*/
/* tftp.c */
-void TftpStart(enum proto_t protocol); /* Begin TFTP get/put */
+void tftp_start(enum proto_t protocol); /* Begin TFTP get/put */
#ifdef CONFIG_CMD_TFTPSRV
-extern void TftpStartServer(void); /* Wait for incoming TFTP put */
+void tftp_start_server(void); /* Wait for incoming TFTP put */
#endif
-extern ulong TftpRRQTimeoutMSecs;
-extern int TftpRRQTimeoutCountMax;
+extern ulong tftp_timeout_ms;
+extern int tftp_timeout_count_max;
/**********************************************************************/
diff --git a/post/cpu/mpc8xx/ether.c b/post/cpu/mpc8xx/ether.c
index 3a8b483e3c..1b75eb6fb8 100644
--- a/post/cpu/mpc8xx/ether.c
+++ b/post/cpu/mpc8xx/ether.c
@@ -212,7 +212,7 @@ static void scc_init (int scc_index)
for (i = 0; i < PKTBUFSRX; i++) {
rtx->rxbd[i].cbd_sc = BD_ENET_RX_EMPTY;
rtx->rxbd[i].cbd_datlen = 0; /* Reset */
- rtx->rxbd[i].cbd_bufaddr = (uint) NetRxPackets[i];
+ rtx->rxbd[i].cbd_bufaddr = (uint) net_rx_packets[i];
}
rtx->rxbd[PKTBUFSRX - 1].cbd_sc |= BD_ENET_RX_WRAP;
@@ -405,8 +405,8 @@ static int scc_recv (int index, void *packet, int max_length)
if (!(rtx->rxbd[rxIdx].cbd_sc & 0x003f)) {
length = rtx->rxbd[rxIdx].cbd_datlen - 4;
memcpy (packet,
- (void *) (NetRxPackets[rxIdx]),
- length < max_length ? length : max_length);
+ (void *)(net_rx_packets[rxIdx]),
+ length < max_length ? length : max_length);
}
/* Give the buffer back to the SCC. */
diff --git a/scripts/Makefile.spl b/scripts/Makefile.spl
index fcacb7fcb4..ea671378d0 100644
--- a/scripts/Makefile.spl
+++ b/scripts/Makefile.spl
@@ -149,7 +149,7 @@ endif
boot.bin: $(obj)/u-boot-spl.bin
$(call if_changed,mkimage)
-ALL-y += $(obj)/$(SPL_BIN).bin
+ALL-y += $(obj)/$(SPL_BIN).bin $(obj)/$(SPL_BIN).cfg
ifdef CONFIG_SAMSUNG
ALL-y += $(obj)/$(BOARD)-spl.bin
@@ -165,6 +165,13 @@ endif
all: $(ALL-y)
+quiet_cmd_cpp_cfg = CFG $@
+cmd_cpp_cfg = $(CPP) -Wp,-MD,$(depfile) $(cpp_flags) $(LDPPFLAGS) -ansi \
+ -D__ASSEMBLY__ -x assembler-with-cpp -P -dM -E -o $@ $<
+
+$(obj)/$(SPL_BIN).cfg: include/config.h
+ $(call if_changed,cpp_cfg)
+
ifdef CONFIG_SAMSUNG
ifdef CONFIG_VAR_SIZE_SPL
VAR_SIZE_PARAM = --vs
diff --git a/test/compression.c b/test/compression.c
index ea2e4ad22e..7ef3a8c9f5 100644
--- a/test/compression.c
+++ b/test/compression.c
@@ -10,6 +10,7 @@
#include <bootm.h>
#include <command.h>
#include <malloc.h>
+#include <mapmem.h>
#include <asm/io.h>
#include <u-boot/zlib.h>
diff --git a/test/dm/Makefile b/test/dm/Makefile
index 612aa957fa..fd9e29f201 100644
--- a/test/dm/Makefile
+++ b/test/dm/Makefile
@@ -17,8 +17,11 @@ obj-$(CONFIG_DM_TEST) += ut.o
obj-$(CONFIG_DM_TEST) += core.o
obj-$(CONFIG_DM_TEST) += ut.o
ifneq ($(CONFIG_SANDBOX),)
+obj-$(CONFIG_DM_ETH) += eth.o
obj-$(CONFIG_DM_GPIO) += gpio.o
-obj-$(CONFIG_DM_SPI) += spi.o
-obj-$(CONFIG_DM_SPI_FLASH) += sf.o
obj-$(CONFIG_DM_I2C) += i2c.o
+obj-$(CONFIG_DM_PCI) += pci.o
+obj-$(CONFIG_DM_SPI_FLASH) += sf.o
+obj-$(CONFIG_DM_SPI) += spi.o
+obj-$(CONFIG_DM_USB) += usb.o
endif
diff --git a/test/dm/bus.c b/test/dm/bus.c
index faffe6a385..116a52db59 100644
--- a/test/dm/bus.c
+++ b/test/dm/bus.c
@@ -273,20 +273,22 @@ DM_TEST(dm_test_bus_parent_data, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
/* As above but the size is controlled by the uclass */
static int dm_test_bus_parent_data_uclass(struct dm_test_state *dms)
{
+ struct driver *drv;
struct udevice *bus;
int size;
int ret;
/* Set the driver size to 0 so that the uclass size is used */
ut_assertok(uclass_find_device(UCLASS_TEST_BUS, 0, &bus));
- size = bus->driver->per_child_auto_alloc_size;
+ drv = (struct driver *)bus->driver;
+ size = drv->per_child_auto_alloc_size;
bus->uclass->uc_drv->per_child_auto_alloc_size = size;
- bus->driver->per_child_auto_alloc_size = 0;
+ drv->per_child_auto_alloc_size = 0;
ret = test_bus_parent_data(dms);
if (ret)
return ret;
bus->uclass->uc_drv->per_child_auto_alloc_size = 0;
- bus->driver->per_child_auto_alloc_size = size;
+ drv->per_child_auto_alloc_size = size;
return 0;
}
@@ -414,19 +416,21 @@ DM_TEST(dm_test_bus_parent_platdata, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
static int dm_test_bus_parent_platdata_uclass(struct dm_test_state *dms)
{
struct udevice *bus;
+ struct driver *drv;
int size;
int ret;
/* Set the driver size to 0 so that the uclass size is used */
ut_assertok(uclass_find_device(UCLASS_TEST_BUS, 0, &bus));
- size = bus->driver->per_child_platdata_auto_alloc_size;
+ drv = (struct driver *)bus->driver;
+ size = drv->per_child_platdata_auto_alloc_size;
bus->uclass->uc_drv->per_child_platdata_auto_alloc_size = size;
- bus->driver->per_child_platdata_auto_alloc_size = 0;
+ drv->per_child_platdata_auto_alloc_size = 0;
ret = test_bus_parent_platdata(dms);
if (ret)
return ret;
bus->uclass->uc_drv->per_child_platdata_auto_alloc_size = 0;
- bus->driver->per_child_platdata_auto_alloc_size = size;
+ drv->per_child_platdata_auto_alloc_size = size;
return 0;
}
diff --git a/test/dm/cmd_dm.c b/test/dm/cmd_dm.c
index 79a674efcc..2f527e959b 100644
--- a/test/dm/cmd_dm.c
+++ b/test/dm/cmd_dm.c
@@ -10,6 +10,7 @@
#include <common.h>
#include <dm.h>
#include <malloc.h>
+#include <mapmem.h>
#include <errno.h>
#include <asm/io.h>
#include <dm/root.h>
@@ -77,8 +78,8 @@ static void dm_display_line(struct udevice *dev)
printf("- %c %s @ %08lx",
dev->flags & DM_FLAG_ACTIVATED ? '*' : ' ',
dev->name, (ulong)map_to_sysmem(dev));
- if (dev->req_seq != -1)
- printf(", %d", dev->req_seq);
+ if (dev->seq != -1 || dev->req_seq != -1)
+ printf(", seq %d, (req %d)", dev->seq, dev->req_seq);
puts("\n");
}
@@ -112,7 +113,12 @@ static int do_dm_dump_uclass(cmd_tbl_t *cmdtp, int flag, int argc,
static int do_dm_test(cmd_tbl_t *cmdtp, int flag, int argc,
char * const argv[])
{
- return dm_test_main();
+ const char *test_name = NULL;
+
+ if (argc > 0)
+ test_name = argv[0];
+
+ return dm_test_main(test_name);
}
#define TEST_HELP "\ndm test Run tests"
#else
@@ -132,7 +138,7 @@ static int do_dm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
cmd_tbl_t *test_cmd;
int ret;
- if (argc != 2)
+ if (argc < 2)
return CMD_RET_USAGE;
test_cmd = find_cmd_tbl(argv[1], test_commands,
ARRAY_SIZE(test_commands));
@@ -147,7 +153,7 @@ static int do_dm(cmd_tbl_t *cmdtp, int flag, int argc, char * const argv[])
}
U_BOOT_CMD(
- dm, 2, 1, do_dm,
+ dm, 3, 1, do_dm,
"Driver model low level access",
"tree Dump driver model tree ('*' = activated)\n"
"dm uclass Dump list of instances for each uclass"
diff --git a/test/dm/core.c b/test/dm/core.c
index eccda0974d..990d390d01 100644
--- a/test/dm/core.c
+++ b/test/dm/core.c
@@ -141,6 +141,7 @@ static int dm_test_autoprobe(struct dm_test_state *dms)
ut_assert(uc);
ut_asserteq(1, dm_testdrv_op_count[DM_TEST_OP_INIT]);
+ ut_asserteq(0, dm_testdrv_op_count[DM_TEST_OP_PRE_PROBE]);
ut_asserteq(0, dm_testdrv_op_count[DM_TEST_OP_POST_PROBE]);
/* The root device should not be activated until needed */
@@ -167,8 +168,12 @@ static int dm_test_autoprobe(struct dm_test_state *dms)
ut_assert(dms->root->flags & DM_FLAG_ACTIVATED);
}
- /* Our 3 dm_test_infox children should be passed to post_probe */
+ /*
+ * Our 3 dm_test_info children should be passed to pre_probe and
+ * post_probe
+ */
ut_asserteq(3, dm_testdrv_op_count[DM_TEST_OP_POST_PROBE]);
+ ut_asserteq(3, dm_testdrv_op_count[DM_TEST_OP_PRE_PROBE]);
/* Also we can check the per-device data */
expected_base_add = 0;
@@ -179,7 +184,7 @@ static int dm_test_autoprobe(struct dm_test_state *dms)
ut_assertok(uclass_find_device(UCLASS_TEST, i, &dev));
ut_assert(dev);
- priv = dev->uclass_priv;
+ priv = dev_get_uclass_priv(dev);
ut_assert(priv);
ut_asserteq(expected_base_add, priv->base_add);
diff --git a/test/dm/eth.c b/test/dm/eth.c
new file mode 100644
index 0000000000..4891f3ad34
--- /dev/null
+++ b/test/dm/eth.c
@@ -0,0 +1,156 @@
+/*
+ * Copyright (c) 2015 National Instruments
+ *
+ * (C) Copyright 2015
+ * Joe Hershberger <joe.hershberger@ni.com>
+ *
+ * SPDX-License-Identifier: GPL-2.0
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <dm/test.h>
+#include <dm/ut.h>
+#include <fdtdec.h>
+#include <malloc.h>
+#include <net.h>
+#include <asm/eth.h>
+
+DECLARE_GLOBAL_DATA_PTR;
+
+static int dm_test_eth(struct dm_test_state *dms)
+{
+ net_ping_ip = string_to_ip("1.1.2.2");
+
+ setenv("ethact", "eth@10002000");
+ ut_assertok(net_loop(PING));
+ ut_asserteq_str("eth@10002000", getenv("ethact"));
+
+ setenv("ethact", "eth@10003000");
+ ut_assertok(net_loop(PING));
+ ut_asserteq_str("eth@10003000", getenv("ethact"));
+
+ setenv("ethact", "eth@10004000");
+ ut_assertok(net_loop(PING));
+ ut_asserteq_str("eth@10004000", getenv("ethact"));
+
+ return 0;
+}
+DM_TEST(dm_test_eth, DM_TESTF_SCAN_FDT);
+
+static int dm_test_eth_alias(struct dm_test_state *dms)
+{
+ net_ping_ip = string_to_ip("1.1.2.2");
+ setenv("ethact", "eth0");
+ ut_assertok(net_loop(PING));
+ ut_asserteq_str("eth@10002000", getenv("ethact"));
+
+ setenv("ethact", "eth1");
+ ut_assertok(net_loop(PING));
+ ut_asserteq_str("eth@10004000", getenv("ethact"));
+
+ /* Expected to fail since eth2 is not defined in the device tree */
+ setenv("ethact", "eth2");
+ ut_assertok(net_loop(PING));
+ ut_asserteq_str("eth@10002000", getenv("ethact"));
+
+ setenv("ethact", "eth5");
+ ut_assertok(net_loop(PING));
+ ut_asserteq_str("eth@10003000", getenv("ethact"));
+
+ return 0;
+}
+DM_TEST(dm_test_eth_alias, DM_TESTF_SCAN_FDT);
+
+static int dm_test_eth_prime(struct dm_test_state *dms)
+{
+ net_ping_ip = string_to_ip("1.1.2.2");
+
+ /* Expected to be "eth@10003000" because of ethprime variable */
+ setenv("ethact", NULL);
+ setenv("ethprime", "eth5");
+ ut_assertok(net_loop(PING));
+ ut_asserteq_str("eth@10003000", getenv("ethact"));
+
+ /* Expected to be "eth@10002000" because it is first */
+ setenv("ethact", NULL);
+ setenv("ethprime", NULL);
+ ut_assertok(net_loop(PING));
+ ut_asserteq_str("eth@10002000", getenv("ethact"));
+
+ return 0;
+}
+DM_TEST(dm_test_eth_prime, DM_TESTF_SCAN_FDT);
+
+static int dm_test_eth_rotate(struct dm_test_state *dms)
+{
+ char ethaddr[18];
+
+ /* Invalidate eth1's MAC address */
+ net_ping_ip = string_to_ip("1.1.2.2");
+ strcpy(ethaddr, getenv("eth1addr"));
+ setenv("eth1addr", NULL);
+
+ /* Make sure that the default is to rotate to the next interface */
+ setenv("ethact", "eth@10004000");
+ ut_assertok(net_loop(PING));
+ ut_asserteq_str("eth@10002000", getenv("ethact"));
+
+ /* If ethrotate is no, then we should fail on a bad MAC */
+ setenv("ethact", "eth@10004000");
+ setenv("ethrotate", "no");
+ ut_asserteq(-EINVAL, net_loop(PING));
+ ut_asserteq_str("eth@10004000", getenv("ethact"));
+
+ /* Restore the env */
+ setenv("eth1addr", ethaddr);
+ setenv("ethrotate", NULL);
+
+ /* Invalidate eth0's MAC address */
+ strcpy(ethaddr, getenv("ethaddr"));
+ setenv(".flags", "ethaddr");
+ setenv("ethaddr", NULL);
+
+ /* Make sure we can skip invalid devices */
+ setenv("ethact", "eth@10004000");
+ ut_assertok(net_loop(PING));
+ ut_asserteq_str("eth@10004000", getenv("ethact"));
+
+ /* Restore the env */
+ setenv("ethaddr", ethaddr);
+ setenv(".flags", NULL);
+
+ return 0;
+}
+DM_TEST(dm_test_eth_rotate, DM_TESTF_SCAN_FDT);
+
+static int dm_test_net_retry(struct dm_test_state *dms)
+{
+ net_ping_ip = string_to_ip("1.1.2.2");
+
+ /*
+ * eth1 is disabled and netretry is yes, so the ping should succeed and
+ * the active device should be eth0
+ */
+ sandbox_eth_disable_response(1, true);
+ setenv("ethact", "eth@10004000");
+ setenv("netretry", "yes");
+ ut_assertok(net_loop(PING));
+ ut_asserteq_str("eth@10002000", getenv("ethact"));
+
+ /*
+ * eth1 is disabled and netretry is no, so the ping should fail and the
+ * active device should be eth1
+ */
+ setenv("ethact", "eth@10004000");
+ setenv("netretry", "no");
+ ut_asserteq(-ETIMEDOUT, net_loop(PING));
+ ut_asserteq_str("eth@10004000", getenv("ethact"));
+
+ /* Restore the env */
+ setenv("netretry", NULL);
+ sandbox_eth_disable_response(1, false);
+
+ return 0;
+}
+DM_TEST(dm_test_net_retry, DM_TESTF_SCAN_FDT);
diff --git a/test/dm/pci.c b/test/dm/pci.c
new file mode 100644
index 0000000000..6c63fa4c1f
--- /dev/null
+++ b/test/dm/pci.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright (C) 2015 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <asm/io.h>
+#include <dm/test.h>
+#include <dm/ut.h>
+
+/* Test that sandbox PCI works correctly */
+static int dm_test_pci_base(struct dm_test_state *dms)
+{
+ struct udevice *bus;
+
+ ut_assertok(uclass_get_device(UCLASS_PCI, 0, &bus));
+
+ return 0;
+}
+DM_TEST(dm_test_pci_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/* Test that we can use the swapcase device correctly */
+static int dm_test_pci_swapcase(struct dm_test_state *dms)
+{
+ pci_dev_t pci_dev = PCI_BDF(0, 0x1f, 0);
+ struct pci_controller *hose;
+ struct udevice *bus, *swap;
+ ulong io_addr, mem_addr;
+ char *ptr;
+
+ /* Check that asking for the device automatically fires up PCI */
+ ut_assertok(uclass_get_device(UCLASS_PCI_EMUL, 0, &swap));
+
+ ut_assertok(uclass_get_device(UCLASS_PCI, 0, &bus));
+ hose = dev_get_uclass_priv(bus);
+
+ /* First test I/O */
+ io_addr = pci_read_bar32(hose, pci_dev, 0);
+ outb(2, io_addr);
+ ut_asserteq(2, inb(io_addr));
+
+ /*
+ * Now test memory mapping - note we must unmap and remap to cause
+ * the swapcase emulation to see our data and response.
+ */
+ mem_addr = pci_read_bar32(hose, pci_dev, 1);
+ ptr = map_sysmem(mem_addr, 20);
+ strcpy(ptr, "This is a TesT");
+ unmap_sysmem(ptr);
+
+ ptr = map_sysmem(mem_addr, 20);
+ ut_asserteq_str("tHIS IS A tESt", ptr);
+ unmap_sysmem(ptr);
+
+ return 0;
+}
+DM_TEST(dm_test_pci_swapcase, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
diff --git a/test/dm/test-dm.sh b/test/dm/test-dm.sh
index 8ebc39297c..6158f6833f 100755
--- a/test/dm/test-dm.sh
+++ b/test/dm/test-dm.sh
@@ -10,5 +10,8 @@ dtc -I dts -O dtb test/dm/test.dts -o test/dm/test.dtb
make O=sandbox sandbox_config || die "Cannot configure U-Boot"
make O=sandbox -s -j${NUM_CPUS} || die "Cannot build U-Boot"
dd if=/dev/zero of=spi.bin bs=1M count=2
+echo -n "this is a test" > testflash.bin
+dd if=/dev/zero bs=1M count=4 >>testflash.bin
./sandbox/u-boot -d test/dm/test.dtb -c "dm test"
rm spi.bin
+rm testflash.bin
diff --git a/test/dm/test-main.c b/test/dm/test-main.c
index 90ca81092f..a47bb37022 100644
--- a/test/dm/test-main.c
+++ b/test/dm/test-main.c
@@ -65,7 +65,7 @@ static int dm_test_destroy(struct dm_test_state *dms)
return 0;
}
-int dm_test_main(void)
+int dm_test_main(const char *test_name)
{
struct dm_test *tests = ll_entry_start(struct dm_test, dm_test);
const int n_ents = ll_entry_count(struct dm_test, dm_test);
@@ -83,9 +83,12 @@ int dm_test_main(void)
ut_assert(gd->fdt_blob);
}
- printf("Running %d driver model tests\n", n_ents);
+ if (!test_name)
+ printf("Running %d driver model tests\n", n_ents);
for (test = tests; test < tests + n_ents; test++) {
+ if (test_name && strcmp(test_name, test->name))
+ continue;
printf("Test: %s\n", test->name);
ut_assertok(dm_test_init(dms));
diff --git a/test/dm/test-uclass.c b/test/dm/test-uclass.c
index 017e097928..7cb37f70c7 100644
--- a/test/dm/test-uclass.c
+++ b/test/dm/test-uclass.c
@@ -31,6 +31,7 @@ int test_ping(struct udevice *dev, int pingval, int *pingret)
static int test_post_bind(struct udevice *dev)
{
dm_testdrv_op_count[DM_TEST_OP_POST_BIND]++;
+ ut_assert(!device_active(dev));
return 0;
}
@@ -42,12 +43,23 @@ static int test_pre_unbind(struct udevice *dev)
return 0;
}
+static int test_pre_probe(struct udevice *dev)
+{
+ struct dm_test_uclass_perdev_priv *priv = dev_get_uclass_priv(dev);
+
+ dm_testdrv_op_count[DM_TEST_OP_PRE_PROBE]++;
+ ut_assert(priv);
+ ut_assert(device_active(dev));
+
+ return 0;
+}
+
static int test_post_probe(struct udevice *dev)
{
struct udevice *prev = list_entry(dev->uclass_node.prev,
struct udevice, uclass_node);
- struct dm_test_uclass_perdev_priv *priv = dev->uclass_priv;
+ struct dm_test_uclass_perdev_priv *priv = dev_get_uclass_priv(dev);
struct uclass *uc = dev->uclass;
dm_testdrv_op_count[DM_TEST_OP_POST_PROBE]++;
@@ -58,7 +70,7 @@ static int test_post_probe(struct udevice *dev)
return 0;
if (&prev->uclass_node != &uc->dev_head) {
struct dm_test_uclass_perdev_priv *prev_uc_priv
- = prev->uclass_priv;
+ = dev_get_uclass_priv(prev);
struct dm_test_pdata *pdata = prev->platdata;
ut_assert(pdata);
@@ -96,6 +108,7 @@ UCLASS_DRIVER(test) = {
.id = UCLASS_TEST,
.post_bind = test_post_bind,
.pre_unbind = test_pre_unbind,
+ .pre_probe = test_pre_probe,
.post_probe = test_post_probe,
.pre_remove = test_pre_remove,
.init = test_init,
diff --git a/test/dm/test.dts b/test/dm/test.dts
index 84024a44a3..d0c40be6b0 100644
--- a/test/dm/test.dts
+++ b/test/dm/test.dts
@@ -10,6 +10,7 @@
console = &uart0;
i2c0 = "/i2c@0";
spi0 = "/spi@0";
+ pci0 = &pci;
testfdt6 = "/e-test";
testbus3 = "/some-bus";
testfdt0 = "/some-bus/c-test@0";
@@ -17,6 +18,11 @@
testfdt3 = "/b-test";
testfdt5 = "/some-bus/c-test@5";
testfdt8 = "/a-test";
+ eth0 = "/eth@10002000";
+ eth5 = &eth_5;
+ usb0 = &usb_0;
+ usb1 = &usb_1;
+ usb2 = &usb_2;
};
uart0: serial {
@@ -135,6 +141,22 @@
};
};
+ pci: pci-controller {
+ compatible = "sandbox,pci";
+ device_type = "pci";
+ #address-cells = <3>;
+ #size-cells = <2>;
+ ranges = <0x02000000 0 0x10000000 0x10000000 0 0x2000
+ 0x01000000 0 0x20000000 0x20000000 0 0x2000>;
+ pci@1f,0 {
+ compatible = "pci-generic";
+ reg = <0xf800 0 0 0 0>;
+ emul@1f,0 {
+ compatible = "sandbox,swap-case";
+ };
+ };
+ };
+
spi@0 {
#address-cells = <1>;
#size-cells = <0>;
@@ -149,4 +171,60 @@
};
};
+ eth@10002000 {
+ compatible = "sandbox,eth";
+ reg = <0x10002000 0x1000>;
+ fake-host-hwaddr = <0x00 0x00 0x66 0x44 0x22 0x00>;
+ };
+
+ eth_5: eth@10003000 {
+ compatible = "sandbox,eth";
+ reg = <0x10003000 0x1000>;
+ fake-host-hwaddr = <0x00 0x00 0x66 0x44 0x22 0x11>;
+ };
+
+ eth@10004000 {
+ compatible = "sandbox,eth";
+ reg = <0x10004000 0x1000>;
+ fake-host-hwaddr = <0x00 0x00 0x66 0x44 0x22 0x22>;
+ };
+
+ usb_0: usb@0 {
+ compatible = "sandbox,usb";
+ status = "disabled";
+ hub {
+ compatible = "sandbox,usb-hub";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ flash-stick {
+ reg = <0>;
+ compatible = "sandbox,usb-flash";
+ };
+ };
+ };
+
+ usb_1: usb@1 {
+ compatible = "sandbox,usb";
+ hub {
+ compatible = "usb-hub";
+ usb,device-class = <9>;
+ hub-emul {
+ compatible = "sandbox,usb-hub";
+ #address-cells = <1>;
+ #size-cells = <0>;
+ flash-stick {
+ reg = <0>;
+ compatible = "sandbox,usb-flash";
+ sandbox,filepath = "testflash.bin";
+ };
+
+ };
+ };
+ };
+
+ usb_2: usb@2 {
+ compatible = "sandbox,usb";
+ status = "disabled";
+ };
+
};
diff --git a/test/dm/usb.c b/test/dm/usb.c
new file mode 100644
index 0000000000..6ea86d7247
--- /dev/null
+++ b/test/dm/usb.c
@@ -0,0 +1,50 @@
+/*
+ * Copyright (C) 2015 Google, Inc
+ *
+ * SPDX-License-Identifier: GPL-2.0+
+ */
+
+#include <common.h>
+#include <dm.h>
+#include <usb.h>
+#include <asm/io.h>
+#include <dm/test.h>
+#include <dm/ut.h>
+
+/* Test that sandbox USB works correctly */
+static int dm_test_usb_base(struct dm_test_state *dms)
+{
+ struct udevice *bus;
+
+ ut_asserteq(-ENODEV, uclass_get_device_by_seq(UCLASS_USB, 0, &bus));
+ ut_assertok(uclass_get_device(UCLASS_USB, 0, &bus));
+ ut_asserteq(-ENODEV, uclass_get_device_by_seq(UCLASS_USB, 2, &bus));
+
+ return 0;
+}
+DM_TEST(dm_test_usb_base, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
+
+/*
+ * Test that we can use the flash stick. This is more of a functional test. It
+ * covers scanning the bug, setting up a hub and a flash stick and reading
+ * data from the flash stick.
+ */
+static int dm_test_usb_flash(struct dm_test_state *dms)
+{
+ struct udevice *dev;
+ block_dev_desc_t *dev_desc;
+ char cmp[1024];
+
+ ut_assertok(usb_init());
+ ut_assertok(uclass_get_device(UCLASS_MASS_STORAGE, 0, &dev));
+ ut_assertok(get_device("usb", "0", &dev_desc));
+
+ /* Read a few blocks and look for the string we expect */
+ ut_asserteq(512, dev_desc->blksz);
+ memset(cmp, '\0', sizeof(cmp));
+ ut_asserteq(2, dev_desc->block_read(dev_desc->dev, 0, 2, cmp));
+ ut_assertok(strcmp(cmp, "this is a test"));
+
+ return 0;
+}
+DM_TEST(dm_test_usb_flash, DM_TESTF_SCAN_PDATA | DM_TESTF_SCAN_FDT);
diff --git a/tools/buildman/builder.py b/tools/buildman/builder.py
index 54f3292208..c7d3c86968 100644
--- a/tools/buildman/builder.py
+++ b/tools/buildman/builder.py
@@ -96,6 +96,13 @@ OUTCOME_OK, OUTCOME_WARNING, OUTCOME_ERROR, OUTCOME_UNKNOWN = range(4)
# Translate a commit subject into a valid filename
trans_valid_chars = string.maketrans("/: ", "---")
+CONFIG_FILENAMES = [
+ '.config', '.config-spl', '.config-tpl',
+ 'autoconf.mk', 'autoconf-spl.mk', 'autoconf-tpl.mk',
+ 'autoconf.h', 'autoconf-spl.h','autoconf-tpl.h',
+ 'u-boot.cfg', 'u-boot-spl.cfg', 'u-boot-tpl.cfg'
+]
+
class Builder:
"""Class for building U-Boot for a particular commit.
@@ -166,12 +173,17 @@ class Builder:
value is itself a dictionary:
key: function name
value: Size of function in bytes
+ config: Dictionary keyed by filename - e.g. '.config'. Each
+ value is itself a dictionary:
+ key: config name
+ value: config value
"""
- def __init__(self, rc, err_lines, sizes, func_sizes):
+ def __init__(self, rc, err_lines, sizes, func_sizes, config):
self.rc = rc
self.err_lines = err_lines
self.sizes = sizes
self.func_sizes = func_sizes
+ self.config = config
def __init__(self, toolchains, base_dir, git_dir, num_threads, num_jobs,
gnu_make='make', checkout=True, show_unknown=True, step=1,
@@ -254,7 +266,7 @@ class Builder:
def SetDisplayOptions(self, show_errors=False, show_sizes=False,
show_detail=False, show_bloat=False,
- list_error_boards=False):
+ list_error_boards=False, show_config=False):
"""Setup display options for the builder.
show_errors: True to show summarised error/warning info
@@ -262,12 +274,14 @@ class Builder:
show_detail: Show detail for each board
show_bloat: Show detail for each function
list_error_boards: Show the boards which caused each error/warning
+ show_config: Show config deltas
"""
self._show_errors = show_errors
self._show_sizes = show_sizes
self._show_detail = show_detail
self._show_bloat = show_bloat
self._list_error_boards = list_error_boards
+ self._show_config = show_config
def _AddTimestamp(self):
"""Add a new timestamp to the list and record the build period.
@@ -335,6 +349,9 @@ class Builder:
cmd = [self.gnu_make] + list(args)
result = command.RunPipe([cmd], capture=True, capture_stderr=True,
cwd=cwd, raise_on_error=False, **kwargs)
+ if self.verbose_build:
+ result.stdout = '%s\n' % (' '.join(cmd)) + result.stdout
+ result.combined = '%s\n' % (' '.join(cmd)) + result.combined
return result
def ProcessResult(self, result):
@@ -516,13 +533,50 @@ class Builder:
sym[name] = sym.get(name, 0) + int(size, 16)
return sym
- def GetBuildOutcome(self, commit_upto, target, read_func_sizes):
+ def _ProcessConfig(self, fname):
+ """Read in a .config, autoconf.mk or autoconf.h file
+
+ This function handles all config file types. It ignores comments and
+ any #defines which don't start with CONFIG_.
+
+ Args:
+ fname: Filename to read
+
+ Returns:
+ Dictionary:
+ key: Config name (e.g. CONFIG_DM)
+ value: Config value (e.g. 1)
+ """
+ config = {}
+ if os.path.exists(fname):
+ with open(fname) as fd:
+ for line in fd:
+ line = line.strip()
+ if line.startswith('#define'):
+ values = line[8:].split(' ', 1)
+ if len(values) > 1:
+ key, value = values
+ else:
+ key = values[0]
+ value = ''
+ if not key.startswith('CONFIG_'):
+ continue
+ elif not line or line[0] in ['#', '*', '/']:
+ continue
+ else:
+ key, value = line.split('=', 1)
+ config[key] = value
+ return config
+
+ def GetBuildOutcome(self, commit_upto, target, read_func_sizes,
+ read_config):
"""Work out the outcome of a build.
Args:
commit_upto: Commit number to check (0..n-1)
target: Target board to check
read_func_sizes: True to read function size information
+ read_config: True to read .config and autoconf.h files
Returns:
Outcome object
@@ -531,6 +585,7 @@ class Builder:
sizes_file = self.GetSizesFile(commit_upto, target)
sizes = {}
func_sizes = {}
+ config = {}
if os.path.exists(done_file):
with open(done_file, 'r') as fd:
return_code = int(fd.readline())
@@ -574,17 +629,25 @@ class Builder:
'')
func_sizes[dict_name] = self.ReadFuncSizes(fname, fd)
- return Builder.Outcome(rc, err_lines, sizes, func_sizes)
+ if read_config:
+ output_dir = self.GetBuildDir(commit_upto, target)
+ for name in CONFIG_FILENAMES:
+ fname = os.path.join(output_dir, name)
+ config[name] = self._ProcessConfig(fname)
+
+ return Builder.Outcome(rc, err_lines, sizes, func_sizes, config)
- return Builder.Outcome(OUTCOME_UNKNOWN, [], {}, {})
+ return Builder.Outcome(OUTCOME_UNKNOWN, [], {}, {}, {})
- def GetResultSummary(self, boards_selected, commit_upto, read_func_sizes):
+ def GetResultSummary(self, boards_selected, commit_upto, read_func_sizes,
+ read_config):
"""Calculate a summary of the results of building a commit.
Args:
board_selected: Dict containing boards to summarise
commit_upto: Commit number to summarize (0..self.count-1)
read_func_sizes: True to read function size information
+ read_config: True to read .config and autoconf.h files
Returns:
Tuple:
@@ -596,6 +659,10 @@ class Builder:
List containing a summary of warning lines
Dict keyed by error line, containing a list of the Board
objects with that warning
+ Dictionary keyed by filename - e.g. '.config'. Each
+ value is itself a dictionary:
+ key: config name
+ value: config value
"""
def AddLine(lines_summary, lines_boards, line, board):
line = line.rstrip()
@@ -610,10 +677,13 @@ class Builder:
err_lines_boards = {}
warn_lines_summary = []
warn_lines_boards = {}
+ config = {}
+ for fname in CONFIG_FILENAMES:
+ config[fname] = {}
for board in boards_selected.itervalues():
outcome = self.GetBuildOutcome(commit_upto, board.target,
- read_func_sizes)
+ read_func_sizes, read_config)
board_dict[board.target] = outcome
last_func = None
last_was_warning = False
@@ -639,8 +709,14 @@ class Builder:
line, board)
last_was_warning = is_warning
last_func = None
+ for fname in CONFIG_FILENAMES:
+ config[fname] = {}
+ if outcome.config:
+ for key, value in outcome.config[fname].iteritems():
+ config[fname][key] = value
+
return (board_dict, err_lines_summary, err_lines_boards,
- warn_lines_summary, warn_lines_boards)
+ warn_lines_summary, warn_lines_boards, config)
def AddOutcome(self, board_dict, arch_list, changes, char, color):
"""Add an output to our list of outcomes for each architecture
@@ -693,11 +769,14 @@ class Builder:
"""
self._base_board_dict = {}
for board in board_selected:
- self._base_board_dict[board] = Builder.Outcome(0, [], [], {})
+ self._base_board_dict[board] = Builder.Outcome(0, [], [], {}, {})
self._base_err_lines = []
self._base_warn_lines = []
self._base_err_line_boards = {}
self._base_warn_line_boards = {}
+ self._base_config = {}
+ for fname in CONFIG_FILENAMES:
+ self._base_config[fname] = {}
def PrintFuncSizeDetail(self, fname, old, new):
grow, shrink, add, remove, up, down = 0, 0, 0, 0, 0, 0
@@ -892,7 +971,8 @@ class Builder:
def PrintResultSummary(self, board_selected, board_dict, err_lines,
err_line_boards, warn_lines, warn_line_boards,
- show_sizes, show_detail, show_bloat):
+ config, show_sizes, show_detail, show_bloat,
+ show_config):
"""Compare results with the base results and display delta.
Only boards mentioned in board_selected will be considered. This
@@ -913,9 +993,14 @@ class Builder:
none, or we don't want to print errors
warn_line_boards: Dict keyed by warning line, containing a list of
the Board objects with that warning
+ config: Dictionary keyed by filename - e.g. '.config'. Each
+ value is itself a dictionary:
+ key: config name
+ value: config value
show_sizes: Show image size deltas
show_detail: Show detail for each board
show_bloat: Show detail for each function
+ show_config: Show config changes
"""
def _BoardList(line, line_boards):
"""Helper function to get a line of boards containing a line
@@ -950,6 +1035,48 @@ class Builder:
_BoardList(line, base_line_boards) + line)
return better_lines, worse_lines
+ def _CalcConfig(delta, name, config):
+ """Calculate configuration changes
+
+ Args:
+ delta: Type of the delta, e.g. '+'
+ name: name of the file which changed (e.g. .config)
+ config: configuration change dictionary
+ key: config name
+ value: config value
+ Returns:
+ String containing the configuration changes which can be
+ printed
+ """
+ out = ''
+ for key in sorted(config.keys()):
+ out += '%s=%s ' % (key, config[key])
+ return '%5s %s: %s' % (delta, name, out)
+
+ def _ShowConfig(name, config_plus, config_minus, config_change):
+ """Show changes in configuration
+
+ Args:
+ config_plus: configurations added, dictionary
+ key: config name
+ value: config value
+ config_minus: configurations removed, dictionary
+ key: config name
+ value: config value
+ config_change: configurations changed, dictionary
+ key: config name
+ value: config value
+ """
+ if config_plus:
+ Print(_CalcConfig('+', name, config_plus),
+ colour=self.col.GREEN)
+ if config_minus:
+ Print(_CalcConfig('-', name, config_minus),
+ colour=self.col.RED)
+ if config_change:
+ Print(_CalcConfig('+/-', name, config_change),
+ colour=self.col.YELLOW)
+
better = [] # List of boards fixed since last commit
worse = [] # List of new broken boards since last commit
new = [] # List of boards that didn't exist last time
@@ -1010,12 +1137,42 @@ class Builder:
self.PrintSizeSummary(board_selected, board_dict, show_detail,
show_bloat)
+ if show_config:
+ all_config_plus = {}
+ all_config_minus = {}
+ all_config_change = {}
+ for name in CONFIG_FILENAMES:
+ if not config[name]:
+ continue
+ config_plus = {}
+ config_minus = {}
+ config_change = {}
+ base = self._base_config[name]
+ for key, value in config[name].iteritems():
+ if key not in base:
+ config_plus[key] = value
+ all_config_plus[key] = value
+ for key, value in base.iteritems():
+ if key not in config[name]:
+ config_minus[key] = value
+ all_config_minus[key] = value
+ for key, value in base.iteritems():
+ new_value = base[key]
+ if key in config[name] and value != new_value:
+ desc = '%s -> %s' % (value, new_value)
+ config_change[key] = desc
+ all_config_change[key] = desc
+ _ShowConfig(name, config_plus, config_minus, config_change)
+ _ShowConfig('all', all_config_plus, all_config_minus,
+ all_config_change)
+
# Save our updated information for the next call to this function
self._base_board_dict = board_dict
self._base_err_lines = err_lines
self._base_warn_lines = warn_lines
self._base_err_line_boards = err_line_boards
self._base_warn_line_boards = warn_line_boards
+ self._base_config = config
# Get a list of boards that did not get built, if needed
not_built = []
@@ -1028,9 +1185,10 @@ class Builder:
def ProduceResultSummary(self, commit_upto, commits, board_selected):
(board_dict, err_lines, err_line_boards, warn_lines,
- warn_line_boards) = self.GetResultSummary(
+ warn_line_boards, config) = self.GetResultSummary(
board_selected, commit_upto,
- read_func_sizes=self._show_bloat)
+ read_func_sizes=self._show_bloat,
+ read_config=self._show_config)
if commits:
msg = '%02d: %s' % (commit_upto + 1,
commits[commit_upto].subject)
@@ -1038,7 +1196,8 @@ class Builder:
self.PrintResultSummary(board_selected, board_dict,
err_lines if self._show_errors else [], err_line_boards,
warn_lines if self._show_errors else [], warn_line_boards,
- self._show_sizes, self._show_detail, self._show_bloat)
+ config, self._show_sizes, self._show_detail,
+ self._show_bloat, self._show_config)
def ShowSummary(self, commits, board_selected):
"""Show a build summary for U-Boot for a given board list.
diff --git a/tools/buildman/builderthread.py b/tools/buildman/builderthread.py
index efb62f16d7..ce1cfddf8c 100644
--- a/tools/buildman/builderthread.py
+++ b/tools/buildman/builderthread.py
@@ -12,6 +12,8 @@ import threading
import command
import gitutil
+RETURN_CODE_RETRY = -1
+
def Mkdir(dirname, parents = False):
"""Make a directory if it doesn't already exist.
@@ -145,7 +147,11 @@ class BuilderThread(threading.Thread):
# Get the return code from that build and use it
with open(done_file, 'r') as fd:
result.return_code = int(fd.readline())
- if will_build:
+
+ # Check the signal that the build needs to be retried
+ if result.return_code == RETURN_CODE_RETRY:
+ will_build = True
+ elif will_build:
err_file = self.builder.GetErrFile(commit_upto, brd.target)
if os.path.exists(err_file) and os.stat(err_file).st_size:
result.stderr = 'bad'
@@ -197,7 +203,9 @@ class BuilderThread(threading.Thread):
src_dir = os.getcwd()
else:
args.append('O=build')
- if not self.builder.verbose_build:
+ if self.builder.verbose_build:
+ args.append('V=1')
+ else:
args.append('-s')
if self.builder.num_jobs is not None:
args.extend(['-j', str(self.builder.num_jobs)])
@@ -209,14 +217,17 @@ class BuilderThread(threading.Thread):
if do_config:
result = self.Make(commit, brd, 'mrproper', cwd,
'mrproper', *args, env=env)
+ config_out = result.combined
result = self.Make(commit, brd, 'config', cwd,
*(args + config_args), env=env)
- config_out = result.combined
+ config_out += result.combined
do_config = False # No need to configure next time
if result.return_code == 0:
result = self.Make(commit, brd, 'build', cwd, *args,
env=env)
result.stderr = result.stderr.replace(src_dir + '/', '')
+ if self.builder.verbose_build:
+ result.stdout = config_out + result.stdout
else:
result.return_code = 1
result.stderr = 'No tool chain for %s\n' % brd.arch
@@ -240,9 +251,10 @@ class BuilderThread(threading.Thread):
if result.return_code < 0:
return
- # Aborted?
- if result.stderr and 'No child processes' in result.stderr:
- return
+ # If we think this might have been aborted with Ctrl-C, record the
+ # failure but not that we are 'done' with this board. A retry may fix
+ # it.
+ maybe_aborted = result.stderr and 'No child processes' in result.stderr
if result.already_done:
return
@@ -272,7 +284,11 @@ class BuilderThread(threading.Thread):
done_file = self.builder.GetDoneFile(result.commit_upto,
result.brd.target)
with open(done_file, 'w') as fd:
- fd.write('%s' % result.return_code)
+ if maybe_aborted:
+ # Special code to indicate we need to retry
+ fd.write('%s' % RETURN_CODE_RETRY)
+ else:
+ fd.write('%s' % result.return_code)
with open(os.path.join(build_dir, 'toolchain'), 'w') as fd:
print >>fd, 'gcc', result.toolchain.gcc
print >>fd, 'path', result.toolchain.path
@@ -331,16 +347,37 @@ class BuilderThread(threading.Thread):
with open(sizes, 'w') as fd:
print >>fd, '\n'.join(lines)
+ # Write out the configuration files, with a special case for SPL
+ for dirname in ['', 'spl', 'tpl']:
+ self.CopyFiles(result.out_dir, build_dir, dirname, ['u-boot.cfg',
+ 'spl/u-boot-spl.cfg', 'tpl/u-boot-tpl.cfg', '.config',
+ 'include/autoconf.mk', 'include/generated/autoconf.h'])
+
# Now write the actual build output
if keep_outputs:
- patterns = ['u-boot', '*.bin', 'u-boot.dtb', '*.map', '*.img',
- 'include/autoconf.mk', 'spl/u-boot-spl',
- 'spl/u-boot-spl.bin']
- for pattern in patterns:
- file_list = glob.glob(os.path.join(result.out_dir, pattern))
- for fname in file_list:
- shutil.copy(fname, build_dir)
+ self.CopyFiles(result.out_dir, build_dir, '', ['u-boot*', '*.bin',
+ '*.map', '*.img', 'MLO', 'include/autoconf.mk',
+ 'spl/u-boot-spl*'])
+ def CopyFiles(self, out_dir, build_dir, dirname, patterns):
+ """Copy files from the build directory to the output.
+
+ Args:
+ out_dir: Path to output directory containing the files
+ build_dir: Place to copy the files
+ dirname: Source directory, '' for normal U-Boot, 'spl' for SPL
+ patterns: A list of filenames (strings) to copy, each relative
+ to the build directory
+ """
+ for pattern in patterns:
+ file_list = glob.glob(os.path.join(out_dir, dirname, pattern))
+ for fname in file_list:
+ target = os.path.basename(fname)
+ if dirname:
+ base, ext = os.path.splitext(target)
+ if ext:
+ target = '%s-%s%s' % (base, dirname, ext)
+ shutil.copy(fname, os.path.join(build_dir, target))
def RunJob(self, job):
"""Run a single job
diff --git a/tools/buildman/cmdline.py b/tools/buildman/cmdline.py
index e8a6dadd1c..916ea57157 100644
--- a/tools/buildman/cmdline.py
+++ b/tools/buildman/cmdline.py
@@ -16,7 +16,7 @@ def ParseArgs():
"""
parser = OptionParser()
parser.add_option('-b', '--branch', type='string',
- help='Branch name to build')
+ help='Branch name to build, or range of commits to build')
parser.add_option('-B', '--bloat', dest='show_bloat',
action='store_true', default=False,
help='Show changes in function code size for each board')
@@ -53,6 +53,8 @@ def ParseArgs():
default=None, help='Number of jobs to run at once (passed to make)')
parser.add_option('-k', '--keep-outputs', action='store_true',
default=False, help='Keep all build output files (e.g. binaries)')
+ parser.add_option('-K', '--show-config', action='store_true',
+ default=False, help='Show configuration changes in summary (both board config files and Kconfig)')
parser.add_option('-l', '--list-error-boards', action='store_true',
default=False, help='Show a list of boards next to each error/warning')
parser.add_option('--list-tool-chains', action='store_true', default=False,
diff --git a/tools/buildman/control.py b/tools/buildman/control.py
index 720b978b23..8b3cd30c00 100644
--- a/tools/buildman/control.py
+++ b/tools/buildman/control.py
@@ -282,7 +282,8 @@ def DoBuildman(options, args, toolchains=None, make_func=None, boards=None,
options.show_detail = True
builder.SetDisplayOptions(options.show_errors, options.show_sizes,
options.show_detail, options.show_bloat,
- options.list_error_boards)
+ options.list_error_boards,
+ options.show_config)
if options.summary:
builder.ShowSummary(commits, board_selected)
else:
diff --git a/tools/patman/patchstream.py b/tools/patman/patchstream.py
index 8c3a0ec9ee..6d3c41f49e 100644
--- a/tools/patman/patchstream.py
+++ b/tools/patman/patchstream.py
@@ -3,6 +3,7 @@
# SPDX-License-Identifier: GPL-2.0+
#
+import math
import os
import re
import shutil
@@ -468,8 +469,10 @@ def InsertCoverLetter(fname, series, count):
prefix = series.GetPatchPrefix()
for line in lines:
if line.startswith('Subject:'):
- # TODO: if more than 10 patches this should save 00/xx, not 0/xx
- line = 'Subject: [%s 0/%d] %s\n' % (prefix, count, text[0])
+ # if more than 10 or 100 patches, it should say 00/xx, 000/xxx, etc
+ zero_repeat = int(math.log10(count)) + 1
+ zero = '0' * zero_repeat
+ line = 'Subject: [%s %s/%d] %s\n' % (prefix, zero, count, text[0])
# Insert our cover letter
elif line.startswith('*** BLURB HERE ***'):