On Saturday 23 January 2016 01:45 AM, Joe Hershberger wrote: > On Fri, Jan 22, 2016 at 2:23 AM, Mugunthan V N <mugunthan...@ti.com> wrote: >> Adopt keystone_net driver to adopt device driver model >> >> Signed-off-by: Mugunthan V N <mugunthan...@ti.com> >> Reviewed-by: Tom Rini <tr...@konsulko.com> >> --- >> drivers/net/keystone_net.c | 418 >> ++++++++++++++++++++++++++++++++++++++++----- >> 1 file changed, 376 insertions(+), 42 deletions(-) >> >> diff --git a/drivers/net/keystone_net.c b/drivers/net/keystone_net.c >> index 209fae9..21ebaeb 100644 >> --- a/drivers/net/keystone_net.c >> +++ b/drivers/net/keystone_net.c >> @@ -10,6 +10,8 @@ >> #include <command.h> >> #include <console.h> >> >> +#include <dm.h> >> + >> #include <net.h> >> #include <phy.h> >> #include <errno.h> >> @@ -18,10 +20,15 @@ >> #include <asm/ti-common/keystone_nav.h> >> #include <asm/ti-common/keystone_net.h> >> #include <asm/ti-common/keystone_serdes.h> >> +#include <asm/arch/psc_defs.h> >> + >> +DECLARE_GLOBAL_DATA_PTR; >> >> +#ifndef CONFIG_DM_ETH >> unsigned int emac_open; >> static struct mii_dev *mdio_bus; >> static unsigned int sys_has_mdio = 1; >> +#endif >> >> #ifdef KEYSTONE2_EMAC_GIG_ENABLE >> #define emac_gigabit_enable(x) keystone2_eth_gigabit_enable(x) >> @@ -36,40 +43,44 @@ static unsigned int sys_has_mdio = 1; >> >> static u8 rx_buffs[RX_BUFF_NUMS * RX_BUFF_LEN] __aligned(16); >> >> +#ifndef CONFIG_DM_ETH >> struct rx_buff_desc net_rx_buffs = { >> .buff_ptr = rx_buffs, >> .num_buffs = RX_BUFF_NUMS, >> .buff_len = RX_BUFF_LEN, >> .rx_flow = 22, >> }; >> - >> -#ifndef CONFIG_SOC_K2G >> -static void keystone2_net_serdes_setup(void); >> #endif >> >> -int keystone2_eth_read_mac_addr(struct eth_device *dev) >> -{ >> - struct eth_priv_t *eth_priv; >> - u32 maca = 0; >> - u32 macb = 0; >> - >> - eth_priv = (struct eth_priv_t *)dev->priv; >> +#ifdef CONFIG_DM_ETH >> >> - /* Read the e-fuse mac address */ >> - if (eth_priv->slave_port == 1) { >> - maca = __raw_readl(MAC_ID_BASE_ADDR); >> - macb = __raw_readl(MAC_ID_BASE_ADDR + 4); >> - } >> - >> - dev->enetaddr[0] = (macb >> 8) & 0xff; >> - dev->enetaddr[1] = (macb >> 0) & 0xff; >> - dev->enetaddr[2] = (maca >> 24) & 0xff; >> - dev->enetaddr[3] = (maca >> 16) & 0xff; >> - dev->enetaddr[4] = (maca >> 8) & 0xff; >> - dev->enetaddr[5] = (maca >> 0) & 0xff; >> +enum link_type { >> + LINK_TYPE_MAC_TO_MAC_AUTO = 0, >> + LINK_TYPE_MAC_TO_PHY_MODE = 1, >> + LINK_TYPE_MAC_TO_MAC_FORCED_MODE = 2, >> + LINK_TYPE_MAC_TO_FIBRE_MODE = 3, >> + LINK_TYPE_MAC_TO_PHY_NO_MDIO_MODE = 4, >> + LINK_TYPE_10G_MAC_TO_PHY_MODE = 10, >> + LINK_TYPE_10G_MAC_TO_MAC_FORCED_MODE = 11, >> +}; >> >> - return 0; >> -} >> +struct ks2_eth_priv { >> + struct udevice *dev; >> + struct phy_device *phydev; >> + struct mii_dev *mdio_bus; >> + int phy_addr; >> + phy_interface_t phy_if; >> + int sgmii_link_type; >> + void *mdio_base; >> + struct rx_buff_desc net_rx_buffs; >> + struct pktdma_cfg *netcp_pktdma; >> + void *hd; >> + int slave_port; >> + enum link_type link_type; >> + bool emac_open; >> + bool has_mdio; >> +}; >> +#endif >> >> /* MDIO */ >> >> @@ -140,6 +151,7 @@ static int keystone2_mdio_write(struct mii_dev *bus, >> return 0; >> } >> >> +#ifndef CONFIG_DM_ETH >> static void __attribute__((unused)) >> keystone2_eth_gigabit_enable(struct eth_device *dev) >> { >> @@ -163,6 +175,31 @@ static void __attribute__((unused)) >> EMAC_MACCONTROL_GIGFORCE | EMAC_MACCONTROL_GIGABIT_ENABLE, >> DEVICE_EMACSL_BASE(eth_priv->slave_port - 1) + >> CPGMACSL_REG_CTL); >> } >> +#else >> +static void __attribute__((unused)) >> + keystone2_eth_gigabit_enable(struct udevice *dev) >> +{ >> + struct ks2_eth_priv *priv = dev_get_priv(dev); >> + u_int16_t data; >> + >> + if (priv->has_mdio) { >> + data = keystone2_mdio_read(priv->mdio_bus, priv->phy_addr, >> + MDIO_DEVAD_NONE, 0); >> + /* speed selection MSB */ >> + if (!(data & (1 << 6))) >> + return; >> + } >> + >> + /* >> + * Check if link detected is giga-bit >> + * If Gigabit mode detected, enable gigbit in MAC >> + */ >> + writel(readl(DEVICE_EMACSL_BASE(priv->slave_port - 1) + >> + CPGMACSL_REG_CTL) | >> + EMAC_MACCONTROL_GIGFORCE | EMAC_MACCONTROL_GIGABIT_ENABLE, >> + DEVICE_EMACSL_BASE(priv->slave_port - 1) + CPGMACSL_REG_CTL); >> +} >> +#endif >> >> #ifdef CONFIG_SOC_K2G >> int keystone_rgmii_config(struct phy_device *phy_dev) >> @@ -401,6 +438,58 @@ int ethss_stop(void) >> return 0; >> } >> >> +struct ks2_serdes ks2_serdes_sgmii_156p25mhz = { >> + .clk = SERDES_CLOCK_156P25M, >> + .rate = SERDES_RATE_5G, >> + .rate_mode = SERDES_QUARTER_RATE, >> + .intf = SERDES_PHY_SGMII, >> + .loopback = 0, >> +}; >> + >> +#ifndef CONFIG_SOC_K2G >> +static void keystone2_net_serdes_setup(void) >> +{ >> + ks2_serdes_init(CONFIG_KSNET_SERDES_SGMII_BASE, >> + &ks2_serdes_sgmii_156p25mhz, >> + CONFIG_KSNET_SERDES_LANES_PER_SGMII); >> + >> +#if defined(CONFIG_SOC_K2E) || defined(CONFIG_SOC_K2L) >> + ks2_serdes_init(CONFIG_KSNET_SERDES_SGMII2_BASE, >> + &ks2_serdes_sgmii_156p25mhz, >> + CONFIG_KSNET_SERDES_LANES_PER_SGMII); >> +#endif >> + >> + /* wait till setup */ >> + udelay(5000); >> +} >> +#endif >> + >> +#ifndef CONFIG_DM_ETH >> + >> +int keystone2_eth_read_mac_addr(struct eth_device *dev) >> +{ >> + struct eth_priv_t *eth_priv; >> + u32 maca = 0; >> + u32 macb = 0; >> + >> + eth_priv = (struct eth_priv_t *)dev->priv; >> + >> + /* Read the e-fuse mac address */ >> + if (eth_priv->slave_port == 1) { >> + maca = __raw_readl(MAC_ID_BASE_ADDR); >> + macb = __raw_readl(MAC_ID_BASE_ADDR + 4); >> + } >> + >> + dev->enetaddr[0] = (macb >> 8) & 0xff; >> + dev->enetaddr[1] = (macb >> 0) & 0xff; >> + dev->enetaddr[2] = (maca >> 24) & 0xff; >> + dev->enetaddr[3] = (maca >> 16) & 0xff; >> + dev->enetaddr[4] = (maca >> 8) & 0xff; >> + dev->enetaddr[5] = (maca >> 0) & 0xff; >> + >> + return 0; >> +} >> + >> int32_t cpmac_drv_send(u32 *buffer, int num_bytes, int slave_port_num) >> { >> if (num_bytes < EMAC_MIN_ETHERNET_PKT_SIZE) >> @@ -556,6 +645,7 @@ int keystone2_emac_initialize(struct eth_priv_t >> *eth_priv) >> int res; >> struct eth_device *dev; >> struct phy_device *phy_dev; >> + struct mdio_regs *adap_mdio = (struct mdio_regs >> *)EMAC_MDIO_BASE_ADDR; >> >> dev = malloc(sizeof(struct eth_device)); >> if (dev == NULL) >> @@ -612,28 +702,272 @@ int keystone2_emac_initialize(struct eth_priv_t >> *eth_priv) >> return 0; >> } >> >> -struct ks2_serdes ks2_serdes_sgmii_156p25mhz = { >> - .clk = SERDES_CLOCK_156P25M, >> - .rate = SERDES_RATE_5G, >> - .rate_mode = SERDES_QUARTER_RATE, >> - .intf = SERDES_PHY_SGMII, >> - .loopback = 0, >> -}; >> +#else >> >> -#ifndef CONFIG_SOC_K2G >> -static void keystone2_net_serdes_setup(void) >> +int keystone2_eth_read_mac_addr(struct ks2_eth_priv *priv, >> + struct eth_pdata *pdata) >> { >> - ks2_serdes_init(CONFIG_KSNET_SERDES_SGMII_BASE, >> - &ks2_serdes_sgmii_156p25mhz, >> - CONFIG_KSNET_SERDES_LANES_PER_SGMII); >> + u32 maca = 0; >> + u32 macb = 0; >> >> -#if defined(CONFIG_SOC_K2E) || defined(CONFIG_SOC_K2L) >> - ks2_serdes_init(CONFIG_KSNET_SERDES_SGMII2_BASE, >> - &ks2_serdes_sgmii_156p25mhz, >> - CONFIG_KSNET_SERDES_LANES_PER_SGMII); >> + /* Read the e-fuse mac address */ >> + if (priv->slave_port == 1) { >> + maca = __raw_readl(MAC_ID_BASE_ADDR); >> + macb = __raw_readl(MAC_ID_BASE_ADDR + 4); >> + } >> + >> + pdata->enetaddr[0] = (macb >> 8) & 0xff; >> + pdata->enetaddr[1] = (macb >> 0) & 0xff; >> + pdata->enetaddr[2] = (maca >> 24) & 0xff; >> + pdata->enetaddr[3] = (maca >> 16) & 0xff; >> + pdata->enetaddr[4] = (maca >> 8) & 0xff; >> + pdata->enetaddr[5] = (maca >> 0) & 0xff; >> + >> + return 0; >> +} >> + >> +static int ks2_eth_start(struct udevice *dev) >> +{ >> + struct ks2_eth_priv *priv = dev_get_priv(dev); >> + >> +#ifdef CONFIG_SOC_K2G >> + keystone_rgmii_config(priv->phydev); >> +#else >> + keystone_sgmii_config(priv->phydev, priv->slave_port - 1, >> + priv->sgmii_link_type); >> #endif >> >> - /* wait till setup */ >> - udelay(5000); >> + udelay(10000); >> + >> + /* On chip switch configuration */ >> + ethss_config(target_get_switch_ctl(), SWITCH_MAX_PKT_SIZE); >> + >> + qm_init(); >> + >> + if (ksnav_init(priv->netcp_pktdma, &priv->net_rx_buffs)) { >> + error("ksnav_init failed\n"); >> + goto err_knav_init; >> + } >> + >> + /* >> + * Streaming switch configuration. If not present this >> + * statement is defined to void in target.h. >> + * If present this is usually defined to a series of register writes >> + */ >> + hw_config_streaming_switch(); >> + >> + if (priv->has_mdio) { >> + phy_startup(priv->phydev); >> + if (priv->phydev->link == 0) { >> + error("phy startup failed\n"); >> + goto err_phy_start; >> + } >> + } >> + >> + emac_gigabit_enable(dev); >> + >> + ethss_start(); >> + >> + priv->emac_open = true; >> + >> + return 0; >> + >> +err_phy_start: >> + ksnav_close(priv->netcp_pktdma); >> +err_knav_init: >> + qm_close(); >> + >> + return -EFAULT; >> +} >> + >> +static int ks2_eth_send(struct udevice *dev, void *packet, int length) >> +{ >> + struct ks2_eth_priv *priv = dev_get_priv(dev); >> + >> + genphy_update_link(priv->phydev); >> + if (priv->phydev->link == 0) >> + return -1; >> + >> + if (length < EMAC_MIN_ETHERNET_PKT_SIZE) >> + length = EMAC_MIN_ETHERNET_PKT_SIZE; >> + >> + return ksnav_send(priv->netcp_pktdma, (u32 *)packet, >> + length, (priv->slave_port) << 16); >> +} >> + >> +static int ks2_eth_recv(struct udevice *dev, int flags, uchar **packetp) >> +{ >> + struct ks2_eth_priv *priv = dev_get_priv(dev); >> + int pkt_size; >> + u32 *pkt = NULL; >> + >> + priv->hd = ksnav_recv(priv->netcp_pktdma, &pkt, &pkt_size); >> + if (priv->hd == NULL) >> + return -EAGAIN; >> + >> + *packetp = (uchar *)pkt; >> + >> + return pkt_size; >> +} >> + >> +static int ks2_eth_free_pkt(struct udevice *dev, uchar *packet, >> + int length) >> +{ >> + struct ks2_eth_priv *priv = dev_get_priv(dev); >> + >> + ksnav_release_rxhd(priv->netcp_pktdma, priv->hd); >> + >> + return 0; >> +} >> + >> +static void ks2_eth_stop(struct udevice *dev) >> +{ >> + struct ks2_eth_priv *priv = dev_get_priv(dev); >> + >> + if (!priv->emac_open) >> + return; >> + ethss_stop(); >> + >> + ksnav_close(priv->netcp_pktdma); >> + qm_close(); >> + phy_shutdown(priv->phydev); >> + priv->emac_open = false; >> +} >> + >> +static int ks2_eth_probe(struct udevice *dev) >> +{ >> + struct ks2_eth_priv *priv = dev_get_priv(dev); >> + struct mii_dev *mdio_bus; >> + int ret; >> + >> + priv->dev = dev; >> + >> + /* These clock enables has to be moved to common location */ >> + if (cpu_is_k2g()) >> + writel(KS2_ETHERNET_RGMII, KS2_ETHERNET_CFG); >> + >> + /* By default, select PA PLL clock as PA clock source */ >> +#ifndef CONFIG_SOC_K2G >> + if (psc_enable_module(KS2_LPSC_PA)) >> + return -1; >> +#endif >> + if (psc_enable_module(KS2_LPSC_CPGMAC)) >> + return -1; >> + if (psc_enable_module(KS2_LPSC_CRYPTO)) >> + return -1; > > Is there not a more appropriate error code that could be used here for these > 3?
Hmmm, moved this code from board_eth_init() to here. Will add appropriate returns here in v3. > >> + >> + if (cpu_is_k2e() || cpu_is_k2l()) >> + pll_pa_clk_sel(); >> + >> + >> + priv->net_rx_buffs.buff_ptr = rx_buffs, >> + priv->net_rx_buffs.num_buffs = RX_BUFF_NUMS, >> + priv->net_rx_buffs.buff_len = RX_BUFF_LEN, >> + >> + /* Register MDIO bus */ >> + mdio_bus = mdio_alloc(); >> + if (!mdio_bus) { >> + error("MDIO alloc failed\n"); >> + return -ENOMEM; >> + } >> + priv->mdio_bus = mdio_bus; >> + mdio_bus->read = keystone2_mdio_read; >> + mdio_bus->write = keystone2_mdio_write; >> + mdio_bus->reset = keystone2_mdio_reset; >> + mdio_bus->priv = priv->mdio_base; >> + sprintf(mdio_bus->name, "ethernet-mdio"); >> + >> + ret = mdio_register(mdio_bus); >> + if (ret) { >> + error("MDIO bus register failed\n"); >> + return ret; >> + } >> + >> +#ifndef CONFIG_SOC_K2G >> + keystone2_net_serdes_setup(); >> +#endif >> + >> + priv->netcp_pktdma = &netcp_pktdma; >> + >> + priv->phydev = phy_connect(mdio_bus, priv->phy_addr, dev, >> priv->phy_if); >> + phy_config(priv->phydev); >> + >> + return 0; >> } >> + >> +static const struct eth_ops ks2_eth_ops = { >> + .start = ks2_eth_start, >> + .send = ks2_eth_send, >> + .recv = ks2_eth_recv, >> + .free_pkt = ks2_eth_free_pkt, >> + .stop = ks2_eth_stop, > > Do you not have a function to set the MAC address in the emac for > packet filtering (write_hwaddr)? Hmmm, There is a register in hardware to writing mac for packet filtering which is never implemented in this driver. Will fix it in next version. > >> +}; >> + >> + >> +static int ks2_eth_ofdata_to_platdata(struct udevice *dev) >> +{ >> + struct ks2_eth_priv *priv = dev_get_priv(dev); >> + struct eth_pdata *pdata = dev_get_platdata(dev); >> + const void *fdt = gd->fdt_blob; >> + int interfaces; >> + int interface_0; >> + int netcp_gbe_0; >> + int phy; >> + int mdio; >> + u32 dma_channel[6]; >> + >> + interfaces = fdt_subnode_offset(fdt, dev->of_offset, >> + "netcp-interfaces"); >> + interface_0 = fdt_subnode_offset(fdt, interfaces, "interface-0"); >> + >> + netcp_gbe_0 = fdtdec_lookup_phandle(fdt, interface_0, "netcp-gbe"); >> + priv->link_type = fdtdec_get_int(fdt, netcp_gbe_0, >> + "link-interface", -1); >> + priv->slave_port = fdtdec_get_int(fdt, netcp_gbe_0, "slave-port", >> -1); >> + /* U-Boot slave port number starts with 1 instead of 0 */ >> + priv->slave_port += 1; >> + >> + phy = fdtdec_lookup_phandle(fdt, netcp_gbe_0, "phy-handle"); >> + priv->phy_addr = fdtdec_get_int(fdt, phy, "reg", -1); >> + >> + mdio = fdt_parent_offset(fdt, phy); >> + if (mdio < 0) { >> + error("mdio dt not found\n"); >> + return -ENODEV; >> + } >> + priv->mdio_base = (void *)fdtdec_get_addr(fdt, mdio, "reg"); >> + >> + keystone2_eth_read_mac_addr(priv, pdata); > > Would this not be more appropriate to just set a pointer to this > function to read_rom_hwaddr in the ops structure? Okay, will move this code to read_rom_hwaddr ops. Regards Mugunthan V N _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de http://lists.denx.de/mailman/listinfo/u-boot