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 13fc9a8e8dSKaricheri, Muralidharan #include <net.h> 143fe93623SKhoronzhuk, Ivan #include <phy.h> 15c05d05e7SKhoronzhuk, Ivan #include <errno.h> 16fc9a8e8dSKaricheri, Muralidharan #include <miiphy.h> 17fc9a8e8dSKaricheri, Muralidharan #include <malloc.h> 18ef454717SKhoronzhuk, Ivan #include <asm/ti-common/keystone_nav.h> 190935cac6SKhoronzhuk, Ivan #include <asm/ti-common/keystone_net.h> 20a43febdeSKhoronzhuk, Ivan #include <asm/ti-common/keystone_serdes.h> 21fc9a8e8dSKaricheri, Muralidharan 22fc9a8e8dSKaricheri, Muralidharan unsigned int emac_open; 23550c5ce6SKhoronzhuk, Ivan static struct mii_dev *mdio_bus; 24fc9a8e8dSKaricheri, Muralidharan static unsigned int sys_has_mdio = 1; 25fc9a8e8dSKaricheri, Muralidharan 26fc9a8e8dSKaricheri, Muralidharan #ifdef KEYSTONE2_EMAC_GIG_ENABLE 27fc9a8e8dSKaricheri, Muralidharan #define emac_gigabit_enable(x) keystone2_eth_gigabit_enable(x) 28fc9a8e8dSKaricheri, Muralidharan #else 29fc9a8e8dSKaricheri, Muralidharan #define emac_gigabit_enable(x) /* no gigabit to enable */ 30fc9a8e8dSKaricheri, Muralidharan #endif 31fc9a8e8dSKaricheri, Muralidharan 32fc9a8e8dSKaricheri, Muralidharan #define RX_BUFF_NUMS 24 33fc9a8e8dSKaricheri, Muralidharan #define RX_BUFF_LEN 1520 34fc9a8e8dSKaricheri, Muralidharan #define MAX_SIZE_STREAM_BUFFER RX_BUFF_LEN 35c05d05e7SKhoronzhuk, Ivan #define SGMII_ANEG_TIMEOUT 4000 36fc9a8e8dSKaricheri, Muralidharan 37fc9a8e8dSKaricheri, Muralidharan static u8 rx_buffs[RX_BUFF_NUMS * RX_BUFF_LEN] __aligned(16); 38fc9a8e8dSKaricheri, Muralidharan 39fc9a8e8dSKaricheri, Muralidharan struct rx_buff_desc net_rx_buffs = { 40fc9a8e8dSKaricheri, Muralidharan .buff_ptr = rx_buffs, 41fc9a8e8dSKaricheri, Muralidharan .num_buffs = RX_BUFF_NUMS, 42fc9a8e8dSKaricheri, Muralidharan .buff_len = RX_BUFF_LEN, 43fc9a8e8dSKaricheri, Muralidharan .rx_flow = 22, 44fc9a8e8dSKaricheri, Muralidharan }; 45fc9a8e8dSKaricheri, Muralidharan 464657a2d4SVitaly Andrianov #ifndef CONFIG_SOC_K2G 47a43febdeSKhoronzhuk, Ivan static void keystone2_net_serdes_setup(void); 484657a2d4SVitaly Andrianov #endif 49fc9a8e8dSKaricheri, Muralidharan 50fc9a8e8dSKaricheri, Muralidharan int keystone2_eth_read_mac_addr(struct eth_device *dev) 51fc9a8e8dSKaricheri, Muralidharan { 52fc9a8e8dSKaricheri, Muralidharan struct eth_priv_t *eth_priv; 53fc9a8e8dSKaricheri, Muralidharan u32 maca = 0; 54fc9a8e8dSKaricheri, Muralidharan u32 macb = 0; 55fc9a8e8dSKaricheri, Muralidharan 56fc9a8e8dSKaricheri, Muralidharan eth_priv = (struct eth_priv_t *)dev->priv; 57fc9a8e8dSKaricheri, Muralidharan 58fc9a8e8dSKaricheri, Muralidharan /* Read the e-fuse mac address */ 59fc9a8e8dSKaricheri, Muralidharan if (eth_priv->slave_port == 1) { 60fc9a8e8dSKaricheri, Muralidharan maca = __raw_readl(MAC_ID_BASE_ADDR); 61fc9a8e8dSKaricheri, Muralidharan macb = __raw_readl(MAC_ID_BASE_ADDR + 4); 62fc9a8e8dSKaricheri, Muralidharan } 63fc9a8e8dSKaricheri, Muralidharan 64fc9a8e8dSKaricheri, Muralidharan dev->enetaddr[0] = (macb >> 8) & 0xff; 65fc9a8e8dSKaricheri, Muralidharan dev->enetaddr[1] = (macb >> 0) & 0xff; 66fc9a8e8dSKaricheri, Muralidharan dev->enetaddr[2] = (maca >> 24) & 0xff; 67fc9a8e8dSKaricheri, Muralidharan dev->enetaddr[3] = (maca >> 16) & 0xff; 68fc9a8e8dSKaricheri, Muralidharan dev->enetaddr[4] = (maca >> 8) & 0xff; 69fc9a8e8dSKaricheri, Muralidharan dev->enetaddr[5] = (maca >> 0) & 0xff; 70fc9a8e8dSKaricheri, Muralidharan 71fc9a8e8dSKaricheri, Muralidharan return 0; 72fc9a8e8dSKaricheri, Muralidharan } 73fc9a8e8dSKaricheri, Muralidharan 74550c5ce6SKhoronzhuk, Ivan /* MDIO */ 75550c5ce6SKhoronzhuk, Ivan 76550c5ce6SKhoronzhuk, Ivan static int keystone2_mdio_reset(struct mii_dev *bus) 77fc9a8e8dSKaricheri, Muralidharan { 78fc9a8e8dSKaricheri, Muralidharan u_int32_t clkdiv; 79550c5ce6SKhoronzhuk, Ivan struct mdio_regs *adap_mdio = bus->priv; 80fc9a8e8dSKaricheri, Muralidharan 81fc9a8e8dSKaricheri, Muralidharan clkdiv = (EMAC_MDIO_BUS_FREQ / EMAC_MDIO_CLOCK_FREQ) - 1; 82fc9a8e8dSKaricheri, Muralidharan 83550c5ce6SKhoronzhuk, Ivan writel((clkdiv & 0xffff) | MDIO_CONTROL_ENABLE | 84550c5ce6SKhoronzhuk, Ivan MDIO_CONTROL_FAULT | MDIO_CONTROL_FAULT_ENABLE, 85fc9a8e8dSKaricheri, Muralidharan &adap_mdio->control); 86fc9a8e8dSKaricheri, Muralidharan 87fc9a8e8dSKaricheri, Muralidharan while (readl(&adap_mdio->control) & MDIO_CONTROL_IDLE) 88fc9a8e8dSKaricheri, Muralidharan ; 89550c5ce6SKhoronzhuk, Ivan 90550c5ce6SKhoronzhuk, Ivan return 0; 91fc9a8e8dSKaricheri, Muralidharan } 92fc9a8e8dSKaricheri, Muralidharan 93550c5ce6SKhoronzhuk, Ivan /** 94550c5ce6SKhoronzhuk, Ivan * keystone2_mdio_read - read a PHY register via MDIO interface. 95550c5ce6SKhoronzhuk, Ivan * Blocks until operation is complete. 96550c5ce6SKhoronzhuk, Ivan */ 97550c5ce6SKhoronzhuk, Ivan static int keystone2_mdio_read(struct mii_dev *bus, 98550c5ce6SKhoronzhuk, Ivan int addr, int devad, int reg) 99fc9a8e8dSKaricheri, Muralidharan { 100fc9a8e8dSKaricheri, Muralidharan int tmp; 101550c5ce6SKhoronzhuk, Ivan struct mdio_regs *adap_mdio = bus->priv; 102fc9a8e8dSKaricheri, Muralidharan 103fc9a8e8dSKaricheri, Muralidharan while (readl(&adap_mdio->useraccess0) & MDIO_USERACCESS0_GO) 104fc9a8e8dSKaricheri, Muralidharan ; 105fc9a8e8dSKaricheri, Muralidharan 106550c5ce6SKhoronzhuk, Ivan writel(MDIO_USERACCESS0_GO | MDIO_USERACCESS0_WRITE_READ | 107550c5ce6SKhoronzhuk, Ivan ((reg & 0x1f) << 21) | ((addr & 0x1f) << 16), 108fc9a8e8dSKaricheri, Muralidharan &adap_mdio->useraccess0); 109fc9a8e8dSKaricheri, Muralidharan 110fc9a8e8dSKaricheri, Muralidharan /* Wait for command to complete */ 111fc9a8e8dSKaricheri, Muralidharan while ((tmp = readl(&adap_mdio->useraccess0)) & MDIO_USERACCESS0_GO) 112fc9a8e8dSKaricheri, Muralidharan ; 113fc9a8e8dSKaricheri, Muralidharan 114550c5ce6SKhoronzhuk, Ivan if (tmp & MDIO_USERACCESS0_ACK) 115550c5ce6SKhoronzhuk, Ivan return tmp & 0xffff; 116fc9a8e8dSKaricheri, Muralidharan 117fc9a8e8dSKaricheri, Muralidharan return -1; 118fc9a8e8dSKaricheri, Muralidharan } 119fc9a8e8dSKaricheri, Muralidharan 120550c5ce6SKhoronzhuk, Ivan /** 121550c5ce6SKhoronzhuk, Ivan * keystone2_mdio_write - write to a PHY register via MDIO interface. 122fc9a8e8dSKaricheri, Muralidharan * Blocks until operation is complete. 123fc9a8e8dSKaricheri, Muralidharan */ 124550c5ce6SKhoronzhuk, Ivan static int keystone2_mdio_write(struct mii_dev *bus, 125550c5ce6SKhoronzhuk, Ivan int addr, int devad, int reg, u16 val) 126fc9a8e8dSKaricheri, Muralidharan { 127550c5ce6SKhoronzhuk, Ivan struct mdio_regs *adap_mdio = bus->priv; 128550c5ce6SKhoronzhuk, Ivan 129fc9a8e8dSKaricheri, Muralidharan while (readl(&adap_mdio->useraccess0) & MDIO_USERACCESS0_GO) 130fc9a8e8dSKaricheri, Muralidharan ; 131fc9a8e8dSKaricheri, Muralidharan 132550c5ce6SKhoronzhuk, Ivan writel(MDIO_USERACCESS0_GO | MDIO_USERACCESS0_WRITE_WRITE | 133550c5ce6SKhoronzhuk, Ivan ((reg & 0x1f) << 21) | ((addr & 0x1f) << 16) | 134550c5ce6SKhoronzhuk, Ivan (val & 0xffff), &adap_mdio->useraccess0); 135fc9a8e8dSKaricheri, Muralidharan 136fc9a8e8dSKaricheri, Muralidharan /* Wait for command to complete */ 137fc9a8e8dSKaricheri, Muralidharan while (readl(&adap_mdio->useraccess0) & MDIO_USERACCESS0_GO) 138fc9a8e8dSKaricheri, Muralidharan ; 139fc9a8e8dSKaricheri, Muralidharan 140fc9a8e8dSKaricheri, Muralidharan return 0; 141fc9a8e8dSKaricheri, Muralidharan } 142fc9a8e8dSKaricheri, Muralidharan 143fc9a8e8dSKaricheri, Muralidharan static void __attribute__((unused)) 144fc9a8e8dSKaricheri, Muralidharan keystone2_eth_gigabit_enable(struct eth_device *dev) 145fc9a8e8dSKaricheri, Muralidharan { 146fc9a8e8dSKaricheri, Muralidharan u_int16_t data; 147fc9a8e8dSKaricheri, Muralidharan struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv; 148fc9a8e8dSKaricheri, Muralidharan 149fc9a8e8dSKaricheri, Muralidharan if (sys_has_mdio) { 150550c5ce6SKhoronzhuk, Ivan data = keystone2_mdio_read(mdio_bus, eth_priv->phy_addr, 151550c5ce6SKhoronzhuk, Ivan MDIO_DEVAD_NONE, 0); 152550c5ce6SKhoronzhuk, Ivan /* speed selection MSB */ 153550c5ce6SKhoronzhuk, Ivan if (!(data & (1 << 6))) 154fc9a8e8dSKaricheri, Muralidharan return; 155fc9a8e8dSKaricheri, Muralidharan } 156fc9a8e8dSKaricheri, Muralidharan 157fc9a8e8dSKaricheri, Muralidharan /* 158fc9a8e8dSKaricheri, Muralidharan * Check if link detected is giga-bit 159fc9a8e8dSKaricheri, Muralidharan * If Gigabit mode detected, enable gigbit in MAC 160fc9a8e8dSKaricheri, Muralidharan */ 161b2cfe322SHao Zhang writel(readl(DEVICE_EMACSL_BASE(eth_priv->slave_port - 1) + 162b2cfe322SHao Zhang CPGMACSL_REG_CTL) | 163fc9a8e8dSKaricheri, Muralidharan EMAC_MACCONTROL_GIGFORCE | EMAC_MACCONTROL_GIGABIT_ENABLE, 164b2cfe322SHao Zhang DEVICE_EMACSL_BASE(eth_priv->slave_port - 1) + CPGMACSL_REG_CTL); 165fc9a8e8dSKaricheri, Muralidharan } 166fc9a8e8dSKaricheri, Muralidharan 1674657a2d4SVitaly Andrianov #ifdef CONFIG_SOC_K2G 1684657a2d4SVitaly Andrianov int keystone_rgmii_config(struct phy_device *phy_dev) 1694657a2d4SVitaly Andrianov { 1704657a2d4SVitaly Andrianov unsigned int i, status; 1714657a2d4SVitaly Andrianov 1724657a2d4SVitaly Andrianov i = 0; 1734657a2d4SVitaly Andrianov do { 1744657a2d4SVitaly Andrianov if (i > SGMII_ANEG_TIMEOUT) { 1754657a2d4SVitaly Andrianov puts(" TIMEOUT !\n"); 1764657a2d4SVitaly Andrianov phy_dev->link = 0; 1774657a2d4SVitaly Andrianov return 0; 1784657a2d4SVitaly Andrianov } 1794657a2d4SVitaly Andrianov 1804657a2d4SVitaly Andrianov if (ctrlc()) { 1814657a2d4SVitaly Andrianov puts("user interrupt!\n"); 1824657a2d4SVitaly Andrianov phy_dev->link = 0; 1834657a2d4SVitaly Andrianov return -EINTR; 1844657a2d4SVitaly Andrianov } 1854657a2d4SVitaly Andrianov 1864657a2d4SVitaly Andrianov if ((i++ % 500) == 0) 1874657a2d4SVitaly Andrianov printf("."); 1884657a2d4SVitaly Andrianov 1894657a2d4SVitaly Andrianov udelay(1000); /* 1 ms */ 1904657a2d4SVitaly Andrianov status = readl(RGMII_STATUS_REG); 1914657a2d4SVitaly Andrianov } while (!(status & RGMII_REG_STATUS_LINK)); 1924657a2d4SVitaly Andrianov 1934657a2d4SVitaly Andrianov puts(" done\n"); 1944657a2d4SVitaly Andrianov 1954657a2d4SVitaly Andrianov return 0; 1964657a2d4SVitaly Andrianov } 1974657a2d4SVitaly Andrianov #else 198c05d05e7SKhoronzhuk, Ivan int keystone_sgmii_config(struct phy_device *phy_dev, int port, int interface) 199fc9a8e8dSKaricheri, Muralidharan { 200fc9a8e8dSKaricheri, Muralidharan unsigned int i, status, mask; 201fc9a8e8dSKaricheri, Muralidharan unsigned int mr_adv_ability, control; 202fc9a8e8dSKaricheri, Muralidharan 203fc9a8e8dSKaricheri, Muralidharan switch (interface) { 204fc9a8e8dSKaricheri, Muralidharan case SGMII_LINK_MAC_MAC_AUTONEG: 205fc9a8e8dSKaricheri, Muralidharan mr_adv_ability = (SGMII_REG_MR_ADV_ENABLE | 206fc9a8e8dSKaricheri, Muralidharan SGMII_REG_MR_ADV_LINK | 207fc9a8e8dSKaricheri, Muralidharan SGMII_REG_MR_ADV_FULL_DUPLEX | 208fc9a8e8dSKaricheri, Muralidharan SGMII_REG_MR_ADV_GIG_MODE); 209fc9a8e8dSKaricheri, Muralidharan control = (SGMII_REG_CONTROL_MASTER | 210fc9a8e8dSKaricheri, Muralidharan SGMII_REG_CONTROL_AUTONEG); 211fc9a8e8dSKaricheri, Muralidharan 212fc9a8e8dSKaricheri, Muralidharan break; 213fc9a8e8dSKaricheri, Muralidharan case SGMII_LINK_MAC_PHY: 214fc9a8e8dSKaricheri, Muralidharan case SGMII_LINK_MAC_PHY_FORCED: 215fc9a8e8dSKaricheri, Muralidharan mr_adv_ability = SGMII_REG_MR_ADV_ENABLE; 216fc9a8e8dSKaricheri, Muralidharan control = SGMII_REG_CONTROL_AUTONEG; 217fc9a8e8dSKaricheri, Muralidharan 218fc9a8e8dSKaricheri, Muralidharan break; 219fc9a8e8dSKaricheri, Muralidharan case SGMII_LINK_MAC_MAC_FORCED: 220fc9a8e8dSKaricheri, Muralidharan mr_adv_ability = (SGMII_REG_MR_ADV_ENABLE | 221fc9a8e8dSKaricheri, Muralidharan SGMII_REG_MR_ADV_LINK | 222fc9a8e8dSKaricheri, Muralidharan SGMII_REG_MR_ADV_FULL_DUPLEX | 223fc9a8e8dSKaricheri, Muralidharan SGMII_REG_MR_ADV_GIG_MODE); 224fc9a8e8dSKaricheri, Muralidharan control = SGMII_REG_CONTROL_MASTER; 225fc9a8e8dSKaricheri, Muralidharan 226fc9a8e8dSKaricheri, Muralidharan break; 227fc9a8e8dSKaricheri, Muralidharan case SGMII_LINK_MAC_FIBER: 228fc9a8e8dSKaricheri, Muralidharan mr_adv_ability = 0x20; 229fc9a8e8dSKaricheri, Muralidharan control = SGMII_REG_CONTROL_AUTONEG; 230fc9a8e8dSKaricheri, Muralidharan 231fc9a8e8dSKaricheri, Muralidharan break; 232fc9a8e8dSKaricheri, Muralidharan default: 233fc9a8e8dSKaricheri, Muralidharan mr_adv_ability = SGMII_REG_MR_ADV_ENABLE; 234fc9a8e8dSKaricheri, Muralidharan control = SGMII_REG_CONTROL_AUTONEG; 235fc9a8e8dSKaricheri, Muralidharan } 236fc9a8e8dSKaricheri, Muralidharan 237fc9a8e8dSKaricheri, Muralidharan __raw_writel(0, SGMII_CTL_REG(port)); 238fc9a8e8dSKaricheri, Muralidharan 239fc9a8e8dSKaricheri, Muralidharan /* 240fc9a8e8dSKaricheri, Muralidharan * Wait for the SerDes pll to lock, 241fc9a8e8dSKaricheri, Muralidharan * but don't trap if lock is never read 242fc9a8e8dSKaricheri, Muralidharan */ 243fc9a8e8dSKaricheri, Muralidharan for (i = 0; i < 1000; i++) { 244fc9a8e8dSKaricheri, Muralidharan udelay(2000); 245fc9a8e8dSKaricheri, Muralidharan status = __raw_readl(SGMII_STATUS_REG(port)); 246fc9a8e8dSKaricheri, Muralidharan if ((status & SGMII_REG_STATUS_LOCK) != 0) 247fc9a8e8dSKaricheri, Muralidharan break; 248fc9a8e8dSKaricheri, Muralidharan } 249fc9a8e8dSKaricheri, Muralidharan 250fc9a8e8dSKaricheri, Muralidharan __raw_writel(mr_adv_ability, SGMII_MRADV_REG(port)); 251fc9a8e8dSKaricheri, Muralidharan __raw_writel(control, SGMII_CTL_REG(port)); 252fc9a8e8dSKaricheri, Muralidharan 253fc9a8e8dSKaricheri, Muralidharan 254fc9a8e8dSKaricheri, Muralidharan mask = SGMII_REG_STATUS_LINK; 255fc9a8e8dSKaricheri, Muralidharan 256fc9a8e8dSKaricheri, Muralidharan if (control & SGMII_REG_CONTROL_AUTONEG) 257fc9a8e8dSKaricheri, Muralidharan mask |= SGMII_REG_STATUS_AUTONEG; 258fc9a8e8dSKaricheri, Muralidharan 259fc9a8e8dSKaricheri, Muralidharan status = __raw_readl(SGMII_STATUS_REG(port)); 260fc9a8e8dSKaricheri, Muralidharan if ((status & mask) == mask) 261c05d05e7SKhoronzhuk, Ivan return 0; 262c05d05e7SKhoronzhuk, Ivan 263c05d05e7SKhoronzhuk, Ivan printf("\n%s Waiting for SGMII auto negotiation to complete", 264c05d05e7SKhoronzhuk, Ivan phy_dev->dev->name); 265c05d05e7SKhoronzhuk, Ivan while ((status & mask) != mask) { 266c05d05e7SKhoronzhuk, Ivan /* 267c05d05e7SKhoronzhuk, Ivan * Timeout reached ? 268c05d05e7SKhoronzhuk, Ivan */ 269c05d05e7SKhoronzhuk, Ivan if (i > SGMII_ANEG_TIMEOUT) { 270c05d05e7SKhoronzhuk, Ivan puts(" TIMEOUT !\n"); 271c05d05e7SKhoronzhuk, Ivan phy_dev->link = 0; 272c05d05e7SKhoronzhuk, Ivan return 0; 273fc9a8e8dSKaricheri, Muralidharan } 274fc9a8e8dSKaricheri, Muralidharan 275c05d05e7SKhoronzhuk, Ivan if (ctrlc()) { 276c05d05e7SKhoronzhuk, Ivan puts("user interrupt!\n"); 277c05d05e7SKhoronzhuk, Ivan phy_dev->link = 0; 278c05d05e7SKhoronzhuk, Ivan return -EINTR; 279c05d05e7SKhoronzhuk, Ivan } 280c05d05e7SKhoronzhuk, Ivan 281c05d05e7SKhoronzhuk, Ivan if ((i++ % 500) == 0) 282c05d05e7SKhoronzhuk, Ivan printf("."); 283c05d05e7SKhoronzhuk, Ivan 284c05d05e7SKhoronzhuk, Ivan udelay(1000); /* 1 ms */ 285c05d05e7SKhoronzhuk, Ivan status = __raw_readl(SGMII_STATUS_REG(port)); 286c05d05e7SKhoronzhuk, Ivan } 287c05d05e7SKhoronzhuk, Ivan puts(" done\n"); 288c05d05e7SKhoronzhuk, Ivan 289fc9a8e8dSKaricheri, Muralidharan return 0; 290fc9a8e8dSKaricheri, Muralidharan } 2914657a2d4SVitaly Andrianov #endif 292fc9a8e8dSKaricheri, Muralidharan 293fc9a8e8dSKaricheri, Muralidharan int mac_sl_reset(u32 port) 294fc9a8e8dSKaricheri, Muralidharan { 295fc9a8e8dSKaricheri, Muralidharan u32 i, v; 296fc9a8e8dSKaricheri, Muralidharan 297fc9a8e8dSKaricheri, Muralidharan if (port >= DEVICE_N_GMACSL_PORTS) 298fc9a8e8dSKaricheri, Muralidharan return GMACSL_RET_INVALID_PORT; 299fc9a8e8dSKaricheri, Muralidharan 300fc9a8e8dSKaricheri, Muralidharan /* Set the soft reset bit */ 301e6c9428aSKhoronzhuk, Ivan writel(CPGMAC_REG_RESET_VAL_RESET, 302e6c9428aSKhoronzhuk, Ivan DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_RESET); 303fc9a8e8dSKaricheri, Muralidharan 304fc9a8e8dSKaricheri, Muralidharan /* Wait for the bit to clear */ 305fc9a8e8dSKaricheri, Muralidharan for (i = 0; i < DEVICE_EMACSL_RESET_POLL_COUNT; i++) { 306e6c9428aSKhoronzhuk, Ivan v = readl(DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_RESET); 307fc9a8e8dSKaricheri, Muralidharan if ((v & CPGMAC_REG_RESET_VAL_RESET_MASK) != 308fc9a8e8dSKaricheri, Muralidharan CPGMAC_REG_RESET_VAL_RESET) 309fc9a8e8dSKaricheri, Muralidharan return GMACSL_RET_OK; 310fc9a8e8dSKaricheri, Muralidharan } 311fc9a8e8dSKaricheri, Muralidharan 312fc9a8e8dSKaricheri, Muralidharan /* Timeout on the reset */ 313fc9a8e8dSKaricheri, Muralidharan return GMACSL_RET_WARN_RESET_INCOMPLETE; 314fc9a8e8dSKaricheri, Muralidharan } 315fc9a8e8dSKaricheri, Muralidharan 316fc9a8e8dSKaricheri, Muralidharan int mac_sl_config(u_int16_t port, struct mac_sl_cfg *cfg) 317fc9a8e8dSKaricheri, Muralidharan { 318fc9a8e8dSKaricheri, Muralidharan u32 v, i; 319fc9a8e8dSKaricheri, Muralidharan int ret = GMACSL_RET_OK; 320fc9a8e8dSKaricheri, Muralidharan 321fc9a8e8dSKaricheri, Muralidharan if (port >= DEVICE_N_GMACSL_PORTS) 322fc9a8e8dSKaricheri, Muralidharan return GMACSL_RET_INVALID_PORT; 323fc9a8e8dSKaricheri, Muralidharan 324fc9a8e8dSKaricheri, Muralidharan if (cfg->max_rx_len > CPGMAC_REG_MAXLEN_LEN) { 325fc9a8e8dSKaricheri, Muralidharan cfg->max_rx_len = CPGMAC_REG_MAXLEN_LEN; 326fc9a8e8dSKaricheri, Muralidharan ret = GMACSL_RET_WARN_MAXLEN_TOO_BIG; 327fc9a8e8dSKaricheri, Muralidharan } 328fc9a8e8dSKaricheri, Muralidharan 329fc9a8e8dSKaricheri, Muralidharan /* Must wait if the device is undergoing reset */ 330fc9a8e8dSKaricheri, Muralidharan for (i = 0; i < DEVICE_EMACSL_RESET_POLL_COUNT; i++) { 331e6c9428aSKhoronzhuk, Ivan v = readl(DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_RESET); 332fc9a8e8dSKaricheri, Muralidharan if ((v & CPGMAC_REG_RESET_VAL_RESET_MASK) != 333fc9a8e8dSKaricheri, Muralidharan CPGMAC_REG_RESET_VAL_RESET) 334fc9a8e8dSKaricheri, Muralidharan break; 335fc9a8e8dSKaricheri, Muralidharan } 336fc9a8e8dSKaricheri, Muralidharan 337fc9a8e8dSKaricheri, Muralidharan if (i == DEVICE_EMACSL_RESET_POLL_COUNT) 338fc9a8e8dSKaricheri, Muralidharan return GMACSL_RET_CONFIG_FAIL_RESET_ACTIVE; 339fc9a8e8dSKaricheri, Muralidharan 340e6c9428aSKhoronzhuk, Ivan writel(cfg->max_rx_len, DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_MAXLEN); 341e6c9428aSKhoronzhuk, Ivan writel(cfg->ctl, DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_CTL); 342fc9a8e8dSKaricheri, Muralidharan 3434657a2d4SVitaly Andrianov #ifndef CONFIG_SOC_K2HK 344ff11c769SKhoronzhuk, Ivan /* Map RX packet flow priority to 0 */ 345ff11c769SKhoronzhuk, Ivan writel(0, DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_RX_PRI_MAP); 346ff11c769SKhoronzhuk, Ivan #endif 347ff11c769SKhoronzhuk, Ivan 348fc9a8e8dSKaricheri, Muralidharan return ret; 349fc9a8e8dSKaricheri, Muralidharan } 350fc9a8e8dSKaricheri, Muralidharan 351fc9a8e8dSKaricheri, Muralidharan int ethss_config(u32 ctl, u32 max_pkt_size) 352fc9a8e8dSKaricheri, Muralidharan { 353fc9a8e8dSKaricheri, Muralidharan u32 i; 354fc9a8e8dSKaricheri, Muralidharan 355fc9a8e8dSKaricheri, Muralidharan /* Max length register */ 356e6c9428aSKhoronzhuk, Ivan writel(max_pkt_size, DEVICE_CPSW_BASE + CPSW_REG_MAXLEN); 357fc9a8e8dSKaricheri, Muralidharan 358fc9a8e8dSKaricheri, Muralidharan /* Control register */ 359e6c9428aSKhoronzhuk, Ivan writel(ctl, DEVICE_CPSW_BASE + CPSW_REG_CTL); 360fc9a8e8dSKaricheri, Muralidharan 361fc9a8e8dSKaricheri, Muralidharan /* All statistics enabled by default */ 362e6c9428aSKhoronzhuk, Ivan writel(CPSW_REG_VAL_STAT_ENABLE_ALL, 363e6c9428aSKhoronzhuk, Ivan DEVICE_CPSW_BASE + CPSW_REG_STAT_PORT_EN); 364fc9a8e8dSKaricheri, Muralidharan 365fc9a8e8dSKaricheri, Muralidharan /* Reset and enable the ALE */ 366e6c9428aSKhoronzhuk, Ivan writel(CPSW_REG_VAL_ALE_CTL_RESET_AND_ENABLE | 367e6c9428aSKhoronzhuk, Ivan CPSW_REG_VAL_ALE_CTL_BYPASS, 368e6c9428aSKhoronzhuk, Ivan DEVICE_CPSW_BASE + CPSW_REG_ALE_CONTROL); 369fc9a8e8dSKaricheri, Muralidharan 370fc9a8e8dSKaricheri, Muralidharan /* All ports put into forward mode */ 371fc9a8e8dSKaricheri, Muralidharan for (i = 0; i < DEVICE_CPSW_NUM_PORTS; i++) 372e6c9428aSKhoronzhuk, Ivan writel(CPSW_REG_VAL_PORTCTL_FORWARD_MODE, 373e6c9428aSKhoronzhuk, Ivan DEVICE_CPSW_BASE + CPSW_REG_ALE_PORTCTL(i)); 374fc9a8e8dSKaricheri, Muralidharan 375fc9a8e8dSKaricheri, Muralidharan return 0; 376fc9a8e8dSKaricheri, Muralidharan } 377fc9a8e8dSKaricheri, Muralidharan 378fc9a8e8dSKaricheri, Muralidharan int ethss_start(void) 379fc9a8e8dSKaricheri, Muralidharan { 380fc9a8e8dSKaricheri, Muralidharan int i; 381fc9a8e8dSKaricheri, Muralidharan struct mac_sl_cfg cfg; 382fc9a8e8dSKaricheri, Muralidharan 383fc9a8e8dSKaricheri, Muralidharan cfg.max_rx_len = MAX_SIZE_STREAM_BUFFER; 384fc9a8e8dSKaricheri, Muralidharan cfg.ctl = GMACSL_ENABLE | GMACSL_RX_ENABLE_EXT_CTL; 385fc9a8e8dSKaricheri, Muralidharan 386fc9a8e8dSKaricheri, Muralidharan for (i = 0; i < DEVICE_N_GMACSL_PORTS; i++) { 387fc9a8e8dSKaricheri, Muralidharan mac_sl_reset(i); 388fc9a8e8dSKaricheri, Muralidharan mac_sl_config(i, &cfg); 389fc9a8e8dSKaricheri, Muralidharan } 390fc9a8e8dSKaricheri, Muralidharan 391fc9a8e8dSKaricheri, Muralidharan return 0; 392fc9a8e8dSKaricheri, Muralidharan } 393fc9a8e8dSKaricheri, Muralidharan 394fc9a8e8dSKaricheri, Muralidharan int ethss_stop(void) 395fc9a8e8dSKaricheri, Muralidharan { 396fc9a8e8dSKaricheri, Muralidharan int i; 397fc9a8e8dSKaricheri, Muralidharan 398fc9a8e8dSKaricheri, Muralidharan for (i = 0; i < DEVICE_N_GMACSL_PORTS; i++) 399fc9a8e8dSKaricheri, Muralidharan mac_sl_reset(i); 400fc9a8e8dSKaricheri, Muralidharan 401fc9a8e8dSKaricheri, Muralidharan return 0; 402fc9a8e8dSKaricheri, Muralidharan } 403fc9a8e8dSKaricheri, Muralidharan 404fc9a8e8dSKaricheri, Muralidharan int32_t cpmac_drv_send(u32 *buffer, int num_bytes, int slave_port_num) 405fc9a8e8dSKaricheri, Muralidharan { 406fc9a8e8dSKaricheri, Muralidharan if (num_bytes < EMAC_MIN_ETHERNET_PKT_SIZE) 407fc9a8e8dSKaricheri, Muralidharan num_bytes = EMAC_MIN_ETHERNET_PKT_SIZE; 408fc9a8e8dSKaricheri, Muralidharan 4099ea9021aSKhoronzhuk, Ivan return ksnav_send(&netcp_pktdma, buffer, 4109ea9021aSKhoronzhuk, Ivan num_bytes, (slave_port_num) << 16); 411fc9a8e8dSKaricheri, Muralidharan } 412fc9a8e8dSKaricheri, Muralidharan 413fc9a8e8dSKaricheri, Muralidharan /* Eth device open */ 414fc9a8e8dSKaricheri, Muralidharan static int keystone2_eth_open(struct eth_device *dev, bd_t *bis) 415fc9a8e8dSKaricheri, Muralidharan { 416fc9a8e8dSKaricheri, Muralidharan struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv; 4173fe93623SKhoronzhuk, Ivan struct phy_device *phy_dev = eth_priv->phy_dev; 418fc9a8e8dSKaricheri, Muralidharan 419fc9a8e8dSKaricheri, Muralidharan debug("+ emac_open\n"); 420fc9a8e8dSKaricheri, Muralidharan 421fc9a8e8dSKaricheri, Muralidharan net_rx_buffs.rx_flow = eth_priv->rx_flow; 422fc9a8e8dSKaricheri, Muralidharan 423fc9a8e8dSKaricheri, Muralidharan sys_has_mdio = 424fc9a8e8dSKaricheri, Muralidharan (eth_priv->sgmii_link_type == SGMII_LINK_MAC_PHY) ? 1 : 0; 425fc9a8e8dSKaricheri, Muralidharan 4266c0fb41aSKhoronzhuk, Ivan if (sys_has_mdio) 4276c0fb41aSKhoronzhuk, Ivan keystone2_mdio_reset(mdio_bus); 4286c0fb41aSKhoronzhuk, Ivan 4294657a2d4SVitaly Andrianov #ifdef CONFIG_SOC_K2G 4304657a2d4SVitaly Andrianov keystone_rgmii_config(phy_dev); 4314657a2d4SVitaly Andrianov #else 432c05d05e7SKhoronzhuk, Ivan keystone_sgmii_config(phy_dev, eth_priv->slave_port - 1, 433fc9a8e8dSKaricheri, Muralidharan eth_priv->sgmii_link_type); 4344657a2d4SVitaly Andrianov #endif 435fc9a8e8dSKaricheri, Muralidharan 436fc9a8e8dSKaricheri, Muralidharan udelay(10000); 437fc9a8e8dSKaricheri, Muralidharan 438fc9a8e8dSKaricheri, Muralidharan /* On chip switch configuration */ 439fc9a8e8dSKaricheri, Muralidharan ethss_config(target_get_switch_ctl(), SWITCH_MAX_PKT_SIZE); 440fc9a8e8dSKaricheri, Muralidharan 441fc9a8e8dSKaricheri, Muralidharan /* TODO: add error handling code */ 442fc9a8e8dSKaricheri, Muralidharan if (qm_init()) { 443fc9a8e8dSKaricheri, Muralidharan printf("ERROR: qm_init()\n"); 444fc9a8e8dSKaricheri, Muralidharan return -1; 445fc9a8e8dSKaricheri, Muralidharan } 4469ea9021aSKhoronzhuk, Ivan if (ksnav_init(&netcp_pktdma, &net_rx_buffs)) { 447fc9a8e8dSKaricheri, Muralidharan qm_close(); 448fc9a8e8dSKaricheri, Muralidharan printf("ERROR: netcp_init()\n"); 449fc9a8e8dSKaricheri, Muralidharan return -1; 450fc9a8e8dSKaricheri, Muralidharan } 451fc9a8e8dSKaricheri, Muralidharan 452fc9a8e8dSKaricheri, Muralidharan /* 453fc9a8e8dSKaricheri, Muralidharan * Streaming switch configuration. If not present this 454fc9a8e8dSKaricheri, Muralidharan * statement is defined to void in target.h. 455fc9a8e8dSKaricheri, Muralidharan * If present this is usually defined to a series of register writes 456fc9a8e8dSKaricheri, Muralidharan */ 457fc9a8e8dSKaricheri, Muralidharan hw_config_streaming_switch(); 458fc9a8e8dSKaricheri, Muralidharan 459fc9a8e8dSKaricheri, Muralidharan if (sys_has_mdio) { 460550c5ce6SKhoronzhuk, Ivan keystone2_mdio_reset(mdio_bus); 461fc9a8e8dSKaricheri, Muralidharan 4623fe93623SKhoronzhuk, Ivan phy_startup(phy_dev); 4633fe93623SKhoronzhuk, Ivan if (phy_dev->link == 0) { 4649ea9021aSKhoronzhuk, Ivan ksnav_close(&netcp_pktdma); 465fc9a8e8dSKaricheri, Muralidharan qm_close(); 466fc9a8e8dSKaricheri, Muralidharan return -1; 467fc9a8e8dSKaricheri, Muralidharan } 468fc9a8e8dSKaricheri, Muralidharan } 469fc9a8e8dSKaricheri, Muralidharan 470fc9a8e8dSKaricheri, Muralidharan emac_gigabit_enable(dev); 471fc9a8e8dSKaricheri, Muralidharan 472fc9a8e8dSKaricheri, Muralidharan ethss_start(); 473fc9a8e8dSKaricheri, Muralidharan 474fc9a8e8dSKaricheri, Muralidharan debug("- emac_open\n"); 475fc9a8e8dSKaricheri, Muralidharan 476fc9a8e8dSKaricheri, Muralidharan emac_open = 1; 477fc9a8e8dSKaricheri, Muralidharan 478fc9a8e8dSKaricheri, Muralidharan return 0; 479fc9a8e8dSKaricheri, Muralidharan } 480fc9a8e8dSKaricheri, Muralidharan 481fc9a8e8dSKaricheri, Muralidharan /* Eth device close */ 482fc9a8e8dSKaricheri, Muralidharan void keystone2_eth_close(struct eth_device *dev) 483fc9a8e8dSKaricheri, Muralidharan { 4843fe93623SKhoronzhuk, Ivan struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv; 4853fe93623SKhoronzhuk, Ivan struct phy_device *phy_dev = eth_priv->phy_dev; 4863fe93623SKhoronzhuk, Ivan 487fc9a8e8dSKaricheri, Muralidharan debug("+ emac_close\n"); 488fc9a8e8dSKaricheri, Muralidharan 489fc9a8e8dSKaricheri, Muralidharan if (!emac_open) 490fc9a8e8dSKaricheri, Muralidharan return; 491fc9a8e8dSKaricheri, Muralidharan 492fc9a8e8dSKaricheri, Muralidharan ethss_stop(); 493fc9a8e8dSKaricheri, Muralidharan 4949ea9021aSKhoronzhuk, Ivan ksnav_close(&netcp_pktdma); 495fc9a8e8dSKaricheri, Muralidharan qm_close(); 4963fe93623SKhoronzhuk, Ivan phy_shutdown(phy_dev); 497fc9a8e8dSKaricheri, Muralidharan 498fc9a8e8dSKaricheri, Muralidharan emac_open = 0; 499fc9a8e8dSKaricheri, Muralidharan 500fc9a8e8dSKaricheri, Muralidharan debug("- emac_close\n"); 501fc9a8e8dSKaricheri, Muralidharan } 502fc9a8e8dSKaricheri, Muralidharan 503fc9a8e8dSKaricheri, Muralidharan /* 504fc9a8e8dSKaricheri, Muralidharan * This function sends a single packet on the network and returns 505fc9a8e8dSKaricheri, Muralidharan * positive number (number of bytes transmitted) or negative for error 506fc9a8e8dSKaricheri, Muralidharan */ 507fc9a8e8dSKaricheri, Muralidharan static int keystone2_eth_send_packet(struct eth_device *dev, 508fc9a8e8dSKaricheri, Muralidharan void *packet, int length) 509fc9a8e8dSKaricheri, Muralidharan { 510fc9a8e8dSKaricheri, Muralidharan int ret_status = -1; 511fc9a8e8dSKaricheri, Muralidharan struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv; 512a4d2adeeSKhoronzhuk, Ivan struct phy_device *phy_dev = eth_priv->phy_dev; 513fc9a8e8dSKaricheri, Muralidharan 514a4d2adeeSKhoronzhuk, Ivan genphy_update_link(phy_dev); 515a4d2adeeSKhoronzhuk, Ivan if (phy_dev->link == 0) 516fc9a8e8dSKaricheri, Muralidharan return -1; 517fc9a8e8dSKaricheri, Muralidharan 518fc9a8e8dSKaricheri, Muralidharan if (cpmac_drv_send((u32 *)packet, length, eth_priv->slave_port) != 0) 519fc9a8e8dSKaricheri, Muralidharan return ret_status; 520fc9a8e8dSKaricheri, Muralidharan 521fc9a8e8dSKaricheri, Muralidharan return length; 522fc9a8e8dSKaricheri, Muralidharan } 523fc9a8e8dSKaricheri, Muralidharan 524fc9a8e8dSKaricheri, Muralidharan /* 525fc9a8e8dSKaricheri, Muralidharan * This function handles receipt of a packet from the network 526fc9a8e8dSKaricheri, Muralidharan */ 527fc9a8e8dSKaricheri, Muralidharan static int keystone2_eth_rcv_packet(struct eth_device *dev) 528fc9a8e8dSKaricheri, Muralidharan { 529fc9a8e8dSKaricheri, Muralidharan void *hd; 530fc9a8e8dSKaricheri, Muralidharan int pkt_size; 531fc9a8e8dSKaricheri, Muralidharan u32 *pkt; 532fc9a8e8dSKaricheri, Muralidharan 5339ea9021aSKhoronzhuk, Ivan hd = ksnav_recv(&netcp_pktdma, &pkt, &pkt_size); 534fc9a8e8dSKaricheri, Muralidharan if (hd == NULL) 535fc9a8e8dSKaricheri, Muralidharan return 0; 536fc9a8e8dSKaricheri, Muralidharan 5371fd92db8SJoe Hershberger net_process_received_packet((uchar *)pkt, pkt_size); 538fc9a8e8dSKaricheri, Muralidharan 5399ea9021aSKhoronzhuk, Ivan ksnav_release_rxhd(&netcp_pktdma, hd); 540fc9a8e8dSKaricheri, Muralidharan 541fc9a8e8dSKaricheri, Muralidharan return pkt_size; 542fc9a8e8dSKaricheri, Muralidharan } 543fc9a8e8dSKaricheri, Muralidharan 5445031ca59SVitaly Andrianov #ifdef CONFIG_MCAST_TFTP 5455031ca59SVitaly Andrianov static int keystone2_eth_bcast_addr(struct eth_device *dev, u32 ip, u8 set) 5465031ca59SVitaly Andrianov { 5475031ca59SVitaly Andrianov return 0; 5485031ca59SVitaly Andrianov } 5495031ca59SVitaly Andrianov #endif 5505031ca59SVitaly Andrianov 551fc9a8e8dSKaricheri, Muralidharan /* 552fc9a8e8dSKaricheri, Muralidharan * This function initializes the EMAC hardware. 553fc9a8e8dSKaricheri, Muralidharan */ 554fc9a8e8dSKaricheri, Muralidharan int keystone2_emac_initialize(struct eth_priv_t *eth_priv) 555fc9a8e8dSKaricheri, Muralidharan { 556550c5ce6SKhoronzhuk, Ivan int res; 557fc9a8e8dSKaricheri, Muralidharan struct eth_device *dev; 5583fe93623SKhoronzhuk, Ivan struct phy_device *phy_dev; 559fc9a8e8dSKaricheri, Muralidharan 560fc9a8e8dSKaricheri, Muralidharan dev = malloc(sizeof(struct eth_device)); 561fc9a8e8dSKaricheri, Muralidharan if (dev == NULL) 562fc9a8e8dSKaricheri, Muralidharan return -1; 563fc9a8e8dSKaricheri, Muralidharan 564fc9a8e8dSKaricheri, Muralidharan memset(dev, 0, sizeof(struct eth_device)); 565fc9a8e8dSKaricheri, Muralidharan 566fc9a8e8dSKaricheri, Muralidharan strcpy(dev->name, eth_priv->int_name); 567fc9a8e8dSKaricheri, Muralidharan dev->priv = eth_priv; 568fc9a8e8dSKaricheri, Muralidharan 569fc9a8e8dSKaricheri, Muralidharan keystone2_eth_read_mac_addr(dev); 570fc9a8e8dSKaricheri, Muralidharan 571fc9a8e8dSKaricheri, Muralidharan dev->iobase = 0; 572fc9a8e8dSKaricheri, Muralidharan dev->init = keystone2_eth_open; 573fc9a8e8dSKaricheri, Muralidharan dev->halt = keystone2_eth_close; 574fc9a8e8dSKaricheri, Muralidharan dev->send = keystone2_eth_send_packet; 575fc9a8e8dSKaricheri, Muralidharan dev->recv = keystone2_eth_rcv_packet; 5765031ca59SVitaly Andrianov #ifdef CONFIG_MCAST_TFTP 5775031ca59SVitaly Andrianov dev->mcast = keystone2_eth_bcast_addr; 5785031ca59SVitaly Andrianov #endif 579fc9a8e8dSKaricheri, Muralidharan 580fc9a8e8dSKaricheri, Muralidharan eth_register(dev); 581fc9a8e8dSKaricheri, Muralidharan 582550c5ce6SKhoronzhuk, Ivan /* Register MDIO bus if it's not registered yet */ 583550c5ce6SKhoronzhuk, Ivan if (!mdio_bus) { 584550c5ce6SKhoronzhuk, Ivan mdio_bus = mdio_alloc(); 585550c5ce6SKhoronzhuk, Ivan mdio_bus->read = keystone2_mdio_read; 586550c5ce6SKhoronzhuk, Ivan mdio_bus->write = keystone2_mdio_write; 587550c5ce6SKhoronzhuk, Ivan mdio_bus->reset = keystone2_mdio_reset; 588550c5ce6SKhoronzhuk, Ivan mdio_bus->priv = (void *)EMAC_MDIO_BASE_ADDR; 589*192bc694SBen Whitten strcpy(mdio_bus->name, "ethernet-mdio"); 590550c5ce6SKhoronzhuk, Ivan 591550c5ce6SKhoronzhuk, Ivan res = mdio_register(mdio_bus); 592550c5ce6SKhoronzhuk, Ivan if (res) 593550c5ce6SKhoronzhuk, Ivan return res; 594550c5ce6SKhoronzhuk, Ivan } 595550c5ce6SKhoronzhuk, Ivan 5964657a2d4SVitaly Andrianov #ifndef CONFIG_SOC_K2G 597312aca4eSVitaly Andrianov keystone2_net_serdes_setup(); 5984657a2d4SVitaly Andrianov #endif 599312aca4eSVitaly Andrianov 6003fe93623SKhoronzhuk, Ivan /* Create phy device and bind it with driver */ 6013fe93623SKhoronzhuk, Ivan #ifdef CONFIG_KSNET_MDIO_PHY_CONFIG_ENABLE 6023fe93623SKhoronzhuk, Ivan phy_dev = phy_connect(mdio_bus, eth_priv->phy_addr, 603bf7bd4e7SMugunthan V N dev, eth_priv->phy_if); 6043fe93623SKhoronzhuk, Ivan phy_config(phy_dev); 6053fe93623SKhoronzhuk, Ivan #else 6063fe93623SKhoronzhuk, Ivan phy_dev = phy_find_by_mask(mdio_bus, 1 << eth_priv->phy_addr, 607bf7bd4e7SMugunthan V N eth_priv->phy_if); 6083fe93623SKhoronzhuk, Ivan phy_dev->dev = dev; 6093fe93623SKhoronzhuk, Ivan #endif 6103fe93623SKhoronzhuk, Ivan eth_priv->phy_dev = phy_dev; 6113fe93623SKhoronzhuk, Ivan 612fc9a8e8dSKaricheri, Muralidharan return 0; 613fc9a8e8dSKaricheri, Muralidharan } 614fc9a8e8dSKaricheri, Muralidharan 61592a16c81SHao Zhang struct ks2_serdes ks2_serdes_sgmii_156p25mhz = { 61692a16c81SHao Zhang .clk = SERDES_CLOCK_156P25M, 61792a16c81SHao Zhang .rate = SERDES_RATE_5G, 61892a16c81SHao Zhang .rate_mode = SERDES_QUARTER_RATE, 61992a16c81SHao Zhang .intf = SERDES_PHY_SGMII, 62092a16c81SHao Zhang .loopback = 0, 62192a16c81SHao Zhang }; 62292a16c81SHao Zhang 6234657a2d4SVitaly Andrianov #ifndef CONFIG_SOC_K2G 624a43febdeSKhoronzhuk, Ivan static void keystone2_net_serdes_setup(void) 625fc9a8e8dSKaricheri, Muralidharan { 62692a16c81SHao Zhang ks2_serdes_init(CONFIG_KSNET_SERDES_SGMII_BASE, 62792a16c81SHao Zhang &ks2_serdes_sgmii_156p25mhz, 62892a16c81SHao Zhang CONFIG_KSNET_SERDES_LANES_PER_SGMII); 62992a16c81SHao Zhang 63087ac27bdSKhoronzhuk, Ivan #if defined(CONFIG_SOC_K2E) || defined(CONFIG_SOC_K2L) 6313c61502aSKhoronzhuk, Ivan ks2_serdes_init(CONFIG_KSNET_SERDES_SGMII2_BASE, 6323c61502aSKhoronzhuk, Ivan &ks2_serdes_sgmii_156p25mhz, 6333c61502aSKhoronzhuk, Ivan CONFIG_KSNET_SERDES_LANES_PER_SGMII); 6343c61502aSKhoronzhuk, Ivan #endif 6353c61502aSKhoronzhuk, Ivan 63692a16c81SHao Zhang /* wait till setup */ 63792a16c81SHao Zhang udelay(5000); 638fc9a8e8dSKaricheri, Muralidharan } 6394657a2d4SVitaly Andrianov #endif 640