Lines Matching +full:mac +full:- +full:clk +full:- +full:tx
4 * Copyright 2012-2013 Stefan Roese <sr@denx.de>
5 * Copyright 2013 Maxime Ripard <maxime.ripard@free-electrons.com>
15 #include <linux/clk.h>
33 #include "sun4i-emac.h"
35 #define DRV_NAME "sun4i-emac"
40 static int debug = -1; /* defaults above */;
72 struct clk *clk; member
98 reg_val = readl(db->membase + EMAC_MAC_SUPP_REG); in emac_update_speed()
100 if (db->speed == SPEED_100) in emac_update_speed()
102 writel(reg_val, db->membase + EMAC_MAC_SUPP_REG); in emac_update_speed()
111 reg_val = readl(db->membase + EMAC_MAC_CTL1_REG); in emac_update_duplex()
113 if (db->duplex) in emac_update_duplex()
115 writel(reg_val, db->membase + EMAC_MAC_CTL1_REG); in emac_update_duplex()
121 struct phy_device *phydev = dev->phydev; in emac_handle_link_change()
125 if (phydev->link) { in emac_handle_link_change()
126 if (db->speed != phydev->speed) { in emac_handle_link_change()
127 spin_lock_irqsave(&db->lock, flags); in emac_handle_link_change()
128 db->speed = phydev->speed; in emac_handle_link_change()
130 spin_unlock_irqrestore(&db->lock, flags); in emac_handle_link_change()
134 if (db->duplex != phydev->duplex) { in emac_handle_link_change()
135 spin_lock_irqsave(&db->lock, flags); in emac_handle_link_change()
136 db->duplex = phydev->duplex; in emac_handle_link_change()
138 spin_unlock_irqrestore(&db->lock, flags); in emac_handle_link_change()
143 if (phydev->link != db->link) { in emac_handle_link_change()
144 if (!phydev->link) { in emac_handle_link_change()
145 db->speed = 0; in emac_handle_link_change()
146 db->duplex = -1; in emac_handle_link_change()
148 db->link = phydev->link; in emac_handle_link_change()
162 /* to-do: PHY interrupts are currently not supported */ in emac_mdio_probe()
164 /* attach the mac to the phy */ in emac_mdio_probe()
165 phydev = of_phy_connect(db->ndev, db->phy_node, in emac_mdio_probe()
167 db->phy_interface); in emac_mdio_probe()
169 netdev_err(db->ndev, "could not find the PHY\n"); in emac_mdio_probe()
170 return -ENODEV; in emac_mdio_probe()
173 /* mask with MAC supported features */ in emac_mdio_probe()
176 db->link = 0; in emac_mdio_probe()
177 db->speed = 0; in emac_mdio_probe()
178 db->duplex = -1; in emac_mdio_probe()
185 phy_disconnect(dev->phydev); in emac_mdio_remove()
190 dev_dbg(db->dev, "resetting device\n"); in emac_reset()
193 writel(0, db->membase + EMAC_CTL_REG); in emac_reset()
195 writel(EMAC_CTL_RESET, db->membase + EMAC_CTL_REG); in emac_reset()
213 strlcpy(info->driver, DRV_NAME, sizeof(info->driver)); in emac_get_drvinfo()
214 strlcpy(info->bus_info, dev_name(&dev->dev), sizeof(info->bus_info)); in emac_get_drvinfo()
221 return db->msg_enable; in emac_get_msglevel()
228 db->msg_enable = value; in emac_set_msglevel()
245 /* set up TX */ in emac_setup()
246 reg_val = readl(db->membase + EMAC_TX_MODE_REG); in emac_setup()
249 db->membase + EMAC_TX_MODE_REG); in emac_setup()
251 /* set MAC */ in emac_setup()
252 /* set MAC CTL0 */ in emac_setup()
253 reg_val = readl(db->membase + EMAC_MAC_CTL0_REG); in emac_setup()
256 db->membase + EMAC_MAC_CTL0_REG); in emac_setup()
258 /* set MAC CTL1 */ in emac_setup()
259 reg_val = readl(db->membase + EMAC_MAC_CTL1_REG); in emac_setup()
263 writel(reg_val, db->membase + EMAC_MAC_CTL1_REG); in emac_setup()
266 writel(EMAC_MAC_IPGT_FULL_DUPLEX, db->membase + EMAC_MAC_IPGT_REG); in emac_setup()
270 db->membase + EMAC_MAC_IPGR_REG); in emac_setup()
274 db->membase + EMAC_MAC_CLRT_REG); in emac_setup()
278 db->membase + EMAC_MAC_MAXF_REG); in emac_setup()
289 reg_val = readl(db->membase + EMAC_RX_CTL_REG); in emac_set_rx_mode()
291 if (ndev->flags & IFF_PROMISC) in emac_set_rx_mode()
300 db->membase + EMAC_RX_CTL_REG); in emac_set_rx_mode()
310 reg_val = readl(db->membase + EMAC_RX_CTL_REG); in emac_powerup()
312 writel(reg_val, db->membase + EMAC_RX_CTL_REG); in emac_powerup()
315 /* initial MAC */ in emac_powerup()
316 /* soft reset MAC */ in emac_powerup()
317 reg_val = readl(db->membase + EMAC_MAC_CTL0_REG); in emac_powerup()
319 writel(reg_val, db->membase + EMAC_MAC_CTL0_REG); in emac_powerup()
322 reg_val = readl(db->membase + EMAC_MAC_MCFG_REG); in emac_powerup()
325 writel(reg_val, db->membase + EMAC_MAC_MCFG_REG); in emac_powerup()
328 writel(0x0, db->membase + EMAC_RX_FBC_REG); in emac_powerup()
331 writel(0, db->membase + EMAC_INT_CTL_REG); in emac_powerup()
332 reg_val = readl(db->membase + EMAC_INT_STA_REG); in emac_powerup()
333 writel(reg_val, db->membase + EMAC_INT_STA_REG); in emac_powerup()
341 writel(ndev->dev_addr[0] << 16 | ndev->dev_addr[1] << 8 | ndev-> in emac_powerup()
342 dev_addr[2], db->membase + EMAC_MAC_A1_REG); in emac_powerup()
343 writel(ndev->dev_addr[3] << 16 | ndev->dev_addr[4] << 8 | ndev-> in emac_powerup()
344 dev_addr[5], db->membase + EMAC_MAC_A0_REG); in emac_powerup()
357 return -EBUSY; in emac_set_mac_address()
359 memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); in emac_set_mac_address()
361 writel(dev->dev_addr[0] << 16 | dev->dev_addr[1] << 8 | dev-> in emac_set_mac_address()
362 dev_addr[2], db->membase + EMAC_MAC_A1_REG); in emac_set_mac_address()
363 writel(dev->dev_addr[3] << 16 | dev->dev_addr[4] << 8 | dev-> in emac_set_mac_address()
364 dev_addr[5], db->membase + EMAC_MAC_A0_REG); in emac_set_mac_address()
376 spin_lock_irqsave(&db->lock, flags); in emac_init_device()
381 /* enable RX/TX */ in emac_init_device()
382 reg_val = readl(db->membase + EMAC_CTL_REG); in emac_init_device()
384 db->membase + EMAC_CTL_REG); in emac_init_device()
387 reg_val = readl(db->membase + EMAC_INT_CTL_REG); in emac_init_device()
389 writel(reg_val, db->membase + EMAC_INT_CTL_REG); in emac_init_device()
391 spin_unlock_irqrestore(&db->lock, flags); in emac_init_device()
401 dev_err(db->dev, "tx time out.\n"); in emac_timeout()
404 spin_lock_irqsave(&db->lock, flags); in emac_timeout()
409 /* We can accept TX packets again */ in emac_timeout()
414 spin_unlock_irqrestore(&db->lock, flags); in emac_timeout()
426 channel = db->tx_fifo_stat & 3; in emac_start_xmit()
432 spin_lock_irqsave(&db->lock, flags); in emac_start_xmit()
434 writel(channel, db->membase + EMAC_TX_INS_REG); in emac_start_xmit()
436 emac_outblk_32bit(db->membase + EMAC_TX_IO_DATA_REG, in emac_start_xmit()
437 skb->data, skb->len); in emac_start_xmit()
438 dev->stats.tx_bytes += skb->len; in emac_start_xmit()
440 db->tx_fifo_stat |= 1 << channel; in emac_start_xmit()
441 /* TX control: First packet immediately send, second packet queue */ in emac_start_xmit()
443 /* set TX len */ in emac_start_xmit()
444 writel(skb->len, db->membase + EMAC_TX_PL0_REG); in emac_start_xmit()
446 writel(readl(db->membase + EMAC_TX_CTL0_REG) | 1, in emac_start_xmit()
447 db->membase + EMAC_TX_CTL0_REG); in emac_start_xmit()
452 /* set TX len */ in emac_start_xmit()
453 writel(skb->len, db->membase + EMAC_TX_PL1_REG); in emac_start_xmit()
455 writel(readl(db->membase + EMAC_TX_CTL1_REG) | 1, in emac_start_xmit()
456 db->membase + EMAC_TX_CTL1_REG); in emac_start_xmit()
462 if ((db->tx_fifo_stat & 3) == 3) { in emac_start_xmit()
467 spin_unlock_irqrestore(&db->lock, flags); in emac_start_xmit()
482 db->tx_fifo_stat &= ~(tx_status & 3); in emac_tx_done()
484 dev->stats.tx_packets += 2; in emac_tx_done()
486 dev->stats.tx_packets++; in emac_tx_done()
489 dev_dbg(db->dev, "tx done, NSR %02x\n", tx_status); in emac_tx_done()
512 rxcount = readl(db->membase + EMAC_RX_FBC_REG); in emac_rx()
515 dev_dbg(db->dev, "RXCount: %x\n", rxcount); in emac_rx()
517 if ((db->skb_last != NULL) && (rxlen_last > 0)) { in emac_rx()
518 dev->stats.rx_bytes += rxlen_last; in emac_rx()
521 db->skb_last->protocol = eth_type_trans(db->skb_last, in emac_rx()
523 netif_rx(db->skb_last); in emac_rx()
524 dev->stats.rx_packets++; in emac_rx()
525 db->skb_last = NULL; in emac_rx()
528 reg_val = readl(db->membase + EMAC_RX_CTL_REG); in emac_rx()
530 writel(reg_val, db->membase + EMAC_RX_CTL_REG); in emac_rx()
534 db->emacrx_completed_flag = 1; in emac_rx()
535 reg_val = readl(db->membase + EMAC_INT_CTL_REG); in emac_rx()
537 writel(reg_val, db->membase + EMAC_INT_CTL_REG); in emac_rx()
540 rxcount = readl(db->membase + EMAC_RX_FBC_REG); in emac_rx()
545 reg_val = readl(db->membase + EMAC_RX_IO_DATA_REG); in emac_rx()
547 dev_dbg(db->dev, "receive header: %x\n", reg_val); in emac_rx()
550 reg_val = readl(db->membase + EMAC_CTL_REG); in emac_rx()
552 db->membase + EMAC_CTL_REG); in emac_rx()
555 reg_val = readl(db->membase + EMAC_RX_CTL_REG); in emac_rx()
557 db->membase + EMAC_RX_CTL_REG); in emac_rx()
560 reg_val = readl(db->membase + EMAC_RX_CTL_REG); in emac_rx()
564 reg_val = readl(db->membase + EMAC_CTL_REG); in emac_rx()
566 db->membase + EMAC_CTL_REG); in emac_rx()
567 reg_val = readl(db->membase + EMAC_INT_CTL_REG); in emac_rx()
569 writel(reg_val, db->membase + EMAC_INT_CTL_REG); in emac_rx()
571 db->emacrx_completed_flag = 1; in emac_rx()
579 rxhdr = readl(db->membase + EMAC_RX_IO_DATA_REG); in emac_rx()
582 dev_dbg(db->dev, "rxhdr: %x\n", *((int *)(&rxhdr))); in emac_rx()
588 dev_dbg(db->dev, "RX: status %02x, length %04x\n", in emac_rx()
595 dev_dbg(db->dev, "RX: Bad Packet (runt)\n"); in emac_rx()
603 dev_dbg(db->dev, "crc error\n"); in emac_rx()
604 dev->stats.rx_crc_errors++; in emac_rx()
609 dev_dbg(db->dev, "length error\n"); in emac_rx()
610 dev->stats.rx_length_errors++; in emac_rx()
620 rdptr = skb_put(skb, rxlen - 4); in emac_rx()
624 dev_dbg(db->dev, "RxLen %x\n", rxlen); in emac_rx()
626 emac_inblk_32bit(db->membase + EMAC_RX_IO_DATA_REG, in emac_rx()
628 dev->stats.rx_bytes += rxlen; in emac_rx()
631 skb->protocol = eth_type_trans(skb, dev); in emac_rx()
633 dev->stats.rx_packets++; in emac_rx()
647 spin_lock(&db->lock); in emac_interrupt()
650 writel(0, db->membase + EMAC_INT_CTL_REG); in emac_interrupt()
654 int_status = readl(db->membase + EMAC_INT_STA_REG); in emac_interrupt()
656 writel(int_status, db->membase + EMAC_INT_STA_REG); in emac_interrupt()
659 dev_dbg(db->dev, "emac interrupt %02x\n", int_status); in emac_interrupt()
662 if ((int_status & 0x100) && (db->emacrx_completed_flag == 1)) { in emac_interrupt()
664 db->emacrx_completed_flag = 0; in emac_interrupt()
675 /* Re-enable interrupt mask */ in emac_interrupt()
676 if (db->emacrx_completed_flag == 1) { in emac_interrupt()
677 reg_val = readl(db->membase + EMAC_INT_CTL_REG); in emac_interrupt()
679 writel(reg_val, db->membase + EMAC_INT_CTL_REG); in emac_interrupt()
681 spin_unlock(&db->lock); in emac_interrupt()
692 disable_irq(dev->irq); in emac_poll_controller()
693 emac_interrupt(dev->irq, dev); in emac_poll_controller()
694 enable_irq(dev->irq); in emac_poll_controller()
707 dev_dbg(db->dev, "enabling %s\n", dev->name); in emac_open()
709 if (request_irq(dev->irq, &emac_interrupt, 0, dev->name, dev)) in emac_open()
710 return -EAGAIN; in emac_open()
718 free_irq(dev->irq, dev); in emac_open()
723 phy_start(dev->phydev); in emac_open()
735 writel(0, db->membase + EMAC_INT_CTL_REG); in emac_shutdown()
738 reg_val = readl(db->membase + EMAC_INT_STA_REG); in emac_shutdown()
739 writel(reg_val, db->membase + EMAC_INT_STA_REG); in emac_shutdown()
741 /* Disable RX/TX */ in emac_shutdown()
742 reg_val = readl(db->membase + EMAC_CTL_REG); in emac_shutdown()
744 writel(reg_val, db->membase + EMAC_CTL_REG); in emac_shutdown()
755 dev_dbg(db->dev, "shutting down %s\n", ndev->name); in emac_stop()
760 phy_stop(ndev->phydev); in emac_stop()
766 free_irq(ndev->irq, ndev); in emac_stop()
789 struct device_node *np = pdev->dev.of_node; in emac_probe()
797 dev_err(&pdev->dev, "could not allocate device.\n"); in emac_probe()
798 return -ENOMEM; in emac_probe()
801 SET_NETDEV_DEV(ndev, &pdev->dev); in emac_probe()
805 db->dev = &pdev->dev; in emac_probe()
806 db->ndev = ndev; in emac_probe()
807 db->pdev = pdev; in emac_probe()
808 db->msg_enable = netif_msg_init(debug, EMAC_DEFAULT_MSG_ENABLE); in emac_probe()
810 spin_lock_init(&db->lock); in emac_probe()
812 db->membase = of_iomap(np, 0); in emac_probe()
813 if (!db->membase) { in emac_probe()
814 dev_err(&pdev->dev, "failed to remap registers\n"); in emac_probe()
815 ret = -ENOMEM; in emac_probe()
819 /* fill in parameters for net-dev structure */ in emac_probe()
820 ndev->base_addr = (unsigned long)db->membase; in emac_probe()
821 ndev->irq = irq_of_parse_and_map(np, 0); in emac_probe()
822 if (ndev->irq == -ENXIO) { in emac_probe()
824 ret = ndev->irq; in emac_probe()
828 db->clk = devm_clk_get(&pdev->dev, NULL); in emac_probe()
829 if (IS_ERR(db->clk)) { in emac_probe()
830 ret = PTR_ERR(db->clk); in emac_probe()
834 ret = clk_prepare_enable(db->clk); in emac_probe()
836 dev_err(&pdev->dev, "Error couldn't enable clock (%d)\n", ret); in emac_probe()
840 ret = sunxi_sram_claim(&pdev->dev); in emac_probe()
842 dev_err(&pdev->dev, "Error couldn't map SRAM to device\n"); in emac_probe()
846 db->phy_node = of_parse_phandle(np, "phy-handle", 0); in emac_probe()
847 if (!db->phy_node) in emac_probe()
848 db->phy_node = of_parse_phandle(np, "phy", 0); in emac_probe()
849 if (!db->phy_node) { in emac_probe()
850 dev_err(&pdev->dev, "no associated PHY\n"); in emac_probe()
851 ret = -ENODEV; in emac_probe()
855 /* Read MAC-address from DT */ in emac_probe()
858 ether_addr_copy(ndev->dev_addr, mac_addr); in emac_probe()
860 /* Check if the MAC address is valid, if not get a random one */ in emac_probe()
861 if (!is_valid_ether_addr(ndev->dev_addr)) { in emac_probe()
863 dev_warn(&pdev->dev, "using random MAC address %pM\n", in emac_probe()
864 ndev->dev_addr); in emac_probe()
867 db->emacrx_completed_flag = 1; in emac_probe()
871 ndev->netdev_ops = &emac_netdev_ops; in emac_probe()
872 ndev->watchdog_timeo = msecs_to_jiffies(watchdog); in emac_probe()
873 ndev->ethtool_ops = &emac_ethtool_ops; in emac_probe()
882 dev_err(&pdev->dev, "Registering netdev failed!\n"); in emac_probe()
883 ret = -ENODEV; in emac_probe()
887 dev_info(&pdev->dev, "%s: at %p, IRQ %d MAC: %pM\n", in emac_probe()
888 ndev->name, db->membase, ndev->irq, ndev->dev_addr); in emac_probe()
893 sunxi_sram_release(&pdev->dev); in emac_probe()
895 clk_disable_unprepare(db->clk); in emac_probe()
897 iounmap(db->membase); in emac_probe()
899 dev_err(db->dev, "not found (%d).\n", ret); in emac_probe()
912 sunxi_sram_release(&pdev->dev); in emac_remove()
913 clk_disable_unprepare(db->clk); in emac_remove()
914 iounmap(db->membase); in emac_remove()
917 dev_dbg(&pdev->dev, "released and freed device\n"); in emac_remove()
945 {.compatible = "allwinner,sun4i-a10-emac",},
948 {.compatible = "allwinner,sun4i-emac",},
956 .name = "sun4i-emac",
968 MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");