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>
34 #include "sun4i-emac.h"
36 #define DRV_NAME "sun4i-emac"
41 static int debug = -1; /* defaults above */;
73 struct clk *clk; member
108 reg_val = readl(db->membase + EMAC_MAC_SUPP_REG); in emac_update_speed()
110 if (db->speed == SPEED_100) in emac_update_speed()
112 writel(reg_val, db->membase + EMAC_MAC_SUPP_REG); in emac_update_speed()
121 reg_val = readl(db->membase + EMAC_MAC_CTL1_REG); in emac_update_duplex()
123 if (db->duplex) in emac_update_duplex()
125 writel(reg_val, db->membase + EMAC_MAC_CTL1_REG); in emac_update_duplex()
131 struct phy_device *phydev = dev->phydev; in emac_handle_link_change()
135 if (phydev->link) { in emac_handle_link_change()
136 if (db->speed != phydev->speed) { in emac_handle_link_change()
137 spin_lock_irqsave(&db->lock, flags); in emac_handle_link_change()
138 db->speed = phydev->speed; in emac_handle_link_change()
140 spin_unlock_irqrestore(&db->lock, flags); in emac_handle_link_change()
144 if (db->duplex != phydev->duplex) { in emac_handle_link_change()
145 spin_lock_irqsave(&db->lock, flags); in emac_handle_link_change()
146 db->duplex = phydev->duplex; in emac_handle_link_change()
148 spin_unlock_irqrestore(&db->lock, flags); in emac_handle_link_change()
153 if (phydev->link != db->link) { in emac_handle_link_change()
154 if (!phydev->link) { in emac_handle_link_change()
155 db->speed = 0; in emac_handle_link_change()
156 db->duplex = -1; in emac_handle_link_change()
158 db->link = phydev->link; in emac_handle_link_change()
172 /* to-do: PHY interrupts are currently not supported */ in emac_mdio_probe()
174 /* attach the mac to the phy */ in emac_mdio_probe()
175 phydev = of_phy_connect(db->ndev, db->phy_node, in emac_mdio_probe()
177 db->phy_interface); in emac_mdio_probe()
179 netdev_err(db->ndev, "could not find the PHY\n"); in emac_mdio_probe()
180 return -ENODEV; in emac_mdio_probe()
183 /* mask with MAC supported features */ in emac_mdio_probe()
186 db->link = 0; in emac_mdio_probe()
187 db->speed = 0; in emac_mdio_probe()
188 db->duplex = -1; in emac_mdio_probe()
195 phy_disconnect(dev->phydev); in emac_mdio_remove()
200 dev_dbg(db->dev, "resetting device\n"); in emac_reset()
203 writel(0, db->membase + EMAC_CTL_REG); in emac_reset()
205 writel(EMAC_CTL_RESET, db->membase + EMAC_CTL_REG); in emac_reset()
230 req->db = db; in emac_alloc_dma_req()
231 req->desc = desc; in emac_alloc_dma_req()
232 req->skb = skb; in emac_alloc_dma_req()
233 req->rxbuf = rxbuf; in emac_alloc_dma_req()
234 req->count = count; in emac_alloc_dma_req()
246 struct emac_board_info *db = req->db; in emac_dma_done_callback()
247 struct sk_buff *skb = req->skb; in emac_dma_done_callback()
248 struct net_device *dev = db->ndev; in emac_dma_done_callback()
249 int rxlen = req->count; in emac_dma_done_callback()
252 dma_unmap_single(db->dev, req->rxbuf, rxlen, DMA_FROM_DEVICE); in emac_dma_done_callback()
254 skb->protocol = eth_type_trans(skb, dev); in emac_dma_done_callback()
256 dev->stats.rx_bytes += rxlen; in emac_dma_done_callback()
258 dev->stats.rx_packets++; in emac_dma_done_callback()
261 reg_val = readl(db->membase + EMAC_RX_CTL_REG); in emac_dma_done_callback()
263 writel(reg_val, db->membase + EMAC_RX_CTL_REG); in emac_dma_done_callback()
266 reg_val = readl(db->membase + EMAC_INT_CTL_REG); in emac_dma_done_callback()
268 writel(reg_val, db->membase + EMAC_INT_CTL_REG); in emac_dma_done_callback()
270 db->emacrx_completed_flag = 1; in emac_dma_done_callback()
283 rxbuf = dma_map_single(db->dev, rdptr, count, DMA_FROM_DEVICE); in emac_dma_inblk_32bit()
284 ret = dma_mapping_error(db->dev, rxbuf); in emac_dma_inblk_32bit()
286 dev_err(db->dev, "dma mapping error.\n"); in emac_dma_inblk_32bit()
290 desc = dmaengine_prep_slave_single(db->rx_chan, rxbuf, count, in emac_dma_inblk_32bit()
294 dev_err(db->dev, "prepare slave single failed\n"); in emac_dma_inblk_32bit()
295 ret = -ENOMEM; in emac_dma_inblk_32bit()
301 dev_err(db->dev, "alloc emac dma req error.\n"); in emac_dma_inblk_32bit()
302 ret = -ENOMEM; in emac_dma_inblk_32bit()
306 desc->callback_param = req; in emac_dma_inblk_32bit()
307 desc->callback = emac_dma_done_callback; in emac_dma_inblk_32bit()
312 dev_err(db->dev, "dma submit error.\n"); in emac_dma_inblk_32bit()
316 dma_async_issue_pending(db->rx_chan); in emac_dma_inblk_32bit()
326 dma_unmap_single(db->dev, rxbuf, count, DMA_FROM_DEVICE); in emac_dma_inblk_32bit()
334 strscpy(info->driver, DRV_NAME, sizeof(info->driver)); in emac_get_drvinfo()
335 strscpy(info->bus_info, dev_name(&dev->dev), sizeof(info->bus_info)); in emac_get_drvinfo()
342 return db->msg_enable; in emac_get_msglevel()
349 db->msg_enable = value; in emac_set_msglevel()
366 /* set up TX */ in emac_setup()
367 reg_val = readl(db->membase + EMAC_TX_MODE_REG); in emac_setup()
370 db->membase + EMAC_TX_MODE_REG); in emac_setup()
372 /* set MAC */ in emac_setup()
373 /* set MAC CTL0 */ in emac_setup()
374 reg_val = readl(db->membase + EMAC_MAC_CTL0_REG); in emac_setup()
377 db->membase + EMAC_MAC_CTL0_REG); in emac_setup()
379 /* set MAC CTL1 */ in emac_setup()
380 reg_val = readl(db->membase + EMAC_MAC_CTL1_REG); in emac_setup()
384 writel(reg_val, db->membase + EMAC_MAC_CTL1_REG); in emac_setup()
387 writel(EMAC_MAC_IPGT_FULL_DUPLEX, db->membase + EMAC_MAC_IPGT_REG); in emac_setup()
391 db->membase + EMAC_MAC_IPGR_REG); in emac_setup()
395 db->membase + EMAC_MAC_CLRT_REG); in emac_setup()
399 db->membase + EMAC_MAC_MAXF_REG); in emac_setup()
410 reg_val = readl(db->membase + EMAC_RX_CTL_REG); in emac_set_rx_mode()
412 if (ndev->flags & IFF_PROMISC) in emac_set_rx_mode()
421 db->membase + EMAC_RX_CTL_REG); in emac_set_rx_mode()
431 reg_val = readl(db->membase + EMAC_RX_CTL_REG); in emac_powerup()
433 writel(reg_val, db->membase + EMAC_RX_CTL_REG); in emac_powerup()
436 /* initial MAC */ in emac_powerup()
437 /* soft reset MAC */ in emac_powerup()
438 reg_val = readl(db->membase + EMAC_MAC_CTL0_REG); in emac_powerup()
440 writel(reg_val, db->membase + EMAC_MAC_CTL0_REG); in emac_powerup()
443 reg_val = readl(db->membase + EMAC_MAC_MCFG_REG); in emac_powerup()
446 writel(reg_val, db->membase + EMAC_MAC_MCFG_REG); in emac_powerup()
449 writel(0x0, db->membase + EMAC_RX_FBC_REG); in emac_powerup()
452 writel(0, db->membase + EMAC_INT_CTL_REG); in emac_powerup()
453 reg_val = readl(db->membase + EMAC_INT_STA_REG); in emac_powerup()
454 writel(reg_val, db->membase + EMAC_INT_STA_REG); in emac_powerup()
462 writel(ndev->dev_addr[0] << 16 | ndev->dev_addr[1] << 8 | ndev-> in emac_powerup()
463 dev_addr[2], db->membase + EMAC_MAC_A1_REG); in emac_powerup()
464 writel(ndev->dev_addr[3] << 16 | ndev->dev_addr[4] << 8 | ndev-> in emac_powerup()
465 dev_addr[5], db->membase + EMAC_MAC_A0_REG); in emac_powerup()
478 return -EBUSY; in emac_set_mac_address()
480 eth_hw_addr_set(dev, addr->sa_data); in emac_set_mac_address()
482 writel(dev->dev_addr[0] << 16 | dev->dev_addr[1] << 8 | dev-> in emac_set_mac_address()
483 dev_addr[2], db->membase + EMAC_MAC_A1_REG); in emac_set_mac_address()
484 writel(dev->dev_addr[3] << 16 | dev->dev_addr[4] << 8 | dev-> in emac_set_mac_address()
485 dev_addr[5], db->membase + EMAC_MAC_A0_REG); in emac_set_mac_address()
497 spin_lock_irqsave(&db->lock, flags); in emac_init_device()
502 /* enable RX/TX */ in emac_init_device()
503 reg_val = readl(db->membase + EMAC_CTL_REG); in emac_init_device()
505 db->membase + EMAC_CTL_REG); in emac_init_device()
508 reg_val = readl(db->membase + EMAC_INT_CTL_REG); in emac_init_device()
510 writel(reg_val, db->membase + EMAC_INT_CTL_REG); in emac_init_device()
512 spin_unlock_irqrestore(&db->lock, flags); in emac_init_device()
522 dev_err(db->dev, "tx time out.\n"); in emac_timeout()
525 spin_lock_irqsave(&db->lock, flags); in emac_timeout()
530 /* We can accept TX packets again */ in emac_timeout()
535 spin_unlock_irqrestore(&db->lock, flags); in emac_timeout()
547 channel = db->tx_fifo_stat & 3; in emac_start_xmit()
553 spin_lock_irqsave(&db->lock, flags); in emac_start_xmit()
555 writel(channel, db->membase + EMAC_TX_INS_REG); in emac_start_xmit()
557 emac_outblk_32bit(db->membase + EMAC_TX_IO_DATA_REG, in emac_start_xmit()
558 skb->data, skb->len); in emac_start_xmit()
559 dev->stats.tx_bytes += skb->len; in emac_start_xmit()
561 db->tx_fifo_stat |= 1 << channel; in emac_start_xmit()
562 /* TX control: First packet immediately send, second packet queue */ in emac_start_xmit()
564 /* set TX len */ in emac_start_xmit()
565 writel(skb->len, db->membase + EMAC_TX_PL0_REG); in emac_start_xmit()
567 writel(readl(db->membase + EMAC_TX_CTL0_REG) | 1, in emac_start_xmit()
568 db->membase + EMAC_TX_CTL0_REG); in emac_start_xmit()
573 /* set TX len */ in emac_start_xmit()
574 writel(skb->len, db->membase + EMAC_TX_PL1_REG); in emac_start_xmit()
576 writel(readl(db->membase + EMAC_TX_CTL1_REG) | 1, in emac_start_xmit()
577 db->membase + EMAC_TX_CTL1_REG); in emac_start_xmit()
583 if ((db->tx_fifo_stat & 3) == 3) { in emac_start_xmit()
588 spin_unlock_irqrestore(&db->lock, flags); in emac_start_xmit()
603 db->tx_fifo_stat &= ~(tx_status & 3); in emac_tx_done()
605 dev->stats.tx_packets += 2; in emac_tx_done()
607 dev->stats.tx_packets++; in emac_tx_done()
610 dev_dbg(db->dev, "tx done, NSR %02x\n", tx_status); in emac_tx_done()
632 rxcount = readl(db->membase + EMAC_RX_FBC_REG); in emac_rx()
635 dev_dbg(db->dev, "RXCount: %x\n", rxcount); in emac_rx()
638 db->emacrx_completed_flag = 1; in emac_rx()
639 reg_val = readl(db->membase + EMAC_INT_CTL_REG); in emac_rx()
643 writel(reg_val, db->membase + EMAC_INT_CTL_REG); in emac_rx()
646 rxcount = readl(db->membase + EMAC_RX_FBC_REG); in emac_rx()
651 reg_val = readl(db->membase + EMAC_RX_IO_DATA_REG); in emac_rx()
653 dev_dbg(db->dev, "receive header: %x\n", reg_val); in emac_rx()
656 reg_val = readl(db->membase + EMAC_CTL_REG); in emac_rx()
658 db->membase + EMAC_CTL_REG); in emac_rx()
661 reg_val = readl(db->membase + EMAC_RX_CTL_REG); in emac_rx()
663 db->membase + EMAC_RX_CTL_REG); in emac_rx()
666 reg_val = readl(db->membase + EMAC_RX_CTL_REG); in emac_rx()
670 reg_val = readl(db->membase + EMAC_CTL_REG); in emac_rx()
672 db->membase + EMAC_CTL_REG); in emac_rx()
673 reg_val = readl(db->membase + EMAC_INT_CTL_REG); in emac_rx()
677 writel(reg_val, db->membase + EMAC_INT_CTL_REG); in emac_rx()
679 db->emacrx_completed_flag = 1; in emac_rx()
687 rxhdr = readl(db->membase + EMAC_RX_IO_DATA_REG); in emac_rx()
690 dev_dbg(db->dev, "rxhdr: %x\n", *((int *)(&rxhdr))); in emac_rx()
696 dev_dbg(db->dev, "RX: status %02x, length %04x\n", in emac_rx()
703 dev_dbg(db->dev, "RX: Bad Packet (runt)\n"); in emac_rx()
711 dev_dbg(db->dev, "crc error\n"); in emac_rx()
712 dev->stats.rx_crc_errors++; in emac_rx()
717 dev_dbg(db->dev, "length error\n"); in emac_rx()
718 dev->stats.rx_length_errors++; in emac_rx()
728 rdptr = skb_put(skb, rxlen - 4); in emac_rx()
732 dev_dbg(db->dev, "RxLen %x\n", rxlen); in emac_rx()
734 if (rxlen >= dev->mtu && db->rx_chan) { in emac_rx()
735 reg_val = readl(db->membase + EMAC_RX_CTL_REG); in emac_rx()
737 writel(reg_val, db->membase + EMAC_RX_CTL_REG); in emac_rx()
742 reg_val = readl(db->membase + EMAC_RX_CTL_REG); in emac_rx()
744 writel(reg_val, db->membase + EMAC_RX_CTL_REG); in emac_rx()
747 emac_inblk_32bit(db->membase + EMAC_RX_IO_DATA_REG, in emac_rx()
749 dev->stats.rx_bytes += rxlen; in emac_rx()
752 skb->protocol = eth_type_trans(skb, dev); in emac_rx()
754 dev->stats.rx_packets++; in emac_rx()
768 spin_lock(&db->lock); in emac_interrupt()
771 writel(0, db->membase + EMAC_INT_CTL_REG); in emac_interrupt()
775 int_status = readl(db->membase + EMAC_INT_STA_REG); in emac_interrupt()
777 writel(int_status, db->membase + EMAC_INT_STA_REG); in emac_interrupt()
780 dev_dbg(db->dev, "emac interrupt %02x\n", int_status); in emac_interrupt()
783 if ((int_status & 0x100) && (db->emacrx_completed_flag == 1)) { in emac_interrupt()
785 db->emacrx_completed_flag = 0; in emac_interrupt()
796 /* Re-enable interrupt mask */ in emac_interrupt()
797 if (db->emacrx_completed_flag == 1) { in emac_interrupt()
798 reg_val = readl(db->membase + EMAC_INT_CTL_REG); in emac_interrupt()
800 writel(reg_val, db->membase + EMAC_INT_CTL_REG); in emac_interrupt()
802 reg_val = readl(db->membase + EMAC_INT_CTL_REG); in emac_interrupt()
804 writel(reg_val, db->membase + EMAC_INT_CTL_REG); in emac_interrupt()
807 spin_unlock(&db->lock); in emac_interrupt()
818 disable_irq(dev->irq); in emac_poll_controller()
819 emac_interrupt(dev->irq, dev); in emac_poll_controller()
820 enable_irq(dev->irq); in emac_poll_controller()
833 dev_dbg(db->dev, "enabling %s\n", dev->name); in emac_open()
835 if (request_irq(dev->irq, &emac_interrupt, 0, dev->name, dev)) in emac_open()
836 return -EAGAIN; in emac_open()
844 free_irq(dev->irq, dev); in emac_open()
849 phy_start(dev->phydev); in emac_open()
861 writel(0, db->membase + EMAC_INT_CTL_REG); in emac_shutdown()
864 reg_val = readl(db->membase + EMAC_INT_STA_REG); in emac_shutdown()
865 writel(reg_val, db->membase + EMAC_INT_STA_REG); in emac_shutdown()
867 /* Disable RX/TX */ in emac_shutdown()
868 reg_val = readl(db->membase + EMAC_CTL_REG); in emac_shutdown()
870 writel(reg_val, db->membase + EMAC_CTL_REG); in emac_shutdown()
881 dev_dbg(db->dev, "shutting down %s\n", ndev->name); in emac_stop()
886 phy_stop(ndev->phydev); in emac_stop()
892 free_irq(ndev->irq, ndev); in emac_stop()
913 struct platform_device *pdev = db->pdev; in emac_configure_dma()
914 struct net_device *ndev = db->ndev; in emac_configure_dma()
922 err = -ENOMEM; in emac_configure_dma()
927 ®s->start, (unsigned int)resource_size(regs)); in emac_configure_dma()
928 db->emac_rx_fifo = regs->start + EMAC_RX_IO_DATA_REG; in emac_configure_dma()
930 db->rx_chan = dma_request_chan(&pdev->dev, "rx"); in emac_configure_dma()
931 if (IS_ERR(db->rx_chan)) { in emac_configure_dma()
934 err = PTR_ERR(db->rx_chan); in emac_configure_dma()
941 conf.src_addr = db->emac_rx_fifo; in emac_configure_dma()
946 err = dmaengine_slave_config(db->rx_chan, &conf); in emac_configure_dma()
949 err = -EINVAL; in emac_configure_dma()
956 dma_release_channel(db->rx_chan); in emac_configure_dma()
959 db->rx_chan = NULL; in emac_configure_dma()
967 struct device_node *np = pdev->dev.of_node; in emac_probe()
974 dev_err(&pdev->dev, "could not allocate device.\n"); in emac_probe()
975 return -ENOMEM; in emac_probe()
978 SET_NETDEV_DEV(ndev, &pdev->dev); in emac_probe()
982 db->dev = &pdev->dev; in emac_probe()
983 db->ndev = ndev; in emac_probe()
984 db->pdev = pdev; in emac_probe()
985 db->msg_enable = netif_msg_init(debug, EMAC_DEFAULT_MSG_ENABLE); in emac_probe()
987 spin_lock_init(&db->lock); in emac_probe()
989 db->membase = of_iomap(np, 0); in emac_probe()
990 if (!db->membase) { in emac_probe()
991 dev_err(&pdev->dev, "failed to remap registers\n"); in emac_probe()
992 ret = -ENOMEM; in emac_probe()
996 /* fill in parameters for net-dev structure */ in emac_probe()
997 ndev->base_addr = (unsigned long)db->membase; in emac_probe()
998 ndev->irq = irq_of_parse_and_map(np, 0); in emac_probe()
999 if (ndev->irq == -ENXIO) { in emac_probe()
1001 ret = ndev->irq; in emac_probe()
1008 db->clk = devm_clk_get(&pdev->dev, NULL); in emac_probe()
1009 if (IS_ERR(db->clk)) { in emac_probe()
1010 ret = PTR_ERR(db->clk); in emac_probe()
1014 ret = clk_prepare_enable(db->clk); in emac_probe()
1016 dev_err(&pdev->dev, "Error couldn't enable clock (%d)\n", ret); in emac_probe()
1020 ret = sunxi_sram_claim(&pdev->dev); in emac_probe()
1022 dev_err(&pdev->dev, "Error couldn't map SRAM to device\n"); in emac_probe()
1026 db->phy_node = of_parse_phandle(np, "phy-handle", 0); in emac_probe()
1027 if (!db->phy_node) in emac_probe()
1028 db->phy_node = of_parse_phandle(np, "phy", 0); in emac_probe()
1029 if (!db->phy_node) { in emac_probe()
1030 dev_err(&pdev->dev, "no associated PHY\n"); in emac_probe()
1031 ret = -ENODEV; in emac_probe()
1035 /* Read MAC-address from DT */ in emac_probe()
1038 /* if the MAC address is invalid get a random one */ in emac_probe()
1040 dev_warn(&pdev->dev, "using random MAC address %pM\n", in emac_probe()
1041 ndev->dev_addr); in emac_probe()
1044 db->emacrx_completed_flag = 1; in emac_probe()
1048 ndev->netdev_ops = &emac_netdev_ops; in emac_probe()
1049 ndev->watchdog_timeo = msecs_to_jiffies(watchdog); in emac_probe()
1050 ndev->ethtool_ops = &emac_ethtool_ops; in emac_probe()
1059 dev_err(&pdev->dev, "Registering netdev failed!\n"); in emac_probe()
1060 ret = -ENODEV; in emac_probe()
1064 dev_info(&pdev->dev, "%s: at %p, IRQ %d MAC: %pM\n", in emac_probe()
1065 ndev->name, db->membase, ndev->irq, ndev->dev_addr); in emac_probe()
1070 sunxi_sram_release(&pdev->dev); in emac_probe()
1072 clk_disable_unprepare(db->clk); in emac_probe()
1074 irq_dispose_mapping(ndev->irq); in emac_probe()
1075 dma_release_channel(db->rx_chan); in emac_probe()
1077 iounmap(db->membase); in emac_probe()
1079 dev_err(db->dev, "not found (%d).\n", ret); in emac_probe()
1091 if (db->rx_chan) { in emac_remove()
1092 dmaengine_terminate_all(db->rx_chan); in emac_remove()
1093 dma_release_channel(db->rx_chan); in emac_remove()
1097 sunxi_sram_release(&pdev->dev); in emac_remove()
1098 clk_disable_unprepare(db->clk); in emac_remove()
1099 irq_dispose_mapping(ndev->irq); in emac_remove()
1100 iounmap(db->membase); in emac_remove()
1103 dev_dbg(&pdev->dev, "released and freed device\n"); in emac_remove()
1130 {.compatible = "allwinner,sun4i-a10-emac",},
1133 {.compatible = "allwinner,sun4i-emac",},
1141 .name = "sun4i-emac",
1153 MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");