mirror of
https://github.com/brain-hackers/u-boot-brain
synced 2024-08-10 20:23:54 +09:00
Merge branch '2020-06-12-next-net' into next
- Merge tbs2910 distro boot support and associated clean-ups and size reduction. - Assorted networking corrections / bugfixes. - Drop smc911x standalone API example as it was likely non-functional for a long time. - Enhanced support for TI PHYs - rtl8139 DM conversion
This commit is contained in:
commit
8a1292ce3e
@ -4,4 +4,5 @@ S: Maintained
|
|||||||
F: arch/arm/dts/imx6q-tbs2910.dts
|
F: arch/arm/dts/imx6q-tbs2910.dts
|
||||||
F: board/tbs/tbs2910/
|
F: board/tbs/tbs2910/
|
||||||
F: configs/tbs2910_defconfig
|
F: configs/tbs2910_defconfig
|
||||||
|
F: doc/board/tbs/
|
||||||
F: include/configs/tbs2910.h
|
F: include/configs/tbs2910.h
|
||||||
|
@ -135,11 +135,15 @@ static void netboot_update_env(void)
|
|||||||
env_set("netmask", tmp);
|
env_set("netmask", tmp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CONFIG_CMD_BOOTP
|
||||||
if (net_hostname[0])
|
if (net_hostname[0])
|
||||||
env_set("hostname", net_hostname);
|
env_set("hostname", net_hostname);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_CMD_BOOTP
|
||||||
if (net_root_path[0])
|
if (net_root_path[0])
|
||||||
env_set("rootpath", net_root_path);
|
env_set("rootpath", net_root_path);
|
||||||
|
#endif
|
||||||
|
|
||||||
if (net_ip.s_addr) {
|
if (net_ip.s_addr) {
|
||||||
ip_to_string(net_ip, tmp);
|
ip_to_string(net_ip, tmp);
|
||||||
@ -165,8 +169,10 @@ static void netboot_update_env(void)
|
|||||||
env_set("dnsip2", tmp);
|
env_set("dnsip2", tmp);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
#ifdef CONFIG_CMD_BOOTP
|
||||||
if (net_nis_domain[0])
|
if (net_nis_domain[0])
|
||||||
env_set("domain", net_nis_domain);
|
env_set("domain", net_nis_domain);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(CONFIG_CMD_SNTP) && defined(CONFIG_BOOTP_TIMEOFFSET)
|
#if defined(CONFIG_CMD_SNTP) && defined(CONFIG_BOOTP_TIMEOFFSET)
|
||||||
if (net_ntp_time_offset) {
|
if (net_ntp_time_offset) {
|
||||||
|
@ -99,7 +99,7 @@ CONFIG_SPI_FLASH_SFDP_SUPPORT=y
|
|||||||
CONFIG_SPI_FLASH_STMICRO=y
|
CONFIG_SPI_FLASH_STMICRO=y
|
||||||
# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
|
# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
|
||||||
CONFIG_SPI_FLASH_MTD=y
|
CONFIG_SPI_FLASH_MTD=y
|
||||||
CONFIG_PHY_TI=y
|
CONFIG_PHY_TI_DP83867=y
|
||||||
CONFIG_PHY_FIXED=y
|
CONFIG_PHY_FIXED=y
|
||||||
CONFIG_DM_ETH=y
|
CONFIG_DM_ETH=y
|
||||||
CONFIG_E1000=y
|
CONFIG_E1000=y
|
||||||
|
@ -101,7 +101,7 @@ CONFIG_SPI_FLASH_SFDP_SUPPORT=y
|
|||||||
CONFIG_SPI_FLASH_STMICRO=y
|
CONFIG_SPI_FLASH_STMICRO=y
|
||||||
# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
|
# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
|
||||||
CONFIG_SPI_FLASH_MTD=y
|
CONFIG_SPI_FLASH_MTD=y
|
||||||
CONFIG_PHY_TI=y
|
CONFIG_PHY_TI_DP83867=y
|
||||||
CONFIG_PHY_FIXED=y
|
CONFIG_PHY_FIXED=y
|
||||||
CONFIG_DM_ETH=y
|
CONFIG_DM_ETH=y
|
||||||
CONFIG_E1000=y
|
CONFIG_E1000=y
|
||||||
|
@ -86,7 +86,7 @@ CONFIG_DM_SPI_FLASH=y
|
|||||||
CONFIG_SF_DEFAULT_MODE=0
|
CONFIG_SF_DEFAULT_MODE=0
|
||||||
CONFIG_SF_DEFAULT_SPEED=76800000
|
CONFIG_SF_DEFAULT_SPEED=76800000
|
||||||
CONFIG_SPI_FLASH_SPANSION=y
|
CONFIG_SPI_FLASH_SPANSION=y
|
||||||
CONFIG_PHY_TI=y
|
CONFIG_PHY_TI_DP83867=y
|
||||||
CONFIG_DM_ETH=y
|
CONFIG_DM_ETH=y
|
||||||
CONFIG_PHY_GIGE=y
|
CONFIG_PHY_GIGE=y
|
||||||
CONFIG_MII=y
|
CONFIG_MII=y
|
||||||
|
@ -89,7 +89,7 @@ CONFIG_DM_SPI_FLASH=y
|
|||||||
CONFIG_SF_DEFAULT_MODE=0
|
CONFIG_SF_DEFAULT_MODE=0
|
||||||
CONFIG_SF_DEFAULT_SPEED=76800000
|
CONFIG_SF_DEFAULT_SPEED=76800000
|
||||||
CONFIG_SPI_FLASH_SPANSION=y
|
CONFIG_SPI_FLASH_SPANSION=y
|
||||||
CONFIG_PHY_TI=y
|
CONFIG_PHY_TI_DP83867=y
|
||||||
CONFIG_DM_ETH=y
|
CONFIG_DM_ETH=y
|
||||||
CONFIG_PHY_GIGE=y
|
CONFIG_PHY_GIGE=y
|
||||||
CONFIG_MII=y
|
CONFIG_MII=y
|
||||||
|
@ -87,7 +87,7 @@ CONFIG_SF_DEFAULT_MODE=0
|
|||||||
CONFIG_SF_DEFAULT_SPEED=76800000
|
CONFIG_SF_DEFAULT_SPEED=76800000
|
||||||
CONFIG_SPI_FLASH_BAR=y
|
CONFIG_SPI_FLASH_BAR=y
|
||||||
CONFIG_SPI_FLASH_SPANSION=y
|
CONFIG_SPI_FLASH_SPANSION=y
|
||||||
CONFIG_PHY_TI=y
|
CONFIG_PHY_TI_DP83867=y
|
||||||
CONFIG_DM_ETH=y
|
CONFIG_DM_ETH=y
|
||||||
CONFIG_PHY_GIGE=y
|
CONFIG_PHY_GIGE=y
|
||||||
CONFIG_MII=y
|
CONFIG_MII=y
|
||||||
|
@ -123,7 +123,7 @@ CONFIG_DM_SPI_FLASH=y
|
|||||||
CONFIG_SPI_FLASH_STMICRO=y
|
CONFIG_SPI_FLASH_STMICRO=y
|
||||||
# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
|
# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
|
||||||
CONFIG_SPI_FLASH_MTD=y
|
CONFIG_SPI_FLASH_MTD=y
|
||||||
CONFIG_PHY_TI=y
|
CONFIG_PHY_TI_DP83867=y
|
||||||
CONFIG_PHY_FIXED=y
|
CONFIG_PHY_FIXED=y
|
||||||
CONFIG_DM_ETH=y
|
CONFIG_DM_ETH=y
|
||||||
CONFIG_TI_AM65_CPSW_NUSS=y
|
CONFIG_TI_AM65_CPSW_NUSS=y
|
||||||
|
@ -113,7 +113,7 @@ CONFIG_DM_SPI_FLASH=y
|
|||||||
CONFIG_SPI_FLASH_STMICRO=y
|
CONFIG_SPI_FLASH_STMICRO=y
|
||||||
# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
|
# CONFIG_SPI_FLASH_USE_4K_SECTORS is not set
|
||||||
CONFIG_SPI_FLASH_MTD=y
|
CONFIG_SPI_FLASH_MTD=y
|
||||||
CONFIG_PHY_TI=y
|
CONFIG_PHY_TI_DP83867=y
|
||||||
CONFIG_PHY_FIXED=y
|
CONFIG_PHY_FIXED=y
|
||||||
CONFIG_DM_ETH=y
|
CONFIG_DM_ETH=y
|
||||||
CONFIG_TI_AM65_CPSW_NUSS=y
|
CONFIG_TI_AM65_CPSW_NUSS=y
|
||||||
|
@ -58,7 +58,7 @@ CONFIG_PHYLIB=y
|
|||||||
CONFIG_PHY_MARVELL=y
|
CONFIG_PHY_MARVELL=y
|
||||||
CONFIG_PHY_MICREL=y
|
CONFIG_PHY_MICREL=y
|
||||||
CONFIG_PHY_MICREL_KSZ8XXX=y
|
CONFIG_PHY_MICREL_KSZ8XXX=y
|
||||||
CONFIG_PHY_TI=y
|
CONFIG_PHY_TI_DP83867=y
|
||||||
CONFIG_DM_ETH=y
|
CONFIG_DM_ETH=y
|
||||||
CONFIG_MII=y
|
CONFIG_MII=y
|
||||||
CONFIG_DRIVER_TI_KEYSTONE_NET=y
|
CONFIG_DRIVER_TI_KEYSTONE_NET=y
|
||||||
|
@ -9,11 +9,15 @@ CONFIG_NR_DRAM_BANKS=1
|
|||||||
CONFIG_PRE_CON_BUF_ADDR=0x7c000000
|
CONFIG_PRE_CON_BUF_ADDR=0x7c000000
|
||||||
CONFIG_CMD_HDMIDETECT=y
|
CONFIG_CMD_HDMIDETECT=y
|
||||||
CONFIG_AHCI=y
|
CONFIG_AHCI=y
|
||||||
|
CONFIG_ENV_VARS_UBOOT_CONFIG=y
|
||||||
CONFIG_BOOTDELAY=3
|
CONFIG_BOOTDELAY=3
|
||||||
|
CONFIG_USE_BOOTCOMMAND=y
|
||||||
|
CONFIG_BOOTCOMMAND="mmc rescan; if run bootcmd_up1; then run bootcmd_up2; else run bootcmd_mmc || run distro_bootcmd; fi"
|
||||||
CONFIG_USE_PREBOOT=y
|
CONFIG_USE_PREBOOT=y
|
||||||
CONFIG_PREBOOT="echo PCI:; pci enum; pci 1; usb start; if hdmidet; then run set_con_hdmi; else run set_con_serial; fi"
|
CONFIG_PREBOOT="echo PCI:; pci enum; pci 1; usb start; if hdmidet; then run set_con_hdmi; else run set_con_serial; fi"
|
||||||
CONFIG_PRE_CONSOLE_BUFFER=y
|
CONFIG_PRE_CONSOLE_BUFFER=y
|
||||||
CONFIG_SUPPORT_RAW_INITRD=y
|
CONFIG_SUPPORT_RAW_INITRD=y
|
||||||
|
CONFIG_DEFAULT_FDT_FILE="imx6q-tbs2910.dtb"
|
||||||
CONFIG_BOUNCE_BUFFER=y
|
CONFIG_BOUNCE_BUFFER=y
|
||||||
CONFIG_BOARD_EARLY_INIT_F=y
|
CONFIG_BOARD_EARLY_INIT_F=y
|
||||||
CONFIG_HUSH_PARSER=y
|
CONFIG_HUSH_PARSER=y
|
||||||
@ -28,6 +32,8 @@ CONFIG_SYS_MEMTEST_START=0x10000000
|
|||||||
CONFIG_SYS_MEMTEST_END=0x2f400000
|
CONFIG_SYS_MEMTEST_END=0x2f400000
|
||||||
CONFIG_CMD_GPIO=y
|
CONFIG_CMD_GPIO=y
|
||||||
CONFIG_CMD_I2C=y
|
CONFIG_CMD_I2C=y
|
||||||
|
# CONFIG_CMD_LOADB is not set
|
||||||
|
# CONFIG_CMD_LOADS is not set
|
||||||
CONFIG_CMD_MMC=y
|
CONFIG_CMD_MMC=y
|
||||||
CONFIG_CMD_PART=y
|
CONFIG_CMD_PART=y
|
||||||
CONFIG_CMD_PCI=y
|
CONFIG_CMD_PCI=y
|
||||||
@ -39,6 +45,7 @@ CONFIG_CMD_MII=y
|
|||||||
CONFIG_CMD_PING=y
|
CONFIG_CMD_PING=y
|
||||||
CONFIG_CMD_CACHE=y
|
CONFIG_CMD_CACHE=y
|
||||||
CONFIG_CMD_TIME=y
|
CONFIG_CMD_TIME=y
|
||||||
|
CONFIG_CMD_SYSBOOT=y
|
||||||
CONFIG_CMD_EXT2=y
|
CONFIG_CMD_EXT2=y
|
||||||
CONFIG_CMD_EXT4=y
|
CONFIG_CMD_EXT4=y
|
||||||
CONFIG_CMD_EXT4_WRITE=y
|
CONFIG_CMD_EXT4_WRITE=y
|
||||||
@ -86,5 +93,6 @@ CONFIG_USB_GADGET_DOWNLOAD=y
|
|||||||
CONFIG_I2C_EDID=y
|
CONFIG_I2C_EDID=y
|
||||||
CONFIG_VIDEO_IPUV3=y
|
CONFIG_VIDEO_IPUV3=y
|
||||||
CONFIG_VIDEO=y
|
CONFIG_VIDEO=y
|
||||||
|
# CONFIG_GZIP is not set
|
||||||
CONFIG_OF_LIBFDT_ASSUME_MASK=0xff
|
CONFIG_OF_LIBFDT_ASSUME_MASK=0xff
|
||||||
# CONFIG_EFI_LOADER is not set
|
# CONFIG_EFI_LOADER is not set
|
||||||
|
@ -63,7 +63,7 @@ CONFIG_SPI_FLASH_WINBOND=y
|
|||||||
CONFIG_PHY_MARVELL=y
|
CONFIG_PHY_MARVELL=y
|
||||||
CONFIG_PHY_NATSEMI=y
|
CONFIG_PHY_NATSEMI=y
|
||||||
CONFIG_PHY_REALTEK=y
|
CONFIG_PHY_REALTEK=y
|
||||||
CONFIG_PHY_TI=y
|
CONFIG_PHY_TI_DP83867=y
|
||||||
CONFIG_PHY_VITESSE=y
|
CONFIG_PHY_VITESSE=y
|
||||||
CONFIG_PHY_FIXED=y
|
CONFIG_PHY_FIXED=y
|
||||||
CONFIG_PHY_GIGE=y
|
CONFIG_PHY_GIGE=y
|
||||||
|
@ -108,7 +108,7 @@ CONFIG_PHY_MICREL=y
|
|||||||
CONFIG_PHY_MICREL_KSZ90X1=y
|
CONFIG_PHY_MICREL_KSZ90X1=y
|
||||||
CONFIG_PHY_NATSEMI=y
|
CONFIG_PHY_NATSEMI=y
|
||||||
CONFIG_PHY_REALTEK=y
|
CONFIG_PHY_REALTEK=y
|
||||||
CONFIG_PHY_TI=y
|
CONFIG_PHY_TI_DP83867=y
|
||||||
CONFIG_PHY_VITESSE=y
|
CONFIG_PHY_VITESSE=y
|
||||||
CONFIG_PHY_XILINX_GMII2RGMII=y
|
CONFIG_PHY_XILINX_GMII2RGMII=y
|
||||||
CONFIG_PHY_FIXED=y
|
CONFIG_PHY_FIXED=y
|
||||||
|
@ -18,5 +18,6 @@ Board-specific doc
|
|||||||
rockchip/index
|
rockchip/index
|
||||||
sifive/index
|
sifive/index
|
||||||
st/index
|
st/index
|
||||||
|
tbs/index
|
||||||
toradex/index
|
toradex/index
|
||||||
xilinx/index
|
xilinx/index
|
||||||
|
9
doc/board/tbs/index.rst
Normal file
9
doc/board/tbs/index.rst
Normal file
@ -0,0 +1,9 @@
|
|||||||
|
.. SPDX-License-Identifier: GPL-2.0+
|
||||||
|
|
||||||
|
TBS
|
||||||
|
===
|
||||||
|
|
||||||
|
.. toctree::
|
||||||
|
:maxdepth: 2
|
||||||
|
|
||||||
|
tbs2910
|
191
doc/board/tbs/tbs2910.rst
Normal file
191
doc/board/tbs/tbs2910.rst
Normal file
@ -0,0 +1,191 @@
|
|||||||
|
TBS2910 Matrix ARM miniPC
|
||||||
|
=========================
|
||||||
|
|
||||||
|
Building
|
||||||
|
--------
|
||||||
|
To build u-boot for the TBS2910 Matrix ARM miniPC, you can use the following
|
||||||
|
procedure:
|
||||||
|
|
||||||
|
First add the ARM toolchain to your PATH
|
||||||
|
|
||||||
|
Then setup the ARCH and cross compilation environment variables.
|
||||||
|
|
||||||
|
When this is done you can then build u-boot for the TBS2910 Matrix ARM miniPC
|
||||||
|
with the following commands:
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
|
make mrproper
|
||||||
|
make tbs2910_defconfig
|
||||||
|
make
|
||||||
|
|
||||||
|
Once the build is complete, you can find the resulting image as u-boot.imx in
|
||||||
|
the current directory.
|
||||||
|
|
||||||
|
UART
|
||||||
|
----
|
||||||
|
The UART voltage is at 3.3V and its settings are 115200bps 8N1
|
||||||
|
|
||||||
|
BOOT/UPDATE boot switch:
|
||||||
|
------------------------
|
||||||
|
The BOOT/UPDATE switch (SW11) is connected to the BOOT_MODE0 and
|
||||||
|
BOOT_MODE1 SoC pins. It has "BOOT" and "UPDATE" markings both on
|
||||||
|
the PCB and on the plastic case.
|
||||||
|
|
||||||
|
When set to the "UPDATE" position, the SoC will use the "Boot From Fuses"
|
||||||
|
configuration, and since BT_FUSE_SEL is 0, this makes the SOC jump to serial
|
||||||
|
downloader.
|
||||||
|
|
||||||
|
When set in the "BOOT" position, the SoC will use the "Internal boot"
|
||||||
|
configuration, and since BT_FUSE_SEL is 0, it will then use the GPIO pins
|
||||||
|
for the boot configuration.
|
||||||
|
|
||||||
|
SW6 binary DIP switch array on the PCB revision 2.1:
|
||||||
|
----------------------------------------------------
|
||||||
|
On that PCB revision, SW6 has 8 positions.
|
||||||
|
|
||||||
|
Switching a position to ON sets the corresponding
|
||||||
|
register to 1.
|
||||||
|
|
||||||
|
See the following table for a correspondence between the switch positions and
|
||||||
|
registers:
|
||||||
|
|
||||||
|
=============== ============
|
||||||
|
Switch position Register
|
||||||
|
=============== ============
|
||||||
|
1 BOOT_CFG2[3]
|
||||||
|
2 BOOT_CFG2[4]
|
||||||
|
3 BOOT_CFG2[5]
|
||||||
|
4 BOOT_CFG2[6]
|
||||||
|
5 BOOT_CFG1[4]
|
||||||
|
6 BOOT_CFG1[5]
|
||||||
|
7 BOOT_CFG1[6]
|
||||||
|
8 BOOT_CFG1[7]
|
||||||
|
=============== ============
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
- To boot from the eMMC: 1:ON , 2:ON, 3:ON, 4:OFF, 5:OFF, 6:ON, 7:ON, 8:OFF
|
||||||
|
- To boot from the microSD slot: 1: ON, 2: OFF, 3: OFF, 4: OFF, 5:OFF, 6:OFF,
|
||||||
|
7:ON, 8:OFF
|
||||||
|
- To boot from the SD slot: 1: OFF, 2: ON, 3: OFF, 4: OFF, 5:OFF, 6:OFF, 7:ON,
|
||||||
|
8:OFF
|
||||||
|
- To boot from SATA: 1: OFF, 2: OFF, 3: OFF, 4: OFF, 5:OFF, 6:ON, 7:OFF, 8:OFF
|
||||||
|
|
||||||
|
You can refer to the BOOT_CFG registers in the I.MX6Q reference manual for
|
||||||
|
additional details.
|
||||||
|
|
||||||
|
SW6 binary DIP switch array on the PCB revision 2.3:
|
||||||
|
----------------------------------------------------
|
||||||
|
On that PCB revision, SW6 has only 4 positions.
|
||||||
|
|
||||||
|
Switching a position to ON sets the corresponding
|
||||||
|
register to 1.
|
||||||
|
|
||||||
|
See the following table for a correspondence between the switch positions and
|
||||||
|
registers:
|
||||||
|
|
||||||
|
=============== ============
|
||||||
|
Switch position Register
|
||||||
|
=============== ============
|
||||||
|
1 BOOT_CFG2[3]
|
||||||
|
2 BOOT_CFG2[4]
|
||||||
|
3 BOOT_CFG2[5]
|
||||||
|
4 BOOT_CFG1[5]
|
||||||
|
=============== ============
|
||||||
|
|
||||||
|
For example:
|
||||||
|
|
||||||
|
- To boot from the eMMC: 1:ON, 2:ON, 3:ON, 4:ON
|
||||||
|
- To boot from the microSD slot: 1:ON, 2:OFF, 3:OFF, 4:OFF
|
||||||
|
- To boot from the SD slot: 1:OFF, 2:ON, 3:OFF, 4:OFF
|
||||||
|
|
||||||
|
You can refer to the BOOT_CFG registers in the I.MX6Q reference manual for
|
||||||
|
additional details.
|
||||||
|
|
||||||
|
Loading u-boot from USB:
|
||||||
|
------------------------
|
||||||
|
If you need to load u-boot from USB, you can use the following instructions:
|
||||||
|
|
||||||
|
First build imx_usb_loader, as we will need it to load u-boot from USB. This
|
||||||
|
can be done with the following commands:
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
|
git clone git://github.com/boundarydevices/imx_usb_loader.git
|
||||||
|
cd imx_usb_loader
|
||||||
|
make
|
||||||
|
|
||||||
|
This will create the resulting imx_usb binary.
|
||||||
|
|
||||||
|
When this is done, you can copy the u-boot.imx image that you built earlier
|
||||||
|
in in the imx_usb_loader directory.
|
||||||
|
|
||||||
|
You will then need to power off the TBS2910 Matrix ARM miniPC and make sure that
|
||||||
|
the boot switch is set to "UPDATE"
|
||||||
|
|
||||||
|
Once this is done you can connect an USB cable between the computer that will
|
||||||
|
run imx_usb and the TBS2910 Matrix ARM miniPC.
|
||||||
|
|
||||||
|
If you also need to access the u-boot console, you will also need to connect an
|
||||||
|
UART cable between the computer running imx_usb and the TBS2910 Matrix ARM
|
||||||
|
miniPC.
|
||||||
|
|
||||||
|
Once everything is connected you can finally power on the TBS2910 Matrix ARM
|
||||||
|
miniPC. The SoC will then jump to the serial download and wait for you.
|
||||||
|
|
||||||
|
Finlay, you can load u-boot through USB with with the following command:
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
|
sudo ./imx_usb -v u-boot.imx
|
||||||
|
|
||||||
|
The u-boot boot messages will then appear in the serial console.
|
||||||
|
|
||||||
|
Install u-boot on the eMMC:
|
||||||
|
---------------------------
|
||||||
|
To install u-boot on the eMMC, you first need to boot the TBS2910 Matrix ARM
|
||||||
|
miniPC.
|
||||||
|
|
||||||
|
Once booted, you can flash u-boot.imx to mmcblk0boot0 with the
|
||||||
|
following commands:
|
||||||
|
|
||||||
|
.. code-block:: none
|
||||||
|
|
||||||
|
sudo echo 0 >/sys/block/mmcblk0boot0/force_ro
|
||||||
|
sudo dd if=u-boot.imx of=/dev/mmcblk0boot0 bs=1k seek=1; sync
|
||||||
|
|
||||||
|
Note that the eMMC card node may vary, so adjust this as needed.
|
||||||
|
|
||||||
|
Once the new u-boot version is installed, to boot on it you then need to power
|
||||||
|
off the TBS2910 Matrix ARM miniPC.
|
||||||
|
|
||||||
|
Once it is off, you need make sure that the boot switch is set to "BOOT" and
|
||||||
|
that the SW6 switch is set to boot on the eMMC as described in the previous
|
||||||
|
sections.
|
||||||
|
|
||||||
|
If you also need to access the u-boot console, you will also need to connect an
|
||||||
|
UART cable between the computer running imx_usb and the TBS2910 Matrix ARM
|
||||||
|
miniPC.
|
||||||
|
|
||||||
|
You can then power up the TBS2910 Matrix ARM miniPC and U-Boot messages will
|
||||||
|
appear in the serial console.
|
||||||
|
|
||||||
|
Booting a distribution:
|
||||||
|
-----------------------
|
||||||
|
When booting on the TBS2910 Matrix ARM miniPC, by default U-Boot will first try
|
||||||
|
to boot from hardcoded offsets from the start of the eMMC. This is for
|
||||||
|
compatibility with the stock GNU/Linux distribution.
|
||||||
|
|
||||||
|
If that fails it will then try to boot from several interfaces using
|
||||||
|
'distro_bootcmd': It will first try to boot from the microSD slot, then the
|
||||||
|
SD slot, then the internal eMMC, then the SATA interface and finally the USB
|
||||||
|
interface. For more information on how to configure your distribution to boot,
|
||||||
|
see 'README.distro'.
|
||||||
|
|
||||||
|
Links:
|
||||||
|
------
|
||||||
|
- https://www.tbsdtv.com/download/document/tbs2910/TBS2910-Matrix-ARM-mini-PC-SCH_rev2.1.pdf
|
||||||
|
- The schematics for the revision 2.1 of the TBS2910 Matrix ARM miniPC.
|
||||||
|
- https://cache.freescale.com/files/32bit/doc/ref_manual/IMX6DQRM.pdf - The
|
||||||
|
SoC reference manual for additional details on the BOOT_CFG registers.
|
@ -243,6 +243,21 @@ config PHY_TERANETICS
|
|||||||
|
|
||||||
config PHY_TI
|
config PHY_TI
|
||||||
bool "Texas Instruments Ethernet PHYs support"
|
bool "Texas Instruments Ethernet PHYs support"
|
||||||
|
---help---
|
||||||
|
Adds PHY registration support for TI PHYs.
|
||||||
|
|
||||||
|
config PHY_TI_DP83867
|
||||||
|
select PHY_TI
|
||||||
|
bool "Texas Instruments Ethernet DP83867 PHY support"
|
||||||
|
---help---
|
||||||
|
Adds support for the TI DP83867 1Gbit PHY.
|
||||||
|
|
||||||
|
config PHY_TI_GENERIC
|
||||||
|
select PHY_TI
|
||||||
|
bool "Texas Instruments Generic Ethernet PHYs support"
|
||||||
|
---help---
|
||||||
|
Adds support for Generic TI PHYs that don't need special handling but
|
||||||
|
the PHY name is associated with a PHY ID.
|
||||||
|
|
||||||
config PHY_VITESSE
|
config PHY_VITESSE
|
||||||
bool "Vitesse Ethernet PHYs support"
|
bool "Vitesse Ethernet PHYs support"
|
||||||
|
@ -25,7 +25,8 @@ obj-$(CONFIG_PHY_NATSEMI) += natsemi.o
|
|||||||
obj-$(CONFIG_PHY_REALTEK) += realtek.o
|
obj-$(CONFIG_PHY_REALTEK) += realtek.o
|
||||||
obj-$(CONFIG_PHY_SMSC) += smsc.o
|
obj-$(CONFIG_PHY_SMSC) += smsc.o
|
||||||
obj-$(CONFIG_PHY_TERANETICS) += teranetics.o
|
obj-$(CONFIG_PHY_TERANETICS) += teranetics.o
|
||||||
obj-$(CONFIG_PHY_TI) += dp83867.o
|
obj-$(CONFIG_PHY_TI) += ti_phy_init.o
|
||||||
|
obj-$(CONFIG_PHY_TI_DP83867) += dp83867.o
|
||||||
obj-$(CONFIG_PHY_XILINX) += xilinx_phy.o
|
obj-$(CONFIG_PHY_XILINX) += xilinx_phy.o
|
||||||
obj-$(CONFIG_PHY_XILINX_GMII2RGMII) += xilinx_gmii2rgmii.o
|
obj-$(CONFIG_PHY_XILINX_GMII2RGMII) += xilinx_gmii2rgmii.o
|
||||||
obj-$(CONFIG_PHY_VITESSE) += vitesse.o
|
obj-$(CONFIG_PHY_VITESSE) += vitesse.o
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include <dm.h>
|
#include <dm.h>
|
||||||
#include <dt-bindings/net/ti-dp83867.h>
|
#include <dt-bindings/net/ti-dp83867.h>
|
||||||
|
|
||||||
|
#include "ti_phy_init.h"
|
||||||
|
|
||||||
/* TI DP83867 */
|
/* TI DP83867 */
|
||||||
#define DP83867_DEVADDR 0x1f
|
#define DP83867_DEVADDR 0x1f
|
||||||
@ -430,7 +431,7 @@ static struct phy_driver DP83867_driver = {
|
|||||||
.shutdown = &genphy_shutdown,
|
.shutdown = &genphy_shutdown,
|
||||||
};
|
};
|
||||||
|
|
||||||
int phy_ti_init(void)
|
int phy_dp83867_init(void)
|
||||||
{
|
{
|
||||||
phy_register(&DP83867_driver);
|
phy_register(&DP83867_driver);
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -82,6 +82,21 @@ static struct phy_driver KSZ8051_driver = {
|
|||||||
.shutdown = &genphy_shutdown,
|
.shutdown = &genphy_shutdown,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static int ksz8061_config(struct phy_device *phydev)
|
||||||
|
{
|
||||||
|
return phy_write(phydev, MDIO_MMD_PMAPMD, MDIO_DEVID1, 0xB61A);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct phy_driver KSZ8061_driver = {
|
||||||
|
.name = "Micrel KSZ8061",
|
||||||
|
.uid = 0x00221570,
|
||||||
|
.mask = 0xfffff0,
|
||||||
|
.features = PHY_BASIC_FEATURES,
|
||||||
|
.config = &ksz8061_config,
|
||||||
|
.startup = &genphy_startup,
|
||||||
|
.shutdown = &genphy_shutdown,
|
||||||
|
};
|
||||||
|
|
||||||
static int ksz8081_config(struct phy_device *phydev)
|
static int ksz8081_config(struct phy_device *phydev)
|
||||||
{
|
{
|
||||||
int ret;
|
int ret;
|
||||||
@ -210,6 +225,7 @@ int phy_micrel_ksz8xxx_init(void)
|
|||||||
phy_register(&KSZ804_driver);
|
phy_register(&KSZ804_driver);
|
||||||
phy_register(&KSZ8031_driver);
|
phy_register(&KSZ8031_driver);
|
||||||
phy_register(&KSZ8051_driver);
|
phy_register(&KSZ8051_driver);
|
||||||
|
phy_register(&KSZ8061_driver);
|
||||||
phy_register(&KSZ8081_driver);
|
phy_register(&KSZ8081_driver);
|
||||||
phy_register(&KS8721_driver);
|
phy_register(&KS8721_driver);
|
||||||
phy_register(&ksz8895_driver);
|
phy_register(&ksz8895_driver);
|
||||||
|
@ -786,17 +786,27 @@ static struct phy_device *get_phy_device_by_mask(struct mii_dev *bus,
|
|||||||
uint phy_mask,
|
uint phy_mask,
|
||||||
phy_interface_t interface)
|
phy_interface_t interface)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
struct phy_device *phydev;
|
struct phy_device *phydev;
|
||||||
|
int devad[] = {
|
||||||
|
/* Clause-22 */
|
||||||
|
MDIO_DEVAD_NONE,
|
||||||
|
/* Clause-45 */
|
||||||
|
MDIO_MMD_PMAPMD,
|
||||||
|
MDIO_MMD_WIS,
|
||||||
|
MDIO_MMD_PCS,
|
||||||
|
MDIO_MMD_PHYXS,
|
||||||
|
MDIO_MMD_VEND1,
|
||||||
|
};
|
||||||
|
int i, devad_cnt;
|
||||||
|
|
||||||
|
devad_cnt = sizeof(devad)/sizeof(int);
|
||||||
phydev = search_for_existing_phy(bus, phy_mask, interface);
|
phydev = search_for_existing_phy(bus, phy_mask, interface);
|
||||||
if (phydev)
|
if (phydev)
|
||||||
return phydev;
|
return phydev;
|
||||||
/* Try Standard (ie Clause 22) access */
|
/* try different access clauses */
|
||||||
/* Otherwise we have to try Clause 45 */
|
for (i = 0; i < devad_cnt; i++) {
|
||||||
for (i = 0; i < 5; i++) {
|
|
||||||
phydev = create_phy_by_mask(bus, phy_mask,
|
phydev = create_phy_by_mask(bus, phy_mask,
|
||||||
i ? i : MDIO_DEVAD_NONE, interface);
|
devad[i], interface);
|
||||||
if (IS_ERR(phydev))
|
if (IS_ERR(phydev))
|
||||||
return NULL;
|
return NULL;
|
||||||
if (phydev)
|
if (phydev)
|
||||||
|
101
drivers/net/phy/ti_phy_init.c
Normal file
101
drivers/net/phy/ti_phy_init.c
Normal file
@ -0,0 +1,101 @@
|
|||||||
|
// SPDX-License-Identifier: GPL-2.0
|
||||||
|
/*
|
||||||
|
* TI Generic PHY Init to register any TI Ethernet PHYs
|
||||||
|
*
|
||||||
|
* Author: Dan Murphy <dmurphy@ti.com>
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019-20 Texas Instruments Inc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <phy.h>
|
||||||
|
#include "ti_phy_init.h"
|
||||||
|
|
||||||
|
#ifdef CONFIG_PHY_TI_GENERIC
|
||||||
|
static struct phy_driver dp83822_driver = {
|
||||||
|
.name = "TI DP83822",
|
||||||
|
.uid = 0x2000a240,
|
||||||
|
.mask = 0xfffffff0,
|
||||||
|
.features = PHY_BASIC_FEATURES,
|
||||||
|
.config = &genphy_config_aneg,
|
||||||
|
.startup = &genphy_startup,
|
||||||
|
.shutdown = &genphy_shutdown,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct phy_driver dp83826nc_driver = {
|
||||||
|
.name = "TI DP83826NC",
|
||||||
|
.uid = 0x2000a110,
|
||||||
|
.mask = 0xfffffff0,
|
||||||
|
.features = PHY_BASIC_FEATURES,
|
||||||
|
.config = &genphy_config_aneg,
|
||||||
|
.startup = &genphy_startup,
|
||||||
|
.shutdown = &genphy_shutdown,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct phy_driver dp83826c_driver = {
|
||||||
|
.name = "TI DP83826C",
|
||||||
|
.uid = 0x2000a130,
|
||||||
|
.mask = 0xfffffff0,
|
||||||
|
.features = PHY_BASIC_FEATURES,
|
||||||
|
.config = &genphy_config_aneg,
|
||||||
|
.startup = &genphy_startup,
|
||||||
|
.shutdown = &genphy_shutdown,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct phy_driver dp83825s_driver = {
|
||||||
|
.name = "TI DP83825S",
|
||||||
|
.uid = 0x2000a140,
|
||||||
|
.mask = 0xfffffff0,
|
||||||
|
.features = PHY_BASIC_FEATURES,
|
||||||
|
.config = &genphy_config_aneg,
|
||||||
|
.startup = &genphy_startup,
|
||||||
|
.shutdown = &genphy_shutdown,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct phy_driver dp83825i_driver = {
|
||||||
|
.name = "TI DP83825I",
|
||||||
|
.uid = 0x2000a150,
|
||||||
|
.mask = 0xfffffff0,
|
||||||
|
.features = PHY_BASIC_FEATURES,
|
||||||
|
.config = &genphy_config_aneg,
|
||||||
|
.startup = &genphy_startup,
|
||||||
|
.shutdown = &genphy_shutdown,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct phy_driver dp83825m_driver = {
|
||||||
|
.name = "TI DP83825M",
|
||||||
|
.uid = 0x2000a160,
|
||||||
|
.mask = 0xfffffff0,
|
||||||
|
.features = PHY_BASIC_FEATURES,
|
||||||
|
.config = &genphy_config_aneg,
|
||||||
|
.startup = &genphy_startup,
|
||||||
|
.shutdown = &genphy_shutdown,
|
||||||
|
};
|
||||||
|
|
||||||
|
static struct phy_driver dp83825cs_driver = {
|
||||||
|
.name = "TI DP83825CS",
|
||||||
|
.uid = 0x2000a170,
|
||||||
|
.mask = 0xfffffff0,
|
||||||
|
.features = PHY_BASIC_FEATURES,
|
||||||
|
.config = &genphy_config_aneg,
|
||||||
|
.startup = &genphy_startup,
|
||||||
|
.shutdown = &genphy_shutdown,
|
||||||
|
};
|
||||||
|
#endif /* CONFIG_PHY_TI_GENERIC */
|
||||||
|
|
||||||
|
int phy_ti_init(void)
|
||||||
|
{
|
||||||
|
#ifdef CONFIG_PHY_TI_DP83867
|
||||||
|
phy_dp83867_init();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#ifdef CONFIG_PHY_TI_GENERIC
|
||||||
|
phy_register(&dp83822_driver);
|
||||||
|
phy_register(&dp83825s_driver);
|
||||||
|
phy_register(&dp83825i_driver);
|
||||||
|
phy_register(&dp83825m_driver);
|
||||||
|
phy_register(&dp83825cs_driver);
|
||||||
|
phy_register(&dp83826c_driver);
|
||||||
|
phy_register(&dp83826nc_driver);
|
||||||
|
#endif
|
||||||
|
return 0;
|
||||||
|
}
|
15
drivers/net/phy/ti_phy_init.h
Normal file
15
drivers/net/phy/ti_phy_init.h
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
/* SPDX-License-Identifier: GPL-2.0-or-later */
|
||||||
|
/*
|
||||||
|
* TI Generic Ethernet PHY
|
||||||
|
*
|
||||||
|
* Author: Dan Murphy <dmurphy@ti.com>
|
||||||
|
*
|
||||||
|
* Copyright (C) 2019-20 Texas Instruments Inc.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifndef _TI_GEN_PHY_H
|
||||||
|
#define _TI_GEN_PHY_H
|
||||||
|
|
||||||
|
int phy_dp83867_init(void);
|
||||||
|
|
||||||
|
#endif /* _TI_GEN_PHY_H */
|
@ -70,6 +70,7 @@
|
|||||||
|
|
||||||
#include <common.h>
|
#include <common.h>
|
||||||
#include <cpu_func.h>
|
#include <cpu_func.h>
|
||||||
|
#include <dm.h>
|
||||||
#include <log.h>
|
#include <log.h>
|
||||||
#include <malloc.h>
|
#include <malloc.h>
|
||||||
#include <net.h>
|
#include <net.h>
|
||||||
@ -96,8 +97,13 @@
|
|||||||
#define DEBUG_TX 0 /* set to 1 to enable debug code */
|
#define DEBUG_TX 0 /* set to 1 to enable debug code */
|
||||||
#define DEBUG_RX 0 /* set to 1 to enable debug code */
|
#define DEBUG_RX 0 /* set to 1 to enable debug code */
|
||||||
|
|
||||||
#define bus_to_phys(a) pci_mem_to_phys((pci_dev_t)dev->priv, a)
|
#ifdef CONFIG_DM_ETH
|
||||||
#define phys_to_bus(a) pci_phys_to_mem((pci_dev_t)dev->priv, a)
|
#define bus_to_phys(devno, a) dm_pci_mem_to_phys((devno), (a))
|
||||||
|
#define phys_to_bus(devno, a) dm_pci_phys_to_mem((devno), (a))
|
||||||
|
#else
|
||||||
|
#define bus_to_phys(devno, a) pci_mem_to_phys((pci_dev_t)(devno), (a))
|
||||||
|
#define phys_to_bus(devno, a) pci_phys_to_mem((pci_dev_t)(devno), (a))
|
||||||
|
#endif
|
||||||
|
|
||||||
/* Symbolic offsets to registers. */
|
/* Symbolic offsets to registers. */
|
||||||
/* Ethernet hardware address. */
|
/* Ethernet hardware address. */
|
||||||
@ -191,8 +197,19 @@
|
|||||||
#define RTL_STS_RXBADALIGN BIT(1)
|
#define RTL_STS_RXBADALIGN BIT(1)
|
||||||
#define RTL_STS_RXSTATUSOK BIT(0)
|
#define RTL_STS_RXSTATUSOK BIT(0)
|
||||||
|
|
||||||
static unsigned int cur_rx, cur_tx;
|
struct rtl8139_priv {
|
||||||
static int ioaddr;
|
#ifndef CONFIG_DM_ETH
|
||||||
|
struct eth_device dev;
|
||||||
|
pci_dev_t devno;
|
||||||
|
#else
|
||||||
|
struct udevice *devno;
|
||||||
|
#endif
|
||||||
|
unsigned int rxstatus;
|
||||||
|
unsigned int cur_rx;
|
||||||
|
unsigned int cur_tx;
|
||||||
|
unsigned long ioaddr;
|
||||||
|
unsigned char enetaddr[6];
|
||||||
|
};
|
||||||
|
|
||||||
/* The RTL8139 can only transmit from a contiguous, aligned memory block. */
|
/* The RTL8139 can only transmit from a contiguous, aligned memory block. */
|
||||||
static unsigned char tx_buffer[TX_BUF_SIZE] __aligned(4);
|
static unsigned char tx_buffer[TX_BUF_SIZE] __aligned(4);
|
||||||
@ -214,51 +231,52 @@ static unsigned char rx_ring[RX_BUF_LEN + 16] __aligned(4);
|
|||||||
#define EE_READ_CMD 6
|
#define EE_READ_CMD 6
|
||||||
#define EE_ERASE_CMD 7
|
#define EE_ERASE_CMD 7
|
||||||
|
|
||||||
static void rtl8139_eeprom_delay(uintptr_t regbase)
|
static void rtl8139_eeprom_delay(struct rtl8139_priv *priv)
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
* Delay between EEPROM clock transitions.
|
* Delay between EEPROM clock transitions.
|
||||||
* No extra delay is needed with 33MHz PCI, but 66MHz may change this.
|
* No extra delay is needed with 33MHz PCI, but 66MHz may change this.
|
||||||
*/
|
*/
|
||||||
inl(regbase + RTL_REG_CFG9346);
|
inl(priv->ioaddr + RTL_REG_CFG9346);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rtl8139_read_eeprom(unsigned int location, unsigned int addr_len)
|
static int rtl8139_read_eeprom(struct rtl8139_priv *priv,
|
||||||
|
unsigned int location, unsigned int addr_len)
|
||||||
{
|
{
|
||||||
unsigned int read_cmd = location | (EE_READ_CMD << addr_len);
|
unsigned int read_cmd = location | (EE_READ_CMD << addr_len);
|
||||||
uintptr_t ee_addr = ioaddr + RTL_REG_CFG9346;
|
uintptr_t ee_addr = priv->ioaddr + RTL_REG_CFG9346;
|
||||||
unsigned int retval = 0;
|
unsigned int retval = 0;
|
||||||
u8 dataval;
|
u8 dataval;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
outb(EE_ENB & ~EE_CS, ee_addr);
|
outb(EE_ENB & ~EE_CS, ee_addr);
|
||||||
outb(EE_ENB, ee_addr);
|
outb(EE_ENB, ee_addr);
|
||||||
rtl8139_eeprom_delay(ioaddr);
|
rtl8139_eeprom_delay(priv);
|
||||||
|
|
||||||
/* Shift the read command bits out. */
|
/* Shift the read command bits out. */
|
||||||
for (i = 4 + addr_len; i >= 0; i--) {
|
for (i = 4 + addr_len; i >= 0; i--) {
|
||||||
dataval = (read_cmd & BIT(i)) ? EE_DATA_WRITE : 0;
|
dataval = (read_cmd & BIT(i)) ? EE_DATA_WRITE : 0;
|
||||||
outb(EE_ENB | dataval, ee_addr);
|
outb(EE_ENB | dataval, ee_addr);
|
||||||
rtl8139_eeprom_delay(ioaddr);
|
rtl8139_eeprom_delay(priv);
|
||||||
outb(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
|
outb(EE_ENB | dataval | EE_SHIFT_CLK, ee_addr);
|
||||||
rtl8139_eeprom_delay(ioaddr);
|
rtl8139_eeprom_delay(priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
outb(EE_ENB, ee_addr);
|
outb(EE_ENB, ee_addr);
|
||||||
rtl8139_eeprom_delay(ioaddr);
|
rtl8139_eeprom_delay(priv);
|
||||||
|
|
||||||
for (i = 16; i > 0; i--) {
|
for (i = 16; i > 0; i--) {
|
||||||
outb(EE_ENB | EE_SHIFT_CLK, ee_addr);
|
outb(EE_ENB | EE_SHIFT_CLK, ee_addr);
|
||||||
rtl8139_eeprom_delay(ioaddr);
|
rtl8139_eeprom_delay(priv);
|
||||||
retval <<= 1;
|
retval <<= 1;
|
||||||
retval |= inb(ee_addr) & EE_DATA_READ;
|
retval |= inb(ee_addr) & EE_DATA_READ;
|
||||||
outb(EE_ENB, ee_addr);
|
outb(EE_ENB, ee_addr);
|
||||||
rtl8139_eeprom_delay(ioaddr);
|
rtl8139_eeprom_delay(priv);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Terminate the EEPROM access. */
|
/* Terminate the EEPROM access. */
|
||||||
outb(~EE_CS, ee_addr);
|
outb(~EE_CS, ee_addr);
|
||||||
rtl8139_eeprom_delay(ioaddr);
|
rtl8139_eeprom_delay(priv);
|
||||||
|
|
||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
@ -268,29 +286,29 @@ static const unsigned int rtl8139_rx_config =
|
|||||||
(RX_FIFO_THRESH << 13) |
|
(RX_FIFO_THRESH << 13) |
|
||||||
(RX_DMA_BURST << 8);
|
(RX_DMA_BURST << 8);
|
||||||
|
|
||||||
static void rtl8139_set_rx_mode(struct eth_device *dev)
|
static void rtl8139_set_rx_mode(struct rtl8139_priv *priv)
|
||||||
{
|
{
|
||||||
/* !IFF_PROMISC */
|
/* !IFF_PROMISC */
|
||||||
unsigned int rx_mode = RTL_REG_RXCONFIG_ACCEPTBROADCAST |
|
unsigned int rx_mode = RTL_REG_RXCONFIG_ACCEPTBROADCAST |
|
||||||
RTL_REG_RXCONFIG_ACCEPTMULTICAST |
|
RTL_REG_RXCONFIG_ACCEPTMULTICAST |
|
||||||
RTL_REG_RXCONFIG_ACCEPTMYPHYS;
|
RTL_REG_RXCONFIG_ACCEPTMYPHYS;
|
||||||
|
|
||||||
outl(rtl8139_rx_config | rx_mode, ioaddr + RTL_REG_RXCONFIG);
|
outl(rtl8139_rx_config | rx_mode, priv->ioaddr + RTL_REG_RXCONFIG);
|
||||||
|
|
||||||
outl(0xffffffff, ioaddr + RTL_REG_MAR0 + 0);
|
outl(0xffffffff, priv->ioaddr + RTL_REG_MAR0 + 0);
|
||||||
outl(0xffffffff, ioaddr + RTL_REG_MAR0 + 4);
|
outl(0xffffffff, priv->ioaddr + RTL_REG_MAR0 + 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rtl8139_hw_reset(struct eth_device *dev)
|
static void rtl8139_hw_reset(struct rtl8139_priv *priv)
|
||||||
{
|
{
|
||||||
u8 reg;
|
u8 reg;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
outb(RTL_REG_CHIPCMD_CMDRESET, ioaddr + RTL_REG_CHIPCMD);
|
outb(RTL_REG_CHIPCMD_CMDRESET, priv->ioaddr + RTL_REG_CHIPCMD);
|
||||||
|
|
||||||
/* Give the chip 10ms to finish the reset. */
|
/* Give the chip 10ms to finish the reset. */
|
||||||
for (i = 0; i < 100; i++) {
|
for (i = 0; i < 100; i++) {
|
||||||
reg = inb(ioaddr + RTL_REG_CHIPCMD);
|
reg = inb(priv->ioaddr + RTL_REG_CHIPCMD);
|
||||||
if (!(reg & RTL_REG_CHIPCMD_CMDRESET))
|
if (!(reg & RTL_REG_CHIPCMD_CMDRESET))
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -298,25 +316,25 @@ static void rtl8139_hw_reset(struct eth_device *dev)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rtl8139_reset(struct eth_device *dev)
|
static void rtl8139_reset(struct rtl8139_priv *priv)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
cur_rx = 0;
|
priv->cur_rx = 0;
|
||||||
cur_tx = 0;
|
priv->cur_tx = 0;
|
||||||
|
|
||||||
rtl8139_hw_reset(dev);
|
rtl8139_hw_reset(priv);
|
||||||
|
|
||||||
for (i = 0; i < ETH_ALEN; i++)
|
for (i = 0; i < ETH_ALEN; i++)
|
||||||
outb(dev->enetaddr[i], ioaddr + RTL_REG_MAC0 + i);
|
outb(priv->enetaddr[i], priv->ioaddr + RTL_REG_MAC0 + i);
|
||||||
|
|
||||||
/* Must enable Tx/Rx before setting transfer thresholds! */
|
/* Must enable Tx/Rx before setting transfer thresholds! */
|
||||||
outb(RTL_REG_CHIPCMD_CMDRXENB | RTL_REG_CHIPCMD_CMDTXENB,
|
outb(RTL_REG_CHIPCMD_CMDRXENB | RTL_REG_CHIPCMD_CMDTXENB,
|
||||||
ioaddr + RTL_REG_CHIPCMD);
|
priv->ioaddr + RTL_REG_CHIPCMD);
|
||||||
|
|
||||||
/* accept no frames yet! */
|
/* accept no frames yet! */
|
||||||
outl(rtl8139_rx_config, ioaddr + RTL_REG_RXCONFIG);
|
outl(rtl8139_rx_config, priv->ioaddr + RTL_REG_RXCONFIG);
|
||||||
outl((TX_DMA_BURST << 8) | 0x03000000, ioaddr + RTL_REG_TXCONFIG);
|
outl((TX_DMA_BURST << 8) | 0x03000000, priv->ioaddr + RTL_REG_TXCONFIG);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* The Linux driver changes RTL_REG_CONFIG1 here to use a different
|
* The Linux driver changes RTL_REG_CONFIG1 here to use a different
|
||||||
@ -331,7 +349,7 @@ static void rtl8139_reset(struct eth_device *dev)
|
|||||||
debug_cond(DEBUG_RX, "rx ring address is %p\n", rx_ring);
|
debug_cond(DEBUG_RX, "rx ring address is %p\n", rx_ring);
|
||||||
|
|
||||||
flush_cache((unsigned long)rx_ring, RX_BUF_LEN);
|
flush_cache((unsigned long)rx_ring, RX_BUF_LEN);
|
||||||
outl(phys_to_bus((int)rx_ring), ioaddr + RTL_REG_RXBUF);
|
outl(phys_to_bus(priv->devno, (int)rx_ring), priv->ioaddr + RTL_REG_RXBUF);
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If we add multicast support, the RTL_REG_MAR0 register would have
|
* If we add multicast support, the RTL_REG_MAR0 register would have
|
||||||
@ -340,28 +358,27 @@ static void rtl8139_reset(struct eth_device *dev)
|
|||||||
* unicast.
|
* unicast.
|
||||||
*/
|
*/
|
||||||
outb(RTL_REG_CHIPCMD_CMDRXENB | RTL_REG_CHIPCMD_CMDTXENB,
|
outb(RTL_REG_CHIPCMD_CMDRXENB | RTL_REG_CHIPCMD_CMDTXENB,
|
||||||
ioaddr + RTL_REG_CHIPCMD);
|
priv->ioaddr + RTL_REG_CHIPCMD);
|
||||||
|
|
||||||
outl(rtl8139_rx_config, ioaddr + RTL_REG_RXCONFIG);
|
outl(rtl8139_rx_config, priv->ioaddr + RTL_REG_RXCONFIG);
|
||||||
|
|
||||||
/* Start the chip's Tx and Rx process. */
|
/* Start the chip's Tx and Rx process. */
|
||||||
outl(0, ioaddr + RTL_REG_RXMISSED);
|
outl(0, priv->ioaddr + RTL_REG_RXMISSED);
|
||||||
|
|
||||||
rtl8139_set_rx_mode(dev);
|
rtl8139_set_rx_mode(priv);
|
||||||
|
|
||||||
/* Disable all known interrupts by setting the interrupt mask. */
|
/* Disable all known interrupts by setting the interrupt mask. */
|
||||||
outw(0, ioaddr + RTL_REG_INTRMASK);
|
outw(0, priv->ioaddr + RTL_REG_INTRMASK);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rtl8139_send(struct eth_device *dev, void *packet, int length)
|
static int rtl8139_send_common(struct rtl8139_priv *priv,
|
||||||
|
void *packet, int length)
|
||||||
{
|
{
|
||||||
unsigned int len = length;
|
unsigned int len = length;
|
||||||
unsigned long txstatus;
|
unsigned long txstatus;
|
||||||
unsigned int status;
|
unsigned int status;
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
ioaddr = dev->iobase;
|
|
||||||
|
|
||||||
memcpy(tx_buffer, packet, length);
|
memcpy(tx_buffer, packet, length);
|
||||||
|
|
||||||
debug_cond(DEBUG_TX, "sending %d bytes\n", len);
|
debug_cond(DEBUG_TX, "sending %d bytes\n", len);
|
||||||
@ -374,13 +391,13 @@ static int rtl8139_send(struct eth_device *dev, void *packet, int length)
|
|||||||
tx_buffer[len++] = '\0';
|
tx_buffer[len++] = '\0';
|
||||||
|
|
||||||
flush_cache((unsigned long)tx_buffer, length);
|
flush_cache((unsigned long)tx_buffer, length);
|
||||||
outl(phys_to_bus((unsigned long)tx_buffer),
|
outl(phys_to_bus(priv->devno, (unsigned long)tx_buffer),
|
||||||
ioaddr + RTL_REG_TXADDR0 + cur_tx * 4);
|
priv->ioaddr + RTL_REG_TXADDR0 + priv->cur_tx * 4);
|
||||||
outl(((TX_FIFO_THRESH << 11) & 0x003f0000) | len,
|
outl(((TX_FIFO_THRESH << 11) & 0x003f0000) | len,
|
||||||
ioaddr + RTL_REG_TXSTATUS0 + cur_tx * 4);
|
priv->ioaddr + RTL_REG_TXSTATUS0 + priv->cur_tx * 4);
|
||||||
|
|
||||||
do {
|
do {
|
||||||
status = inw(ioaddr + RTL_REG_INTRSTATUS);
|
status = inw(priv->ioaddr + RTL_REG_INTRSTATUS);
|
||||||
/*
|
/*
|
||||||
* Only acknlowledge interrupt sources we can properly
|
* Only acknlowledge interrupt sources we can properly
|
||||||
* handle here - the RTL_REG_INTRSTATUS_RXOVERFLOW/
|
* handle here - the RTL_REG_INTRSTATUS_RXOVERFLOW/
|
||||||
@ -389,26 +406,26 @@ static int rtl8139_send(struct eth_device *dev, void *packet, int length)
|
|||||||
*/
|
*/
|
||||||
status &= RTL_REG_INTRSTATUS_TXOK | RTL_REG_INTRSTATUS_TXERR |
|
status &= RTL_REG_INTRSTATUS_TXOK | RTL_REG_INTRSTATUS_TXERR |
|
||||||
RTL_REG_INTRSTATUS_PCIERR;
|
RTL_REG_INTRSTATUS_PCIERR;
|
||||||
outw(status, ioaddr + RTL_REG_INTRSTATUS);
|
outw(status, priv->ioaddr + RTL_REG_INTRSTATUS);
|
||||||
if (status)
|
if (status)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
udelay(10);
|
udelay(10);
|
||||||
} while (i++ < RTL_TIMEOUT);
|
} while (i++ < RTL_TIMEOUT);
|
||||||
|
|
||||||
txstatus = inl(ioaddr + RTL_REG_TXSTATUS0 + cur_tx * 4);
|
txstatus = inl(priv->ioaddr + RTL_REG_TXSTATUS0 + priv->cur_tx * 4);
|
||||||
|
|
||||||
if (!(status & RTL_REG_INTRSTATUS_TXOK)) {
|
if (!(status & RTL_REG_INTRSTATUS_TXOK)) {
|
||||||
debug_cond(DEBUG_TX,
|
debug_cond(DEBUG_TX,
|
||||||
"tx timeout/error (%d usecs), status %hX txstatus %lX\n",
|
"tx timeout/error (%d usecs), status %hX txstatus %lX\n",
|
||||||
10 * i, status, txstatus);
|
10 * i, status, txstatus);
|
||||||
|
|
||||||
rtl8139_reset(dev);
|
rtl8139_reset(priv);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
cur_tx = (cur_tx + 1) % NUM_TX_DESC;
|
priv->cur_tx = (priv->cur_tx + 1) % NUM_TX_DESC;
|
||||||
|
|
||||||
debug_cond(DEBUG_TX, "tx done, status %hX txstatus %lX\n",
|
debug_cond(DEBUG_TX, "tx done, status %hX txstatus %lX\n",
|
||||||
status, txstatus);
|
status, txstatus);
|
||||||
@ -416,28 +433,26 @@ static int rtl8139_send(struct eth_device *dev, void *packet, int length)
|
|||||||
return length;
|
return length;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rtl8139_recv(struct eth_device *dev)
|
static int rtl8139_recv_common(struct rtl8139_priv *priv, unsigned char *rxdata,
|
||||||
|
uchar **packetp)
|
||||||
{
|
{
|
||||||
const unsigned int rxstat = RTL_REG_INTRSTATUS_RXFIFOOVER |
|
const unsigned int rxstat = RTL_REG_INTRSTATUS_RXFIFOOVER |
|
||||||
RTL_REG_INTRSTATUS_RXOVERFLOW |
|
RTL_REG_INTRSTATUS_RXOVERFLOW |
|
||||||
RTL_REG_INTRSTATUS_RXOK;
|
RTL_REG_INTRSTATUS_RXOK;
|
||||||
unsigned int rx_size, rx_status;
|
unsigned int rx_size, rx_status;
|
||||||
unsigned int ring_offs;
|
unsigned int ring_offs;
|
||||||
unsigned int status;
|
|
||||||
int length = 0;
|
int length = 0;
|
||||||
|
|
||||||
ioaddr = dev->iobase;
|
if (inb(priv->ioaddr + RTL_REG_CHIPCMD) & RTL_REG_CHIPCMD_RXBUFEMPTY)
|
||||||
|
|
||||||
if (inb(ioaddr + RTL_REG_CHIPCMD) & RTL_REG_CHIPCMD_RXBUFEMPTY)
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
status = inw(ioaddr + RTL_REG_INTRSTATUS);
|
priv->rxstatus = inw(priv->ioaddr + RTL_REG_INTRSTATUS);
|
||||||
/* See below for the rest of the interrupt acknowledges. */
|
/* See below for the rest of the interrupt acknowledges. */
|
||||||
outw(status & ~rxstat, ioaddr + RTL_REG_INTRSTATUS);
|
outw(priv->rxstatus & ~rxstat, priv->ioaddr + RTL_REG_INTRSTATUS);
|
||||||
|
|
||||||
debug_cond(DEBUG_RX, "%s: int %hX ", __func__, status);
|
debug_cond(DEBUG_RX, "%s: int %hX ", __func__, priv->rxstatus);
|
||||||
|
|
||||||
ring_offs = cur_rx % RX_BUF_LEN;
|
ring_offs = priv->cur_rx % RX_BUF_LEN;
|
||||||
/* ring_offs is guaranteed being 4-byte aligned */
|
/* ring_offs is guaranteed being 4-byte aligned */
|
||||||
rx_status = le32_to_cpu(*(unsigned int *)(rx_ring + ring_offs));
|
rx_status = le32_to_cpu(*(unsigned int *)(rx_ring + ring_offs));
|
||||||
rx_size = rx_status >> 16;
|
rx_size = rx_status >> 16;
|
||||||
@ -450,59 +465,61 @@ static int rtl8139_recv(struct eth_device *dev)
|
|||||||
(rx_size > ETH_FRAME_LEN + 4)) {
|
(rx_size > ETH_FRAME_LEN + 4)) {
|
||||||
printf("rx error %hX\n", rx_status);
|
printf("rx error %hX\n", rx_status);
|
||||||
/* this clears all interrupts still pending */
|
/* this clears all interrupts still pending */
|
||||||
rtl8139_reset(dev);
|
rtl8139_reset(priv);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Received a good packet */
|
/* Received a good packet */
|
||||||
length = rx_size - 4; /* no one cares about the FCS */
|
length = rx_size - 4; /* no one cares about the FCS */
|
||||||
if (ring_offs + 4 + rx_size - 4 > RX_BUF_LEN) {
|
if (ring_offs + 4 + rx_size - 4 > RX_BUF_LEN) {
|
||||||
unsigned char rxdata[RX_BUF_LEN];
|
|
||||||
int semi_count = RX_BUF_LEN - ring_offs - 4;
|
int semi_count = RX_BUF_LEN - ring_offs - 4;
|
||||||
|
|
||||||
memcpy(rxdata, rx_ring + ring_offs + 4, semi_count);
|
memcpy(rxdata, rx_ring + ring_offs + 4, semi_count);
|
||||||
memcpy(&rxdata[semi_count], rx_ring,
|
memcpy(&rxdata[semi_count], rx_ring,
|
||||||
rx_size - 4 - semi_count);
|
rx_size - 4 - semi_count);
|
||||||
|
|
||||||
net_process_received_packet(rxdata, length);
|
*packetp = rxdata;
|
||||||
debug_cond(DEBUG_RX, "rx packet %d+%d bytes",
|
debug_cond(DEBUG_RX, "rx packet %d+%d bytes",
|
||||||
semi_count, rx_size - 4 - semi_count);
|
semi_count, rx_size - 4 - semi_count);
|
||||||
} else {
|
} else {
|
||||||
net_process_received_packet(rx_ring + ring_offs + 4, length);
|
*packetp = rx_ring + ring_offs + 4;
|
||||||
debug_cond(DEBUG_RX, "rx packet %d bytes", rx_size - 4);
|
debug_cond(DEBUG_RX, "rx packet %d bytes", rx_size - 4);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return length;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rtl8139_free_pkt_common(struct rtl8139_priv *priv, unsigned int len)
|
||||||
|
{
|
||||||
|
const unsigned int rxstat = RTL_REG_INTRSTATUS_RXFIFOOVER |
|
||||||
|
RTL_REG_INTRSTATUS_RXOVERFLOW |
|
||||||
|
RTL_REG_INTRSTATUS_RXOK;
|
||||||
|
unsigned int rx_size = len + 4;
|
||||||
|
|
||||||
flush_cache((unsigned long)rx_ring, RX_BUF_LEN);
|
flush_cache((unsigned long)rx_ring, RX_BUF_LEN);
|
||||||
|
|
||||||
cur_rx = ROUND(cur_rx + rx_size + 4, 4);
|
priv->cur_rx = ROUND(priv->cur_rx + rx_size + 4, 4);
|
||||||
outw(cur_rx - 16, ioaddr + RTL_REG_RXBUFPTR);
|
outw(priv->cur_rx - 16, priv->ioaddr + RTL_REG_RXBUFPTR);
|
||||||
/*
|
/*
|
||||||
* See RTL8139 Programming Guide V0.1 for the official handling of
|
* See RTL8139 Programming Guide V0.1 for the official handling of
|
||||||
* Rx overflow situations. The document itself contains basically
|
* Rx overflow situations. The document itself contains basically
|
||||||
* no usable information, except for a few exception handling rules.
|
* no usable information, except for a few exception handling rules.
|
||||||
*/
|
*/
|
||||||
outw(status & rxstat, ioaddr + RTL_REG_INTRSTATUS);
|
outw(priv->rxstatus & rxstat, priv->ioaddr + RTL_REG_INTRSTATUS);
|
||||||
|
|
||||||
return length;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int rtl8139_init(struct eth_device *dev, bd_t *bis)
|
static int rtl8139_init_common(struct rtl8139_priv *priv)
|
||||||
{
|
{
|
||||||
unsigned short *ap = (unsigned short *)dev->enetaddr;
|
|
||||||
int addr_len, i;
|
|
||||||
u8 reg;
|
u8 reg;
|
||||||
|
|
||||||
ioaddr = dev->iobase;
|
|
||||||
|
|
||||||
/* Bring the chip out of low-power mode. */
|
/* Bring the chip out of low-power mode. */
|
||||||
outb(0x00, ioaddr + RTL_REG_CONFIG1);
|
outb(0x00, priv->ioaddr + RTL_REG_CONFIG1);
|
||||||
|
|
||||||
addr_len = rtl8139_read_eeprom(0, 8) == 0x8129 ? 8 : 6;
|
rtl8139_reset(priv);
|
||||||
for (i = 0; i < 3; i++)
|
|
||||||
*ap++ = le16_to_cpu(rtl8139_read_eeprom(i + 7, addr_len));
|
|
||||||
|
|
||||||
rtl8139_reset(dev);
|
reg = inb(priv->ioaddr + RTL_REG_MEDIASTATUS);
|
||||||
|
|
||||||
reg = inb(ioaddr + RTL_REG_MEDIASTATUS);
|
|
||||||
if (reg & RTL_REG_MEDIASTATUS_MSRLINKFAIL) {
|
if (reg & RTL_REG_MEDIASTATUS_MSRLINKFAIL) {
|
||||||
printf("Cable not connected or other link failure\n");
|
printf("Cable not connected or other link failure\n");
|
||||||
return -1;
|
return -1;
|
||||||
@ -511,27 +528,82 @@ static int rtl8139_init(struct eth_device *dev, bd_t *bis)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void rtl8139_stop(struct eth_device *dev)
|
static void rtl8139_stop_common(struct rtl8139_priv *priv)
|
||||||
{
|
{
|
||||||
ioaddr = dev->iobase;
|
rtl8139_hw_reset(priv);
|
||||||
|
|
||||||
rtl8139_hw_reset(dev);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void rtl8139_get_hwaddr(struct rtl8139_priv *priv)
|
||||||
|
{
|
||||||
|
unsigned short *ap = (unsigned short *)priv->enetaddr;
|
||||||
|
int i, addr_len;
|
||||||
|
|
||||||
|
/* Bring the chip out of low-power mode. */
|
||||||
|
outb(0x00, priv->ioaddr + RTL_REG_CONFIG1);
|
||||||
|
|
||||||
|
addr_len = rtl8139_read_eeprom(priv, 0, 8) == 0x8129 ? 8 : 6;
|
||||||
|
for (i = 0; i < 3; i++)
|
||||||
|
*ap++ = le16_to_cpu(rtl8139_read_eeprom(priv, i + 7, addr_len));
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rtl8139_name(char *str, int card_number)
|
||||||
|
{
|
||||||
|
sprintf(str, "RTL8139#%u", card_number);
|
||||||
|
}
|
||||||
|
|
||||||
|
static struct pci_device_id supported[] = {
|
||||||
|
{ PCI_DEVICE(PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8139) },
|
||||||
|
{ PCI_DEVICE(PCI_VENDOR_ID_DLINK, PCI_DEVICE_ID_DLINK_8139) },
|
||||||
|
{ }
|
||||||
|
};
|
||||||
|
|
||||||
|
#ifndef CONFIG_DM_ETH
|
||||||
static int rtl8139_bcast_addr(struct eth_device *dev, const u8 *bcast_mac,
|
static int rtl8139_bcast_addr(struct eth_device *dev, const u8 *bcast_mac,
|
||||||
int join)
|
int join)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct pci_device_id supported[] = {
|
static int rtl8139_init(struct eth_device *dev, bd_t *bis)
|
||||||
{ PCI_VENDOR_ID_REALTEK, PCI_DEVICE_ID_REALTEK_8139 },
|
{
|
||||||
{ PCI_VENDOR_ID_DLINK, PCI_DEVICE_ID_DLINK_8139 },
|
struct rtl8139_priv *priv = container_of(dev, struct rtl8139_priv, dev);
|
||||||
{ }
|
|
||||||
};
|
return rtl8139_init_common(priv);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rtl8139_stop(struct eth_device *dev)
|
||||||
|
{
|
||||||
|
struct rtl8139_priv *priv = container_of(dev, struct rtl8139_priv, dev);
|
||||||
|
|
||||||
|
return rtl8139_stop_common(priv);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rtl8139_send(struct eth_device *dev, void *packet, int length)
|
||||||
|
{
|
||||||
|
struct rtl8139_priv *priv = container_of(dev, struct rtl8139_priv, dev);
|
||||||
|
|
||||||
|
return rtl8139_send_common(priv, packet, length);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rtl8139_recv(struct eth_device *dev)
|
||||||
|
{
|
||||||
|
struct rtl8139_priv *priv = container_of(dev, struct rtl8139_priv, dev);
|
||||||
|
unsigned char rxdata[RX_BUF_LEN];
|
||||||
|
uchar *packet;
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = rtl8139_recv_common(priv, rxdata, &packet);
|
||||||
|
if (ret) {
|
||||||
|
net_process_received_packet(packet, ret);
|
||||||
|
rtl8139_free_pkt_common(priv, ret);
|
||||||
|
}
|
||||||
|
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
int rtl8139_initialize(bd_t *bis)
|
int rtl8139_initialize(bd_t *bis)
|
||||||
{
|
{
|
||||||
|
struct rtl8139_priv *priv;
|
||||||
struct eth_device *dev;
|
struct eth_device *dev;
|
||||||
int card_number = 0;
|
int card_number = 0;
|
||||||
pci_dev_t devno;
|
pci_dev_t devno;
|
||||||
@ -549,23 +621,31 @@ int rtl8139_initialize(bd_t *bis)
|
|||||||
|
|
||||||
debug("rtl8139: REALTEK RTL8139 @0x%x\n", iobase);
|
debug("rtl8139: REALTEK RTL8139 @0x%x\n", iobase);
|
||||||
|
|
||||||
dev = (struct eth_device *)malloc(sizeof(*dev));
|
priv = calloc(1, sizeof(*priv));
|
||||||
if (!dev) {
|
if (!priv) {
|
||||||
printf("Can not allocate memory of rtl8139\n");
|
printf("Can not allocate memory of rtl8139\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
memset(dev, 0, sizeof(*dev));
|
|
||||||
|
|
||||||
sprintf(dev->name, "RTL8139#%d", card_number);
|
priv->devno = devno;
|
||||||
|
priv->ioaddr = (unsigned long)bus_to_phys(devno, iobase);
|
||||||
|
|
||||||
dev->priv = (void *)devno;
|
dev = &priv->dev;
|
||||||
dev->iobase = (int)bus_to_phys(iobase);
|
|
||||||
|
rtl8139_name(dev->name, card_number);
|
||||||
|
|
||||||
|
dev->iobase = priv->ioaddr; /* Non-DM compatibility */
|
||||||
dev->init = rtl8139_init;
|
dev->init = rtl8139_init;
|
||||||
dev->halt = rtl8139_stop;
|
dev->halt = rtl8139_stop;
|
||||||
dev->send = rtl8139_send;
|
dev->send = rtl8139_send;
|
||||||
dev->recv = rtl8139_recv;
|
dev->recv = rtl8139_recv;
|
||||||
dev->mcast = rtl8139_bcast_addr;
|
dev->mcast = rtl8139_bcast_addr;
|
||||||
|
|
||||||
|
rtl8139_get_hwaddr(priv);
|
||||||
|
|
||||||
|
/* Non-DM compatibility */
|
||||||
|
memcpy(priv->dev.enetaddr, priv->enetaddr, 6);
|
||||||
|
|
||||||
eth_register(dev);
|
eth_register(dev);
|
||||||
|
|
||||||
card_number++;
|
card_number++;
|
||||||
@ -577,3 +657,123 @@ int rtl8139_initialize(bd_t *bis)
|
|||||||
|
|
||||||
return card_number;
|
return card_number;
|
||||||
}
|
}
|
||||||
|
#else /* DM_ETH */
|
||||||
|
static int rtl8139_start(struct udevice *dev)
|
||||||
|
{
|
||||||
|
struct eth_pdata *plat = dev_get_platdata(dev);
|
||||||
|
struct rtl8139_priv *priv = dev_get_priv(dev);
|
||||||
|
|
||||||
|
memcpy(priv->enetaddr, plat->enetaddr, sizeof(plat->enetaddr));
|
||||||
|
|
||||||
|
return rtl8139_init_common(priv);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void rtl8139_stop(struct udevice *dev)
|
||||||
|
{
|
||||||
|
struct rtl8139_priv *priv = dev_get_priv(dev);
|
||||||
|
|
||||||
|
rtl8139_stop_common(priv);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rtl8139_send(struct udevice *dev, void *packet, int length)
|
||||||
|
{
|
||||||
|
struct rtl8139_priv *priv = dev_get_priv(dev);
|
||||||
|
int ret;
|
||||||
|
|
||||||
|
ret = rtl8139_send_common(priv, packet, length);
|
||||||
|
|
||||||
|
return ret ? 0 : -ETIMEDOUT;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rtl8139_recv(struct udevice *dev, int flags, uchar **packetp)
|
||||||
|
{
|
||||||
|
struct rtl8139_priv *priv = dev_get_priv(dev);
|
||||||
|
static unsigned char rxdata[RX_BUF_LEN];
|
||||||
|
|
||||||
|
return rtl8139_recv_common(priv, rxdata, packetp);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rtl8139_free_pkt(struct udevice *dev, uchar *packet, int length)
|
||||||
|
{
|
||||||
|
struct rtl8139_priv *priv = dev_get_priv(dev);
|
||||||
|
|
||||||
|
rtl8139_free_pkt_common(priv, length);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rtl8139_write_hwaddr(struct udevice *dev)
|
||||||
|
{
|
||||||
|
struct eth_pdata *plat = dev_get_platdata(dev);
|
||||||
|
struct rtl8139_priv *priv = dev_get_priv(dev);
|
||||||
|
|
||||||
|
memcpy(priv->enetaddr, plat->enetaddr, sizeof(plat->enetaddr));
|
||||||
|
|
||||||
|
rtl8139_reset(priv);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rtl8139_read_rom_hwaddr(struct udevice *dev)
|
||||||
|
{
|
||||||
|
struct rtl8139_priv *priv = dev_get_priv(dev);
|
||||||
|
|
||||||
|
rtl8139_get_hwaddr(priv);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rtl8139_bind(struct udevice *dev)
|
||||||
|
{
|
||||||
|
static int card_number;
|
||||||
|
char name[16];
|
||||||
|
|
||||||
|
rtl8139_name(name, card_number++);
|
||||||
|
|
||||||
|
return device_set_name(dev, name);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int rtl8139_probe(struct udevice *dev)
|
||||||
|
{
|
||||||
|
struct eth_pdata *plat = dev_get_platdata(dev);
|
||||||
|
struct rtl8139_priv *priv = dev_get_priv(dev);
|
||||||
|
u32 iobase;
|
||||||
|
|
||||||
|
dm_pci_read_config32(dev, PCI_BASE_ADDRESS_1, &iobase);
|
||||||
|
iobase &= ~0xf;
|
||||||
|
|
||||||
|
debug("rtl8139: REALTEK RTL8139 @0x%x\n", iobase);
|
||||||
|
|
||||||
|
priv->devno = dev;
|
||||||
|
priv->ioaddr = (unsigned long)bus_to_phys(dev, iobase);
|
||||||
|
|
||||||
|
rtl8139_get_hwaddr(priv);
|
||||||
|
memcpy(plat->enetaddr, priv->enetaddr, sizeof(priv->enetaddr));
|
||||||
|
|
||||||
|
dm_pci_write_config8(dev, PCI_LATENCY_TIMER, 0x20);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static const struct eth_ops rtl8139_ops = {
|
||||||
|
.start = rtl8139_start,
|
||||||
|
.send = rtl8139_send,
|
||||||
|
.recv = rtl8139_recv,
|
||||||
|
.stop = rtl8139_stop,
|
||||||
|
.free_pkt = rtl8139_free_pkt,
|
||||||
|
.write_hwaddr = rtl8139_write_hwaddr,
|
||||||
|
.read_rom_hwaddr = rtl8139_read_rom_hwaddr,
|
||||||
|
};
|
||||||
|
|
||||||
|
U_BOOT_DRIVER(eth_rtl8139) = {
|
||||||
|
.name = "eth_rtl8139",
|
||||||
|
.id = UCLASS_ETH,
|
||||||
|
.bind = rtl8139_bind,
|
||||||
|
.probe = rtl8139_probe,
|
||||||
|
.ops = &rtl8139_ops,
|
||||||
|
.priv_auto_alloc_size = sizeof(struct rtl8139_priv),
|
||||||
|
.platdata_auto_alloc_size = sizeof(struct eth_pdata),
|
||||||
|
};
|
||||||
|
|
||||||
|
U_BOOT_PCI_DEVICE(eth_rtl8139, supported);
|
||||||
|
#endif
|
||||||
|
@ -240,6 +240,9 @@ enum RTL8169_register_content {
|
|||||||
|
|
||||||
/*_TBICSRBit*/
|
/*_TBICSRBit*/
|
||||||
TBILinkOK = 0x02000000,
|
TBILinkOK = 0x02000000,
|
||||||
|
|
||||||
|
/* FuncEvent/Misc */
|
||||||
|
RxDv_Gated_En = 0x80000,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct {
|
static struct {
|
||||||
@ -1210,6 +1213,19 @@ static int rtl8169_eth_probe(struct udevice *dev)
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* WAR for DHCP failure after rebooting from kernel.
|
||||||
|
* Clear RxDv_Gated_En bit which was set by kernel driver.
|
||||||
|
* Without this, U-Boot can't get an IP via DHCP.
|
||||||
|
* Register (FuncEvent, aka MISC) and RXDV_GATED_EN bit are from
|
||||||
|
* the r8169.c kernel driver.
|
||||||
|
*/
|
||||||
|
|
||||||
|
u32 val = RTL_R32(FuncEvent);
|
||||||
|
debug("%s: FuncEvent/Misc (0xF0) = 0x%08X\n", __func__, val);
|
||||||
|
val &= ~RxDv_Gated_En;
|
||||||
|
RTL_W32(FuncEvent, val);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -8,10 +8,6 @@ extra-$(CONFIG_SMC91111) += smc91111_eeprom
|
|||||||
extra-$(CONFIG_SPI_FLASH_ATMEL) += atmel_df_pow2
|
extra-$(CONFIG_SPI_FLASH_ATMEL) += atmel_df_pow2
|
||||||
extra-$(CONFIG_PPC) += sched
|
extra-$(CONFIG_PPC) += sched
|
||||||
|
|
||||||
ifndef CONFIG_DM_ETH
|
|
||||||
extra-$(CONFIG_SMC911X) += smc911x_eeprom
|
|
||||||
endif
|
|
||||||
|
|
||||||
#
|
#
|
||||||
# Some versions of make do not handle trailing white spaces properly;
|
# Some versions of make do not handle trailing white spaces properly;
|
||||||
# leading to build failures. The problem was found with GNU Make 3.80.
|
# leading to build failures. The problem was found with GNU Make 3.80.
|
||||||
|
@ -1,530 +0,0 @@
|
|||||||
/*
|
|
||||||
* smc911x_eeprom.c - EEPROM interface to SMC911x parts.
|
|
||||||
* Only tested on SMSC9118 though ...
|
|
||||||
*
|
|
||||||
* Copyright 2004-2009 Analog Devices Inc.
|
|
||||||
*
|
|
||||||
* Licensed under the GPL-2 or later.
|
|
||||||
*
|
|
||||||
* Based on smc91111_eeprom.c which:
|
|
||||||
* Heavily borrowed from the following peoples GPL'ed software:
|
|
||||||
* - Wolfgang Denk, DENX Software Engineering, wd@denx.de
|
|
||||||
* Das U-Boot
|
|
||||||
* - Ladislav Michl ladis@linux-mips.org
|
|
||||||
* A rejected patch on the U-Boot mailing list
|
|
||||||
*/
|
|
||||||
|
|
||||||
#include <common.h>
|
|
||||||
#include <console.h>
|
|
||||||
#include <exports.h>
|
|
||||||
#include <net.h>
|
|
||||||
#include <linux/ctype.h>
|
|
||||||
#include <linux/types.h>
|
|
||||||
#include "../drivers/net/smc911x.h"
|
|
||||||
|
|
||||||
#define DRIVERNAME "smc911x"
|
|
||||||
|
|
||||||
#if defined (CONFIG_SMC911X_32_BIT) && \
|
|
||||||
defined (CONFIG_SMC911X_16_BIT)
|
|
||||||
#error "SMC911X: Only one of CONFIG_SMC911X_32_BIT and \
|
|
||||||
CONFIG_SMC911X_16_BIT shall be set"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
struct chip_id {
|
|
||||||
u16 id;
|
|
||||||
char *name;
|
|
||||||
};
|
|
||||||
|
|
||||||
static const struct chip_id chip_ids[] = {
|
|
||||||
{ CHIP_89218, "LAN89218" },
|
|
||||||
{ CHIP_9115, "LAN9115" },
|
|
||||||
{ CHIP_9116, "LAN9116" },
|
|
||||||
{ CHIP_9117, "LAN9117" },
|
|
||||||
{ CHIP_9118, "LAN9118" },
|
|
||||||
{ CHIP_9211, "LAN9211" },
|
|
||||||
{ CHIP_9215, "LAN9215" },
|
|
||||||
{ CHIP_9216, "LAN9216" },
|
|
||||||
{ CHIP_9217, "LAN9217" },
|
|
||||||
{ CHIP_9218, "LAN9218" },
|
|
||||||
{ CHIP_9220, "LAN9220" },
|
|
||||||
{ CHIP_9221, "LAN9221" },
|
|
||||||
{ 0, NULL },
|
|
||||||
};
|
|
||||||
|
|
||||||
#if defined (CONFIG_SMC911X_32_BIT)
|
|
||||||
static u32 smc911x_reg_read(struct eth_device *dev, u32 offset)
|
|
||||||
{
|
|
||||||
return *(volatile u32*)(dev->iobase + offset);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void smc911x_reg_write(struct eth_device *dev, u32 offset, u32 val)
|
|
||||||
{
|
|
||||||
*(volatile u32*)(dev->iobase + offset) = val;
|
|
||||||
}
|
|
||||||
#elif defined (CONFIG_SMC911X_16_BIT)
|
|
||||||
static u32 smc911x_reg_read(struct eth_device *dev, u32 offset)
|
|
||||||
{
|
|
||||||
volatile u16 *addr_16 = (u16 *)(dev->iobase + offset);
|
|
||||||
return (*addr_16 & 0x0000ffff) | (*(addr_16 + 1) << 16);
|
|
||||||
}
|
|
||||||
static void smc911x_reg_write(struct eth_device *dev, u32 offset, u32 val)
|
|
||||||
{
|
|
||||||
*(volatile u16 *)(dev->iobase + offset) = (u16)val;
|
|
||||||
*(volatile u16 *)(dev->iobase + offset + 2) = (u16)(val >> 16);
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
#error "SMC911X: undefined bus width"
|
|
||||||
#endif /* CONFIG_SMC911X_16_BIT */
|
|
||||||
|
|
||||||
static u32 smc911x_get_mac_csr(struct eth_device *dev, u8 reg)
|
|
||||||
{
|
|
||||||
while (smc911x_reg_read(dev, MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY)
|
|
||||||
;
|
|
||||||
smc911x_reg_write(dev, MAC_CSR_CMD,
|
|
||||||
MAC_CSR_CMD_CSR_BUSY | MAC_CSR_CMD_R_NOT_W | reg);
|
|
||||||
while (smc911x_reg_read(dev, MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY)
|
|
||||||
;
|
|
||||||
|
|
||||||
return smc911x_reg_read(dev, MAC_CSR_DATA);
|
|
||||||
}
|
|
||||||
|
|
||||||
static void smc911x_set_mac_csr(struct eth_device *dev, u8 reg, u32 data)
|
|
||||||
{
|
|
||||||
while (smc911x_reg_read(dev, MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY)
|
|
||||||
;
|
|
||||||
smc911x_reg_write(dev, MAC_CSR_DATA, data);
|
|
||||||
smc911x_reg_write(dev, MAC_CSR_CMD, MAC_CSR_CMD_CSR_BUSY | reg);
|
|
||||||
while (smc911x_reg_read(dev, MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY)
|
|
||||||
;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int smc911x_detect_chip(struct eth_device *dev)
|
|
||||||
{
|
|
||||||
unsigned long val, i;
|
|
||||||
|
|
||||||
val = smc911x_reg_read(dev, BYTE_TEST);
|
|
||||||
if (val == 0xffffffff) {
|
|
||||||
/* Special case -- no chip present */
|
|
||||||
return -1;
|
|
||||||
} else if (val != 0x87654321) {
|
|
||||||
printf(DRIVERNAME ": Invalid chip endian 0x%08lx\n", val);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
val = smc911x_reg_read(dev, ID_REV) >> 16;
|
|
||||||
for (i = 0; chip_ids[i].id != 0; i++) {
|
|
||||||
if (chip_ids[i].id == val) break;
|
|
||||||
}
|
|
||||||
if (!chip_ids[i].id) {
|
|
||||||
printf(DRIVERNAME ": Unknown chip ID %04lx\n", val);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
dev->priv = (void *)&chip_ids[i];
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void smc911x_reset(struct eth_device *dev)
|
|
||||||
{
|
|
||||||
int timeout;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Take out of PM setting first
|
|
||||||
* Device is already wake up if PMT_CTRL_READY bit is set
|
|
||||||
*/
|
|
||||||
if ((smc911x_reg_read(dev, PMT_CTRL) & PMT_CTRL_READY) == 0) {
|
|
||||||
/* Write to the bytetest will take out of powerdown */
|
|
||||||
smc911x_reg_write(dev, BYTE_TEST, 0x0);
|
|
||||||
|
|
||||||
timeout = 10;
|
|
||||||
|
|
||||||
while (timeout-- &&
|
|
||||||
!(smc911x_reg_read(dev, PMT_CTRL) & PMT_CTRL_READY))
|
|
||||||
udelay(10);
|
|
||||||
if (timeout < 0) {
|
|
||||||
printf(DRIVERNAME
|
|
||||||
": timeout waiting for PM restore\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Disable interrupts */
|
|
||||||
smc911x_reg_write(dev, INT_EN, 0);
|
|
||||||
|
|
||||||
smc911x_reg_write(dev, HW_CFG, HW_CFG_SRST);
|
|
||||||
|
|
||||||
timeout = 1000;
|
|
||||||
while (timeout-- && smc911x_reg_read(dev, E2P_CMD) & E2P_CMD_EPC_BUSY)
|
|
||||||
udelay(10);
|
|
||||||
|
|
||||||
if (timeout < 0) {
|
|
||||||
printf(DRIVERNAME ": reset timeout\n");
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Reset the FIFO level and flow control settings */
|
|
||||||
smc911x_set_mac_csr(dev, FLOW, FLOW_FCPT | FLOW_FCEN);
|
|
||||||
smc911x_reg_write(dev, AFC_CFG, 0x0050287F);
|
|
||||||
|
|
||||||
/* Set to LED outputs */
|
|
||||||
smc911x_reg_write(dev, GPIO_CFG, 0x70070000);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* smsc_ctrlc - detect press of CTRL+C (common ctrlc() isnt exported!?)
|
|
||||||
*/
|
|
||||||
static int smsc_ctrlc(void)
|
|
||||||
{
|
|
||||||
return (tstc() && getc() == 0x03);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* usage - dump usage information
|
|
||||||
*/
|
|
||||||
static void usage(void)
|
|
||||||
{
|
|
||||||
puts(
|
|
||||||
"MAC/EEPROM Commands:\n"
|
|
||||||
" P : Print the MAC addresses\n"
|
|
||||||
" D : Dump the EEPROM contents\n"
|
|
||||||
" M : Dump the MAC contents\n"
|
|
||||||
" C : Copy the MAC address from the EEPROM to the MAC\n"
|
|
||||||
" W : Write a register in the EEPROM or in the MAC\n"
|
|
||||||
" Q : Quit\n"
|
|
||||||
"\n"
|
|
||||||
"Some commands take arguments:\n"
|
|
||||||
" W <E|M> <register> <value>\n"
|
|
||||||
" E: EEPROM M: MAC\n"
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* dump_regs - dump the MAC registers
|
|
||||||
*
|
|
||||||
* Registers 0x00 - 0x50 are FIFOs. The 0x50+ are the control registers
|
|
||||||
* and they're all 32bits long. 0xB8+ are reserved, so don't bother.
|
|
||||||
*/
|
|
||||||
static void dump_regs(struct eth_device *dev)
|
|
||||||
{
|
|
||||||
u8 i, j = 0;
|
|
||||||
for (i = 0x50; i < 0xB8; i += sizeof(u32))
|
|
||||||
printf("%02x: 0x%08x %c", i,
|
|
||||||
smc911x_reg_read(dev, i),
|
|
||||||
(j++ % 2 ? '\n' : ' '));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* do_eeprom_cmd - handle eeprom communication
|
|
||||||
*/
|
|
||||||
static int do_eeprom_cmd(struct eth_device *dev, int cmd, u8 reg)
|
|
||||||
{
|
|
||||||
if (smc911x_reg_read(dev, E2P_CMD) & E2P_CMD_EPC_BUSY) {
|
|
||||||
printf("eeprom_cmd: busy at start (E2P_CMD = 0x%08x)\n",
|
|
||||||
smc911x_reg_read(dev, E2P_CMD));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
smc911x_reg_write(dev, E2P_CMD, E2P_CMD_EPC_BUSY | cmd | reg);
|
|
||||||
|
|
||||||
while (smc911x_reg_read(dev, E2P_CMD) & E2P_CMD_EPC_BUSY)
|
|
||||||
if (smsc_ctrlc()) {
|
|
||||||
printf("eeprom_cmd: timeout (E2P_CMD = 0x%08x)\n",
|
|
||||||
smc911x_reg_read(dev, E2P_CMD));
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* read_eeprom_reg - read specified register in EEPROM
|
|
||||||
*/
|
|
||||||
static u8 read_eeprom_reg(struct eth_device *dev, u8 reg)
|
|
||||||
{
|
|
||||||
int ret = do_eeprom_cmd(dev, E2P_CMD_EPC_CMD_READ, reg);
|
|
||||||
return (ret ? : smc911x_reg_read(dev, E2P_DATA));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* write_eeprom_reg - write specified value into specified register in EEPROM
|
|
||||||
*/
|
|
||||||
static int write_eeprom_reg(struct eth_device *dev, u8 value, u8 reg)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
/* enable erasing/writing */
|
|
||||||
ret = do_eeprom_cmd(dev, E2P_CMD_EPC_CMD_EWEN, reg);
|
|
||||||
if (ret)
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
/* erase the eeprom reg */
|
|
||||||
ret = do_eeprom_cmd(dev, E2P_CMD_EPC_CMD_ERASE, reg);
|
|
||||||
if (ret)
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
/* write the eeprom reg */
|
|
||||||
smc911x_reg_write(dev, E2P_DATA, value);
|
|
||||||
ret = do_eeprom_cmd(dev, E2P_CMD_EPC_CMD_WRITE, reg);
|
|
||||||
if (ret)
|
|
||||||
goto done;
|
|
||||||
|
|
||||||
/* disable erasing/writing */
|
|
||||||
ret = do_eeprom_cmd(dev, E2P_CMD_EPC_CMD_EWDS, reg);
|
|
||||||
|
|
||||||
done:
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* skip_space - find first non-whitespace in given pointer
|
|
||||||
*/
|
|
||||||
static char *skip_space(char *buf)
|
|
||||||
{
|
|
||||||
while (isblank(buf[0]))
|
|
||||||
++buf;
|
|
||||||
return buf;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* write_stuff - handle writing of MAC registers / eeprom
|
|
||||||
*/
|
|
||||||
static void write_stuff(struct eth_device *dev, char *line)
|
|
||||||
{
|
|
||||||
char dest;
|
|
||||||
char *endp;
|
|
||||||
u8 reg;
|
|
||||||
u32 value;
|
|
||||||
|
|
||||||
/* Skip over the "W " part of the command */
|
|
||||||
line = skip_space(line + 1);
|
|
||||||
|
|
||||||
/* Figure out destination */
|
|
||||||
switch (line[0]) {
|
|
||||||
case 'E':
|
|
||||||
case 'M':
|
|
||||||
dest = line[0];
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
invalid_usage:
|
|
||||||
printf("ERROR: Invalid write usage\n");
|
|
||||||
usage();
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Get the register to write */
|
|
||||||
line = skip_space(line + 1);
|
|
||||||
reg = simple_strtoul(line, &endp, 16);
|
|
||||||
if (line == endp)
|
|
||||||
goto invalid_usage;
|
|
||||||
|
|
||||||
/* Get the value to write */
|
|
||||||
line = skip_space(endp);
|
|
||||||
value = simple_strtoul(line, &endp, 16);
|
|
||||||
if (line == endp)
|
|
||||||
goto invalid_usage;
|
|
||||||
|
|
||||||
/* Check for trailing cruft */
|
|
||||||
line = skip_space(endp);
|
|
||||||
if (line[0])
|
|
||||||
goto invalid_usage;
|
|
||||||
|
|
||||||
/* Finally, execute the command */
|
|
||||||
if (dest == 'E') {
|
|
||||||
printf("Writing EEPROM register %02x with %02x\n", reg, value);
|
|
||||||
write_eeprom_reg(dev, value, reg);
|
|
||||||
} else {
|
|
||||||
printf("Writing MAC register %02x with %08x\n", reg, value);
|
|
||||||
smc911x_reg_write(dev, reg, value);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* copy_from_eeprom - copy MAC address in eeprom to address registers
|
|
||||||
*/
|
|
||||||
static void copy_from_eeprom(struct eth_device *dev)
|
|
||||||
{
|
|
||||||
ulong addrl =
|
|
||||||
read_eeprom_reg(dev, 0x01) |
|
|
||||||
read_eeprom_reg(dev, 0x02) << 8 |
|
|
||||||
read_eeprom_reg(dev, 0x03) << 16 |
|
|
||||||
read_eeprom_reg(dev, 0x04) << 24;
|
|
||||||
ulong addrh =
|
|
||||||
read_eeprom_reg(dev, 0x05) |
|
|
||||||
read_eeprom_reg(dev, 0x06) << 8;
|
|
||||||
smc911x_set_mac_csr(dev, ADDRL, addrl);
|
|
||||||
smc911x_set_mac_csr(dev, ADDRH, addrh);
|
|
||||||
puts("EEPROM contents copied to MAC\n");
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* print_macaddr - print MAC address registers and MAC address in eeprom
|
|
||||||
*/
|
|
||||||
static void print_macaddr(struct eth_device *dev)
|
|
||||||
{
|
|
||||||
puts("Current MAC Address in MAC: ");
|
|
||||||
ulong addrl = smc911x_get_mac_csr(dev, ADDRL);
|
|
||||||
ulong addrh = smc911x_get_mac_csr(dev, ADDRH);
|
|
||||||
printf("%02x:%02x:%02x:%02x:%02x:%02x\n",
|
|
||||||
(u8)(addrl), (u8)(addrl >> 8), (u8)(addrl >> 16),
|
|
||||||
(u8)(addrl >> 24), (u8)(addrh), (u8)(addrh >> 8));
|
|
||||||
|
|
||||||
puts("Current MAC Address in EEPROM: ");
|
|
||||||
int i;
|
|
||||||
for (i = 1; i < 6; ++i)
|
|
||||||
printf("%02x:", read_eeprom_reg(dev, i));
|
|
||||||
printf("%02x\n", read_eeprom_reg(dev, i));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* dump_eeprom - dump the whole content of the EEPROM
|
|
||||||
*/
|
|
||||||
static void dump_eeprom(struct eth_device *dev)
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
puts("EEPROM:\n");
|
|
||||||
for (i = 0; i < 7; ++i)
|
|
||||||
printf("%02x: 0x%02x\n", i, read_eeprom_reg(dev, i));
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* smc911x_init - get the MAC/EEPROM up and ready for use
|
|
||||||
*/
|
|
||||||
static int smc911x_init(struct eth_device *dev)
|
|
||||||
{
|
|
||||||
/* See if there is anything there */
|
|
||||||
if (smc911x_detect_chip(dev))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
smc911x_reset(dev);
|
|
||||||
|
|
||||||
/* Make sure we set EEDIO/EECLK to the EEPROM */
|
|
||||||
if (smc911x_reg_read(dev, GPIO_CFG) & GPIO_CFG_EEPR_EN) {
|
|
||||||
while (smc911x_reg_read(dev, E2P_CMD) & E2P_CMD_EPC_BUSY)
|
|
||||||
if (smsc_ctrlc()) {
|
|
||||||
printf("init: timeout (E2P_CMD = 0x%08x)\n",
|
|
||||||
smc911x_reg_read(dev, E2P_CMD));
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
smc911x_reg_write(dev, GPIO_CFG,
|
|
||||||
smc911x_reg_read(dev, GPIO_CFG) & ~GPIO_CFG_EEPR_EN);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* getline - consume a line of input and handle some escape sequences
|
|
||||||
*/
|
|
||||||
static char *getline(void)
|
|
||||||
{
|
|
||||||
static char buffer[100];
|
|
||||||
char c;
|
|
||||||
size_t i;
|
|
||||||
|
|
||||||
i = 0;
|
|
||||||
while (1) {
|
|
||||||
buffer[i] = '\0';
|
|
||||||
while (!tstc())
|
|
||||||
continue;
|
|
||||||
|
|
||||||
c = getc();
|
|
||||||
/* Convert to uppercase */
|
|
||||||
if (c >= 'a' && c <= 'z')
|
|
||||||
c -= ('a' - 'A');
|
|
||||||
|
|
||||||
switch (c) {
|
|
||||||
case '\r': /* Enter/Return key */
|
|
||||||
case '\n':
|
|
||||||
puts("\n");
|
|
||||||
return buffer;
|
|
||||||
|
|
||||||
case 0x03: /* ^C - break */
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
case 0x5F:
|
|
||||||
case 0x08: /* ^H - backspace */
|
|
||||||
case 0x7F: /* DEL - backspace */
|
|
||||||
if (i) {
|
|
||||||
puts("\b \b");
|
|
||||||
i--;
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
/* Ignore control characters */
|
|
||||||
if (c < 0x20)
|
|
||||||
break;
|
|
||||||
/* Queue up all other characters */
|
|
||||||
buffer[i++] = c;
|
|
||||||
printf("%c", c);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* smc911x_eeprom - our application's main() function
|
|
||||||
*/
|
|
||||||
int smc911x_eeprom(int argc, char *const argv[])
|
|
||||||
{
|
|
||||||
/* Avoid initializing on stack as gcc likes to call memset() */
|
|
||||||
struct eth_device dev;
|
|
||||||
dev.iobase = CONFIG_SMC911X_BASE;
|
|
||||||
|
|
||||||
/* Print the ABI version */
|
|
||||||
app_startup(argv);
|
|
||||||
if (XF_VERSION != get_version()) {
|
|
||||||
printf("Expects ABI version %d\n", XF_VERSION);
|
|
||||||
printf("Actual U-Boot ABI version %lu\n", get_version());
|
|
||||||
printf("Can't run\n\n");
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Initialize the MAC/EEPROM somewhat */
|
|
||||||
puts("\n");
|
|
||||||
if (smc911x_init(&dev))
|
|
||||||
return 1;
|
|
||||||
|
|
||||||
/* Dump helpful usage information */
|
|
||||||
puts("\n");
|
|
||||||
usage();
|
|
||||||
puts("\n");
|
|
||||||
|
|
||||||
while (1) {
|
|
||||||
char *line;
|
|
||||||
|
|
||||||
/* Send the prompt and wait for a line */
|
|
||||||
puts("eeprom> ");
|
|
||||||
line = getline();
|
|
||||||
|
|
||||||
/* Got a ctrl+c */
|
|
||||||
if (!line)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* Eat leading space */
|
|
||||||
line = skip_space(line);
|
|
||||||
|
|
||||||
/* Empty line, try again */
|
|
||||||
if (!line[0])
|
|
||||||
continue;
|
|
||||||
|
|
||||||
/* Only accept 1 letter commands */
|
|
||||||
if (line[0] && line[1] && !isblank(line[1]))
|
|
||||||
goto unknown_cmd;
|
|
||||||
|
|
||||||
/* Now parse the command */
|
|
||||||
switch (line[0]) {
|
|
||||||
case 'W': write_stuff(&dev, line); break;
|
|
||||||
case 'D': dump_eeprom(&dev); break;
|
|
||||||
case 'M': dump_regs(&dev); break;
|
|
||||||
case 'C': copy_from_eeprom(&dev); break;
|
|
||||||
case 'P': print_macaddr(&dev); break;
|
|
||||||
unknown_cmd:
|
|
||||||
default: puts("ERROR: Unknown command!\n\n");
|
|
||||||
case '?':
|
|
||||||
case 'H': usage(); break;
|
|
||||||
case 'Q': return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -76,6 +76,7 @@
|
|||||||
#define CONFIG_BOARD_SIZE_LIMIT 392192 /* (CONFIG_ENV_OFFSET - 1024) */
|
#define CONFIG_BOARD_SIZE_LIMIT 392192 /* (CONFIG_ENV_OFFSET - 1024) */
|
||||||
|
|
||||||
#define CONFIG_EXTRA_ENV_SETTINGS \
|
#define CONFIG_EXTRA_ENV_SETTINGS \
|
||||||
|
BOOTENV \
|
||||||
"bootargs_mmc1=console=ttymxc0,115200 di0_primary console=tty1\0" \
|
"bootargs_mmc1=console=ttymxc0,115200 di0_primary console=tty1\0" \
|
||||||
"bootargs_mmc2=video=mxcfb0:dev=hdmi,1920x1080M@60 " \
|
"bootargs_mmc2=video=mxcfb0:dev=hdmi,1920x1080M@60 " \
|
||||||
"video=mxcfb1:off video=mxcfb2:off fbmem=28M\0" \
|
"video=mxcfb1:off video=mxcfb2:off fbmem=28M\0" \
|
||||||
@ -92,6 +93,13 @@
|
|||||||
"bootm 0x10800000 0x10d00000\0" \
|
"bootm 0x10800000 0x10d00000\0" \
|
||||||
"console=ttymxc0\0" \
|
"console=ttymxc0\0" \
|
||||||
"fan=gpio set 92\0" \
|
"fan=gpio set 92\0" \
|
||||||
|
"fdt_addr=0x13000000\0" \
|
||||||
|
"fdt_addr_r=0x13000000\0" \
|
||||||
|
"fdtfile=" CONFIG_DEFAULT_FDT_FILE "\0" \
|
||||||
|
"kernel_addr_r=0x10008000\0" \
|
||||||
|
"pxefile_addr_r=0x10008000\0" \
|
||||||
|
"ramdisk_addr_r=0x18000000\0" \
|
||||||
|
"scriptaddr=0x14000000\0" \
|
||||||
"set_con_serial=setenv stdout serial; " \
|
"set_con_serial=setenv stdout serial; " \
|
||||||
"setenv stderr serial\0" \
|
"setenv stderr serial\0" \
|
||||||
"set_con_hdmi=setenv stdout serial,vga; " \
|
"set_con_hdmi=setenv stdout serial,vga; " \
|
||||||
@ -100,12 +108,14 @@
|
|||||||
"stdin=serial,usbkbd\0" \
|
"stdin=serial,usbkbd\0" \
|
||||||
"stdout=serial,vga\0"
|
"stdout=serial,vga\0"
|
||||||
|
|
||||||
#define CONFIG_BOOTCOMMAND \
|
/* Enable distro boot */
|
||||||
"mmc rescan; " \
|
#define BOOT_TARGET_DEVICES(func) \
|
||||||
"if run bootcmd_up1; then " \
|
func(MMC, mmc, 0) \
|
||||||
"run bootcmd_up2; " \
|
func(MMC, mmc, 1) \
|
||||||
"else " \
|
func(MMC, mmc, 2) \
|
||||||
"run bootcmd_mmc; " \
|
func(SATA, sata, 0) \
|
||||||
"fi"
|
func(USB, usb, 0)
|
||||||
|
|
||||||
|
#include <config_distro_bootcmd.h>
|
||||||
|
|
||||||
#endif /* __TBS2910_CONFIG_H * */
|
#endif /* __TBS2910_CONFIG_H * */
|
||||||
|
@ -897,9 +897,6 @@ int is_serverip_in_cmd(void);
|
|||||||
*/
|
*/
|
||||||
int net_parse_bootfile(struct in_addr *ipaddr, char *filename, int max_len);
|
int net_parse_bootfile(struct in_addr *ipaddr, char *filename, int max_len);
|
||||||
|
|
||||||
/* get a random source port */
|
|
||||||
unsigned int random_port(void);
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* update_tftp - Update firmware over TFTP (via DFU)
|
* update_tftp - Update firmware over TFTP (via DFU)
|
||||||
*
|
*
|
||||||
|
112
include/phy.h
112
include/phy.h
@ -170,6 +170,13 @@ struct fixed_link {
|
|||||||
int asym_pause;
|
int asym_pause;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* phy_read - Convenience function for reading a given PHY register
|
||||||
|
* @phydev: the phy_device struct
|
||||||
|
* @devad: The MMD to read from
|
||||||
|
* @regnum: register number to read
|
||||||
|
* @return: value for success or negative errno for failure
|
||||||
|
*/
|
||||||
static inline int phy_read(struct phy_device *phydev, int devad, int regnum)
|
static inline int phy_read(struct phy_device *phydev, int devad, int regnum)
|
||||||
{
|
{
|
||||||
struct mii_dev *bus = phydev->bus;
|
struct mii_dev *bus = phydev->bus;
|
||||||
@ -182,6 +189,14 @@ static inline int phy_read(struct phy_device *phydev, int devad, int regnum)
|
|||||||
return bus->read(bus, phydev->addr, devad, regnum);
|
return bus->read(bus, phydev->addr, devad, regnum);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* phy_write - Convenience function for writing a given PHY register
|
||||||
|
* @phydev: the phy_device struct
|
||||||
|
* @devad: The MMD to read from
|
||||||
|
* @regnum: register number to write
|
||||||
|
* @val: value to write to @regnum
|
||||||
|
* @return: 0 for success or negative errno for failure
|
||||||
|
*/
|
||||||
static inline int phy_write(struct phy_device *phydev, int devad, int regnum,
|
static inline int phy_write(struct phy_device *phydev, int devad, int regnum,
|
||||||
u16 val)
|
u16 val)
|
||||||
{
|
{
|
||||||
@ -195,6 +210,13 @@ static inline int phy_write(struct phy_device *phydev, int devad, int regnum,
|
|||||||
return bus->write(bus, phydev->addr, devad, regnum, val);
|
return bus->write(bus, phydev->addr, devad, regnum, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* phy_mmd_start_indirect - Convenience function for writing MMD registers
|
||||||
|
* @phydev: the phy_device struct
|
||||||
|
* @devad: The MMD to read from
|
||||||
|
* @regnum: register number to write
|
||||||
|
* @return: None
|
||||||
|
*/
|
||||||
static inline void phy_mmd_start_indirect(struct phy_device *phydev, int devad,
|
static inline void phy_mmd_start_indirect(struct phy_device *phydev, int devad,
|
||||||
int regnum)
|
int regnum)
|
||||||
{
|
{
|
||||||
@ -209,6 +231,14 @@ static inline void phy_mmd_start_indirect(struct phy_device *phydev, int devad,
|
|||||||
(devad | MII_MMD_CTRL_NOINCR));
|
(devad | MII_MMD_CTRL_NOINCR));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* phy_read_mmd - Convenience function for reading a register
|
||||||
|
* from an MMD on a given PHY.
|
||||||
|
* @phydev: The phy_device struct
|
||||||
|
* @devad: The MMD to read from
|
||||||
|
* @regnum: The register on the MMD to read
|
||||||
|
* @return: Value for success or negative errno for failure
|
||||||
|
*/
|
||||||
static inline int phy_read_mmd(struct phy_device *phydev, int devad,
|
static inline int phy_read_mmd(struct phy_device *phydev, int devad,
|
||||||
int regnum)
|
int regnum)
|
||||||
{
|
{
|
||||||
@ -233,6 +263,15 @@ static inline int phy_read_mmd(struct phy_device *phydev, int devad,
|
|||||||
return phy_read(phydev, MDIO_DEVAD_NONE, MII_MMD_DATA);
|
return phy_read(phydev, MDIO_DEVAD_NONE, MII_MMD_DATA);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* phy_write_mmd - Convenience function for writing a register
|
||||||
|
* on an MMD on a given PHY.
|
||||||
|
* @phydev: The phy_device struct
|
||||||
|
* @devad: The MMD to read from
|
||||||
|
* @regnum: The register on the MMD to read
|
||||||
|
* @val: value to write to @regnum
|
||||||
|
* @return: 0 for success or negative errno for failure
|
||||||
|
*/
|
||||||
static inline int phy_write_mmd(struct phy_device *phydev, int devad,
|
static inline int phy_write_mmd(struct phy_device *phydev, int devad,
|
||||||
int regnum, u16 val)
|
int regnum, u16 val)
|
||||||
{
|
{
|
||||||
@ -257,6 +296,60 @@ static inline int phy_write_mmd(struct phy_device *phydev, int devad,
|
|||||||
return phy_write(phydev, MDIO_DEVAD_NONE, MII_MMD_DATA, val);
|
return phy_write(phydev, MDIO_DEVAD_NONE, MII_MMD_DATA, val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* phy_set_bits_mmd - Convenience function for setting bits in a register
|
||||||
|
* on MMD
|
||||||
|
* @phydev: the phy_device struct
|
||||||
|
* @devad: the MMD containing register to modify
|
||||||
|
* @regnum: register number to modify
|
||||||
|
* @val: bits to set
|
||||||
|
* @return: 0 for success or negative errno for failure
|
||||||
|
*/
|
||||||
|
static inline int phy_set_bits_mmd(struct phy_device *phydev, int devad,
|
||||||
|
u32 regnum, u16 val)
|
||||||
|
{
|
||||||
|
int value, ret;
|
||||||
|
|
||||||
|
value = phy_read_mmd(phydev, devad, regnum);
|
||||||
|
if (value < 0)
|
||||||
|
return value;
|
||||||
|
|
||||||
|
value |= val;
|
||||||
|
|
||||||
|
ret = phy_write_mmd(phydev, devad, regnum, value);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* phy_clear_bits_mmd - Convenience function for clearing bits in a register
|
||||||
|
* on MMD
|
||||||
|
* @phydev: the phy_device struct
|
||||||
|
* @devad: the MMD containing register to modify
|
||||||
|
* @regnum: register number to modify
|
||||||
|
* @val: bits to clear
|
||||||
|
* @return: 0 for success or negative errno for failure
|
||||||
|
*/
|
||||||
|
static inline int phy_clear_bits_mmd(struct phy_device *phydev, int devad,
|
||||||
|
u32 regnum, u16 val)
|
||||||
|
{
|
||||||
|
int value, ret;
|
||||||
|
|
||||||
|
value = phy_read_mmd(phydev, devad, regnum);
|
||||||
|
if (value < 0)
|
||||||
|
return value;
|
||||||
|
|
||||||
|
value &= ~val;
|
||||||
|
|
||||||
|
ret = phy_write_mmd(phydev, devad, regnum, value);
|
||||||
|
if (ret < 0)
|
||||||
|
return ret;
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_PHYLIB_10G
|
#ifdef CONFIG_PHYLIB_10G
|
||||||
extern struct phy_driver gen10g_driver;
|
extern struct phy_driver gen10g_driver;
|
||||||
|
|
||||||
@ -275,26 +368,23 @@ static inline int is_10g_interface(phy_interface_t interface)
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* phy_init() - Initializes the PHY drivers
|
* phy_init() - Initializes the PHY drivers
|
||||||
*
|
|
||||||
* This function registers all available PHY drivers
|
* This function registers all available PHY drivers
|
||||||
*
|
*
|
||||||
* @return 0 if OK, -ve on error
|
* @return: 0 if OK, -ve on error
|
||||||
*/
|
*/
|
||||||
int phy_init(void);
|
int phy_init(void);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* phy_reset() - Resets the specified PHY
|
* phy_reset() - Resets the specified PHY
|
||||||
*
|
|
||||||
* Issues a reset of the PHY and waits for it to complete
|
* Issues a reset of the PHY and waits for it to complete
|
||||||
*
|
*
|
||||||
* @phydev: PHY to reset
|
* @phydev: PHY to reset
|
||||||
* @return 0 if OK, -ve on error
|
* @return: 0 if OK, -ve on error
|
||||||
*/
|
*/
|
||||||
int phy_reset(struct phy_device *phydev);
|
int phy_reset(struct phy_device *phydev);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* phy_find_by_mask() - Searches for a PHY on the specified MDIO bus
|
* phy_find_by_mask() - Searches for a PHY on the specified MDIO bus
|
||||||
*
|
|
||||||
* The function checks the PHY addresses flagged in phy_mask and returns a
|
* The function checks the PHY addresses flagged in phy_mask and returns a
|
||||||
* phy_device pointer if it detects a PHY.
|
* phy_device pointer if it detects a PHY.
|
||||||
* This function should only be called if just one PHY is expected to be present
|
* This function should only be called if just one PHY is expected to be present
|
||||||
@ -304,7 +394,7 @@ int phy_reset(struct phy_device *phydev);
|
|||||||
* @bus: MII/MDIO bus to scan
|
* @bus: MII/MDIO bus to scan
|
||||||
* @phy_mask: bitmap of PYH addresses to scan
|
* @phy_mask: bitmap of PYH addresses to scan
|
||||||
* @interface: type of MAC-PHY interface
|
* @interface: type of MAC-PHY interface
|
||||||
* @return pointer to phy_device if a PHY is found, or NULL otherwise
|
* @return: pointer to phy_device if a PHY is found, or NULL otherwise
|
||||||
*/
|
*/
|
||||||
struct phy_device *phy_find_by_mask(struct mii_dev *bus, unsigned phy_mask,
|
struct phy_device *phy_find_by_mask(struct mii_dev *bus, unsigned phy_mask,
|
||||||
phy_interface_t interface);
|
phy_interface_t interface);
|
||||||
@ -320,7 +410,6 @@ void phy_connect_dev(struct phy_device *phydev, struct udevice *dev);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* phy_connect() - Creates a PHY device for the Ethernet interface
|
* phy_connect() - Creates a PHY device for the Ethernet interface
|
||||||
*
|
|
||||||
* Creates a PHY device for the PHY at the given address, if one doesn't exist
|
* Creates a PHY device for the PHY at the given address, if one doesn't exist
|
||||||
* already, and associates it with the Ethernet device.
|
* already, and associates it with the Ethernet device.
|
||||||
* The function may be called with addr <= 0, in this case addr value is ignored
|
* The function may be called with addr <= 0, in this case addr value is ignored
|
||||||
@ -332,7 +421,7 @@ void phy_connect_dev(struct phy_device *phydev, struct udevice *dev);
|
|||||||
* @addr: PHY address on MDIO bus
|
* @addr: PHY address on MDIO bus
|
||||||
* @dev: Ethernet device to associate to the PHY
|
* @dev: Ethernet device to associate to the PHY
|
||||||
* @interface: type of MAC-PHY interface
|
* @interface: type of MAC-PHY interface
|
||||||
* @return pointer to phy_device if a PHY is found, or NULL otherwise
|
* @return: pointer to phy_device if a PHY is found, or NULL otherwise
|
||||||
*/
|
*/
|
||||||
struct phy_device *phy_connect(struct mii_dev *bus, int addr,
|
struct phy_device *phy_connect(struct mii_dev *bus, int addr,
|
||||||
struct udevice *dev,
|
struct udevice *dev,
|
||||||
@ -356,7 +445,6 @@ void phy_connect_dev(struct phy_device *phydev, struct eth_device *dev);
|
|||||||
|
|
||||||
/**
|
/**
|
||||||
* phy_connect() - Creates a PHY device for the Ethernet interface
|
* phy_connect() - Creates a PHY device for the Ethernet interface
|
||||||
*
|
|
||||||
* Creates a PHY device for the PHY at the given address, if one doesn't exist
|
* Creates a PHY device for the PHY at the given address, if one doesn't exist
|
||||||
* already, and associates it with the Ethernet device.
|
* already, and associates it with the Ethernet device.
|
||||||
* The function may be called with addr <= 0, in this case addr value is ignored
|
* The function may be called with addr <= 0, in this case addr value is ignored
|
||||||
@ -368,7 +456,7 @@ void phy_connect_dev(struct phy_device *phydev, struct eth_device *dev);
|
|||||||
* @addr: PHY address on MDIO bus
|
* @addr: PHY address on MDIO bus
|
||||||
* @dev: Ethernet device to associate to the PHY
|
* @dev: Ethernet device to associate to the PHY
|
||||||
* @interface: type of MAC-PHY interface
|
* @interface: type of MAC-PHY interface
|
||||||
* @return pointer to phy_device if a PHY is found, or NULL otherwise
|
* @return: pointer to phy_device if a PHY is found, or NULL otherwise
|
||||||
*/
|
*/
|
||||||
struct phy_device *phy_connect(struct mii_dev *bus, int addr,
|
struct phy_device *phy_connect(struct mii_dev *bus, int addr,
|
||||||
struct eth_device *dev,
|
struct eth_device *dev,
|
||||||
@ -428,7 +516,7 @@ int get_phy_id(struct mii_dev *bus, int addr, int devad, u32 *phy_id);
|
|||||||
* phy_get_interface_by_name() - Look up a PHY interface name
|
* phy_get_interface_by_name() - Look up a PHY interface name
|
||||||
*
|
*
|
||||||
* @str: PHY interface name, e.g. "mii"
|
* @str: PHY interface name, e.g. "mii"
|
||||||
* @return PHY_INTERFACE_MODE_... value, or -1 if not found
|
* @return: PHY_INTERFACE_MODE_... value, or -1 if not found
|
||||||
*/
|
*/
|
||||||
int phy_get_interface_by_name(const char *str);
|
int phy_get_interface_by_name(const char *str);
|
||||||
|
|
||||||
@ -436,6 +524,7 @@ int phy_get_interface_by_name(const char *str);
|
|||||||
* phy_interface_is_rgmii - Convenience function for testing if a PHY interface
|
* phy_interface_is_rgmii - Convenience function for testing if a PHY interface
|
||||||
* is RGMII (all variants)
|
* is RGMII (all variants)
|
||||||
* @phydev: the phy_device struct
|
* @phydev: the phy_device struct
|
||||||
|
* @return: true if MII bus is RGMII or false if it is not
|
||||||
*/
|
*/
|
||||||
static inline bool phy_interface_is_rgmii(struct phy_device *phydev)
|
static inline bool phy_interface_is_rgmii(struct phy_device *phydev)
|
||||||
{
|
{
|
||||||
@ -447,6 +536,7 @@ static inline bool phy_interface_is_rgmii(struct phy_device *phydev)
|
|||||||
* phy_interface_is_sgmii - Convenience function for testing if a PHY interface
|
* phy_interface_is_sgmii - Convenience function for testing if a PHY interface
|
||||||
* is SGMII (all variants)
|
* is SGMII (all variants)
|
||||||
* @phydev: the phy_device struct
|
* @phydev: the phy_device struct
|
||||||
|
* @return: true if MII bus is SGMII or false if it is not
|
||||||
*/
|
*/
|
||||||
static inline bool phy_interface_is_sgmii(struct phy_device *phydev)
|
static inline bool phy_interface_is_sgmii(struct phy_device *phydev)
|
||||||
{
|
{
|
||||||
|
10
net/dns.c
10
net/dns.c
@ -36,6 +36,16 @@ char *net_dns_env_var; /* The envvar to store the answer in */
|
|||||||
|
|
||||||
static int dns_our_port;
|
static int dns_our_port;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* make port a little random (1024-17407)
|
||||||
|
* This keeps the math somewhat trivial to compute, and seems to work with
|
||||||
|
* all supported protocols/clients/servers
|
||||||
|
*/
|
||||||
|
static unsigned int random_port(void)
|
||||||
|
{
|
||||||
|
return 1024 + (get_timer(0) % 0x4000);
|
||||||
|
}
|
||||||
|
|
||||||
static void dns_send(void)
|
static void dns_send(void)
|
||||||
{
|
{
|
||||||
struct header *header;
|
struct header *header;
|
||||||
|
20
net/net.c
20
net/net.c
@ -456,6 +456,7 @@ restart:
|
|||||||
net_dev_exists = 1;
|
net_dev_exists = 1;
|
||||||
net_boot_file_size = 0;
|
net_boot_file_size = 0;
|
||||||
switch (protocol) {
|
switch (protocol) {
|
||||||
|
#ifdef CONFIG_CMD_TFTPBOOT
|
||||||
case TFTPGET:
|
case TFTPGET:
|
||||||
#ifdef CONFIG_CMD_TFTPPUT
|
#ifdef CONFIG_CMD_TFTPPUT
|
||||||
case TFTPPUT:
|
case TFTPPUT:
|
||||||
@ -463,6 +464,7 @@ restart:
|
|||||||
/* always use ARP to get server ethernet address */
|
/* always use ARP to get server ethernet address */
|
||||||
tftp_start(protocol);
|
tftp_start(protocol);
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
#ifdef CONFIG_CMD_TFTPSRV
|
#ifdef CONFIG_CMD_TFTPSRV
|
||||||
case TFTPSRV:
|
case TFTPSRV:
|
||||||
tftp_start_server();
|
tftp_start_server();
|
||||||
@ -480,13 +482,13 @@ restart:
|
|||||||
dhcp_request(); /* Basically same as BOOTP */
|
dhcp_request(); /* Basically same as BOOTP */
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
|
#if defined(CONFIG_CMD_BOOTP)
|
||||||
case BOOTP:
|
case BOOTP:
|
||||||
bootp_reset();
|
bootp_reset();
|
||||||
net_ip.s_addr = 0;
|
net_ip.s_addr = 0;
|
||||||
bootp_request();
|
bootp_request();
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
#if defined(CONFIG_CMD_RARP)
|
#if defined(CONFIG_CMD_RARP)
|
||||||
case RARP:
|
case RARP:
|
||||||
rarp_try = 0;
|
rarp_try = 0;
|
||||||
@ -1562,20 +1564,6 @@ int net_parse_bootfile(struct in_addr *ipaddr, char *filename, int max_len)
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(CONFIG_CMD_NFS) || \
|
|
||||||
defined(CONFIG_CMD_SNTP) || \
|
|
||||||
defined(CONFIG_CMD_DNS)
|
|
||||||
/*
|
|
||||||
* make port a little random (1024-17407)
|
|
||||||
* This keeps the math somewhat trivial to compute, and seems to work with
|
|
||||||
* all supported protocols/clients/servers
|
|
||||||
*/
|
|
||||||
unsigned int random_port(void)
|
|
||||||
{
|
|
||||||
return 1024 + (get_timer(0) % 0x4000);
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
void ip_to_string(struct in_addr x, char *s)
|
void ip_to_string(struct in_addr x, char *s)
|
||||||
{
|
{
|
||||||
x.s_addr = ntohl(x.s_addr);
|
x.s_addr = ntohl(x.s_addr);
|
||||||
|
75
net/tftp.c
75
net/tftp.c
@ -70,6 +70,7 @@ enum {
|
|||||||
TFTP_ERR_UNEXPECTED_OPCODE = 4,
|
TFTP_ERR_UNEXPECTED_OPCODE = 4,
|
||||||
TFTP_ERR_UNKNOWN_TRANSFER_ID = 5,
|
TFTP_ERR_UNKNOWN_TRANSFER_ID = 5,
|
||||||
TFTP_ERR_FILE_ALREADY_EXISTS = 6,
|
TFTP_ERR_FILE_ALREADY_EXISTS = 6,
|
||||||
|
TFTP_ERR_OPTION_NEGOTIATION = 8,
|
||||||
};
|
};
|
||||||
|
|
||||||
static struct in_addr tftp_remote_ip;
|
static struct in_addr tftp_remote_ip;
|
||||||
@ -113,6 +114,7 @@ static int tftp_put_final_block_sent;
|
|||||||
#define STATE_OACK 5
|
#define STATE_OACK 5
|
||||||
#define STATE_RECV_WRQ 6
|
#define STATE_RECV_WRQ 6
|
||||||
#define STATE_SEND_WRQ 7
|
#define STATE_SEND_WRQ 7
|
||||||
|
#define STATE_INVALID_OPTION 8
|
||||||
|
|
||||||
/* default TFTP block size */
|
/* default TFTP block size */
|
||||||
#define TFTP_BLOCK_SIZE 512
|
#define TFTP_BLOCK_SIZE 512
|
||||||
@ -233,9 +235,11 @@ static void tftp_timeout_handler(void);
|
|||||||
|
|
||||||
static void show_block_marker(void)
|
static void show_block_marker(void)
|
||||||
{
|
{
|
||||||
|
ulong pos;
|
||||||
|
|
||||||
#ifdef CONFIG_TFTP_TSIZE
|
#ifdef CONFIG_TFTP_TSIZE
|
||||||
if (tftp_tsize) {
|
if (tftp_tsize) {
|
||||||
ulong pos = tftp_cur_block * tftp_block_size +
|
pos = tftp_cur_block * tftp_block_size +
|
||||||
tftp_block_wrap_offset;
|
tftp_block_wrap_offset;
|
||||||
if (pos > tftp_tsize)
|
if (pos > tftp_tsize)
|
||||||
pos = tftp_tsize;
|
pos = tftp_tsize;
|
||||||
@ -247,9 +251,11 @@ static void show_block_marker(void)
|
|||||||
} else
|
} else
|
||||||
#endif
|
#endif
|
||||||
{
|
{
|
||||||
if (((tftp_cur_block - 1) % 10) == 0)
|
pos = (tftp_cur_block - 1) +
|
||||||
|
(tftp_block_wrap * TFTP_SEQUENCE_SIZE);
|
||||||
|
if ((pos % 10) == 0)
|
||||||
putc('#');
|
putc('#');
|
||||||
else if ((tftp_cur_block % (10 * HASHES_PER_LINE)) == 0)
|
else if (((pos + 1) % (10 * HASHES_PER_LINE)) == 0)
|
||||||
puts("\n\t ");
|
puts("\n\t ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -282,9 +288,8 @@ static void update_block_number(void)
|
|||||||
tftp_block_wrap++;
|
tftp_block_wrap++;
|
||||||
tftp_block_wrap_offset += tftp_block_size * TFTP_SEQUENCE_SIZE;
|
tftp_block_wrap_offset += tftp_block_size * TFTP_SEQUENCE_SIZE;
|
||||||
timeout_count = 0; /* we've done well, reset the timeout */
|
timeout_count = 0; /* we've done well, reset the timeout */
|
||||||
} else {
|
|
||||||
show_block_marker();
|
|
||||||
}
|
}
|
||||||
|
show_block_marker();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The TFTP get or put is complete */
|
/* The TFTP get or put is complete */
|
||||||
@ -315,6 +320,7 @@ static void tftp_send(void)
|
|||||||
uchar *xp;
|
uchar *xp;
|
||||||
int len = 0;
|
int len = 0;
|
||||||
ushort *s;
|
ushort *s;
|
||||||
|
bool err_pkt = false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We will always be sending some sort of packet, so
|
* We will always be sending some sort of packet, so
|
||||||
@ -385,6 +391,7 @@ static void tftp_send(void)
|
|||||||
strcpy((char *)pkt, "File too large");
|
strcpy((char *)pkt, "File too large");
|
||||||
pkt += 14 /*strlen("File too large")*/ + 1;
|
pkt += 14 /*strlen("File too large")*/ + 1;
|
||||||
len = pkt - xp;
|
len = pkt - xp;
|
||||||
|
err_pkt = true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case STATE_BAD_MAGIC:
|
case STATE_BAD_MAGIC:
|
||||||
@ -396,11 +403,28 @@ static void tftp_send(void)
|
|||||||
strcpy((char *)pkt, "File has bad magic");
|
strcpy((char *)pkt, "File has bad magic");
|
||||||
pkt += 18 /*strlen("File has bad magic")*/ + 1;
|
pkt += 18 /*strlen("File has bad magic")*/ + 1;
|
||||||
len = pkt - xp;
|
len = pkt - xp;
|
||||||
|
err_pkt = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case STATE_INVALID_OPTION:
|
||||||
|
xp = pkt;
|
||||||
|
s = (ushort *)pkt;
|
||||||
|
*s++ = htons(TFTP_ERROR);
|
||||||
|
*s++ = htons(TFTP_ERR_OPTION_NEGOTIATION);
|
||||||
|
pkt = (uchar *)s;
|
||||||
|
strcpy((char *)pkt, "Option Negotiation Failed");
|
||||||
|
/* strlen("Option Negotiation Failed") + NULL*/
|
||||||
|
pkt += 25 + 1;
|
||||||
|
len = pkt - xp;
|
||||||
|
err_pkt = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
net_send_udp_packet(net_server_ethaddr, tftp_remote_ip,
|
net_send_udp_packet(net_server_ethaddr, tftp_remote_ip,
|
||||||
tftp_remote_port, tftp_our_port, len);
|
tftp_remote_port, tftp_our_port, len);
|
||||||
|
|
||||||
|
if (err_pkt)
|
||||||
|
net_set_state(NETLOOP_FAIL);
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef CONFIG_CMD_TFTPPUT
|
#ifdef CONFIG_CMD_TFTPPUT
|
||||||
@ -421,6 +445,7 @@ static void tftp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
|
|||||||
__be16 proto;
|
__be16 proto;
|
||||||
__be16 *s;
|
__be16 *s;
|
||||||
int i;
|
int i;
|
||||||
|
u16 timeout_val_rcvd;
|
||||||
|
|
||||||
if (dest != tftp_our_port) {
|
if (dest != tftp_our_port) {
|
||||||
return;
|
return;
|
||||||
@ -477,8 +502,14 @@ static void tftp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
case TFTP_OACK:
|
case TFTP_OACK:
|
||||||
debug("Got OACK: %s %s\n",
|
debug("Got OACK: ");
|
||||||
pkt, pkt + strlen((char *)pkt) + 1);
|
for (i = 0; i < len; i++) {
|
||||||
|
if (pkt[i] == '\0')
|
||||||
|
debug(" ");
|
||||||
|
else
|
||||||
|
debug("%c", pkt[i]);
|
||||||
|
}
|
||||||
|
debug("\n");
|
||||||
tftp_state = STATE_OACK;
|
tftp_state = STATE_OACK;
|
||||||
tftp_remote_port = src;
|
tftp_remote_port = src;
|
||||||
/*
|
/*
|
||||||
@ -487,15 +518,32 @@ static void tftp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
|
|||||||
* something like "len-8" may give a *huge* number
|
* something like "len-8" may give a *huge* number
|
||||||
*/
|
*/
|
||||||
for (i = 0; i+8 < len; i++) {
|
for (i = 0; i+8 < len; i++) {
|
||||||
if (strcmp((char *)pkt + i, "blksize") == 0) {
|
if (strcasecmp((char *)pkt + i, "blksize") == 0) {
|
||||||
tftp_block_size = (unsigned short)
|
tftp_block_size = (unsigned short)
|
||||||
simple_strtoul((char *)pkt + i + 8,
|
simple_strtoul((char *)pkt + i + 8,
|
||||||
NULL, 10);
|
NULL, 10);
|
||||||
debug("Blocksize ack: %s, %d\n",
|
debug("Blocksize oack: %s, %d\n",
|
||||||
(char *)pkt + i + 8, tftp_block_size);
|
(char *)pkt + i + 8, tftp_block_size);
|
||||||
|
if (tftp_block_size > tftp_block_size_option) {
|
||||||
|
printf("Invalid blk size(=%d)\n",
|
||||||
|
tftp_block_size);
|
||||||
|
tftp_state = STATE_INVALID_OPTION;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (strcasecmp((char *)pkt + i, "timeout") == 0) {
|
||||||
|
timeout_val_rcvd = (unsigned short)
|
||||||
|
simple_strtoul((char *)pkt + i + 8,
|
||||||
|
NULL, 10);
|
||||||
|
debug("Timeout oack: %s, %d\n",
|
||||||
|
(char *)pkt + i + 8, timeout_val_rcvd);
|
||||||
|
if (timeout_val_rcvd != (timeout_ms / 1000)) {
|
||||||
|
printf("Invalid timeout val(=%d s)\n",
|
||||||
|
timeout_val_rcvd);
|
||||||
|
tftp_state = STATE_INVALID_OPTION;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
#ifdef CONFIG_TFTP_TSIZE
|
#ifdef CONFIG_TFTP_TSIZE
|
||||||
if (strcmp((char *)pkt+i, "tsize") == 0) {
|
if (strcasecmp((char *)pkt + i, "tsize") == 0) {
|
||||||
tftp_tsize = simple_strtoul((char *)pkt + i + 6,
|
tftp_tsize = simple_strtoul((char *)pkt + i + 6,
|
||||||
NULL, 10);
|
NULL, 10);
|
||||||
debug("size = %s, %d\n",
|
debug("size = %s, %d\n",
|
||||||
@ -504,7 +552,7 @@ static void tftp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
#ifdef CONFIG_CMD_TFTPPUT
|
#ifdef CONFIG_CMD_TFTPPUT
|
||||||
if (tftp_put_active) {
|
if (tftp_put_active && tftp_state == STATE_OACK) {
|
||||||
/* Get ready to send the first block */
|
/* Get ready to send the first block */
|
||||||
tftp_state = STATE_DATA;
|
tftp_state = STATE_DATA;
|
||||||
tftp_cur_block++;
|
tftp_cur_block++;
|
||||||
@ -518,10 +566,8 @@ static void tftp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
|
|||||||
len -= 2;
|
len -= 2;
|
||||||
tftp_cur_block = ntohs(*(__be16 *)pkt);
|
tftp_cur_block = ntohs(*(__be16 *)pkt);
|
||||||
|
|
||||||
update_block_number();
|
|
||||||
|
|
||||||
if (tftp_state == STATE_SEND_RRQ)
|
if (tftp_state == STATE_SEND_RRQ)
|
||||||
debug("Server did not acknowledge timeout option!\n");
|
debug("Server did not acknowledge any options!\n");
|
||||||
|
|
||||||
if (tftp_state == STATE_SEND_RRQ || tftp_state == STATE_OACK ||
|
if (tftp_state == STATE_SEND_RRQ || tftp_state == STATE_OACK ||
|
||||||
tftp_state == STATE_RECV_WRQ) {
|
tftp_state == STATE_RECV_WRQ) {
|
||||||
@ -545,6 +591,7 @@ static void tftp_handler(uchar *pkt, unsigned dest, struct in_addr sip,
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
update_block_number();
|
||||||
tftp_prev_block = tftp_cur_block;
|
tftp_prev_block = tftp_cur_block;
|
||||||
timeout_count_max = tftp_timeout_count_max;
|
timeout_count_max = tftp_timeout_count_max;
|
||||||
net_set_timeout_handler(timeout_ms, tftp_timeout_handler);
|
net_set_timeout_handler(timeout_ms, tftp_timeout_handler);
|
||||||
|
Loading…
Reference in New Issue
Block a user