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> 11fc9a8e8dSKaricheri, Muralidharan 12fc9a8e8dSKaricheri, Muralidharan #include <net.h> 133fe93623SKhoronzhuk, Ivan #include <phy.h> 14c05d05e7SKhoronzhuk, Ivan #include <errno.h> 15fc9a8e8dSKaricheri, Muralidharan #include <miiphy.h> 16fc9a8e8dSKaricheri, Muralidharan #include <malloc.h> 17ef454717SKhoronzhuk, Ivan #include <asm/ti-common/keystone_nav.h> 180935cac6SKhoronzhuk, Ivan #include <asm/ti-common/keystone_net.h> 19a43febdeSKhoronzhuk, Ivan #include <asm/ti-common/keystone_serdes.h> 20fc9a8e8dSKaricheri, Muralidharan 21fc9a8e8dSKaricheri, Muralidharan unsigned int emac_open; 22550c5ce6SKhoronzhuk, Ivan static struct mii_dev *mdio_bus; 23fc9a8e8dSKaricheri, Muralidharan static unsigned int sys_has_mdio = 1; 24fc9a8e8dSKaricheri, Muralidharan 25fc9a8e8dSKaricheri, Muralidharan #ifdef KEYSTONE2_EMAC_GIG_ENABLE 26fc9a8e8dSKaricheri, Muralidharan #define emac_gigabit_enable(x) keystone2_eth_gigabit_enable(x) 27fc9a8e8dSKaricheri, Muralidharan #else 28fc9a8e8dSKaricheri, Muralidharan #define emac_gigabit_enable(x) /* no gigabit to enable */ 29fc9a8e8dSKaricheri, Muralidharan #endif 30fc9a8e8dSKaricheri, Muralidharan 31fc9a8e8dSKaricheri, Muralidharan #define RX_BUFF_NUMS 24 32fc9a8e8dSKaricheri, Muralidharan #define RX_BUFF_LEN 1520 33fc9a8e8dSKaricheri, Muralidharan #define MAX_SIZE_STREAM_BUFFER RX_BUFF_LEN 34c05d05e7SKhoronzhuk, Ivan #define SGMII_ANEG_TIMEOUT 4000 35fc9a8e8dSKaricheri, Muralidharan 36fc9a8e8dSKaricheri, Muralidharan static u8 rx_buffs[RX_BUFF_NUMS * RX_BUFF_LEN] __aligned(16); 37fc9a8e8dSKaricheri, Muralidharan 38fc9a8e8dSKaricheri, Muralidharan struct rx_buff_desc net_rx_buffs = { 39fc9a8e8dSKaricheri, Muralidharan .buff_ptr = rx_buffs, 40fc9a8e8dSKaricheri, Muralidharan .num_buffs = RX_BUFF_NUMS, 41fc9a8e8dSKaricheri, Muralidharan .buff_len = RX_BUFF_LEN, 42fc9a8e8dSKaricheri, Muralidharan .rx_flow = 22, 43fc9a8e8dSKaricheri, Muralidharan }; 44fc9a8e8dSKaricheri, Muralidharan 45*4657a2d4SVitaly Andrianov #ifndef CONFIG_SOC_K2G 46a43febdeSKhoronzhuk, Ivan static void keystone2_net_serdes_setup(void); 47*4657a2d4SVitaly Andrianov #endif 48fc9a8e8dSKaricheri, Muralidharan 49fc9a8e8dSKaricheri, Muralidharan int keystone2_eth_read_mac_addr(struct eth_device *dev) 50fc9a8e8dSKaricheri, Muralidharan { 51fc9a8e8dSKaricheri, Muralidharan struct eth_priv_t *eth_priv; 52fc9a8e8dSKaricheri, Muralidharan u32 maca = 0; 53fc9a8e8dSKaricheri, Muralidharan u32 macb = 0; 54fc9a8e8dSKaricheri, Muralidharan 55fc9a8e8dSKaricheri, Muralidharan eth_priv = (struct eth_priv_t *)dev->priv; 56fc9a8e8dSKaricheri, Muralidharan 57fc9a8e8dSKaricheri, Muralidharan /* Read the e-fuse mac address */ 58fc9a8e8dSKaricheri, Muralidharan if (eth_priv->slave_port == 1) { 59fc9a8e8dSKaricheri, Muralidharan maca = __raw_readl(MAC_ID_BASE_ADDR); 60fc9a8e8dSKaricheri, Muralidharan macb = __raw_readl(MAC_ID_BASE_ADDR + 4); 61fc9a8e8dSKaricheri, Muralidharan } 62fc9a8e8dSKaricheri, Muralidharan 63fc9a8e8dSKaricheri, Muralidharan dev->enetaddr[0] = (macb >> 8) & 0xff; 64fc9a8e8dSKaricheri, Muralidharan dev->enetaddr[1] = (macb >> 0) & 0xff; 65fc9a8e8dSKaricheri, Muralidharan dev->enetaddr[2] = (maca >> 24) & 0xff; 66fc9a8e8dSKaricheri, Muralidharan dev->enetaddr[3] = (maca >> 16) & 0xff; 67fc9a8e8dSKaricheri, Muralidharan dev->enetaddr[4] = (maca >> 8) & 0xff; 68fc9a8e8dSKaricheri, Muralidharan dev->enetaddr[5] = (maca >> 0) & 0xff; 69fc9a8e8dSKaricheri, Muralidharan 70fc9a8e8dSKaricheri, Muralidharan return 0; 71fc9a8e8dSKaricheri, Muralidharan } 72fc9a8e8dSKaricheri, Muralidharan 73550c5ce6SKhoronzhuk, Ivan /* MDIO */ 74550c5ce6SKhoronzhuk, Ivan 75550c5ce6SKhoronzhuk, Ivan static int keystone2_mdio_reset(struct mii_dev *bus) 76fc9a8e8dSKaricheri, Muralidharan { 77fc9a8e8dSKaricheri, Muralidharan u_int32_t clkdiv; 78550c5ce6SKhoronzhuk, Ivan struct mdio_regs *adap_mdio = bus->priv; 79fc9a8e8dSKaricheri, Muralidharan 80fc9a8e8dSKaricheri, Muralidharan clkdiv = (EMAC_MDIO_BUS_FREQ / EMAC_MDIO_CLOCK_FREQ) - 1; 81fc9a8e8dSKaricheri, Muralidharan 82550c5ce6SKhoronzhuk, Ivan writel((clkdiv & 0xffff) | MDIO_CONTROL_ENABLE | 83550c5ce6SKhoronzhuk, Ivan MDIO_CONTROL_FAULT | MDIO_CONTROL_FAULT_ENABLE, 84fc9a8e8dSKaricheri, Muralidharan &adap_mdio->control); 85fc9a8e8dSKaricheri, Muralidharan 86fc9a8e8dSKaricheri, Muralidharan while (readl(&adap_mdio->control) & MDIO_CONTROL_IDLE) 87fc9a8e8dSKaricheri, Muralidharan ; 88550c5ce6SKhoronzhuk, Ivan 89550c5ce6SKhoronzhuk, Ivan return 0; 90fc9a8e8dSKaricheri, Muralidharan } 91fc9a8e8dSKaricheri, Muralidharan 92550c5ce6SKhoronzhuk, Ivan /** 93550c5ce6SKhoronzhuk, Ivan * keystone2_mdio_read - read a PHY register via MDIO interface. 94550c5ce6SKhoronzhuk, Ivan * Blocks until operation is complete. 95550c5ce6SKhoronzhuk, Ivan */ 96550c5ce6SKhoronzhuk, Ivan static int keystone2_mdio_read(struct mii_dev *bus, 97550c5ce6SKhoronzhuk, Ivan int addr, int devad, int reg) 98fc9a8e8dSKaricheri, Muralidharan { 99fc9a8e8dSKaricheri, Muralidharan int tmp; 100550c5ce6SKhoronzhuk, Ivan struct mdio_regs *adap_mdio = bus->priv; 101fc9a8e8dSKaricheri, Muralidharan 102fc9a8e8dSKaricheri, Muralidharan while (readl(&adap_mdio->useraccess0) & MDIO_USERACCESS0_GO) 103fc9a8e8dSKaricheri, Muralidharan ; 104fc9a8e8dSKaricheri, Muralidharan 105550c5ce6SKhoronzhuk, Ivan writel(MDIO_USERACCESS0_GO | MDIO_USERACCESS0_WRITE_READ | 106550c5ce6SKhoronzhuk, Ivan ((reg & 0x1f) << 21) | ((addr & 0x1f) << 16), 107fc9a8e8dSKaricheri, Muralidharan &adap_mdio->useraccess0); 108fc9a8e8dSKaricheri, Muralidharan 109fc9a8e8dSKaricheri, Muralidharan /* Wait for command to complete */ 110fc9a8e8dSKaricheri, Muralidharan while ((tmp = readl(&adap_mdio->useraccess0)) & MDIO_USERACCESS0_GO) 111fc9a8e8dSKaricheri, Muralidharan ; 112fc9a8e8dSKaricheri, Muralidharan 113550c5ce6SKhoronzhuk, Ivan if (tmp & MDIO_USERACCESS0_ACK) 114550c5ce6SKhoronzhuk, Ivan return tmp & 0xffff; 115fc9a8e8dSKaricheri, Muralidharan 116fc9a8e8dSKaricheri, Muralidharan return -1; 117fc9a8e8dSKaricheri, Muralidharan } 118fc9a8e8dSKaricheri, Muralidharan 119550c5ce6SKhoronzhuk, Ivan /** 120550c5ce6SKhoronzhuk, Ivan * keystone2_mdio_write - write to a PHY register via MDIO interface. 121fc9a8e8dSKaricheri, Muralidharan * Blocks until operation is complete. 122fc9a8e8dSKaricheri, Muralidharan */ 123550c5ce6SKhoronzhuk, Ivan static int keystone2_mdio_write(struct mii_dev *bus, 124550c5ce6SKhoronzhuk, Ivan int addr, int devad, int reg, u16 val) 125fc9a8e8dSKaricheri, Muralidharan { 126550c5ce6SKhoronzhuk, Ivan struct mdio_regs *adap_mdio = bus->priv; 127550c5ce6SKhoronzhuk, Ivan 128fc9a8e8dSKaricheri, Muralidharan while (readl(&adap_mdio->useraccess0) & MDIO_USERACCESS0_GO) 129fc9a8e8dSKaricheri, Muralidharan ; 130fc9a8e8dSKaricheri, Muralidharan 131550c5ce6SKhoronzhuk, Ivan writel(MDIO_USERACCESS0_GO | MDIO_USERACCESS0_WRITE_WRITE | 132550c5ce6SKhoronzhuk, Ivan ((reg & 0x1f) << 21) | ((addr & 0x1f) << 16) | 133550c5ce6SKhoronzhuk, Ivan (val & 0xffff), &adap_mdio->useraccess0); 134fc9a8e8dSKaricheri, Muralidharan 135fc9a8e8dSKaricheri, Muralidharan /* Wait for command to complete */ 136fc9a8e8dSKaricheri, Muralidharan while (readl(&adap_mdio->useraccess0) & MDIO_USERACCESS0_GO) 137fc9a8e8dSKaricheri, Muralidharan ; 138fc9a8e8dSKaricheri, Muralidharan 139fc9a8e8dSKaricheri, Muralidharan return 0; 140fc9a8e8dSKaricheri, Muralidharan } 141fc9a8e8dSKaricheri, Muralidharan 142fc9a8e8dSKaricheri, Muralidharan static void __attribute__((unused)) 143fc9a8e8dSKaricheri, Muralidharan keystone2_eth_gigabit_enable(struct eth_device *dev) 144fc9a8e8dSKaricheri, Muralidharan { 145fc9a8e8dSKaricheri, Muralidharan u_int16_t data; 146fc9a8e8dSKaricheri, Muralidharan struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv; 147fc9a8e8dSKaricheri, Muralidharan 148fc9a8e8dSKaricheri, Muralidharan if (sys_has_mdio) { 149550c5ce6SKhoronzhuk, Ivan data = keystone2_mdio_read(mdio_bus, eth_priv->phy_addr, 150550c5ce6SKhoronzhuk, Ivan MDIO_DEVAD_NONE, 0); 151550c5ce6SKhoronzhuk, Ivan /* speed selection MSB */ 152550c5ce6SKhoronzhuk, Ivan if (!(data & (1 << 6))) 153fc9a8e8dSKaricheri, Muralidharan return; 154fc9a8e8dSKaricheri, Muralidharan } 155fc9a8e8dSKaricheri, Muralidharan 156fc9a8e8dSKaricheri, Muralidharan /* 157fc9a8e8dSKaricheri, Muralidharan * Check if link detected is giga-bit 158fc9a8e8dSKaricheri, Muralidharan * If Gigabit mode detected, enable gigbit in MAC 159fc9a8e8dSKaricheri, Muralidharan */ 160b2cfe322SHao Zhang writel(readl(DEVICE_EMACSL_BASE(eth_priv->slave_port - 1) + 161b2cfe322SHao Zhang CPGMACSL_REG_CTL) | 162fc9a8e8dSKaricheri, Muralidharan EMAC_MACCONTROL_GIGFORCE | EMAC_MACCONTROL_GIGABIT_ENABLE, 163b2cfe322SHao Zhang DEVICE_EMACSL_BASE(eth_priv->slave_port - 1) + CPGMACSL_REG_CTL); 164fc9a8e8dSKaricheri, Muralidharan } 165fc9a8e8dSKaricheri, Muralidharan 166fc9a8e8dSKaricheri, Muralidharan int keystone_sgmii_link_status(int port) 167fc9a8e8dSKaricheri, Muralidharan { 168fc9a8e8dSKaricheri, Muralidharan u32 status = 0; 169fc9a8e8dSKaricheri, Muralidharan 170fc9a8e8dSKaricheri, Muralidharan status = __raw_readl(SGMII_STATUS_REG(port)); 171fc9a8e8dSKaricheri, Muralidharan 172a4d2adeeSKhoronzhuk, Ivan return (status & SGMII_REG_STATUS_LOCK) && 173a4d2adeeSKhoronzhuk, Ivan (status & SGMII_REG_STATUS_LINK); 174fc9a8e8dSKaricheri, Muralidharan } 175fc9a8e8dSKaricheri, Muralidharan 176*4657a2d4SVitaly Andrianov #ifdef CONFIG_SOC_K2G 177*4657a2d4SVitaly Andrianov int keystone_rgmii_config(struct phy_device *phy_dev) 178*4657a2d4SVitaly Andrianov { 179*4657a2d4SVitaly Andrianov unsigned int i, status; 180*4657a2d4SVitaly Andrianov 181*4657a2d4SVitaly Andrianov i = 0; 182*4657a2d4SVitaly Andrianov do { 183*4657a2d4SVitaly Andrianov if (i > SGMII_ANEG_TIMEOUT) { 184*4657a2d4SVitaly Andrianov puts(" TIMEOUT !\n"); 185*4657a2d4SVitaly Andrianov phy_dev->link = 0; 186*4657a2d4SVitaly Andrianov return 0; 187*4657a2d4SVitaly Andrianov } 188*4657a2d4SVitaly Andrianov 189*4657a2d4SVitaly Andrianov if (ctrlc()) { 190*4657a2d4SVitaly Andrianov puts("user interrupt!\n"); 191*4657a2d4SVitaly Andrianov phy_dev->link = 0; 192*4657a2d4SVitaly Andrianov return -EINTR; 193*4657a2d4SVitaly Andrianov } 194*4657a2d4SVitaly Andrianov 195*4657a2d4SVitaly Andrianov if ((i++ % 500) == 0) 196*4657a2d4SVitaly Andrianov printf("."); 197*4657a2d4SVitaly Andrianov 198*4657a2d4SVitaly Andrianov udelay(1000); /* 1 ms */ 199*4657a2d4SVitaly Andrianov status = readl(RGMII_STATUS_REG); 200*4657a2d4SVitaly Andrianov } while (!(status & RGMII_REG_STATUS_LINK)); 201*4657a2d4SVitaly Andrianov 202*4657a2d4SVitaly Andrianov puts(" done\n"); 203*4657a2d4SVitaly Andrianov 204*4657a2d4SVitaly Andrianov return 0; 205*4657a2d4SVitaly Andrianov } 206*4657a2d4SVitaly Andrianov #else 207c05d05e7SKhoronzhuk, Ivan int keystone_sgmii_config(struct phy_device *phy_dev, int port, int interface) 208fc9a8e8dSKaricheri, Muralidharan { 209fc9a8e8dSKaricheri, Muralidharan unsigned int i, status, mask; 210fc9a8e8dSKaricheri, Muralidharan unsigned int mr_adv_ability, control; 211fc9a8e8dSKaricheri, Muralidharan 212fc9a8e8dSKaricheri, Muralidharan switch (interface) { 213fc9a8e8dSKaricheri, Muralidharan case SGMII_LINK_MAC_MAC_AUTONEG: 214fc9a8e8dSKaricheri, Muralidharan mr_adv_ability = (SGMII_REG_MR_ADV_ENABLE | 215fc9a8e8dSKaricheri, Muralidharan SGMII_REG_MR_ADV_LINK | 216fc9a8e8dSKaricheri, Muralidharan SGMII_REG_MR_ADV_FULL_DUPLEX | 217fc9a8e8dSKaricheri, Muralidharan SGMII_REG_MR_ADV_GIG_MODE); 218fc9a8e8dSKaricheri, Muralidharan control = (SGMII_REG_CONTROL_MASTER | 219fc9a8e8dSKaricheri, Muralidharan SGMII_REG_CONTROL_AUTONEG); 220fc9a8e8dSKaricheri, Muralidharan 221fc9a8e8dSKaricheri, Muralidharan break; 222fc9a8e8dSKaricheri, Muralidharan case SGMII_LINK_MAC_PHY: 223fc9a8e8dSKaricheri, Muralidharan case SGMII_LINK_MAC_PHY_FORCED: 224fc9a8e8dSKaricheri, Muralidharan mr_adv_ability = SGMII_REG_MR_ADV_ENABLE; 225fc9a8e8dSKaricheri, Muralidharan control = SGMII_REG_CONTROL_AUTONEG; 226fc9a8e8dSKaricheri, Muralidharan 227fc9a8e8dSKaricheri, Muralidharan break; 228fc9a8e8dSKaricheri, Muralidharan case SGMII_LINK_MAC_MAC_FORCED: 229fc9a8e8dSKaricheri, Muralidharan mr_adv_ability = (SGMII_REG_MR_ADV_ENABLE | 230fc9a8e8dSKaricheri, Muralidharan SGMII_REG_MR_ADV_LINK | 231fc9a8e8dSKaricheri, Muralidharan SGMII_REG_MR_ADV_FULL_DUPLEX | 232fc9a8e8dSKaricheri, Muralidharan SGMII_REG_MR_ADV_GIG_MODE); 233fc9a8e8dSKaricheri, Muralidharan control = SGMII_REG_CONTROL_MASTER; 234fc9a8e8dSKaricheri, Muralidharan 235fc9a8e8dSKaricheri, Muralidharan break; 236fc9a8e8dSKaricheri, Muralidharan case SGMII_LINK_MAC_FIBER: 237fc9a8e8dSKaricheri, Muralidharan mr_adv_ability = 0x20; 238fc9a8e8dSKaricheri, Muralidharan control = SGMII_REG_CONTROL_AUTONEG; 239fc9a8e8dSKaricheri, Muralidharan 240fc9a8e8dSKaricheri, Muralidharan break; 241fc9a8e8dSKaricheri, Muralidharan default: 242fc9a8e8dSKaricheri, Muralidharan mr_adv_ability = SGMII_REG_MR_ADV_ENABLE; 243fc9a8e8dSKaricheri, Muralidharan control = SGMII_REG_CONTROL_AUTONEG; 244fc9a8e8dSKaricheri, Muralidharan } 245fc9a8e8dSKaricheri, Muralidharan 246fc9a8e8dSKaricheri, Muralidharan __raw_writel(0, SGMII_CTL_REG(port)); 247fc9a8e8dSKaricheri, Muralidharan 248fc9a8e8dSKaricheri, Muralidharan /* 249fc9a8e8dSKaricheri, Muralidharan * Wait for the SerDes pll to lock, 250fc9a8e8dSKaricheri, Muralidharan * but don't trap if lock is never read 251fc9a8e8dSKaricheri, Muralidharan */ 252fc9a8e8dSKaricheri, Muralidharan for (i = 0; i < 1000; i++) { 253fc9a8e8dSKaricheri, Muralidharan udelay(2000); 254fc9a8e8dSKaricheri, Muralidharan status = __raw_readl(SGMII_STATUS_REG(port)); 255fc9a8e8dSKaricheri, Muralidharan if ((status & SGMII_REG_STATUS_LOCK) != 0) 256fc9a8e8dSKaricheri, Muralidharan break; 257fc9a8e8dSKaricheri, Muralidharan } 258fc9a8e8dSKaricheri, Muralidharan 259fc9a8e8dSKaricheri, Muralidharan __raw_writel(mr_adv_ability, SGMII_MRADV_REG(port)); 260fc9a8e8dSKaricheri, Muralidharan __raw_writel(control, SGMII_CTL_REG(port)); 261fc9a8e8dSKaricheri, Muralidharan 262fc9a8e8dSKaricheri, Muralidharan 263fc9a8e8dSKaricheri, Muralidharan mask = SGMII_REG_STATUS_LINK; 264fc9a8e8dSKaricheri, Muralidharan 265fc9a8e8dSKaricheri, Muralidharan if (control & SGMII_REG_CONTROL_AUTONEG) 266fc9a8e8dSKaricheri, Muralidharan mask |= SGMII_REG_STATUS_AUTONEG; 267fc9a8e8dSKaricheri, Muralidharan 268fc9a8e8dSKaricheri, Muralidharan status = __raw_readl(SGMII_STATUS_REG(port)); 269fc9a8e8dSKaricheri, Muralidharan if ((status & mask) == mask) 270c05d05e7SKhoronzhuk, Ivan return 0; 271c05d05e7SKhoronzhuk, Ivan 272c05d05e7SKhoronzhuk, Ivan printf("\n%s Waiting for SGMII auto negotiation to complete", 273c05d05e7SKhoronzhuk, Ivan phy_dev->dev->name); 274c05d05e7SKhoronzhuk, Ivan while ((status & mask) != mask) { 275c05d05e7SKhoronzhuk, Ivan /* 276c05d05e7SKhoronzhuk, Ivan * Timeout reached ? 277c05d05e7SKhoronzhuk, Ivan */ 278c05d05e7SKhoronzhuk, Ivan if (i > SGMII_ANEG_TIMEOUT) { 279c05d05e7SKhoronzhuk, Ivan puts(" TIMEOUT !\n"); 280c05d05e7SKhoronzhuk, Ivan phy_dev->link = 0; 281c05d05e7SKhoronzhuk, Ivan return 0; 282fc9a8e8dSKaricheri, Muralidharan } 283fc9a8e8dSKaricheri, Muralidharan 284c05d05e7SKhoronzhuk, Ivan if (ctrlc()) { 285c05d05e7SKhoronzhuk, Ivan puts("user interrupt!\n"); 286c05d05e7SKhoronzhuk, Ivan phy_dev->link = 0; 287c05d05e7SKhoronzhuk, Ivan return -EINTR; 288c05d05e7SKhoronzhuk, Ivan } 289c05d05e7SKhoronzhuk, Ivan 290c05d05e7SKhoronzhuk, Ivan if ((i++ % 500) == 0) 291c05d05e7SKhoronzhuk, Ivan printf("."); 292c05d05e7SKhoronzhuk, Ivan 293c05d05e7SKhoronzhuk, Ivan udelay(1000); /* 1 ms */ 294c05d05e7SKhoronzhuk, Ivan status = __raw_readl(SGMII_STATUS_REG(port)); 295c05d05e7SKhoronzhuk, Ivan } 296c05d05e7SKhoronzhuk, Ivan puts(" done\n"); 297c05d05e7SKhoronzhuk, Ivan 298fc9a8e8dSKaricheri, Muralidharan return 0; 299fc9a8e8dSKaricheri, Muralidharan } 300*4657a2d4SVitaly Andrianov #endif 301fc9a8e8dSKaricheri, Muralidharan 302fc9a8e8dSKaricheri, Muralidharan int mac_sl_reset(u32 port) 303fc9a8e8dSKaricheri, Muralidharan { 304fc9a8e8dSKaricheri, Muralidharan u32 i, v; 305fc9a8e8dSKaricheri, Muralidharan 306fc9a8e8dSKaricheri, Muralidharan if (port >= DEVICE_N_GMACSL_PORTS) 307fc9a8e8dSKaricheri, Muralidharan return GMACSL_RET_INVALID_PORT; 308fc9a8e8dSKaricheri, Muralidharan 309fc9a8e8dSKaricheri, Muralidharan /* Set the soft reset bit */ 310e6c9428aSKhoronzhuk, Ivan writel(CPGMAC_REG_RESET_VAL_RESET, 311e6c9428aSKhoronzhuk, Ivan DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_RESET); 312fc9a8e8dSKaricheri, Muralidharan 313fc9a8e8dSKaricheri, Muralidharan /* Wait for the bit to clear */ 314fc9a8e8dSKaricheri, Muralidharan for (i = 0; i < DEVICE_EMACSL_RESET_POLL_COUNT; i++) { 315e6c9428aSKhoronzhuk, Ivan v = readl(DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_RESET); 316fc9a8e8dSKaricheri, Muralidharan if ((v & CPGMAC_REG_RESET_VAL_RESET_MASK) != 317fc9a8e8dSKaricheri, Muralidharan CPGMAC_REG_RESET_VAL_RESET) 318fc9a8e8dSKaricheri, Muralidharan return GMACSL_RET_OK; 319fc9a8e8dSKaricheri, Muralidharan } 320fc9a8e8dSKaricheri, Muralidharan 321fc9a8e8dSKaricheri, Muralidharan /* Timeout on the reset */ 322fc9a8e8dSKaricheri, Muralidharan return GMACSL_RET_WARN_RESET_INCOMPLETE; 323fc9a8e8dSKaricheri, Muralidharan } 324fc9a8e8dSKaricheri, Muralidharan 325fc9a8e8dSKaricheri, Muralidharan int mac_sl_config(u_int16_t port, struct mac_sl_cfg *cfg) 326fc9a8e8dSKaricheri, Muralidharan { 327fc9a8e8dSKaricheri, Muralidharan u32 v, i; 328fc9a8e8dSKaricheri, Muralidharan int ret = GMACSL_RET_OK; 329fc9a8e8dSKaricheri, Muralidharan 330fc9a8e8dSKaricheri, Muralidharan if (port >= DEVICE_N_GMACSL_PORTS) 331fc9a8e8dSKaricheri, Muralidharan return GMACSL_RET_INVALID_PORT; 332fc9a8e8dSKaricheri, Muralidharan 333fc9a8e8dSKaricheri, Muralidharan if (cfg->max_rx_len > CPGMAC_REG_MAXLEN_LEN) { 334fc9a8e8dSKaricheri, Muralidharan cfg->max_rx_len = CPGMAC_REG_MAXLEN_LEN; 335fc9a8e8dSKaricheri, Muralidharan ret = GMACSL_RET_WARN_MAXLEN_TOO_BIG; 336fc9a8e8dSKaricheri, Muralidharan } 337fc9a8e8dSKaricheri, Muralidharan 338fc9a8e8dSKaricheri, Muralidharan /* Must wait if the device is undergoing reset */ 339fc9a8e8dSKaricheri, Muralidharan for (i = 0; i < DEVICE_EMACSL_RESET_POLL_COUNT; i++) { 340e6c9428aSKhoronzhuk, Ivan v = readl(DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_RESET); 341fc9a8e8dSKaricheri, Muralidharan if ((v & CPGMAC_REG_RESET_VAL_RESET_MASK) != 342fc9a8e8dSKaricheri, Muralidharan CPGMAC_REG_RESET_VAL_RESET) 343fc9a8e8dSKaricheri, Muralidharan break; 344fc9a8e8dSKaricheri, Muralidharan } 345fc9a8e8dSKaricheri, Muralidharan 346fc9a8e8dSKaricheri, Muralidharan if (i == DEVICE_EMACSL_RESET_POLL_COUNT) 347fc9a8e8dSKaricheri, Muralidharan return GMACSL_RET_CONFIG_FAIL_RESET_ACTIVE; 348fc9a8e8dSKaricheri, Muralidharan 349e6c9428aSKhoronzhuk, Ivan writel(cfg->max_rx_len, DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_MAXLEN); 350e6c9428aSKhoronzhuk, Ivan writel(cfg->ctl, DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_CTL); 351fc9a8e8dSKaricheri, Muralidharan 352*4657a2d4SVitaly Andrianov #ifndef CONFIG_SOC_K2HK 353ff11c769SKhoronzhuk, Ivan /* Map RX packet flow priority to 0 */ 354ff11c769SKhoronzhuk, Ivan writel(0, DEVICE_EMACSL_BASE(port) + CPGMACSL_REG_RX_PRI_MAP); 355ff11c769SKhoronzhuk, Ivan #endif 356ff11c769SKhoronzhuk, Ivan 357fc9a8e8dSKaricheri, Muralidharan return ret; 358fc9a8e8dSKaricheri, Muralidharan } 359fc9a8e8dSKaricheri, Muralidharan 360fc9a8e8dSKaricheri, Muralidharan int ethss_config(u32 ctl, u32 max_pkt_size) 361fc9a8e8dSKaricheri, Muralidharan { 362fc9a8e8dSKaricheri, Muralidharan u32 i; 363fc9a8e8dSKaricheri, Muralidharan 364fc9a8e8dSKaricheri, Muralidharan /* Max length register */ 365e6c9428aSKhoronzhuk, Ivan writel(max_pkt_size, DEVICE_CPSW_BASE + CPSW_REG_MAXLEN); 366fc9a8e8dSKaricheri, Muralidharan 367fc9a8e8dSKaricheri, Muralidharan /* Control register */ 368e6c9428aSKhoronzhuk, Ivan writel(ctl, DEVICE_CPSW_BASE + CPSW_REG_CTL); 369fc9a8e8dSKaricheri, Muralidharan 370fc9a8e8dSKaricheri, Muralidharan /* All statistics enabled by default */ 371e6c9428aSKhoronzhuk, Ivan writel(CPSW_REG_VAL_STAT_ENABLE_ALL, 372e6c9428aSKhoronzhuk, Ivan DEVICE_CPSW_BASE + CPSW_REG_STAT_PORT_EN); 373fc9a8e8dSKaricheri, Muralidharan 374fc9a8e8dSKaricheri, Muralidharan /* Reset and enable the ALE */ 375e6c9428aSKhoronzhuk, Ivan writel(CPSW_REG_VAL_ALE_CTL_RESET_AND_ENABLE | 376e6c9428aSKhoronzhuk, Ivan CPSW_REG_VAL_ALE_CTL_BYPASS, 377e6c9428aSKhoronzhuk, Ivan DEVICE_CPSW_BASE + CPSW_REG_ALE_CONTROL); 378fc9a8e8dSKaricheri, Muralidharan 379fc9a8e8dSKaricheri, Muralidharan /* All ports put into forward mode */ 380fc9a8e8dSKaricheri, Muralidharan for (i = 0; i < DEVICE_CPSW_NUM_PORTS; i++) 381e6c9428aSKhoronzhuk, Ivan writel(CPSW_REG_VAL_PORTCTL_FORWARD_MODE, 382e6c9428aSKhoronzhuk, Ivan DEVICE_CPSW_BASE + CPSW_REG_ALE_PORTCTL(i)); 383fc9a8e8dSKaricheri, Muralidharan 384fc9a8e8dSKaricheri, Muralidharan return 0; 385fc9a8e8dSKaricheri, Muralidharan } 386fc9a8e8dSKaricheri, Muralidharan 387fc9a8e8dSKaricheri, Muralidharan int ethss_start(void) 388fc9a8e8dSKaricheri, Muralidharan { 389fc9a8e8dSKaricheri, Muralidharan int i; 390fc9a8e8dSKaricheri, Muralidharan struct mac_sl_cfg cfg; 391fc9a8e8dSKaricheri, Muralidharan 392fc9a8e8dSKaricheri, Muralidharan cfg.max_rx_len = MAX_SIZE_STREAM_BUFFER; 393fc9a8e8dSKaricheri, Muralidharan cfg.ctl = GMACSL_ENABLE | GMACSL_RX_ENABLE_EXT_CTL; 394fc9a8e8dSKaricheri, Muralidharan 395fc9a8e8dSKaricheri, Muralidharan for (i = 0; i < DEVICE_N_GMACSL_PORTS; i++) { 396fc9a8e8dSKaricheri, Muralidharan mac_sl_reset(i); 397fc9a8e8dSKaricheri, Muralidharan mac_sl_config(i, &cfg); 398fc9a8e8dSKaricheri, Muralidharan } 399fc9a8e8dSKaricheri, Muralidharan 400fc9a8e8dSKaricheri, Muralidharan return 0; 401fc9a8e8dSKaricheri, Muralidharan } 402fc9a8e8dSKaricheri, Muralidharan 403fc9a8e8dSKaricheri, Muralidharan int ethss_stop(void) 404fc9a8e8dSKaricheri, Muralidharan { 405fc9a8e8dSKaricheri, Muralidharan int i; 406fc9a8e8dSKaricheri, Muralidharan 407fc9a8e8dSKaricheri, Muralidharan for (i = 0; i < DEVICE_N_GMACSL_PORTS; i++) 408fc9a8e8dSKaricheri, Muralidharan mac_sl_reset(i); 409fc9a8e8dSKaricheri, Muralidharan 410fc9a8e8dSKaricheri, Muralidharan return 0; 411fc9a8e8dSKaricheri, Muralidharan } 412fc9a8e8dSKaricheri, Muralidharan 413fc9a8e8dSKaricheri, Muralidharan int32_t cpmac_drv_send(u32 *buffer, int num_bytes, int slave_port_num) 414fc9a8e8dSKaricheri, Muralidharan { 415fc9a8e8dSKaricheri, Muralidharan if (num_bytes < EMAC_MIN_ETHERNET_PKT_SIZE) 416fc9a8e8dSKaricheri, Muralidharan num_bytes = EMAC_MIN_ETHERNET_PKT_SIZE; 417fc9a8e8dSKaricheri, Muralidharan 4189ea9021aSKhoronzhuk, Ivan return ksnav_send(&netcp_pktdma, buffer, 4199ea9021aSKhoronzhuk, Ivan num_bytes, (slave_port_num) << 16); 420fc9a8e8dSKaricheri, Muralidharan } 421fc9a8e8dSKaricheri, Muralidharan 422fc9a8e8dSKaricheri, Muralidharan /* Eth device open */ 423fc9a8e8dSKaricheri, Muralidharan static int keystone2_eth_open(struct eth_device *dev, bd_t *bis) 424fc9a8e8dSKaricheri, Muralidharan { 425fc9a8e8dSKaricheri, Muralidharan struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv; 4263fe93623SKhoronzhuk, Ivan struct phy_device *phy_dev = eth_priv->phy_dev; 427fc9a8e8dSKaricheri, Muralidharan 428fc9a8e8dSKaricheri, Muralidharan debug("+ emac_open\n"); 429fc9a8e8dSKaricheri, Muralidharan 430fc9a8e8dSKaricheri, Muralidharan net_rx_buffs.rx_flow = eth_priv->rx_flow; 431fc9a8e8dSKaricheri, Muralidharan 432fc9a8e8dSKaricheri, Muralidharan sys_has_mdio = 433fc9a8e8dSKaricheri, Muralidharan (eth_priv->sgmii_link_type == SGMII_LINK_MAC_PHY) ? 1 : 0; 434fc9a8e8dSKaricheri, Muralidharan 4356c0fb41aSKhoronzhuk, Ivan if (sys_has_mdio) 4366c0fb41aSKhoronzhuk, Ivan keystone2_mdio_reset(mdio_bus); 4376c0fb41aSKhoronzhuk, Ivan 438*4657a2d4SVitaly Andrianov #ifdef CONFIG_SOC_K2G 439*4657a2d4SVitaly Andrianov keystone_rgmii_config(phy_dev); 440*4657a2d4SVitaly Andrianov #else 441c05d05e7SKhoronzhuk, Ivan keystone_sgmii_config(phy_dev, eth_priv->slave_port - 1, 442fc9a8e8dSKaricheri, Muralidharan eth_priv->sgmii_link_type); 443*4657a2d4SVitaly Andrianov #endif 444fc9a8e8dSKaricheri, Muralidharan 445fc9a8e8dSKaricheri, Muralidharan udelay(10000); 446fc9a8e8dSKaricheri, Muralidharan 447fc9a8e8dSKaricheri, Muralidharan /* On chip switch configuration */ 448fc9a8e8dSKaricheri, Muralidharan ethss_config(target_get_switch_ctl(), SWITCH_MAX_PKT_SIZE); 449fc9a8e8dSKaricheri, Muralidharan 450fc9a8e8dSKaricheri, Muralidharan /* TODO: add error handling code */ 451fc9a8e8dSKaricheri, Muralidharan if (qm_init()) { 452fc9a8e8dSKaricheri, Muralidharan printf("ERROR: qm_init()\n"); 453fc9a8e8dSKaricheri, Muralidharan return -1; 454fc9a8e8dSKaricheri, Muralidharan } 4559ea9021aSKhoronzhuk, Ivan if (ksnav_init(&netcp_pktdma, &net_rx_buffs)) { 456fc9a8e8dSKaricheri, Muralidharan qm_close(); 457fc9a8e8dSKaricheri, Muralidharan printf("ERROR: netcp_init()\n"); 458fc9a8e8dSKaricheri, Muralidharan return -1; 459fc9a8e8dSKaricheri, Muralidharan } 460fc9a8e8dSKaricheri, Muralidharan 461fc9a8e8dSKaricheri, Muralidharan /* 462fc9a8e8dSKaricheri, Muralidharan * Streaming switch configuration. If not present this 463fc9a8e8dSKaricheri, Muralidharan * statement is defined to void in target.h. 464fc9a8e8dSKaricheri, Muralidharan * If present this is usually defined to a series of register writes 465fc9a8e8dSKaricheri, Muralidharan */ 466fc9a8e8dSKaricheri, Muralidharan hw_config_streaming_switch(); 467fc9a8e8dSKaricheri, Muralidharan 468fc9a8e8dSKaricheri, Muralidharan if (sys_has_mdio) { 469550c5ce6SKhoronzhuk, Ivan keystone2_mdio_reset(mdio_bus); 470fc9a8e8dSKaricheri, Muralidharan 4713fe93623SKhoronzhuk, Ivan phy_startup(phy_dev); 4723fe93623SKhoronzhuk, Ivan if (phy_dev->link == 0) { 4739ea9021aSKhoronzhuk, Ivan ksnav_close(&netcp_pktdma); 474fc9a8e8dSKaricheri, Muralidharan qm_close(); 475fc9a8e8dSKaricheri, Muralidharan return -1; 476fc9a8e8dSKaricheri, Muralidharan } 477fc9a8e8dSKaricheri, Muralidharan } 478fc9a8e8dSKaricheri, Muralidharan 479fc9a8e8dSKaricheri, Muralidharan emac_gigabit_enable(dev); 480fc9a8e8dSKaricheri, Muralidharan 481fc9a8e8dSKaricheri, Muralidharan ethss_start(); 482fc9a8e8dSKaricheri, Muralidharan 483fc9a8e8dSKaricheri, Muralidharan debug("- emac_open\n"); 484fc9a8e8dSKaricheri, Muralidharan 485fc9a8e8dSKaricheri, Muralidharan emac_open = 1; 486fc9a8e8dSKaricheri, Muralidharan 487fc9a8e8dSKaricheri, Muralidharan return 0; 488fc9a8e8dSKaricheri, Muralidharan } 489fc9a8e8dSKaricheri, Muralidharan 490fc9a8e8dSKaricheri, Muralidharan /* Eth device close */ 491fc9a8e8dSKaricheri, Muralidharan void keystone2_eth_close(struct eth_device *dev) 492fc9a8e8dSKaricheri, Muralidharan { 4933fe93623SKhoronzhuk, Ivan struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv; 4943fe93623SKhoronzhuk, Ivan struct phy_device *phy_dev = eth_priv->phy_dev; 4953fe93623SKhoronzhuk, Ivan 496fc9a8e8dSKaricheri, Muralidharan debug("+ emac_close\n"); 497fc9a8e8dSKaricheri, Muralidharan 498fc9a8e8dSKaricheri, Muralidharan if (!emac_open) 499fc9a8e8dSKaricheri, Muralidharan return; 500fc9a8e8dSKaricheri, Muralidharan 501fc9a8e8dSKaricheri, Muralidharan ethss_stop(); 502fc9a8e8dSKaricheri, Muralidharan 5039ea9021aSKhoronzhuk, Ivan ksnav_close(&netcp_pktdma); 504fc9a8e8dSKaricheri, Muralidharan qm_close(); 5053fe93623SKhoronzhuk, Ivan phy_shutdown(phy_dev); 506fc9a8e8dSKaricheri, Muralidharan 507fc9a8e8dSKaricheri, Muralidharan emac_open = 0; 508fc9a8e8dSKaricheri, Muralidharan 509fc9a8e8dSKaricheri, Muralidharan debug("- emac_close\n"); 510fc9a8e8dSKaricheri, Muralidharan } 511fc9a8e8dSKaricheri, Muralidharan 512fc9a8e8dSKaricheri, Muralidharan /* 513fc9a8e8dSKaricheri, Muralidharan * This function sends a single packet on the network and returns 514fc9a8e8dSKaricheri, Muralidharan * positive number (number of bytes transmitted) or negative for error 515fc9a8e8dSKaricheri, Muralidharan */ 516fc9a8e8dSKaricheri, Muralidharan static int keystone2_eth_send_packet(struct eth_device *dev, 517fc9a8e8dSKaricheri, Muralidharan void *packet, int length) 518fc9a8e8dSKaricheri, Muralidharan { 519fc9a8e8dSKaricheri, Muralidharan int ret_status = -1; 520fc9a8e8dSKaricheri, Muralidharan struct eth_priv_t *eth_priv = (struct eth_priv_t *)dev->priv; 521a4d2adeeSKhoronzhuk, Ivan struct phy_device *phy_dev = eth_priv->phy_dev; 522fc9a8e8dSKaricheri, Muralidharan 523a4d2adeeSKhoronzhuk, Ivan genphy_update_link(phy_dev); 524a4d2adeeSKhoronzhuk, Ivan if (phy_dev->link == 0) 525fc9a8e8dSKaricheri, Muralidharan return -1; 526fc9a8e8dSKaricheri, Muralidharan 527fc9a8e8dSKaricheri, Muralidharan if (cpmac_drv_send((u32 *)packet, length, eth_priv->slave_port) != 0) 528fc9a8e8dSKaricheri, Muralidharan return ret_status; 529fc9a8e8dSKaricheri, Muralidharan 530fc9a8e8dSKaricheri, Muralidharan return length; 531fc9a8e8dSKaricheri, Muralidharan } 532fc9a8e8dSKaricheri, Muralidharan 533fc9a8e8dSKaricheri, Muralidharan /* 534fc9a8e8dSKaricheri, Muralidharan * This function handles receipt of a packet from the network 535fc9a8e8dSKaricheri, Muralidharan */ 536fc9a8e8dSKaricheri, Muralidharan static int keystone2_eth_rcv_packet(struct eth_device *dev) 537fc9a8e8dSKaricheri, Muralidharan { 538fc9a8e8dSKaricheri, Muralidharan void *hd; 539fc9a8e8dSKaricheri, Muralidharan int pkt_size; 540fc9a8e8dSKaricheri, Muralidharan u32 *pkt; 541fc9a8e8dSKaricheri, Muralidharan 5429ea9021aSKhoronzhuk, Ivan hd = ksnav_recv(&netcp_pktdma, &pkt, &pkt_size); 543fc9a8e8dSKaricheri, Muralidharan if (hd == NULL) 544fc9a8e8dSKaricheri, Muralidharan return 0; 545fc9a8e8dSKaricheri, Muralidharan 5461fd92db8SJoe Hershberger net_process_received_packet((uchar *)pkt, pkt_size); 547fc9a8e8dSKaricheri, Muralidharan 5489ea9021aSKhoronzhuk, Ivan ksnav_release_rxhd(&netcp_pktdma, hd); 549fc9a8e8dSKaricheri, Muralidharan 550fc9a8e8dSKaricheri, Muralidharan return pkt_size; 551fc9a8e8dSKaricheri, Muralidharan } 552fc9a8e8dSKaricheri, Muralidharan 5535031ca59SVitaly Andrianov #ifdef CONFIG_MCAST_TFTP 5545031ca59SVitaly Andrianov static int keystone2_eth_bcast_addr(struct eth_device *dev, u32 ip, u8 set) 5555031ca59SVitaly Andrianov { 5565031ca59SVitaly Andrianov return 0; 5575031ca59SVitaly Andrianov } 5585031ca59SVitaly Andrianov #endif 5595031ca59SVitaly Andrianov 560fc9a8e8dSKaricheri, Muralidharan /* 561fc9a8e8dSKaricheri, Muralidharan * This function initializes the EMAC hardware. 562fc9a8e8dSKaricheri, Muralidharan */ 563fc9a8e8dSKaricheri, Muralidharan int keystone2_emac_initialize(struct eth_priv_t *eth_priv) 564fc9a8e8dSKaricheri, Muralidharan { 565550c5ce6SKhoronzhuk, Ivan int res; 566fc9a8e8dSKaricheri, Muralidharan struct eth_device *dev; 5673fe93623SKhoronzhuk, Ivan struct phy_device *phy_dev; 568fc9a8e8dSKaricheri, Muralidharan 569fc9a8e8dSKaricheri, Muralidharan dev = malloc(sizeof(struct eth_device)); 570fc9a8e8dSKaricheri, Muralidharan if (dev == NULL) 571fc9a8e8dSKaricheri, Muralidharan return -1; 572fc9a8e8dSKaricheri, Muralidharan 573fc9a8e8dSKaricheri, Muralidharan memset(dev, 0, sizeof(struct eth_device)); 574fc9a8e8dSKaricheri, Muralidharan 575fc9a8e8dSKaricheri, Muralidharan strcpy(dev->name, eth_priv->int_name); 576fc9a8e8dSKaricheri, Muralidharan dev->priv = eth_priv; 577fc9a8e8dSKaricheri, Muralidharan 578fc9a8e8dSKaricheri, Muralidharan keystone2_eth_read_mac_addr(dev); 579fc9a8e8dSKaricheri, Muralidharan 580fc9a8e8dSKaricheri, Muralidharan dev->iobase = 0; 581fc9a8e8dSKaricheri, Muralidharan dev->init = keystone2_eth_open; 582fc9a8e8dSKaricheri, Muralidharan dev->halt = keystone2_eth_close; 583fc9a8e8dSKaricheri, Muralidharan dev->send = keystone2_eth_send_packet; 584fc9a8e8dSKaricheri, Muralidharan dev->recv = keystone2_eth_rcv_packet; 5855031ca59SVitaly Andrianov #ifdef CONFIG_MCAST_TFTP 5865031ca59SVitaly Andrianov dev->mcast = keystone2_eth_bcast_addr; 5875031ca59SVitaly Andrianov #endif 588fc9a8e8dSKaricheri, Muralidharan 589fc9a8e8dSKaricheri, Muralidharan eth_register(dev); 590fc9a8e8dSKaricheri, Muralidharan 591550c5ce6SKhoronzhuk, Ivan /* Register MDIO bus if it's not registered yet */ 592550c5ce6SKhoronzhuk, Ivan if (!mdio_bus) { 593550c5ce6SKhoronzhuk, Ivan mdio_bus = mdio_alloc(); 594550c5ce6SKhoronzhuk, Ivan mdio_bus->read = keystone2_mdio_read; 595550c5ce6SKhoronzhuk, Ivan mdio_bus->write = keystone2_mdio_write; 596550c5ce6SKhoronzhuk, Ivan mdio_bus->reset = keystone2_mdio_reset; 597550c5ce6SKhoronzhuk, Ivan mdio_bus->priv = (void *)EMAC_MDIO_BASE_ADDR; 598550c5ce6SKhoronzhuk, Ivan sprintf(mdio_bus->name, "ethernet-mdio"); 599550c5ce6SKhoronzhuk, Ivan 600550c5ce6SKhoronzhuk, Ivan res = mdio_register(mdio_bus); 601550c5ce6SKhoronzhuk, Ivan if (res) 602550c5ce6SKhoronzhuk, Ivan return res; 603550c5ce6SKhoronzhuk, Ivan } 604550c5ce6SKhoronzhuk, Ivan 605*4657a2d4SVitaly Andrianov #ifndef CONFIG_SOC_K2G 606312aca4eSVitaly Andrianov keystone2_net_serdes_setup(); 607*4657a2d4SVitaly Andrianov #endif 608312aca4eSVitaly Andrianov 6093fe93623SKhoronzhuk, Ivan /* Create phy device and bind it with driver */ 6103fe93623SKhoronzhuk, Ivan #ifdef CONFIG_KSNET_MDIO_PHY_CONFIG_ENABLE 6113fe93623SKhoronzhuk, Ivan phy_dev = phy_connect(mdio_bus, eth_priv->phy_addr, 612bf7bd4e7SMugunthan V N dev, eth_priv->phy_if); 6133fe93623SKhoronzhuk, Ivan phy_config(phy_dev); 6143fe93623SKhoronzhuk, Ivan #else 6153fe93623SKhoronzhuk, Ivan phy_dev = phy_find_by_mask(mdio_bus, 1 << eth_priv->phy_addr, 616bf7bd4e7SMugunthan V N eth_priv->phy_if); 6173fe93623SKhoronzhuk, Ivan phy_dev->dev = dev; 6183fe93623SKhoronzhuk, Ivan #endif 6193fe93623SKhoronzhuk, Ivan eth_priv->phy_dev = phy_dev; 6203fe93623SKhoronzhuk, Ivan 621fc9a8e8dSKaricheri, Muralidharan return 0; 622fc9a8e8dSKaricheri, Muralidharan } 623fc9a8e8dSKaricheri, Muralidharan 62492a16c81SHao Zhang struct ks2_serdes ks2_serdes_sgmii_156p25mhz = { 62592a16c81SHao Zhang .clk = SERDES_CLOCK_156P25M, 62692a16c81SHao Zhang .rate = SERDES_RATE_5G, 62792a16c81SHao Zhang .rate_mode = SERDES_QUARTER_RATE, 62892a16c81SHao Zhang .intf = SERDES_PHY_SGMII, 62992a16c81SHao Zhang .loopback = 0, 63092a16c81SHao Zhang }; 63192a16c81SHao Zhang 632*4657a2d4SVitaly Andrianov #ifndef CONFIG_SOC_K2G 633a43febdeSKhoronzhuk, Ivan static void keystone2_net_serdes_setup(void) 634fc9a8e8dSKaricheri, Muralidharan { 63592a16c81SHao Zhang ks2_serdes_init(CONFIG_KSNET_SERDES_SGMII_BASE, 63692a16c81SHao Zhang &ks2_serdes_sgmii_156p25mhz, 63792a16c81SHao Zhang CONFIG_KSNET_SERDES_LANES_PER_SGMII); 63892a16c81SHao Zhang 63987ac27bdSKhoronzhuk, Ivan #if defined(CONFIG_SOC_K2E) || defined(CONFIG_SOC_K2L) 6403c61502aSKhoronzhuk, Ivan ks2_serdes_init(CONFIG_KSNET_SERDES_SGMII2_BASE, 6413c61502aSKhoronzhuk, Ivan &ks2_serdes_sgmii_156p25mhz, 6423c61502aSKhoronzhuk, Ivan CONFIG_KSNET_SERDES_LANES_PER_SGMII); 6433c61502aSKhoronzhuk, Ivan #endif 6443c61502aSKhoronzhuk, Ivan 64592a16c81SHao Zhang /* wait till setup */ 64692a16c81SHao Zhang udelay(5000); 647fc9a8e8dSKaricheri, Muralidharan } 648*4657a2d4SVitaly Andrianov #endif 649