1fc9a8e8dSKaricheri, Muralidharan /* 2fc9a8e8dSKaricheri, Muralidharan * Ethernet driver for TI K2HK EVM. 3fc9a8e8dSKaricheri, Muralidharan * 4fc9a8e8dSKaricheri, Muralidharan * (C) Copyright 2012-2014 5fc9a8e8dSKaricheri, Muralidharan * Texas Instruments Incorporated, <www.ti.com> 6fc9a8e8dSKaricheri, Muralidharan * 7fc9a8e8dSKaricheri, Muralidharan * SPDX-License-Identifier: GPL-2.0+ 8fc9a8e8dSKaricheri, Muralidharan */ 9fc9a8e8dSKaricheri, Muralidharan #include <common.h> 10fc9a8e8dSKaricheri, Muralidharan #include <command.h> 1124b852a7SSimon Glass #include <console.h> 12fc9a8e8dSKaricheri, Muralidharan 136599f369SMugunthan V N #include <dm.h> 146599f369SMugunthan V N 15fc9a8e8dSKaricheri, Muralidharan #include <net.h> 163fe93623SKhoronzhuk, Ivan #include <phy.h> 17c05d05e7SKhoronzhuk, Ivan #include <errno.h> 18fc9a8e8dSKaricheri, Muralidharan #include <miiphy.h> 19fc9a8e8dSKaricheri, Muralidharan #include <malloc.h> 20ef454717SKhoronzhuk, Ivan #include <asm/ti-common/keystone_nav.h> 210935cac6SKhoronzhuk, Ivan #include <asm/ti-common/keystone_net.h> 22a43febdeSKhoronzhuk, Ivan #include <asm/ti-common/keystone_serdes.h> 236599f369SMugunthan V N #include <asm/arch/psc_defs.h> 24fc9a8e8dSKaricheri, Muralidharan 256599f369SMugunthan V N DECLARE_GLOBAL_DATA_PTR; 266599f369SMugunthan V N 276599f369SMugunthan V N #ifndef CONFIG_DM_ETH 28fc9a8e8dSKaricheri, Muralidharan unsigned int emac_open; 29550c5ce6SKhoronzhuk, Ivan static struct mii_dev *mdio_bus; 30fc9a8e8dSKaricheri, Muralidharan static unsigned int sys_has_mdio = 1; 316599f369SMugunthan V N #endif 32fc9a8e8dSKaricheri, Muralidharan 33fc9a8e8dSKaricheri, Muralidharan #ifdef KEYSTONE2_EMAC_GIG_ENABLE 34fc9a8e8dSKaricheri, Muralidharan #define emac_gigabit_enable(x) keystone2_eth_gigabit_enable(x) 35fc9a8e8dSKaricheri, Muralidharan #else 36fc9a8e8dSKaricheri, Muralidharan #define emac_gigabit_enable(x) /* no gigabit to enable */ 37fc9a8e8dSKaricheri, Muralidharan #endif 38fc9a8e8dSKaricheri, Muralidharan 39fc9a8e8dSKaricheri, Muralidharan #define RX_BUFF_NUMS 24 40fc9a8e8dSKaricheri, Muralidharan #define RX_BUFF_LEN 1520 41fc9a8e8dSKaricheri, Muralidharan #define MAX_SIZE_STREAM_BUFFER RX_BUFF_LEN 42c05d05e7SKhoronzhuk, Ivan #define SGMII_ANEG_TIMEOUT 4000 43fc9a8e8dSKaricheri, Muralidharan 44fc9a8e8dSKaricheri, Muralidharan static u8 rx_buffs[RX_BUFF_NUMS * RX_BUFF_LEN] __aligned(16); 45fc9a8e8dSKaricheri, Muralidharan 466599f369SMugunthan V N #ifndef CONFIG_DM_ETH 47fc9a8e8dSKaricheri, Muralidharan struct rx_buff_desc net_rx_buffs = { 48fc9a8e8dSKaricheri, Muralidharan .buff_ptr = rx_buffs, 49fc9a8e8dSKaricheri, Muralidharan .num_buffs = RX_BUFF_NUMS, 50fc9a8e8dSKaricheri, Muralidharan .buff_len = RX_BUFF_LEN, 51fc9a8e8dSKaricheri, Muralidharan .rx_flow = 22, 52fc9a8e8dSKaricheri, Muralidharan }; 534657a2d4SVitaly Andrianov #endif 54fc9a8e8dSKaricheri, Muralidharan 556599f369SMugunthan V N #ifdef CONFIG_DM_ETH 56fc9a8e8dSKaricheri, Muralidharan 576599f369SMugunthan V N enum link_type { 586599f369SMugunthan V N LINK_TYPE_MAC_TO_MAC_AUTO = 0, 596599f369SMugunthan V N LINK_TYPE_MAC_TO_PHY_MODE = 1, 606599f369SMugunthan V N LINK_TYPE_MAC_TO_MAC_FORCED_MODE = 2, 616599f369SMugunthan V N LINK_TYPE_MAC_TO_FIBRE_MODE = 3, 626599f369SMugunthan V N LINK_TYPE_MAC_TO_PHY_NO_MDIO_MODE = 4, 636599f369SMugunthan V N LINK_TYPE_10G_MAC_TO_PHY_MODE = 10, 646599f369SMugunthan V N LINK_TYPE_10G_MAC_TO_MAC_FORCED_MODE = 11, 656599f369SMugunthan V N }; 66fc9a8e8dSKaricheri, Muralidharan 676599f369SMugunthan V N #define mac_hi(mac) (((mac)[0] << 0) | ((mac)[1] << 8) | \ 686599f369SMugunthan V N ((mac)[2] << 16) | ((mac)[3] << 24)) 696599f369SMugunthan V N #define mac_lo(mac) (((mac)[4] << 0) | ((mac)[5] << 8)) 70fc9a8e8dSKaricheri, Muralidharan 716599f369SMugunthan V N #ifdef CONFIG_KSNET_NETCP_V1_0 72fc9a8e8dSKaricheri, Muralidharan 736599f369SMugunthan V N #define EMAC_EMACSW_BASE_OFS 0x90800 746599f369SMugunthan V N #define EMAC_EMACSW_PORT_BASE_OFS (EMAC_EMACSW_BASE_OFS + 0x60) 756599f369SMugunthan V N 766599f369SMugunthan V N /* CPSW Switch slave registers */ 776599f369SMugunthan V N #define CPGMACSL_REG_SA_LO 0x10 786599f369SMugunthan V N #define CPGMACSL_REG_SA_HI 0x14 796599f369SMugunthan V N 806599f369SMugunthan V N #define DEVICE_EMACSW_BASE(base, x) ((base) + EMAC_EMACSW_PORT_BASE_OFS + \ 816599f369SMugunthan V N (x) * 0x30) 826599f369SMugunthan V N 836599f369SMugunthan V N #elif defined CONFIG_KSNET_NETCP_V1_5 846599f369SMugunthan V N 856599f369SMugunthan V N #define EMAC_EMACSW_PORT_BASE_OFS 0x222000 866599f369SMugunthan V N 876599f369SMugunthan V N /* CPSW Switch slave registers */ 886599f369SMugunthan V N #define CPGMACSL_REG_SA_LO 0x308 896599f369SMugunthan V N #define CPGMACSL_REG_SA_HI 0x30c 906599f369SMugunthan V N 916599f369SMugunthan V N #define DEVICE_EMACSW_BASE(base, x) ((base) + EMAC_EMACSW_PORT_BASE_OFS + \ 926599f369SMugunthan V N (x) * 0x1000) 936599f369SMugunthan V N 946599f369SMugunthan V N #endif 956599f369SMugunthan V N 966599f369SMugunthan V N 976599f369SMugunthan V N struct ks2_eth_priv { 986599f369SMugunthan V N struct udevice *dev; 996599f369SMugunthan V N struct phy_device *phydev; 1006599f369SMugunthan V N struct mii_dev *mdio_bus; 1016599f369SMugunthan V N int phy_addr; 1026599f369SMugunthan V N phy_interface_t phy_if; 1036599f369SMugunthan V N int sgmii_link_type; 1046599f369SMugunthan V N void *mdio_base; 1056599f369SMugunthan V N struct rx_buff_desc net_rx_buffs; 1066599f369SMugunthan V N struct pktdma_cfg *netcp_pktdma; 1076599f369SMugunthan V N void *hd; 1086599f369SMugunthan V N int slave_port; 1096599f369SMugunthan V N enum link_type link_type; 1106599f369SMugunthan V N bool emac_open; 1116599f369SMugunthan V N bool has_mdio; 1126599f369SMugunthan V N }; 1136599f369SMugunthan V N #endif 114fc9a8e8dSKaricheri, Muralidharan 115550c5ce6SKhoronzhuk, Ivan /* MDIO */ 116550c5ce6SKhoronzhuk, Ivan 117550c5ce6SKhoronzhuk, Ivan static int keystone2_mdio_reset(struct mii_dev *bus) 118fc9a8e8dSKaricheri, Muralidharan { 119fc9a8e8dSKaricheri, Muralidharan u_int32_t clkdiv; 120550c5ce6SKhoronzhuk, Ivan struct mdio_regs *adap_mdio = bus->priv; 121fc9a8e8dSKaricheri, Muralidharan 122fc9a8e8dSKaricheri, Muralidharan clkdiv = (EMAC_MDIO_BUS_FREQ / EMAC_MDIO_CLOCK_FREQ) - 1; 123fc9a8e8dSKaricheri, Muralidharan 124550c5ce6SKhoronzhuk, Ivan writel((clkdiv & 0xffff) | MDIO_CONTROL_ENABLE | 125550c5ce6SKhoronzhuk, Ivan MDIO_CONTROL_FAULT | MDIO_CONTROL_FAULT_ENABLE, 126fc9a8e8dSKaricheri, Muralidharan &adap_mdio->control); 127fc9a8e8dSKaricheri, Muralidharan 128fc9a8e8dSKaricheri, Muralidharan while (readl(&adap_mdio->control) & MDIO_CONTROL_IDLE) 129fc9a8e8dSKaricheri, Muralidharan ; 130550c5ce6SKhoronzhuk, Ivan 131550c5ce6SKhoronzhuk, Ivan return 0; 132fc9a8e8dSKaricheri, Muralidharan } 133fc9a8e8dSKaricheri, Muralidharan 134550c5ce6SKhoronzhuk, Ivan /** 135550c5ce6SKhoronzhuk, Ivan * keystone2_mdio_read - read a PHY register via MDIO interface. 136550c5ce6SKhoronzhuk, Ivan * Blocks until operation is complete. 137550c5ce6SKhoronzhuk, Ivan */ 138550c5ce6SKhoronzhuk, Ivan static int keystone2_mdio_read(struct mii_dev *bus, 139550c5ce6SKhoronzhuk, Ivan int addr, int devad, int reg) 140fc9a8e8dSKaricheri, Muralidharan { 141fc9a8e8dSKaricheri, Muralidharan int tmp; 142550c5ce6SKhoronzhuk, Ivan struct mdio_regs *adap_mdio = bus->priv; 143fc9a8e8dSKaricheri, Muralidharan 144fc9a8e8dSKaricheri, Muralidharan while (readl(&adap_mdio->useraccess0) & MDIO_USERACCESS0_GO) 145fc9a8e8dSKaricheri, Muralidharan ; 146fc9a8e8dSKaricheri, Muralidharan 147550c5ce6SKhoronzhuk, Ivan writel(MDIO_USERACCESS0_GO | MDIO_USERACCESS0_WRITE_READ | 148550c5ce6SKhoronzhuk, Ivan ((reg & 0x1f) << 21) | ((addr & 0x1f) << 16), 149fc9a8e8dSKaricheri, Muralidharan &adap_mdio->useraccess0); 150fc9a8e8dSKaricheri, Muralidharan 151fc9a8e8dSKaricheri, Muralidharan /* Wait for command to complete */ 152fc9a8e8dSKaricheri, Muralidharan while ((tmp = readl(&adap_mdio->useraccess0)) & MDIO_USERACCESS0_GO) 153fc9a8e8dSKaricheri, Muralidharan ; 154fc9a8e8dSKaricheri, Muralidharan 155550c5ce6SKhoronzhuk, Ivan if (tmp & MDIO_USERACCESS0_ACK) 156550c5ce6SKhoronzhuk, Ivan return tmp & 0xffff; 157fc9a8e8dSKaricheri, Muralidharan 158fc9a8e8dSKaricheri, Muralidharan return -1; 159fc9a8e8dSKaricheri, Muralidharan } 160fc9a8e8dSKaricheri, Muralidharan 161550c5ce6SKhoronzhuk, Ivan /** 162550c5ce6SKhoronzhuk, Ivan * keystone2_mdio_write - write to a PHY register via MDIO interface. 163fc9a8e8dSKaricheri, Muralidharan * Blocks until operation is complete. 164fc9a8e8dSKaricheri, Muralidharan */ 165550c5ce6SKhoronzhuk, Ivan static int keystone2_mdio_write(struct mii_dev *bus, 166550c5ce6SKhoronzhuk, Ivan int addr, int devad, int reg, u16 val) 167fc9a8e8dSKaricheri, Muralidharan { 168550c5ce6SKhoronzhuk, Ivan struct mdio_regs *adap_mdio = bus->priv; 169550c5ce6SKhoronzhuk, Ivan 170fc9a8e8dSKaricheri, Muralidharan while (readl(&adap_mdio->useraccess0) & MDIO_USERACCESS0_GO) 171fc9a8e8dSKaricheri, Muralidharan ; 172fc9a8e8dSKaricheri, Muralidharan 173550c5ce6SKhoronzhuk, Ivan writel(MDIO_USERACCESS0_GO | MDIO_USERACCESS0_WRITE_WRITE | 174550c5ce6SKhoronzhuk, Ivan ((reg & 0x1f) << 21) | ((addr & 0x1f) << 16) | 175550c5ce6SKhoronzhuk, Ivan (val & 0xffff), &adap_mdio->useraccess0); 176fc9a8e8dSKaricheri, Muralidharan 177fc9a8e8dSKaricheri, Muralidharan /* Wait for command to complete */ 178fc9a8e8dSKaricheri, Muralidharan while (readl(&adap_mdio->useraccess0) & MDIO_USERACCESS0_GO) 179fc9a8e8dSKaricheri, Muralidharan ; 180fc9a8e8dSKaricheri, Muralidharan 181fc9a8e8dSKaricheri, Muralidharan return 0; 182fc9a8e8dSKaricheri, Muralidharan } 183fc9a8e8dSKaricheri, Muralidharan 1846599f369SMugunthan V N #ifndef CONFIG_DM_ETH 185fc9a8e8dSKaricheri, Muralidharan static void __attribute__((unused)) 186fc9a8e8dSKaricheri, Muralidharan keystone2_eth_gigabit_enable(struct eth_device *dev) 187fc9a8e8dSKaricheri, Muralidharan { 188fc9a8e8dSKaricheri, Muralidharan u_int16_t data; 189fc9a8e8dSKaricheri, Muralidharan struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv; 190fc9a8e8dSKaricheri, Muralidharan 191fc9a8e8dSKaricheri, Muralidharan if (sys_has_mdio) { 192550c5ce6SKhoronzhuk, Ivan data = keystone2_mdio_read(mdio_bus, eth_priv->phy_addr, 193550c5ce6SKhoronzhuk, Ivan MDIO_DEVAD_NONE, 0); 194550c5ce6SKhoronzhuk, Ivan /* speed selection MSB */ 195550c5ce6SKhoronzhuk, Ivan if (!(data & (1 << 6))) 196fc9a8e8dSKaricheri, Muralidharan return; 197fc9a8e8dSKaricheri, Muralidharan } 198fc9a8e8dSKaricheri, Muralidharan 199fc9a8e8dSKaricheri, Muralidharan /* 200fc9a8e8dSKaricheri, Muralidharan * Check if link detected is giga-bit 201fc9a8e8dSKaricheri, Muralidharan * If Gigabit mode detected, enable gigbit in MAC 202fc9a8e8dSKaricheri, Muralidharan */ 203b2cfe322SHao Zhang writel(readl(DEVICE_EMACSL_BASE(eth_priv->slave_port - 1) + 204b2cfe322SHao Zhang CPGMACSL_REG_CTL) | 205fc9a8e8dSKaricheri, Muralidharan EMAC_MACCONTROL_GIGFORCE | EMAC_MACCONTROL_GIGABIT_ENABLE, 206b2cfe322SHao Zhang DEVICE_EMACSL_BASE(eth_priv->slave_port - 1) + CPGMACSL_REG_CTL); 207fc9a8e8dSKaricheri, Muralidharan } 2086599f369SMugunthan V N #else 2096599f369SMugunthan V N static void __attribute__((unused)) 2106599f369SMugunthan V N keystone2_eth_gigabit_enable(struct udevice *dev) 2116599f369SMugunthan V N { 2126599f369SMugunthan V N struct ks2_eth_priv *priv = dev_get_priv(dev); 2136599f369SMugunthan V N u_int16_t data; 2146599f369SMugunthan V N 2156599f369SMugunthan V N if (priv->has_mdio) { 2166599f369SMugunthan V N data = keystone2_mdio_read(priv->mdio_bus, priv->phy_addr, 2176599f369SMugunthan V N MDIO_DEVAD_NONE, 0); 2186599f369SMugunthan V N /* speed selection MSB */ 2196599f369SMugunthan V N if (!(data & (1 << 6))) 2206599f369SMugunthan V N return; 2216599f369SMugunthan V N } 2226599f369SMugunthan V N 2236599f369SMugunthan V N /* 2246599f369SMugunthan V N * Check if link detected is giga-bit 2256599f369SMugunthan V N * If Gigabit mode detected, enable gigbit in MAC 2266599f369SMugunthan V N */ 2276599f369SMugunthan V N writel(readl(DEVICE_EMACSL_BASE(priv->slave_port - 1) + 2286599f369SMugunthan V N CPGMACSL_REG_CTL) | 2296599f369SMugunthan V N EMAC_MACCONTROL_GIGFORCE | EMAC_MACCONTROL_GIGABIT_ENABLE, 2306599f369SMugunthan V N DEVICE_EMACSL_BASE(priv->slave_port - 1) + CPGMACSL_REG_CTL); 2316599f369SMugunthan V N } 2326599f369SMugunthan V N #endif 233fc9a8e8dSKaricheri, Muralidharan 2344657a2d4SVitaly Andrianov #ifdef CONFIG_SOC_K2G 2354657a2d4SVitaly Andrianov int keystone_rgmii_config(struct phy_device *phy_dev) 2364657a2d4SVitaly Andrianov { 2374657a2d4SVitaly Andrianov unsigned int i, status; 2384657a2d4SVitaly Andrianov 2394657a2d4SVitaly Andrianov i = 0; 2404657a2d4SVitaly Andrianov do { 2414657a2d4SVitaly Andrianov if (i > SGMII_ANEG_TIMEOUT) { 2424657a2d4SVitaly Andrianov puts(" TIMEOUT !\n"); 2434657a2d4SVitaly Andrianov phy_dev->link = 0; 2444657a2d4SVitaly Andrianov return 0; 2454657a2d4SVitaly Andrianov } 2464657a2d4SVitaly Andrianov 2474657a2d4SVitaly Andrianov if (ctrlc()) { 2484657a2d4SVitaly Andrianov puts("user interrupt!\n"); 2494657a2d4SVitaly Andrianov phy_dev->link = 0; 2504657a2d4SVitaly Andrianov return -EINTR; 2514657a2d4SVitaly Andrianov } 2524657a2d4SVitaly Andrianov 2534657a2d4SVitaly Andrianov if ((i++ % 500) == 0) 2544657a2d4SVitaly Andrianov printf("."); 2554657a2d4SVitaly Andrianov 2564657a2d4SVitaly Andrianov udelay(1000); /* 1 ms */ 2574657a2d4SVitaly Andrianov status = readl(RGMII_STATUS_REG); 2584657a2d4SVitaly Andrianov } while (!(status & RGMII_REG_STATUS_LINK)); 2594657a2d4SVitaly Andrianov 2604657a2d4SVitaly Andrianov puts(" done\n"); 2614657a2d4SVitaly Andrianov 2624657a2d4SVitaly Andrianov return 0; 2634657a2d4SVitaly Andrianov } 2644657a2d4SVitaly Andrianov #else 265c05d05e7SKhoronzhuk, Ivan int keystone_sgmii_config(struct phy_device *phy_dev, int port, int interface) 266fc9a8e8dSKaricheri, Muralidharan { 267fc9a8e8dSKaricheri, Muralidharan unsigned int i, status, mask; 268fc9a8e8dSKaricheri, Muralidharan unsigned int mr_adv_ability, control; 269fc9a8e8dSKaricheri, Muralidharan 270fc9a8e8dSKaricheri, Muralidharan switch (interface) { 271fc9a8e8dSKaricheri, Muralidharan case SGMII_LINK_MAC_MAC_AUTONEG: 272fc9a8e8dSKaricheri, Muralidharan mr_adv_ability = (SGMII_REG_MR_ADV_ENABLE | 273fc9a8e8dSKaricheri, Muralidharan SGMII_REG_MR_ADV_LINK | 274fc9a8e8dSKaricheri, Muralidharan SGMII_REG_MR_ADV_FULL_DUPLEX | 275fc9a8e8dSKaricheri, Muralidharan SGMII_REG_MR_ADV_GIG_MODE); 276fc9a8e8dSKaricheri, Muralidharan control = (SGMII_REG_CONTROL_MASTER | 277fc9a8e8dSKaricheri, Muralidharan SGMII_REG_CONTROL_AUTONEG); 278fc9a8e8dSKaricheri, Muralidharan 279fc9a8e8dSKaricheri, Muralidharan break; 280fc9a8e8dSKaricheri, Muralidharan case SGMII_LINK_MAC_PHY: 281fc9a8e8dSKaricheri, Muralidharan case SGMII_LINK_MAC_PHY_FORCED: 282fc9a8e8dSKaricheri, Muralidharan mr_adv_ability = SGMII_REG_MR_ADV_ENABLE; 283fc9a8e8dSKaricheri, Muralidharan control = SGMII_REG_CONTROL_AUTONEG; 284fc9a8e8dSKaricheri, Muralidharan 285fc9a8e8dSKaricheri, Muralidharan break; 286fc9a8e8dSKaricheri, Muralidharan case SGMII_LINK_MAC_MAC_FORCED: 287fc9a8e8dSKaricheri, Muralidharan mr_adv_ability = (SGMII_REG_MR_ADV_ENABLE | 288fc9a8e8dSKaricheri, Muralidharan SGMII_REG_MR_ADV_LINK | 289fc9a8e8dSKaricheri, Muralidharan SGMII_REG_MR_ADV_FULL_DUPLEX | 290fc9a8e8dSKaricheri, Muralidharan SGMII_REG_MR_ADV_GIG_MODE); 291fc9a8e8dSKaricheri, Muralidharan control = SGMII_REG_CONTROL_MASTER; 292fc9a8e8dSKaricheri, Muralidharan 293fc9a8e8dSKaricheri, Muralidharan break; 294fc9a8e8dSKaricheri, Muralidharan case SGMII_LINK_MAC_FIBER: 295fc9a8e8dSKaricheri, Muralidharan mr_adv_ability = 0x20; 296fc9a8e8dSKaricheri, Muralidharan control = SGMII_REG_CONTROL_AUTONEG; 297fc9a8e8dSKaricheri, Muralidharan 298fc9a8e8dSKaricheri, Muralidharan break; 299fc9a8e8dSKaricheri, Muralidharan default: 300fc9a8e8dSKaricheri, Muralidharan mr_adv_ability = SGMII_REG_MR_ADV_ENABLE; 301fc9a8e8dSKaricheri, Muralidharan control = SGMII_REG_CONTROL_AUTONEG; 302fc9a8e8dSKaricheri, Muralidharan } 303fc9a8e8dSKaricheri, Muralidharan 304fc9a8e8dSKaricheri, Muralidharan __raw_writel(0, SGMII_CTL_REG(port)); 305fc9a8e8dSKaricheri, Muralidharan 306fc9a8e8dSKaricheri, Muralidharan /* 307fc9a8e8dSKaricheri, Muralidharan * Wait for the SerDes pll to lock, 308fc9a8e8dSKaricheri, Muralidharan * but don't trap if lock is never read 309fc9a8e8dSKaricheri, Muralidharan */ 310fc9a8e8dSKaricheri, Muralidharan for (i = 0; i < 1000; i++) { 311fc9a8e8dSKaricheri, Muralidharan udelay(2000); 312fc9a8e8dSKaricheri, Muralidharan status = __raw_readl(SGMII_STATUS_REG(port)); 313fc9a8e8dSKaricheri, Muralidharan if ((status & SGMII_REG_STATUS_LOCK) != 0) 314fc9a8e8dSKaricheri, Muralidharan break; 315fc9a8e8dSKaricheri, Muralidharan } 316fc9a8e8dSKaricheri, Muralidharan 317fc9a8e8dSKaricheri, Muralidharan __raw_writel(mr_adv_ability, SGMII_MRADV_REG(port)); 318fc9a8e8dSKaricheri, Muralidharan __raw_writel(control, SGMII_CTL_REG(port)); 319fc9a8e8dSKaricheri, Muralidharan 320fc9a8e8dSKaricheri, Muralidharan 321fc9a8e8dSKaricheri, Muralidharan mask = SGMII_REG_STATUS_LINK; 322fc9a8e8dSKaricheri, Muralidharan 323fc9a8e8dSKaricheri, Muralidharan if (control & SGMII_REG_CONTROL_AUTONEG) 324fc9a8e8dSKaricheri, Muralidharan mask |= SGMII_REG_STATUS_AUTONEG; 325fc9a8e8dSKaricheri, Muralidharan 326fc9a8e8dSKaricheri, Muralidharan status = __raw_readl(SGMII_STATUS_REG(port)); 327fc9a8e8dSKaricheri, Muralidharan if ((status & mask) == mask) 328c05d05e7SKhoronzhuk, Ivan return 0; 329c05d05e7SKhoronzhuk, Ivan 330c05d05e7SKhoronzhuk, Ivan printf("\n%s Waiting for SGMII auto negotiation to complete", 331c05d05e7SKhoronzhuk, Ivan phy_dev->dev->name); 332c05d05e7SKhoronzhuk, Ivan while ((status & mask) != mask) { 333c05d05e7SKhoronzhuk, Ivan /* 334c05d05e7SKhoronzhuk, Ivan * Timeout reached ? 335c05d05e7SKhoronzhuk, Ivan */ 336c05d05e7SKhoronzhuk, Ivan if (i > SGMII_ANEG_TIMEOUT) { 337c05d05e7SKhoronzhuk, Ivan puts(" TIMEOUT !\n"); 338c05d05e7SKhoronzhuk, Ivan phy_dev->link = 0; 339c05d05e7SKhoronzhuk, Ivan return 0; 340fc9a8e8dSKaricheri, Muralidharan } 341fc9a8e8dSKaricheri, Muralidharan 342c05d05e7SKhoronzhuk, Ivan if (ctrlc()) { 343c05d05e7SKhoronzhuk, Ivan puts("user interrupt!\n"); 344c05d05e7SKhoronzhuk, Ivan phy_dev->link = 0; 345c05d05e7SKhoronzhuk, Ivan return -EINTR; 346c05d05e7SKhoronzhuk, Ivan } 347c05d05e7SKhoronzhuk, Ivan 348c05d05e7SKhoronzhuk, Ivan if ((i++ % 500) == 0) 349c05d05e7SKhoronzhuk, Ivan printf("."); 350c05d05e7SKhoronzhuk, Ivan 351c05d05e7SKhoronzhuk, Ivan udelay(1000); /* 1 ms */ 352c05d05e7SKhoronzhuk, Ivan status = __raw_readl(SGMII_STATUS_REG(port)); 353c05d05e7SKhoronzhuk, Ivan } 354c05d05e7SKhoronzhuk, Ivan puts(" done\n"); 355c05d05e7SKhoronzhuk, Ivan 356fc9a8e8dSKaricheri, Muralidharan return 0; 357fc9a8e8dSKaricheri, Muralidharan } 3584657a2d4SVitaly Andrianov #endif 359fc9a8e8dSKaricheri, Muralidharan 360fc9a8e8dSKaricheri, Muralidharan int mac_sl_reset(u32 port) 361fc9a8e8dSKaricheri, Muralidharan { 362fc9a8e8dSKaricheri, Muralidharan u32 i, v; 363fc9a8e8dSKaricheri, Muralidharan 364fc9a8e8dSKaricheri, Muralidharan if (port >= DEVICE_N_GMACSL_PORTS) 365fc9a8e8dSKaricheri, Muralidharan return GMACSL_RET_INVALID_PORT; 366fc9a8e8dSKaricheri, Muralidharan 367fc9a8e8dSKaricheri, Muralidharan /* Set the soft reset bit */ 368e6c9428aSKhoronzhuk, Ivan writel(CPGMAC_REG_RESET_VAL_RESET, 369e6c9428aSKhoronzhuk, Ivan DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_RESET); 370fc9a8e8dSKaricheri, Muralidharan 371fc9a8e8dSKaricheri, Muralidharan /* Wait for the bit to clear */ 372fc9a8e8dSKaricheri, Muralidharan for (i = 0; i < DEVICE_EMACSL_RESET_POLL_COUNT; i++) { 373e6c9428aSKhoronzhuk, Ivan v = readl(DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_RESET); 374fc9a8e8dSKaricheri, Muralidharan if ((v & CPGMAC_REG_RESET_VAL_RESET_MASK) != 375fc9a8e8dSKaricheri, Muralidharan CPGMAC_REG_RESET_VAL_RESET) 376fc9a8e8dSKaricheri, Muralidharan return GMACSL_RET_OK; 377fc9a8e8dSKaricheri, Muralidharan } 378fc9a8e8dSKaricheri, Muralidharan 379fc9a8e8dSKaricheri, Muralidharan /* Timeout on the reset */ 380fc9a8e8dSKaricheri, Muralidharan return GMACSL_RET_WARN_RESET_INCOMPLETE; 381fc9a8e8dSKaricheri, Muralidharan } 382fc9a8e8dSKaricheri, Muralidharan 383fc9a8e8dSKaricheri, Muralidharan int mac_sl_config(u_int16_t port, struct mac_sl_cfg *cfg) 384fc9a8e8dSKaricheri, Muralidharan { 385fc9a8e8dSKaricheri, Muralidharan u32 v, i; 386fc9a8e8dSKaricheri, Muralidharan int ret = GMACSL_RET_OK; 387fc9a8e8dSKaricheri, Muralidharan 388fc9a8e8dSKaricheri, Muralidharan if (port >= DEVICE_N_GMACSL_PORTS) 389fc9a8e8dSKaricheri, Muralidharan return GMACSL_RET_INVALID_PORT; 390fc9a8e8dSKaricheri, Muralidharan 391fc9a8e8dSKaricheri, Muralidharan if (cfg->max_rx_len > CPGMAC_REG_MAXLEN_LEN) { 392fc9a8e8dSKaricheri, Muralidharan cfg->max_rx_len = CPGMAC_REG_MAXLEN_LEN; 393fc9a8e8dSKaricheri, Muralidharan ret = GMACSL_RET_WARN_MAXLEN_TOO_BIG; 394fc9a8e8dSKaricheri, Muralidharan } 395fc9a8e8dSKaricheri, Muralidharan 396fc9a8e8dSKaricheri, Muralidharan /* Must wait if the device is undergoing reset */ 397fc9a8e8dSKaricheri, Muralidharan for (i = 0; i < DEVICE_EMACSL_RESET_POLL_COUNT; i++) { 398e6c9428aSKhoronzhuk, Ivan v = readl(DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_RESET); 399fc9a8e8dSKaricheri, Muralidharan if ((v & CPGMAC_REG_RESET_VAL_RESET_MASK) != 400fc9a8e8dSKaricheri, Muralidharan CPGMAC_REG_RESET_VAL_RESET) 401fc9a8e8dSKaricheri, Muralidharan break; 402fc9a8e8dSKaricheri, Muralidharan } 403fc9a8e8dSKaricheri, Muralidharan 404fc9a8e8dSKaricheri, Muralidharan if (i == DEVICE_EMACSL_RESET_POLL_COUNT) 405fc9a8e8dSKaricheri, Muralidharan return GMACSL_RET_CONFIG_FAIL_RESET_ACTIVE; 406fc9a8e8dSKaricheri, Muralidharan 407e6c9428aSKhoronzhuk, Ivan writel(cfg->max_rx_len, DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_MAXLEN); 408e6c9428aSKhoronzhuk, Ivan writel(cfg->ctl, DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_CTL); 409fc9a8e8dSKaricheri, Muralidharan 4104657a2d4SVitaly Andrianov #ifndef CONFIG_SOC_K2HK 411ff11c769SKhoronzhuk, Ivan /* Map RX packet flow priority to 0 */ 412ff11c769SKhoronzhuk, Ivan writel(0, DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_RX_PRI_MAP); 413ff11c769SKhoronzhuk, Ivan #endif 414ff11c769SKhoronzhuk, Ivan 415fc9a8e8dSKaricheri, Muralidharan return ret; 416fc9a8e8dSKaricheri, Muralidharan } 417fc9a8e8dSKaricheri, Muralidharan 418fc9a8e8dSKaricheri, Muralidharan int ethss_config(u32 ctl, u32 max_pkt_size) 419fc9a8e8dSKaricheri, Muralidharan { 420fc9a8e8dSKaricheri, Muralidharan u32 i; 421fc9a8e8dSKaricheri, Muralidharan 422fc9a8e8dSKaricheri, Muralidharan /* Max length register */ 423e6c9428aSKhoronzhuk, Ivan writel(max_pkt_size, DEVICE_CPSW_BASE + CPSW_REG_MAXLEN); 424fc9a8e8dSKaricheri, Muralidharan 425fc9a8e8dSKaricheri, Muralidharan /* Control register */ 426e6c9428aSKhoronzhuk, Ivan writel(ctl, DEVICE_CPSW_BASE + CPSW_REG_CTL); 427fc9a8e8dSKaricheri, Muralidharan 428fc9a8e8dSKaricheri, Muralidharan /* All statistics enabled by default */ 429e6c9428aSKhoronzhuk, Ivan writel(CPSW_REG_VAL_STAT_ENABLE_ALL, 430e6c9428aSKhoronzhuk, Ivan DEVICE_CPSW_BASE + CPSW_REG_STAT_PORT_EN); 431fc9a8e8dSKaricheri, Muralidharan 432fc9a8e8dSKaricheri, Muralidharan /* Reset and enable the ALE */ 433e6c9428aSKhoronzhuk, Ivan writel(CPSW_REG_VAL_ALE_CTL_RESET_AND_ENABLE | 434e6c9428aSKhoronzhuk, Ivan CPSW_REG_VAL_ALE_CTL_BYPASS, 435e6c9428aSKhoronzhuk, Ivan DEVICE_CPSW_BASE + CPSW_REG_ALE_CONTROL); 436fc9a8e8dSKaricheri, Muralidharan 437fc9a8e8dSKaricheri, Muralidharan /* All ports put into forward mode */ 438fc9a8e8dSKaricheri, Muralidharan for (i = 0; i < DEVICE_CPSW_NUM_PORTS; i++) 439e6c9428aSKhoronzhuk, Ivan writel(CPSW_REG_VAL_PORTCTL_FORWARD_MODE, 440e6c9428aSKhoronzhuk, Ivan DEVICE_CPSW_BASE + CPSW_REG_ALE_PORTCTL(i)); 441fc9a8e8dSKaricheri, Muralidharan 442fc9a8e8dSKaricheri, Muralidharan return 0; 443fc9a8e8dSKaricheri, Muralidharan } 444fc9a8e8dSKaricheri, Muralidharan 445fc9a8e8dSKaricheri, Muralidharan int ethss_start(void) 446fc9a8e8dSKaricheri, Muralidharan { 447fc9a8e8dSKaricheri, Muralidharan int i; 448fc9a8e8dSKaricheri, Muralidharan struct mac_sl_cfg cfg; 449fc9a8e8dSKaricheri, Muralidharan 450fc9a8e8dSKaricheri, Muralidharan cfg.max_rx_len = MAX_SIZE_STREAM_BUFFER; 451fc9a8e8dSKaricheri, Muralidharan cfg.ctl = GMACSL_ENABLE | GMACSL_RX_ENABLE_EXT_CTL; 452fc9a8e8dSKaricheri, Muralidharan 453fc9a8e8dSKaricheri, Muralidharan for (i = 0; i < DEVICE_N_GMACSL_PORTS; i++) { 454fc9a8e8dSKaricheri, Muralidharan mac_sl_reset(i); 455fc9a8e8dSKaricheri, Muralidharan mac_sl_config(i, &cfg); 456fc9a8e8dSKaricheri, Muralidharan } 457fc9a8e8dSKaricheri, Muralidharan 458fc9a8e8dSKaricheri, Muralidharan return 0; 459fc9a8e8dSKaricheri, Muralidharan } 460fc9a8e8dSKaricheri, Muralidharan 461fc9a8e8dSKaricheri, Muralidharan int ethss_stop(void) 462fc9a8e8dSKaricheri, Muralidharan { 463fc9a8e8dSKaricheri, Muralidharan int i; 464fc9a8e8dSKaricheri, Muralidharan 465fc9a8e8dSKaricheri, Muralidharan for (i = 0; i < DEVICE_N_GMACSL_PORTS; i++) 466fc9a8e8dSKaricheri, Muralidharan mac_sl_reset(i); 467fc9a8e8dSKaricheri, Muralidharan 468fc9a8e8dSKaricheri, Muralidharan return 0; 469fc9a8e8dSKaricheri, Muralidharan } 470fc9a8e8dSKaricheri, Muralidharan 4716599f369SMugunthan V N struct ks2_serdes ks2_serdes_sgmii_156p25mhz = { 4726599f369SMugunthan V N .clk = SERDES_CLOCK_156P25M, 4736599f369SMugunthan V N .rate = SERDES_RATE_5G, 4746599f369SMugunthan V N .rate_mode = SERDES_QUARTER_RATE, 4756599f369SMugunthan V N .intf = SERDES_PHY_SGMII, 4766599f369SMugunthan V N .loopback = 0, 4776599f369SMugunthan V N }; 4786599f369SMugunthan V N 4796599f369SMugunthan V N #ifndef CONFIG_SOC_K2G 4806599f369SMugunthan V N static void keystone2_net_serdes_setup(void) 4816599f369SMugunthan V N { 4826599f369SMugunthan V N ks2_serdes_init(CONFIG_KSNET_SERDES_SGMII_BASE, 4836599f369SMugunthan V N &ks2_serdes_sgmii_156p25mhz, 4846599f369SMugunthan V N CONFIG_KSNET_SERDES_LANES_PER_SGMII); 4856599f369SMugunthan V N 4866599f369SMugunthan V N #if defined(CONFIG_SOC_K2E) || defined(CONFIG_SOC_K2L) 4876599f369SMugunthan V N ks2_serdes_init(CONFIG_KSNET_SERDES_SGMII2_BASE, 4886599f369SMugunthan V N &ks2_serdes_sgmii_156p25mhz, 4896599f369SMugunthan V N CONFIG_KSNET_SERDES_LANES_PER_SGMII); 4906599f369SMugunthan V N #endif 4916599f369SMugunthan V N 4926599f369SMugunthan V N /* wait till setup */ 4936599f369SMugunthan V N udelay(5000); 4946599f369SMugunthan V N } 4956599f369SMugunthan V N #endif 4966599f369SMugunthan V N 4976599f369SMugunthan V N #ifndef CONFIG_DM_ETH 4986599f369SMugunthan V N 4996599f369SMugunthan V N int keystone2_eth_read_mac_addr(struct eth_device *dev) 5006599f369SMugunthan V N { 5016599f369SMugunthan V N struct eth_priv_t *eth_priv; 5026599f369SMugunthan V N u32 maca = 0; 5036599f369SMugunthan V N u32 macb = 0; 5046599f369SMugunthan V N 5056599f369SMugunthan V N eth_priv = (struct eth_priv_t *)dev->priv; 5066599f369SMugunthan V N 5076599f369SMugunthan V N /* Read the e-fuse mac address */ 5086599f369SMugunthan V N if (eth_priv->slave_port == 1) { 5096599f369SMugunthan V N maca = __raw_readl(MAC_ID_BASE_ADDR); 5106599f369SMugunthan V N macb = __raw_readl(MAC_ID_BASE_ADDR + 4); 5116599f369SMugunthan V N } 5126599f369SMugunthan V N 5136599f369SMugunthan V N dev->enetaddr[0] = (macb >> 8) & 0xff; 5146599f369SMugunthan V N dev->enetaddr[1] = (macb >> 0) & 0xff; 5156599f369SMugunthan V N dev->enetaddr[2] = (maca >> 24) & 0xff; 5166599f369SMugunthan V N dev->enetaddr[3] = (maca >> 16) & 0xff; 5176599f369SMugunthan V N dev->enetaddr[4] = (maca >> 8) & 0xff; 5186599f369SMugunthan V N dev->enetaddr[5] = (maca >> 0) & 0xff; 5196599f369SMugunthan V N 5206599f369SMugunthan V N return 0; 5216599f369SMugunthan V N } 5226599f369SMugunthan V N 523fc9a8e8dSKaricheri, Muralidharan int32_t cpmac_drv_send(u32 *buffer, int num_bytes, int slave_port_num) 524fc9a8e8dSKaricheri, Muralidharan { 525fc9a8e8dSKaricheri, Muralidharan if (num_bytes < EMAC_MIN_ETHERNET_PKT_SIZE) 526fc9a8e8dSKaricheri, Muralidharan num_bytes = EMAC_MIN_ETHERNET_PKT_SIZE; 527fc9a8e8dSKaricheri, Muralidharan 5289ea9021aSKhoronzhuk, Ivan return ksnav_send(&netcp_pktdma, buffer, 5299ea9021aSKhoronzhuk, Ivan num_bytes, (slave_port_num) << 16); 530fc9a8e8dSKaricheri, Muralidharan } 531fc9a8e8dSKaricheri, Muralidharan 532fc9a8e8dSKaricheri, Muralidharan /* Eth device open */ 533fc9a8e8dSKaricheri, Muralidharan static int keystone2_eth_open(struct eth_device *dev, bd_t *bis) 534fc9a8e8dSKaricheri, Muralidharan { 535fc9a8e8dSKaricheri, Muralidharan struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv; 5363fe93623SKhoronzhuk, Ivan struct phy_device *phy_dev = eth_priv->phy_dev; 537fc9a8e8dSKaricheri, Muralidharan 538fc9a8e8dSKaricheri, Muralidharan debug("+ emac_open\n"); 539fc9a8e8dSKaricheri, Muralidharan 540fc9a8e8dSKaricheri, Muralidharan net_rx_buffs.rx_flow = eth_priv->rx_flow; 541fc9a8e8dSKaricheri, Muralidharan 542fc9a8e8dSKaricheri, Muralidharan sys_has_mdio = 543fc9a8e8dSKaricheri, Muralidharan (eth_priv->sgmii_link_type == SGMII_LINK_MAC_PHY) ? 1 : 0; 544fc9a8e8dSKaricheri, Muralidharan 5456c0fb41aSKhoronzhuk, Ivan if (sys_has_mdio) 5466c0fb41aSKhoronzhuk, Ivan keystone2_mdio_reset(mdio_bus); 5476c0fb41aSKhoronzhuk, Ivan 5484657a2d4SVitaly Andrianov #ifdef CONFIG_SOC_K2G 5494657a2d4SVitaly Andrianov keystone_rgmii_config(phy_dev); 5504657a2d4SVitaly Andrianov #else 551c05d05e7SKhoronzhuk, Ivan keystone_sgmii_config(phy_dev, eth_priv->slave_port - 1, 552fc9a8e8dSKaricheri, Muralidharan eth_priv->sgmii_link_type); 5534657a2d4SVitaly Andrianov #endif 554fc9a8e8dSKaricheri, Muralidharan 555fc9a8e8dSKaricheri, Muralidharan udelay(10000); 556fc9a8e8dSKaricheri, Muralidharan 557fc9a8e8dSKaricheri, Muralidharan /* On chip switch configuration */ 558fc9a8e8dSKaricheri, Muralidharan ethss_config(target_get_switch_ctl(), SWITCH_MAX_PKT_SIZE); 559fc9a8e8dSKaricheri, Muralidharan 560fc9a8e8dSKaricheri, Muralidharan /* TODO: add error handling code */ 561fc9a8e8dSKaricheri, Muralidharan if (qm_init()) { 562fc9a8e8dSKaricheri, Muralidharan printf("ERROR: qm_init()\n"); 563fc9a8e8dSKaricheri, Muralidharan return -1; 564fc9a8e8dSKaricheri, Muralidharan } 5659ea9021aSKhoronzhuk, Ivan if (ksnav_init(&netcp_pktdma, &net_rx_buffs)) { 566fc9a8e8dSKaricheri, Muralidharan qm_close(); 567fc9a8e8dSKaricheri, Muralidharan printf("ERROR: netcp_init()\n"); 568fc9a8e8dSKaricheri, Muralidharan return -1; 569fc9a8e8dSKaricheri, Muralidharan } 570fc9a8e8dSKaricheri, Muralidharan 571fc9a8e8dSKaricheri, Muralidharan /* 572fc9a8e8dSKaricheri, Muralidharan * Streaming switch configuration. If not present this 573fc9a8e8dSKaricheri, Muralidharan * statement is defined to void in target.h. 574fc9a8e8dSKaricheri, Muralidharan * If present this is usually defined to a series of register writes 575fc9a8e8dSKaricheri, Muralidharan */ 576fc9a8e8dSKaricheri, Muralidharan hw_config_streaming_switch(); 577fc9a8e8dSKaricheri, Muralidharan 578fc9a8e8dSKaricheri, Muralidharan if (sys_has_mdio) { 579550c5ce6SKhoronzhuk, Ivan keystone2_mdio_reset(mdio_bus); 580fc9a8e8dSKaricheri, Muralidharan 5813fe93623SKhoronzhuk, Ivan phy_startup(phy_dev); 5823fe93623SKhoronzhuk, Ivan if (phy_dev->link == 0) { 5839ea9021aSKhoronzhuk, Ivan ksnav_close(&netcp_pktdma); 584fc9a8e8dSKaricheri, Muralidharan qm_close(); 585fc9a8e8dSKaricheri, Muralidharan return -1; 586fc9a8e8dSKaricheri, Muralidharan } 587fc9a8e8dSKaricheri, Muralidharan } 588fc9a8e8dSKaricheri, Muralidharan 589fc9a8e8dSKaricheri, Muralidharan emac_gigabit_enable(dev); 590fc9a8e8dSKaricheri, Muralidharan 591fc9a8e8dSKaricheri, Muralidharan ethss_start(); 592fc9a8e8dSKaricheri, Muralidharan 593fc9a8e8dSKaricheri, Muralidharan debug("- emac_open\n"); 594fc9a8e8dSKaricheri, Muralidharan 595fc9a8e8dSKaricheri, Muralidharan emac_open = 1; 596fc9a8e8dSKaricheri, Muralidharan 597fc9a8e8dSKaricheri, Muralidharan return 0; 598fc9a8e8dSKaricheri, Muralidharan } 599fc9a8e8dSKaricheri, Muralidharan 600fc9a8e8dSKaricheri, Muralidharan /* Eth device close */ 601fc9a8e8dSKaricheri, Muralidharan void keystone2_eth_close(struct eth_device *dev) 602fc9a8e8dSKaricheri, Muralidharan { 6033fe93623SKhoronzhuk, Ivan struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv; 6043fe93623SKhoronzhuk, Ivan struct phy_device *phy_dev = eth_priv->phy_dev; 6053fe93623SKhoronzhuk, Ivan 606fc9a8e8dSKaricheri, Muralidharan debug("+ emac_close\n"); 607fc9a8e8dSKaricheri, Muralidharan 608fc9a8e8dSKaricheri, Muralidharan if (!emac_open) 609fc9a8e8dSKaricheri, Muralidharan return; 610fc9a8e8dSKaricheri, Muralidharan 611fc9a8e8dSKaricheri, Muralidharan ethss_stop(); 612fc9a8e8dSKaricheri, Muralidharan 6139ea9021aSKhoronzhuk, Ivan ksnav_close(&netcp_pktdma); 614fc9a8e8dSKaricheri, Muralidharan qm_close(); 6153fe93623SKhoronzhuk, Ivan phy_shutdown(phy_dev); 616fc9a8e8dSKaricheri, Muralidharan 617fc9a8e8dSKaricheri, Muralidharan emac_open = 0; 618fc9a8e8dSKaricheri, Muralidharan 619fc9a8e8dSKaricheri, Muralidharan debug("- emac_close\n"); 620fc9a8e8dSKaricheri, Muralidharan } 621fc9a8e8dSKaricheri, Muralidharan 622fc9a8e8dSKaricheri, Muralidharan /* 623fc9a8e8dSKaricheri, Muralidharan * This function sends a single packet on the network and returns 624fc9a8e8dSKaricheri, Muralidharan * positive number (number of bytes transmitted) or negative for error 625fc9a8e8dSKaricheri, Muralidharan */ 626fc9a8e8dSKaricheri, Muralidharan static int keystone2_eth_send_packet(struct eth_device *dev, 627fc9a8e8dSKaricheri, Muralidharan void *packet, int length) 628fc9a8e8dSKaricheri, Muralidharan { 629fc9a8e8dSKaricheri, Muralidharan int ret_status = -1; 630fc9a8e8dSKaricheri, Muralidharan struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv; 631a4d2adeeSKhoronzhuk, Ivan struct phy_device *phy_dev = eth_priv->phy_dev; 632fc9a8e8dSKaricheri, Muralidharan 633a4d2adeeSKhoronzhuk, Ivan genphy_update_link(phy_dev); 634a4d2adeeSKhoronzhuk, Ivan if (phy_dev->link == 0) 635fc9a8e8dSKaricheri, Muralidharan return -1; 636fc9a8e8dSKaricheri, Muralidharan 637fc9a8e8dSKaricheri, Muralidharan if (cpmac_drv_send((u32 *)packet, length, eth_priv->slave_port) != 0) 638fc9a8e8dSKaricheri, Muralidharan return ret_status; 639fc9a8e8dSKaricheri, Muralidharan 640fc9a8e8dSKaricheri, Muralidharan return length; 641fc9a8e8dSKaricheri, Muralidharan } 642fc9a8e8dSKaricheri, Muralidharan 643fc9a8e8dSKaricheri, Muralidharan /* 644fc9a8e8dSKaricheri, Muralidharan * This function handles receipt of a packet from the network 645fc9a8e8dSKaricheri, Muralidharan */ 646fc9a8e8dSKaricheri, Muralidharan static int keystone2_eth_rcv_packet(struct eth_device *dev) 647fc9a8e8dSKaricheri, Muralidharan { 648fc9a8e8dSKaricheri, Muralidharan void *hd; 649fc9a8e8dSKaricheri, Muralidharan int pkt_size; 650fc9a8e8dSKaricheri, Muralidharan u32 *pkt; 651fc9a8e8dSKaricheri, Muralidharan 6529ea9021aSKhoronzhuk, Ivan hd = ksnav_recv(&netcp_pktdma, &pkt, &pkt_size); 653fc9a8e8dSKaricheri, Muralidharan if (hd == NULL) 654fc9a8e8dSKaricheri, Muralidharan return 0; 655fc9a8e8dSKaricheri, Muralidharan 6561fd92db8SJoe Hershberger net_process_received_packet((uchar *)pkt, pkt_size); 657fc9a8e8dSKaricheri, Muralidharan 6589ea9021aSKhoronzhuk, Ivan ksnav_release_rxhd(&netcp_pktdma, hd); 659fc9a8e8dSKaricheri, Muralidharan 660fc9a8e8dSKaricheri, Muralidharan return pkt_size; 661fc9a8e8dSKaricheri, Muralidharan } 662fc9a8e8dSKaricheri, Muralidharan 6635031ca59SVitaly Andrianov #ifdef CONFIG_MCAST_TFTP 6645031ca59SVitaly Andrianov static int keystone2_eth_bcast_addr(struct eth_device *dev, u32 ip, u8 set) 6655031ca59SVitaly Andrianov { 6665031ca59SVitaly Andrianov return 0; 6675031ca59SVitaly Andrianov } 6685031ca59SVitaly Andrianov #endif 6695031ca59SVitaly Andrianov 670fc9a8e8dSKaricheri, Muralidharan /* 671fc9a8e8dSKaricheri, Muralidharan * This function initializes the EMAC hardware. 672fc9a8e8dSKaricheri, Muralidharan */ 673fc9a8e8dSKaricheri, Muralidharan int keystone2_emac_initialize(struct eth_priv_t *eth_priv) 674fc9a8e8dSKaricheri, Muralidharan { 675550c5ce6SKhoronzhuk, Ivan int res; 676fc9a8e8dSKaricheri, Muralidharan struct eth_device *dev; 6773fe93623SKhoronzhuk, Ivan struct phy_device *phy_dev; 6786599f369SMugunthan V N struct mdio_regs *adap_mdio = (struct mdio_regs *)EMAC_MDIO_BASE_ADDR; 679fc9a8e8dSKaricheri, Muralidharan 680fc9a8e8dSKaricheri, Muralidharan dev = malloc(sizeof(struct eth_device)); 681fc9a8e8dSKaricheri, Muralidharan if (dev == NULL) 682fc9a8e8dSKaricheri, Muralidharan return -1; 683fc9a8e8dSKaricheri, Muralidharan 684fc9a8e8dSKaricheri, Muralidharan memset(dev, 0, sizeof(struct eth_device)); 685fc9a8e8dSKaricheri, Muralidharan 686fc9a8e8dSKaricheri, Muralidharan strcpy(dev->name, eth_priv->int_name); 687fc9a8e8dSKaricheri, Muralidharan dev->priv = eth_priv; 688fc9a8e8dSKaricheri, Muralidharan 689fc9a8e8dSKaricheri, Muralidharan keystone2_eth_read_mac_addr(dev); 690fc9a8e8dSKaricheri, Muralidharan 691fc9a8e8dSKaricheri, Muralidharan dev->iobase = 0; 692fc9a8e8dSKaricheri, Muralidharan dev->init = keystone2_eth_open; 693fc9a8e8dSKaricheri, Muralidharan dev->halt = keystone2_eth_close; 694fc9a8e8dSKaricheri, Muralidharan dev->send = keystone2_eth_send_packet; 695fc9a8e8dSKaricheri, Muralidharan dev->recv = keystone2_eth_rcv_packet; 6965031ca59SVitaly Andrianov #ifdef CONFIG_MCAST_TFTP 6975031ca59SVitaly Andrianov dev->mcast = keystone2_eth_bcast_addr; 6985031ca59SVitaly Andrianov #endif 699fc9a8e8dSKaricheri, Muralidharan 700fc9a8e8dSKaricheri, Muralidharan eth_register(dev); 701fc9a8e8dSKaricheri, Muralidharan 702550c5ce6SKhoronzhuk, Ivan /* Register MDIO bus if it's not registered yet */ 703550c5ce6SKhoronzhuk, Ivan if (!mdio_bus) { 704550c5ce6SKhoronzhuk, Ivan mdio_bus = mdio_alloc(); 705550c5ce6SKhoronzhuk, Ivan mdio_bus->read = keystone2_mdio_read; 706550c5ce6SKhoronzhuk, Ivan mdio_bus->write = keystone2_mdio_write; 707550c5ce6SKhoronzhuk, Ivan mdio_bus->reset = keystone2_mdio_reset; 708550c5ce6SKhoronzhuk, Ivan mdio_bus->priv = (void *)EMAC_MDIO_BASE_ADDR; 709192bc694SBen Whitten strcpy(mdio_bus->name, "ethernet-mdio"); 710550c5ce6SKhoronzhuk, Ivan 711550c5ce6SKhoronzhuk, Ivan res = mdio_register(mdio_bus); 712550c5ce6SKhoronzhuk, Ivan if (res) 713550c5ce6SKhoronzhuk, Ivan return res; 714550c5ce6SKhoronzhuk, Ivan } 715550c5ce6SKhoronzhuk, Ivan 7164657a2d4SVitaly Andrianov #ifndef CONFIG_SOC_K2G 717312aca4eSVitaly Andrianov keystone2_net_serdes_setup(); 7184657a2d4SVitaly Andrianov #endif 719312aca4eSVitaly Andrianov 7203fe93623SKhoronzhuk, Ivan /* Create phy device and bind it with driver */ 7213fe93623SKhoronzhuk, Ivan #ifdef CONFIG_KSNET_MDIO_PHY_CONFIG_ENABLE 7223fe93623SKhoronzhuk, Ivan phy_dev = phy_connect(mdio_bus, eth_priv->phy_addr, 723bf7bd4e7SMugunthan V N dev, eth_priv->phy_if); 7243fe93623SKhoronzhuk, Ivan phy_config(phy_dev); 7253fe93623SKhoronzhuk, Ivan #else 7263fe93623SKhoronzhuk, Ivan phy_dev = phy_find_by_mask(mdio_bus, 1 << eth_priv->phy_addr, 727bf7bd4e7SMugunthan V N eth_priv->phy_if); 7283fe93623SKhoronzhuk, Ivan phy_dev->dev = dev; 7293fe93623SKhoronzhuk, Ivan #endif 7303fe93623SKhoronzhuk, Ivan eth_priv->phy_dev = phy_dev; 7313fe93623SKhoronzhuk, Ivan 732fc9a8e8dSKaricheri, Muralidharan return 0; 733fc9a8e8dSKaricheri, Muralidharan } 734fc9a8e8dSKaricheri, Muralidharan 7356599f369SMugunthan V N #else 73692a16c81SHao Zhang 7376599f369SMugunthan V N static int ks2_eth_start(struct udevice *dev) 738fc9a8e8dSKaricheri, Muralidharan { 7396599f369SMugunthan V N struct ks2_eth_priv *priv = dev_get_priv(dev); 74092a16c81SHao Zhang 7416599f369SMugunthan V N #ifdef CONFIG_SOC_K2G 7426599f369SMugunthan V N keystone_rgmii_config(priv->phydev); 7436599f369SMugunthan V N #else 7446599f369SMugunthan V N keystone_sgmii_config(priv->phydev, priv->slave_port - 1, 7456599f369SMugunthan V N priv->sgmii_link_type); 7463c61502aSKhoronzhuk, Ivan #endif 7473c61502aSKhoronzhuk, Ivan 7486599f369SMugunthan V N udelay(10000); 7496599f369SMugunthan V N 7506599f369SMugunthan V N /* On chip switch configuration */ 7516599f369SMugunthan V N ethss_config(target_get_switch_ctl(), SWITCH_MAX_PKT_SIZE); 7526599f369SMugunthan V N 7536599f369SMugunthan V N qm_init(); 7546599f369SMugunthan V N 7556599f369SMugunthan V N if (ksnav_init(priv->netcp_pktdma, &priv->net_rx_buffs)) { 7566599f369SMugunthan V N error("ksnav_init failed\n"); 7576599f369SMugunthan V N goto err_knav_init; 758fc9a8e8dSKaricheri, Muralidharan } 7596599f369SMugunthan V N 7606599f369SMugunthan V N /* 7616599f369SMugunthan V N * Streaming switch configuration. If not present this 7626599f369SMugunthan V N * statement is defined to void in target.h. 7636599f369SMugunthan V N * If present this is usually defined to a series of register writes 7646599f369SMugunthan V N */ 7656599f369SMugunthan V N hw_config_streaming_switch(); 7666599f369SMugunthan V N 7676599f369SMugunthan V N if (priv->has_mdio) { 7686599f369SMugunthan V N phy_startup(priv->phydev); 7696599f369SMugunthan V N if (priv->phydev->link == 0) { 7706599f369SMugunthan V N error("phy startup failed\n"); 7716599f369SMugunthan V N goto err_phy_start; 7726599f369SMugunthan V N } 7736599f369SMugunthan V N } 7746599f369SMugunthan V N 7756599f369SMugunthan V N emac_gigabit_enable(dev); 7766599f369SMugunthan V N 7776599f369SMugunthan V N ethss_start(); 7786599f369SMugunthan V N 7796599f369SMugunthan V N priv->emac_open = true; 7806599f369SMugunthan V N 7816599f369SMugunthan V N return 0; 7826599f369SMugunthan V N 7836599f369SMugunthan V N err_phy_start: 7846599f369SMugunthan V N ksnav_close(priv->netcp_pktdma); 7856599f369SMugunthan V N err_knav_init: 7866599f369SMugunthan V N qm_close(); 7876599f369SMugunthan V N 7886599f369SMugunthan V N return -EFAULT; 7896599f369SMugunthan V N } 7906599f369SMugunthan V N 7916599f369SMugunthan V N static int ks2_eth_send(struct udevice *dev, void *packet, int length) 7926599f369SMugunthan V N { 7936599f369SMugunthan V N struct ks2_eth_priv *priv = dev_get_priv(dev); 7946599f369SMugunthan V N 7956599f369SMugunthan V N genphy_update_link(priv->phydev); 7966599f369SMugunthan V N if (priv->phydev->link == 0) 7976599f369SMugunthan V N return -1; 7986599f369SMugunthan V N 7996599f369SMugunthan V N if (length < EMAC_MIN_ETHERNET_PKT_SIZE) 8006599f369SMugunthan V N length = EMAC_MIN_ETHERNET_PKT_SIZE; 8016599f369SMugunthan V N 8026599f369SMugunthan V N return ksnav_send(priv->netcp_pktdma, (u32 *)packet, 8036599f369SMugunthan V N length, (priv->slave_port) << 16); 8046599f369SMugunthan V N } 8056599f369SMugunthan V N 8066599f369SMugunthan V N static int ks2_eth_recv(struct udevice *dev, int flags, uchar **packetp) 8076599f369SMugunthan V N { 8086599f369SMugunthan V N struct ks2_eth_priv *priv = dev_get_priv(dev); 8096599f369SMugunthan V N int pkt_size; 8106599f369SMugunthan V N u32 *pkt = NULL; 8116599f369SMugunthan V N 8126599f369SMugunthan V N priv->hd = ksnav_recv(priv->netcp_pktdma, &pkt, &pkt_size); 8136599f369SMugunthan V N if (priv->hd == NULL) 8146599f369SMugunthan V N return -EAGAIN; 8156599f369SMugunthan V N 8166599f369SMugunthan V N *packetp = (uchar *)pkt; 8176599f369SMugunthan V N 8186599f369SMugunthan V N return pkt_size; 8196599f369SMugunthan V N } 8206599f369SMugunthan V N 8216599f369SMugunthan V N static int ks2_eth_free_pkt(struct udevice *dev, uchar *packet, 8226599f369SMugunthan V N int length) 8236599f369SMugunthan V N { 8246599f369SMugunthan V N struct ks2_eth_priv *priv = dev_get_priv(dev); 8256599f369SMugunthan V N 8266599f369SMugunthan V N ksnav_release_rxhd(priv->netcp_pktdma, priv->hd); 8276599f369SMugunthan V N 8286599f369SMugunthan V N return 0; 8296599f369SMugunthan V N } 8306599f369SMugunthan V N 8316599f369SMugunthan V N static void ks2_eth_stop(struct udevice *dev) 8326599f369SMugunthan V N { 8336599f369SMugunthan V N struct ks2_eth_priv *priv = dev_get_priv(dev); 8346599f369SMugunthan V N 8356599f369SMugunthan V N if (!priv->emac_open) 8366599f369SMugunthan V N return; 8376599f369SMugunthan V N ethss_stop(); 8386599f369SMugunthan V N 8396599f369SMugunthan V N ksnav_close(priv->netcp_pktdma); 8406599f369SMugunthan V N qm_close(); 8416599f369SMugunthan V N phy_shutdown(priv->phydev); 8426599f369SMugunthan V N priv->emac_open = false; 8436599f369SMugunthan V N } 8446599f369SMugunthan V N 8456599f369SMugunthan V N int ks2_eth_read_rom_hwaddr(struct udevice *dev) 8466599f369SMugunthan V N { 8476599f369SMugunthan V N struct ks2_eth_priv *priv = dev_get_priv(dev); 8486599f369SMugunthan V N struct eth_pdata *pdata = dev_get_platdata(dev); 8496599f369SMugunthan V N u32 maca = 0; 8506599f369SMugunthan V N u32 macb = 0; 8516599f369SMugunthan V N 8526599f369SMugunthan V N /* Read the e-fuse mac address */ 8536599f369SMugunthan V N if (priv->slave_port == 1) { 8546599f369SMugunthan V N maca = __raw_readl(MAC_ID_BASE_ADDR); 8556599f369SMugunthan V N macb = __raw_readl(MAC_ID_BASE_ADDR + 4); 8566599f369SMugunthan V N } 8576599f369SMugunthan V N 8586599f369SMugunthan V N pdata->enetaddr[0] = (macb >> 8) & 0xff; 8596599f369SMugunthan V N pdata->enetaddr[1] = (macb >> 0) & 0xff; 8606599f369SMugunthan V N pdata->enetaddr[2] = (maca >> 24) & 0xff; 8616599f369SMugunthan V N pdata->enetaddr[3] = (maca >> 16) & 0xff; 8626599f369SMugunthan V N pdata->enetaddr[4] = (maca >> 8) & 0xff; 8636599f369SMugunthan V N pdata->enetaddr[5] = (maca >> 0) & 0xff; 8646599f369SMugunthan V N 8656599f369SMugunthan V N return 0; 8666599f369SMugunthan V N } 8676599f369SMugunthan V N 8686599f369SMugunthan V N int ks2_eth_write_hwaddr(struct udevice *dev) 8696599f369SMugunthan V N { 8706599f369SMugunthan V N struct ks2_eth_priv *priv = dev_get_priv(dev); 8716599f369SMugunthan V N struct eth_pdata *pdata = dev_get_platdata(dev); 8726599f369SMugunthan V N 8736599f369SMugunthan V N writel(mac_hi(pdata->enetaddr), 8746599f369SMugunthan V N DEVICE_EMACSW_BASE(pdata->iobase, priv->slave_port - 1) + 8756599f369SMugunthan V N CPGMACSL_REG_SA_HI); 8766599f369SMugunthan V N writel(mac_lo(pdata->enetaddr), 8776599f369SMugunthan V N DEVICE_EMACSW_BASE(pdata->iobase, priv->slave_port - 1) + 8786599f369SMugunthan V N CPGMACSL_REG_SA_LO); 8796599f369SMugunthan V N 8806599f369SMugunthan V N return 0; 8816599f369SMugunthan V N } 8826599f369SMugunthan V N 8836599f369SMugunthan V N static int ks2_eth_probe(struct udevice *dev) 8846599f369SMugunthan V N { 8856599f369SMugunthan V N struct ks2_eth_priv *priv = dev_get_priv(dev); 8866599f369SMugunthan V N struct mii_dev *mdio_bus; 8876599f369SMugunthan V N int ret; 8886599f369SMugunthan V N 8896599f369SMugunthan V N priv->dev = dev; 8906599f369SMugunthan V N 8916599f369SMugunthan V N /* These clock enables has to be moved to common location */ 8926599f369SMugunthan V N if (cpu_is_k2g()) 8936599f369SMugunthan V N writel(KS2_ETHERNET_RGMII, KS2_ETHERNET_CFG); 8946599f369SMugunthan V N 8956599f369SMugunthan V N /* By default, select PA PLL clock as PA clock source */ 8966599f369SMugunthan V N #ifndef CONFIG_SOC_K2G 8976599f369SMugunthan V N if (psc_enable_module(KS2_LPSC_PA)) 8986599f369SMugunthan V N return -EACCES; 8996599f369SMugunthan V N #endif 9006599f369SMugunthan V N if (psc_enable_module(KS2_LPSC_CPGMAC)) 9016599f369SMugunthan V N return -EACCES; 9026599f369SMugunthan V N if (psc_enable_module(KS2_LPSC_CRYPTO)) 9036599f369SMugunthan V N return -EACCES; 9046599f369SMugunthan V N 9056599f369SMugunthan V N if (cpu_is_k2e() || cpu_is_k2l()) 9066599f369SMugunthan V N pll_pa_clk_sel(); 9076599f369SMugunthan V N 9086599f369SMugunthan V N 909*1610a921SMugunthan V N priv->net_rx_buffs.buff_ptr = rx_buffs; 910*1610a921SMugunthan V N priv->net_rx_buffs.num_buffs = RX_BUFF_NUMS; 911*1610a921SMugunthan V N priv->net_rx_buffs.buff_len = RX_BUFF_LEN; 9126599f369SMugunthan V N 9136599f369SMugunthan V N /* Register MDIO bus */ 9146599f369SMugunthan V N mdio_bus = mdio_alloc(); 9156599f369SMugunthan V N if (!mdio_bus) { 9166599f369SMugunthan V N error("MDIO alloc failed\n"); 9176599f369SMugunthan V N return -ENOMEM; 9186599f369SMugunthan V N } 9196599f369SMugunthan V N priv->mdio_bus = mdio_bus; 9206599f369SMugunthan V N mdio_bus->read = keystone2_mdio_read; 9216599f369SMugunthan V N mdio_bus->write = keystone2_mdio_write; 9226599f369SMugunthan V N mdio_bus->reset = keystone2_mdio_reset; 9236599f369SMugunthan V N mdio_bus->priv = priv->mdio_base; 9246599f369SMugunthan V N sprintf(mdio_bus->name, "ethernet-mdio"); 9256599f369SMugunthan V N 9266599f369SMugunthan V N ret = mdio_register(mdio_bus); 9276599f369SMugunthan V N if (ret) { 9286599f369SMugunthan V N error("MDIO bus register failed\n"); 9296599f369SMugunthan V N return ret; 9306599f369SMugunthan V N } 9316599f369SMugunthan V N 9326599f369SMugunthan V N #ifndef CONFIG_SOC_K2G 9336599f369SMugunthan V N keystone2_net_serdes_setup(); 9346599f369SMugunthan V N #endif 9356599f369SMugunthan V N 9366599f369SMugunthan V N priv->netcp_pktdma = &netcp_pktdma; 9376599f369SMugunthan V N 9386599f369SMugunthan V N priv->phydev = phy_connect(mdio_bus, priv->phy_addr, dev, priv->phy_if); 9396599f369SMugunthan V N phy_config(priv->phydev); 9406599f369SMugunthan V N 9416599f369SMugunthan V N return 0; 9426599f369SMugunthan V N } 9436599f369SMugunthan V N 9446599f369SMugunthan V N int ks2_eth_remove(struct udevice *dev) 9456599f369SMugunthan V N { 9466599f369SMugunthan V N struct ks2_eth_priv *priv = dev_get_priv(dev); 9476599f369SMugunthan V N 9486599f369SMugunthan V N free(priv->phydev); 9496599f369SMugunthan V N mdio_unregister(priv->mdio_bus); 9506599f369SMugunthan V N mdio_free(priv->mdio_bus); 9516599f369SMugunthan V N 9526599f369SMugunthan V N return 0; 9536599f369SMugunthan V N } 9546599f369SMugunthan V N 9556599f369SMugunthan V N static const struct eth_ops ks2_eth_ops = { 9566599f369SMugunthan V N .start = ks2_eth_start, 9576599f369SMugunthan V N .send = ks2_eth_send, 9586599f369SMugunthan V N .recv = ks2_eth_recv, 9596599f369SMugunthan V N .free_pkt = ks2_eth_free_pkt, 9606599f369SMugunthan V N .stop = ks2_eth_stop, 9616599f369SMugunthan V N .read_rom_hwaddr = ks2_eth_read_rom_hwaddr, 9626599f369SMugunthan V N .write_hwaddr = ks2_eth_write_hwaddr, 9636599f369SMugunthan V N }; 9646599f369SMugunthan V N 9656599f369SMugunthan V N 9666599f369SMugunthan V N static int ks2_eth_ofdata_to_platdata(struct udevice *dev) 9676599f369SMugunthan V N { 9686599f369SMugunthan V N struct ks2_eth_priv *priv = dev_get_priv(dev); 9696599f369SMugunthan V N struct eth_pdata *pdata = dev_get_platdata(dev); 9706599f369SMugunthan V N const void *fdt = gd->fdt_blob; 9716599f369SMugunthan V N int interfaces; 9726599f369SMugunthan V N int interface_0; 9736599f369SMugunthan V N int netcp_gbe_0; 9746599f369SMugunthan V N int phy; 9756599f369SMugunthan V N int mdio; 9766599f369SMugunthan V N u32 dma_channel[6]; 9776599f369SMugunthan V N 9786599f369SMugunthan V N interfaces = fdt_subnode_offset(fdt, dev->of_offset, 9796599f369SMugunthan V N "netcp-interfaces"); 9806599f369SMugunthan V N interface_0 = fdt_subnode_offset(fdt, interfaces, "interface-0"); 9816599f369SMugunthan V N 9826599f369SMugunthan V N netcp_gbe_0 = fdtdec_lookup_phandle(fdt, interface_0, "netcp-gbe"); 9836599f369SMugunthan V N priv->link_type = fdtdec_get_int(fdt, netcp_gbe_0, 9846599f369SMugunthan V N "link-interface", -1); 9856599f369SMugunthan V N priv->slave_port = fdtdec_get_int(fdt, netcp_gbe_0, "slave-port", -1); 9866599f369SMugunthan V N /* U-Boot slave port number starts with 1 instead of 0 */ 9876599f369SMugunthan V N priv->slave_port += 1; 9886599f369SMugunthan V N 9896599f369SMugunthan V N phy = fdtdec_lookup_phandle(fdt, netcp_gbe_0, "phy-handle"); 9906599f369SMugunthan V N priv->phy_addr = fdtdec_get_int(fdt, phy, "reg", -1); 9916599f369SMugunthan V N 9926599f369SMugunthan V N mdio = fdt_parent_offset(fdt, phy); 9936599f369SMugunthan V N if (mdio < 0) { 9946599f369SMugunthan V N error("mdio dt not found\n"); 9956599f369SMugunthan V N return -ENODEV; 9966599f369SMugunthan V N } 9976599f369SMugunthan V N priv->mdio_base = (void *)fdtdec_get_addr(fdt, mdio, "reg"); 9986599f369SMugunthan V N 9996599f369SMugunthan V N if (priv->link_type == LINK_TYPE_MAC_TO_PHY_MODE) { 10006599f369SMugunthan V N priv->phy_if = PHY_INTERFACE_MODE_SGMII; 10016599f369SMugunthan V N pdata->phy_interface = priv->phy_if; 10026599f369SMugunthan V N priv->sgmii_link_type = SGMII_LINK_MAC_PHY; 10036599f369SMugunthan V N priv->has_mdio = true; 10046599f369SMugunthan V N } 10056599f369SMugunthan V N pdata->iobase = dev_get_addr(dev); 10066599f369SMugunthan V N 10076599f369SMugunthan V N fdtdec_get_int_array(fdt, dev->of_offset, "ti,navigator-dmas", 10086599f369SMugunthan V N dma_channel, 6); 10096599f369SMugunthan V N priv->net_rx_buffs.rx_flow = dma_channel[1]; 10106599f369SMugunthan V N 10116599f369SMugunthan V N return 0; 10126599f369SMugunthan V N } 10136599f369SMugunthan V N 10146599f369SMugunthan V N static const struct udevice_id ks2_eth_ids[] = { 10156599f369SMugunthan V N { .compatible = "ti,netcp-1.0" }, 10166599f369SMugunthan V N { } 10176599f369SMugunthan V N }; 10186599f369SMugunthan V N 10196599f369SMugunthan V N 10206599f369SMugunthan V N U_BOOT_DRIVER(eth_ks2) = { 10216599f369SMugunthan V N .name = "eth_ks2", 10226599f369SMugunthan V N .id = UCLASS_ETH, 10236599f369SMugunthan V N .of_match = ks2_eth_ids, 10246599f369SMugunthan V N .ofdata_to_platdata = ks2_eth_ofdata_to_platdata, 10256599f369SMugunthan V N .probe = ks2_eth_probe, 10266599f369SMugunthan V N .remove = ks2_eth_remove, 10276599f369SMugunthan V N .ops = &ks2_eth_ops, 10286599f369SMugunthan V N .priv_auto_alloc_size = sizeof(struct ks2_eth_priv), 10296599f369SMugunthan V N .platdata_auto_alloc_size = sizeof(struct eth_pdata), 10306599f369SMugunthan V N .flags = DM_FLAG_ALLOC_PRIV_DMA, 10316599f369SMugunthan V N }; 10324657a2d4SVitaly Andrianov #endif 1033