uboot/drivers/net/smc911x.h
<<
>>
Prefs
   1/*
   2 * SMSC LAN9[12]1[567] Network driver
   3 *
   4 * (c) 2007 Pengutronix, Sascha Hauer <s.hauer@pengutronix.de>
   5 *
   6 * SPDX-License-Identifier:     GPL-2.0+
   7 */
   8
   9#ifndef _SMC911X_H_
  10#define _SMC911X_H_
  11
  12#include <linux/types.h>
  13
  14#define DRIVERNAME "smc911x"
  15
  16#if defined (CONFIG_SMC911X_32_BIT) && \
  17        defined (CONFIG_SMC911X_16_BIT)
  18#error "SMC911X: Only one of CONFIG_SMC911X_32_BIT and \
  19        CONFIG_SMC911X_16_BIT shall be set"
  20#endif
  21
  22#if defined (CONFIG_SMC911X_32_BIT)
  23static inline u32 __smc911x_reg_read(struct eth_device *dev, u32 offset)
  24{
  25        return *(volatile u32*)(dev->iobase + offset);
  26}
  27u32 smc911x_reg_read(struct eth_device *dev, u32 offset)
  28        __attribute__((weak, alias("__smc911x_reg_read")));
  29
  30static inline void __smc911x_reg_write(struct eth_device *dev,
  31                                        u32 offset, u32 val)
  32{
  33        *(volatile u32*)(dev->iobase + offset) = val;
  34}
  35void smc911x_reg_write(struct eth_device *dev, u32 offset, u32 val)
  36        __attribute__((weak, alias("__smc911x_reg_write")));
  37#elif defined (CONFIG_SMC911X_16_BIT)
  38static inline u32 smc911x_reg_read(struct eth_device *dev, u32 offset)
  39{
  40        volatile u16 *addr_16 = (u16 *)(dev->iobase + offset);
  41        return ((*addr_16 & 0x0000ffff) | (*(addr_16 + 1) << 16));
  42}
  43static inline void smc911x_reg_write(struct eth_device *dev,
  44                                        u32 offset, u32 val)
  45{
  46        *(volatile u16 *)(dev->iobase + offset) = (u16)val;
  47        *(volatile u16 *)(dev->iobase + offset + 2) = (u16)(val >> 16);
  48}
  49#else
  50#error "SMC911X: undefined bus width"
  51#endif /* CONFIG_SMC911X_16_BIT */
  52
  53/* Below are the register offsets and bit definitions
  54 * of the Lan911x memory space
  55 */
  56#define RX_DATA_FIFO                            0x00
  57
  58#define TX_DATA_FIFO                            0x20
  59#define TX_CMD_A_INT_ON_COMP                    0x80000000
  60#define TX_CMD_A_INT_BUF_END_ALGN               0x03000000
  61#define TX_CMD_A_INT_4_BYTE_ALGN                0x00000000
  62#define TX_CMD_A_INT_16_BYTE_ALGN               0x01000000
  63#define TX_CMD_A_INT_32_BYTE_ALGN               0x02000000
  64#define TX_CMD_A_INT_DATA_OFFSET                0x001F0000
  65#define TX_CMD_A_INT_FIRST_SEG                  0x00002000
  66#define TX_CMD_A_INT_LAST_SEG                   0x00001000
  67#define TX_CMD_A_BUF_SIZE                       0x000007FF
  68#define TX_CMD_B_PKT_TAG                        0xFFFF0000
  69#define TX_CMD_B_ADD_CRC_DISABLE                0x00002000
  70#define TX_CMD_B_DISABLE_PADDING                0x00001000
  71#define TX_CMD_B_PKT_BYTE_LENGTH                0x000007FF
  72
  73#define RX_STATUS_FIFO                          0x40
  74#define RX_STS_PKT_LEN                          0x3FFF0000
  75#define RX_STS_ES                               0x00008000
  76#define RX_STS_BCST                             0x00002000
  77#define RX_STS_LEN_ERR                          0x00001000
  78#define RX_STS_RUNT_ERR                         0x00000800
  79#define RX_STS_MCAST                            0x00000400
  80#define RX_STS_TOO_LONG                         0x00000080
  81#define RX_STS_COLL                             0x00000040
  82#define RX_STS_ETH_TYPE                         0x00000020
  83#define RX_STS_WDOG_TMT                         0x00000010
  84#define RX_STS_MII_ERR                          0x00000008
  85#define RX_STS_DRIBBLING                        0x00000004
  86#define RX_STS_CRC_ERR                          0x00000002
  87#define RX_STATUS_FIFO_PEEK                     0x44
  88#define TX_STATUS_FIFO                          0x48
  89#define TX_STS_TAG                              0xFFFF0000
  90#define TX_STS_ES                               0x00008000
  91#define TX_STS_LOC                              0x00000800
  92#define TX_STS_NO_CARR                          0x00000400
  93#define TX_STS_LATE_COLL                        0x00000200
  94#define TX_STS_MANY_COLL                        0x00000100
  95#define TX_STS_COLL_CNT                         0x00000078
  96#define TX_STS_MANY_DEFER                       0x00000004
  97#define TX_STS_UNDERRUN                         0x00000002
  98#define TX_STS_DEFERRED                         0x00000001
  99#define TX_STATUS_FIFO_PEEK                     0x4C
 100#define ID_REV                                  0x50
 101#define ID_REV_CHIP_ID                          0xFFFF0000  /* RO */
 102#define ID_REV_REV_ID                           0x0000FFFF  /* RO */
 103
 104#define INT_CFG                                 0x54
 105#define INT_CFG_INT_DEAS                        0xFF000000  /* R/W */
 106#define INT_CFG_INT_DEAS_CLR                    0x00004000
 107#define INT_CFG_INT_DEAS_STS                    0x00002000
 108#define INT_CFG_IRQ_INT                         0x00001000  /* RO */
 109#define INT_CFG_IRQ_EN                          0x00000100  /* R/W */
 110                                        /* R/W Not Affected by SW Reset */
 111#define INT_CFG_IRQ_POL                         0x00000010
 112                                        /* R/W Not Affected by SW Reset */
 113#define INT_CFG_IRQ_TYPE                        0x00000001
 114
 115#define INT_STS                                 0x58
 116#define INT_STS_SW_INT                          0x80000000  /* R/WC */
 117#define INT_STS_TXSTOP_INT                      0x02000000  /* R/WC */
 118#define INT_STS_RXSTOP_INT                      0x01000000  /* R/WC */
 119#define INT_STS_RXDFH_INT                       0x00800000  /* R/WC */
 120#define INT_STS_RXDF_INT                        0x00400000  /* R/WC */
 121#define INT_STS_TX_IOC                          0x00200000  /* R/WC */
 122#define INT_STS_RXD_INT                         0x00100000  /* R/WC */
 123#define INT_STS_GPT_INT                         0x00080000  /* R/WC */
 124#define INT_STS_PHY_INT                         0x00040000  /* RO */
 125#define INT_STS_PME_INT                         0x00020000  /* R/WC */
 126#define INT_STS_TXSO                            0x00010000  /* R/WC */
 127#define INT_STS_RWT                             0x00008000  /* R/WC */
 128#define INT_STS_RXE                             0x00004000  /* R/WC */
 129#define INT_STS_TXE                             0x00002000  /* R/WC */
 130/*#define       INT_STS_ERX             0x00001000*/  /* R/WC */
 131#define INT_STS_TDFU                            0x00000800  /* R/WC */
 132#define INT_STS_TDFO                            0x00000400  /* R/WC */
 133#define INT_STS_TDFA                            0x00000200  /* R/WC */
 134#define INT_STS_TSFF                            0x00000100  /* R/WC */
 135#define INT_STS_TSFL                            0x00000080  /* R/WC */
 136/*#define       INT_STS_RXDF            0x00000040*/  /* R/WC */
 137#define INT_STS_RDFO                            0x00000040  /* R/WC */
 138#define INT_STS_RDFL                            0x00000020  /* R/WC */
 139#define INT_STS_RSFF                            0x00000010  /* R/WC */
 140#define INT_STS_RSFL                            0x00000008  /* R/WC */
 141#define INT_STS_GPIO2_INT                       0x00000004  /* R/WC */
 142#define INT_STS_GPIO1_INT                       0x00000002  /* R/WC */
 143#define INT_STS_GPIO0_INT                       0x00000001  /* R/WC */
 144#define INT_EN                                  0x5C
 145#define INT_EN_SW_INT_EN                        0x80000000  /* R/W */
 146#define INT_EN_TXSTOP_INT_EN                    0x02000000  /* R/W */
 147#define INT_EN_RXSTOP_INT_EN                    0x01000000  /* R/W */
 148#define INT_EN_RXDFH_INT_EN                     0x00800000  /* R/W */
 149/*#define       INT_EN_RXDF_INT_EN              0x00400000*/  /* R/W */
 150#define INT_EN_TIOC_INT_EN                      0x00200000  /* R/W */
 151#define INT_EN_RXD_INT_EN                       0x00100000  /* R/W */
 152#define INT_EN_GPT_INT_EN                       0x00080000  /* R/W */
 153#define INT_EN_PHY_INT_EN                       0x00040000  /* R/W */
 154#define INT_EN_PME_INT_EN                       0x00020000  /* R/W */
 155#define INT_EN_TXSO_EN                          0x00010000  /* R/W */
 156#define INT_EN_RWT_EN                           0x00008000  /* R/W */
 157#define INT_EN_RXE_EN                           0x00004000  /* R/W */
 158#define INT_EN_TXE_EN                           0x00002000  /* R/W */
 159/*#define       INT_EN_ERX_EN                   0x00001000*/  /* R/W */
 160#define INT_EN_TDFU_EN                          0x00000800  /* R/W */
 161#define INT_EN_TDFO_EN                          0x00000400  /* R/W */
 162#define INT_EN_TDFA_EN                          0x00000200  /* R/W */
 163#define INT_EN_TSFF_EN                          0x00000100  /* R/W */
 164#define INT_EN_TSFL_EN                          0x00000080  /* R/W */
 165/*#define       INT_EN_RXDF_EN                  0x00000040*/  /* R/W */
 166#define INT_EN_RDFO_EN                          0x00000040  /* R/W */
 167#define INT_EN_RDFL_EN                          0x00000020  /* R/W */
 168#define INT_EN_RSFF_EN                          0x00000010  /* R/W */
 169#define INT_EN_RSFL_EN                          0x00000008  /* R/W */
 170#define INT_EN_GPIO2_INT                        0x00000004  /* R/W */
 171#define INT_EN_GPIO1_INT                        0x00000002  /* R/W */
 172#define INT_EN_GPIO0_INT                        0x00000001  /* R/W */
 173
 174#define BYTE_TEST                               0x64
 175#define FIFO_INT                                0x68
 176#define FIFO_INT_TX_AVAIL_LEVEL                 0xFF000000  /* R/W */
 177#define FIFO_INT_TX_STS_LEVEL                   0x00FF0000  /* R/W */
 178#define FIFO_INT_RX_AVAIL_LEVEL                 0x0000FF00  /* R/W */
 179#define FIFO_INT_RX_STS_LEVEL                   0x000000FF  /* R/W */
 180
 181#define RX_CFG                                  0x6C
 182#define RX_CFG_RX_END_ALGN                      0xC0000000  /* R/W */
 183#define         RX_CFG_RX_END_ALGN4             0x00000000  /* R/W */
 184#define         RX_CFG_RX_END_ALGN16            0x40000000  /* R/W */
 185#define         RX_CFG_RX_END_ALGN32            0x80000000  /* R/W */
 186#define RX_CFG_RX_DMA_CNT                       0x0FFF0000  /* R/W */
 187#define RX_CFG_RX_DUMP                          0x00008000  /* R/W */
 188#define RX_CFG_RXDOFF                           0x00001F00  /* R/W */
 189/*#define       RX_CFG_RXBAD                    0x00000001*/  /* R/W */
 190
 191#define TX_CFG                                  0x70
 192/*#define       TX_CFG_TX_DMA_LVL               0xE0000000*/     /* R/W */
 193                                                 /* R/W Self Clearing */
 194/*#define       TX_CFG_TX_DMA_CNT               0x0FFF0000*/
 195#define TX_CFG_TXS_DUMP                         0x00008000  /* Self Clearing */
 196#define TX_CFG_TXD_DUMP                         0x00004000  /* Self Clearing */
 197#define TX_CFG_TXSAO                            0x00000004  /* R/W */
 198#define TX_CFG_TX_ON                            0x00000002  /* R/W */
 199#define TX_CFG_STOP_TX                          0x00000001  /* Self Clearing */
 200
 201#define HW_CFG                                  0x74
 202#define HW_CFG_TTM                              0x00200000  /* R/W */
 203#define HW_CFG_SF                               0x00100000  /* R/W */
 204#define HW_CFG_TX_FIF_SZ                        0x000F0000  /* R/W */
 205#define HW_CFG_TR                               0x00003000  /* R/W */
 206#define HW_CFG_PHY_CLK_SEL                      0x00000060  /* R/W */
 207#define HW_CFG_PHY_CLK_SEL_INT_PHY              0x00000000 /* R/W */
 208#define HW_CFG_PHY_CLK_SEL_EXT_PHY              0x00000020 /* R/W */
 209#define HW_CFG_PHY_CLK_SEL_CLK_DIS              0x00000040 /* R/W */
 210#define HW_CFG_SMI_SEL                          0x00000010  /* R/W */
 211#define HW_CFG_EXT_PHY_DET                      0x00000008  /* RO */
 212#define HW_CFG_EXT_PHY_EN                       0x00000004  /* R/W */
 213#define HW_CFG_32_16_BIT_MODE                   0x00000004  /* RO */
 214#define HW_CFG_SRST_TO                          0x00000002  /* RO */
 215#define HW_CFG_SRST                             0x00000001  /* Self Clearing */
 216
 217#define RX_DP_CTRL                              0x78
 218#define RX_DP_CTRL_RX_FFWD                      0x80000000  /* R/W */
 219#define RX_DP_CTRL_FFWD_BUSY                    0x80000000  /* RO */
 220
 221#define RX_FIFO_INF                             0x7C
 222#define  RX_FIFO_INF_RXSUSED                    0x00FF0000  /* RO */
 223#define  RX_FIFO_INF_RXDUSED                    0x0000FFFF  /* RO */
 224
 225#define TX_FIFO_INF                             0x80
 226#define TX_FIFO_INF_TSUSED                      0x00FF0000  /* RO */
 227#define TX_FIFO_INF_TDFREE                      0x0000FFFF  /* RO */
 228
 229#define PMT_CTRL                                0x84
 230#define PMT_CTRL_PM_MODE                        0x00003000  /* Self Clearing */
 231#define PMT_CTRL_PHY_RST                        0x00000400  /* Self Clearing */
 232#define PMT_CTRL_WOL_EN                         0x00000200  /* R/W */
 233#define PMT_CTRL_ED_EN                          0x00000100  /* R/W */
 234                                        /* R/W Not Affected by SW Reset */
 235#define PMT_CTRL_PME_TYPE                       0x00000040
 236#define PMT_CTRL_WUPS                           0x00000030  /* R/WC */
 237#define PMT_CTRL_WUPS_NOWAKE                    0x00000000  /* R/WC */
 238#define PMT_CTRL_WUPS_ED                        0x00000010  /* R/WC */
 239#define PMT_CTRL_WUPS_WOL                       0x00000020  /* R/WC */
 240#define PMT_CTRL_WUPS_MULTI                     0x00000030  /* R/WC */
 241#define PMT_CTRL_PME_IND                        0x00000008  /* R/W */
 242#define PMT_CTRL_PME_POL                        0x00000004  /* R/W */
 243                                        /* R/W Not Affected by SW Reset */
 244#define PMT_CTRL_PME_EN                         0x00000002
 245#define PMT_CTRL_READY                          0x00000001  /* RO */
 246
 247#define GPIO_CFG                                0x88
 248#define GPIO_CFG_LED3_EN                        0x40000000  /* R/W */
 249#define GPIO_CFG_LED2_EN                        0x20000000  /* R/W */
 250#define GPIO_CFG_LED1_EN                        0x10000000  /* R/W */
 251#define GPIO_CFG_GPIO2_INT_POL                  0x04000000  /* R/W */
 252#define GPIO_CFG_GPIO1_INT_POL                  0x02000000  /* R/W */
 253#define GPIO_CFG_GPIO0_INT_POL                  0x01000000  /* R/W */
 254#define GPIO_CFG_EEPR_EN                        0x00700000  /* R/W */
 255#define GPIO_CFG_GPIOBUF2                       0x00040000  /* R/W */
 256#define GPIO_CFG_GPIOBUF1                       0x00020000  /* R/W */
 257#define GPIO_CFG_GPIOBUF0                       0x00010000  /* R/W */
 258#define GPIO_CFG_GPIODIR2                       0x00000400  /* R/W */
 259#define GPIO_CFG_GPIODIR1                       0x00000200  /* R/W */
 260#define GPIO_CFG_GPIODIR0                       0x00000100  /* R/W */
 261#define GPIO_CFG_GPIOD4                         0x00000010  /* R/W */
 262#define GPIO_CFG_GPIOD3                         0x00000008  /* R/W */
 263#define GPIO_CFG_GPIOD2                         0x00000004  /* R/W */
 264#define GPIO_CFG_GPIOD1                         0x00000002  /* R/W */
 265#define GPIO_CFG_GPIOD0                         0x00000001  /* R/W */
 266
 267#define GPT_CFG                                 0x8C
 268#define GPT_CFG_TIMER_EN                        0x20000000  /* R/W */
 269#define GPT_CFG_GPT_LOAD                        0x0000FFFF  /* R/W */
 270
 271#define GPT_CNT                                 0x90
 272#define GPT_CNT_GPT_CNT                         0x0000FFFF  /* RO */
 273
 274#define ENDIAN                                  0x98
 275#define FREE_RUN                                0x9C
 276#define RX_DROP                                 0xA0
 277#define MAC_CSR_CMD                             0xA4
 278#define  MAC_CSR_CMD_CSR_BUSY                   0x80000000  /* Self Clearing */
 279#define  MAC_CSR_CMD_R_NOT_W                    0x40000000  /* R/W */
 280#define  MAC_CSR_CMD_CSR_ADDR                   0x000000FF  /* R/W */
 281
 282#define MAC_CSR_DATA                            0xA8
 283#define AFC_CFG                                 0xAC
 284#define         AFC_CFG_AFC_HI                  0x00FF0000  /* R/W */
 285#define         AFC_CFG_AFC_LO                  0x0000FF00  /* R/W */
 286#define         AFC_CFG_BACK_DUR                0x000000F0  /* R/W */
 287#define         AFC_CFG_FCMULT                  0x00000008  /* R/W */
 288#define         AFC_CFG_FCBRD                   0x00000004  /* R/W */
 289#define         AFC_CFG_FCADD                   0x00000002  /* R/W */
 290#define         AFC_CFG_FCANY                   0x00000001  /* R/W */
 291
 292#define E2P_CMD                                 0xB0
 293#define         E2P_CMD_EPC_BUSY                0x80000000  /* Self Clearing */
 294#define         E2P_CMD_EPC_CMD                 0x70000000  /* R/W */
 295#define         E2P_CMD_EPC_CMD_READ            0x00000000  /* R/W */
 296#define         E2P_CMD_EPC_CMD_EWDS            0x10000000  /* R/W */
 297#define         E2P_CMD_EPC_CMD_EWEN            0x20000000  /* R/W */
 298#define         E2P_CMD_EPC_CMD_WRITE           0x30000000  /* R/W */
 299#define         E2P_CMD_EPC_CMD_WRAL            0x40000000  /* R/W */
 300#define         E2P_CMD_EPC_CMD_ERASE           0x50000000  /* R/W */
 301#define         E2P_CMD_EPC_CMD_ERAL            0x60000000  /* R/W */
 302#define         E2P_CMD_EPC_CMD_RELOAD          0x70000000  /* R/W */
 303#define         E2P_CMD_EPC_TIMEOUT             0x00000200  /* RO */
 304#define         E2P_CMD_MAC_ADDR_LOADED         0x00000100  /* RO */
 305#define         E2P_CMD_EPC_ADDR                0x000000FF  /* R/W */
 306
 307#define E2P_DATA                                0xB4
 308#define E2P_DATA_EEPROM_DATA                    0x000000FF  /* R/W */
 309/* end of LAN register offsets and bit definitions */
 310
 311/* MAC Control and Status registers */
 312#define MAC_CR                  0x01  /* R/W */
 313
 314/* MAC_CR - MAC Control Register */
 315#define MAC_CR_RXALL                    0x80000000
 316/* TODO: delete this bit? It is not described in the data sheet. */
 317#define MAC_CR_HBDIS                    0x10000000
 318#define MAC_CR_RCVOWN                   0x00800000
 319#define MAC_CR_LOOPBK                   0x00200000
 320#define MAC_CR_FDPX                     0x00100000
 321#define MAC_CR_MCPAS                    0x00080000
 322#define MAC_CR_PRMS                     0x00040000
 323#define MAC_CR_INVFILT                  0x00020000
 324#define MAC_CR_PASSBAD                  0x00010000
 325#define MAC_CR_HFILT                    0x00008000
 326#define MAC_CR_HPFILT                   0x00002000
 327#define MAC_CR_LCOLL                    0x00001000
 328#define MAC_CR_BCAST                    0x00000800
 329#define MAC_CR_DISRTY                   0x00000400
 330#define MAC_CR_PADSTR                   0x00000100
 331#define MAC_CR_BOLMT_MASK               0x000000C0
 332#define MAC_CR_DFCHK                    0x00000020
 333#define MAC_CR_TXEN                     0x00000008
 334#define MAC_CR_RXEN                     0x00000004
 335
 336#define ADDRH                   0x02      /* R/W mask 0x0000FFFFUL */
 337#define ADDRL                   0x03      /* R/W mask 0xFFFFFFFFUL */
 338#define HASHH                   0x04      /* R/W */
 339#define HASHL                   0x05      /* R/W */
 340
 341#define MII_ACC                 0x06      /* R/W */
 342#define MII_ACC_PHY_ADDR                0x0000F800
 343#define MII_ACC_MIIRINDA                0x000007C0
 344#define MII_ACC_MII_WRITE               0x00000002
 345#define MII_ACC_MII_BUSY                0x00000001
 346
 347#define MII_DATA                0x07      /* R/W mask 0x0000FFFFUL */
 348
 349#define FLOW                    0x08      /* R/W */
 350#define FLOW_FCPT                       0xFFFF0000
 351#define FLOW_FCPASS                     0x00000004
 352#define FLOW_FCEN                       0x00000002
 353#define FLOW_FCBSY                      0x00000001
 354
 355#define VLAN1                   0x09      /* R/W mask 0x0000FFFFUL */
 356#define VLAN1_VTI1                      0x0000ffff
 357
 358#define VLAN2                   0x0A      /* R/W mask 0x0000FFFFUL */
 359#define VLAN2_VTI2                      0x0000ffff
 360
 361#define WUFF                    0x0B      /* WO */
 362
 363#define WUCSR                   0x0C      /* R/W */
 364#define WUCSR_GUE                       0x00000200
 365#define WUCSR_WUFR                      0x00000040
 366#define WUCSR_MPR                       0x00000020
 367#define WUCSR_WAKE_EN                   0x00000004
 368#define WUCSR_MPEN                      0x00000002
 369
 370/* Chip ID values */
 371#define CHIP_89218      0x218a
 372#define CHIP_9115       0x115
 373#define CHIP_9116       0x116
 374#define CHIP_9117       0x117
 375#define CHIP_9118       0x118
 376#define CHIP_9211       0x9211
 377#define CHIP_9215       0x115a
 378#define CHIP_9216       0x116a
 379#define CHIP_9217       0x117a
 380#define CHIP_9218       0x118a
 381#define CHIP_9220       0x9220
 382#define CHIP_9221       0x9221
 383
 384struct chip_id {
 385        u16 id;
 386        char *name;
 387};
 388
 389static const struct chip_id chip_ids[] =  {
 390        { CHIP_89218, "LAN89218" },
 391        { CHIP_9115, "LAN9115" },
 392        { CHIP_9116, "LAN9116" },
 393        { CHIP_9117, "LAN9117" },
 394        { CHIP_9118, "LAN9118" },
 395        { CHIP_9211, "LAN9211" },
 396        { CHIP_9215, "LAN9215" },
 397        { CHIP_9216, "LAN9216" },
 398        { CHIP_9217, "LAN9217" },
 399        { CHIP_9218, "LAN9218" },
 400        { CHIP_9220, "LAN9220" },
 401        { CHIP_9221, "LAN9221" },
 402        { 0, NULL },
 403};
 404
 405static u32 smc911x_get_mac_csr(struct eth_device *dev, u8 reg)
 406{
 407        while (smc911x_reg_read(dev, MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY)
 408                ;
 409        smc911x_reg_write(dev, MAC_CSR_CMD,
 410                        MAC_CSR_CMD_CSR_BUSY | MAC_CSR_CMD_R_NOT_W | reg);
 411        while (smc911x_reg_read(dev, MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY)
 412                ;
 413
 414        return smc911x_reg_read(dev, MAC_CSR_DATA);
 415}
 416
 417static void smc911x_set_mac_csr(struct eth_device *dev, u8 reg, u32 data)
 418{
 419        while (smc911x_reg_read(dev, MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY)
 420                ;
 421        smc911x_reg_write(dev, MAC_CSR_DATA, data);
 422        smc911x_reg_write(dev, MAC_CSR_CMD, MAC_CSR_CMD_CSR_BUSY | reg);
 423        while (smc911x_reg_read(dev, MAC_CSR_CMD) & MAC_CSR_CMD_CSR_BUSY)
 424                ;
 425}
 426
 427static int smc911x_detect_chip(struct eth_device *dev)
 428{
 429        unsigned long val, i;
 430
 431        val = smc911x_reg_read(dev, BYTE_TEST);
 432        if (val == 0xffffffff) {
 433                /* Special case -- no chip present */
 434                return -1;
 435        } else if (val != 0x87654321) {
 436                printf(DRIVERNAME ": Invalid chip endian 0x%08lx\n", val);
 437                return -1;
 438        }
 439
 440        val = smc911x_reg_read(dev, ID_REV) >> 16;
 441        for (i = 0; chip_ids[i].id != 0; i++) {
 442                if (chip_ids[i].id == val) break;
 443        }
 444        if (!chip_ids[i].id) {
 445                printf(DRIVERNAME ": Unknown chip ID %04lx\n", val);
 446                return -1;
 447        }
 448
 449        dev->priv = (void *)&chip_ids[i];
 450
 451        return 0;
 452}
 453
 454static void smc911x_reset(struct eth_device *dev)
 455{
 456        int timeout;
 457
 458        /*
 459         *  Take out of PM setting first
 460         *  Device is already wake up if PMT_CTRL_READY bit is set
 461         */
 462        if ((smc911x_reg_read(dev, PMT_CTRL) & PMT_CTRL_READY) == 0) {
 463                /* Write to the bytetest will take out of powerdown */
 464                smc911x_reg_write(dev, BYTE_TEST, 0x0);
 465
 466                timeout = 10;
 467
 468                while (timeout-- &&
 469                        !(smc911x_reg_read(dev, PMT_CTRL) & PMT_CTRL_READY))
 470                        udelay(10);
 471                if (timeout < 0) {
 472                        printf(DRIVERNAME
 473                                ": timeout waiting for PM restore\n");
 474                        return;
 475                }
 476        }
 477
 478        /* Disable interrupts */
 479        smc911x_reg_write(dev, INT_EN, 0);
 480
 481        smc911x_reg_write(dev, HW_CFG, HW_CFG_SRST);
 482
 483        timeout = 1000;
 484        while (timeout-- && smc911x_reg_read(dev, E2P_CMD) & E2P_CMD_EPC_BUSY)
 485                udelay(10);
 486
 487        if (timeout < 0) {
 488                printf(DRIVERNAME ": reset timeout\n");
 489                return;
 490        }
 491
 492        /* Reset the FIFO level and flow control settings */
 493        smc911x_set_mac_csr(dev, FLOW, FLOW_FCPT | FLOW_FCEN);
 494        smc911x_reg_write(dev, AFC_CFG, 0x0050287F);
 495
 496        /* Set to LED outputs */
 497        smc911x_reg_write(dev, GPIO_CFG, 0x70070000);
 498}
 499
 500#endif
 501