Lines Matching +full:12 +full:bit +full:- +full:clkdiv +full:- +full:mode
1 // SPDX-License-Identifier: GPL-2.0-only
5 * Copyright (C) 2007-2008 Avionic Design Development GmbH
6 * Copyright (C) 2008-2009 Avionic Design GmbH
8 * Written by Thierry Reding <thierry.reding@avionic-design.de>
11 #include <linux/dma-mapping.h>
55 /* mode register */
60 #define MODER_IAM (1 << 4) /* individual address mode */
61 #define MODER_PRO (1 << 5) /* promiscuous mode */
64 #define MODER_NBO (1 << 8) /* no back-off */
68 #define MODER_DCRC (1 << 12) /* delayed CRC enable */
102 /* control module mode register */
107 /* MII mode register */
142 #define TX_BD_PAD (1 << 12) /* pad enable for short packets */
177 * struct ethoc - driver-private device structure
228 * struct ethoc_bd - buffer descriptor
239 if (dev->big_endian) in ethoc_read()
240 return ioread32be(dev->iobase + offset); in ethoc_read()
242 return ioread32(dev->iobase + offset); in ethoc_read()
247 if (dev->big_endian) in ethoc_write()
248 iowrite32be(data, dev->iobase + offset); in ethoc_write()
250 iowrite32(data, dev->iobase + offset); in ethoc_write()
257 bd->stat = ethoc_read(dev, offset + 0); in ethoc_read_bd()
258 bd->addr = ethoc_read(dev, offset + 4); in ethoc_read_bd()
265 ethoc_write(dev, offset + 0, bd->stat); in ethoc_write_bd()
266 ethoc_write(dev, offset + 4, bd->addr); in ethoc_write_bd()
290 u32 mode = ethoc_read(dev, MODER); in ethoc_enable_rx_and_tx() local
291 mode |= MODER_RXEN | MODER_TXEN; in ethoc_enable_rx_and_tx()
292 ethoc_write(dev, MODER, mode); in ethoc_enable_rx_and_tx()
297 u32 mode = ethoc_read(dev, MODER); in ethoc_disable_rx_and_tx() local
298 mode &= ~(MODER_RXEN | MODER_TXEN); in ethoc_disable_rx_and_tx()
299 ethoc_write(dev, MODER, mode); in ethoc_disable_rx_and_tx()
308 dev->cur_tx = 0; in ethoc_init_ring()
309 dev->dty_tx = 0; in ethoc_init_ring()
310 dev->cur_rx = 0; in ethoc_init_ring()
312 ethoc_write(dev, TX_BD_NUM, dev->num_tx); in ethoc_init_ring()
317 vma = dev->membase; in ethoc_init_ring()
319 for (i = 0; i < dev->num_tx; i++) { in ethoc_init_ring()
320 if (i == dev->num_tx - 1) in ethoc_init_ring()
326 dev->vma[i] = vma; in ethoc_init_ring()
332 for (i = 0; i < dev->num_rx; i++) { in ethoc_init_ring()
333 if (i == dev->num_rx - 1) in ethoc_init_ring()
336 ethoc_write_bd(dev, dev->num_tx + i, &bd); in ethoc_init_ring()
339 dev->vma[dev->num_tx + i] = vma; in ethoc_init_ring()
348 u32 mode; in ethoc_reset() local
357 mode = ethoc_read(dev, MODER); in ethoc_reset()
358 mode |= MODER_CRC | MODER_PAD; in ethoc_reset()
359 ethoc_write(dev, MODER, mode); in ethoc_reset()
361 /* set full-duplex mode */ in ethoc_reset()
362 mode = ethoc_read(dev, MODER); in ethoc_reset()
363 mode |= MODER_FULLD; in ethoc_reset()
364 ethoc_write(dev, MODER, mode); in ethoc_reset()
376 struct net_device *netdev = dev->netdev; in ethoc_update_rx_stats()
379 if (bd->stat & RX_BD_TL) { in ethoc_update_rx_stats()
380 dev_err(&netdev->dev, "RX: frame too long\n"); in ethoc_update_rx_stats()
381 netdev->stats.rx_length_errors++; in ethoc_update_rx_stats()
385 if (bd->stat & RX_BD_SF) { in ethoc_update_rx_stats()
386 dev_err(&netdev->dev, "RX: frame too short\n"); in ethoc_update_rx_stats()
387 netdev->stats.rx_length_errors++; in ethoc_update_rx_stats()
391 if (bd->stat & RX_BD_DN) { in ethoc_update_rx_stats()
392 dev_err(&netdev->dev, "RX: dribble nibble\n"); in ethoc_update_rx_stats()
393 netdev->stats.rx_frame_errors++; in ethoc_update_rx_stats()
396 if (bd->stat & RX_BD_CRC) { in ethoc_update_rx_stats()
397 dev_err(&netdev->dev, "RX: wrong CRC\n"); in ethoc_update_rx_stats()
398 netdev->stats.rx_crc_errors++; in ethoc_update_rx_stats()
402 if (bd->stat & RX_BD_OR) { in ethoc_update_rx_stats()
403 dev_err(&netdev->dev, "RX: overrun\n"); in ethoc_update_rx_stats()
404 netdev->stats.rx_over_errors++; in ethoc_update_rx_stats()
408 if (bd->stat & RX_BD_MISS) in ethoc_update_rx_stats()
409 netdev->stats.rx_missed_errors++; in ethoc_update_rx_stats()
411 if (bd->stat & RX_BD_LC) { in ethoc_update_rx_stats()
412 dev_err(&netdev->dev, "RX: late collision\n"); in ethoc_update_rx_stats()
413 netdev->stats.collisions++; in ethoc_update_rx_stats()
429 entry = priv->num_tx + priv->cur_rx; in ethoc_rx()
449 size -= 4; /* strip the CRC */ in ethoc_rx()
453 void *src = priv->vma[entry]; in ethoc_rx()
455 skb->protocol = eth_type_trans(skb, dev); in ethoc_rx()
456 dev->stats.rx_packets++; in ethoc_rx()
457 dev->stats.rx_bytes += size; in ethoc_rx()
461 dev_warn(&dev->dev, in ethoc_rx()
462 "low on memory - packet dropped\n"); in ethoc_rx()
464 dev->stats.rx_dropped++; in ethoc_rx()
473 if (++priv->cur_rx == priv->num_rx) in ethoc_rx()
474 priv->cur_rx = 0; in ethoc_rx()
482 struct net_device *netdev = dev->netdev; in ethoc_update_tx_stats()
484 if (bd->stat & TX_BD_LC) { in ethoc_update_tx_stats()
485 dev_err(&netdev->dev, "TX: late collision\n"); in ethoc_update_tx_stats()
486 netdev->stats.tx_window_errors++; in ethoc_update_tx_stats()
489 if (bd->stat & TX_BD_RL) { in ethoc_update_tx_stats()
490 dev_err(&netdev->dev, "TX: retransmit limit\n"); in ethoc_update_tx_stats()
491 netdev->stats.tx_aborted_errors++; in ethoc_update_tx_stats()
494 if (bd->stat & TX_BD_UR) { in ethoc_update_tx_stats()
495 dev_err(&netdev->dev, "TX: underrun\n"); in ethoc_update_tx_stats()
496 netdev->stats.tx_fifo_errors++; in ethoc_update_tx_stats()
499 if (bd->stat & TX_BD_CS) { in ethoc_update_tx_stats()
500 dev_err(&netdev->dev, "TX: carrier sense lost\n"); in ethoc_update_tx_stats()
501 netdev->stats.tx_carrier_errors++; in ethoc_update_tx_stats()
504 if (bd->stat & TX_BD_STATS) in ethoc_update_tx_stats()
505 netdev->stats.tx_errors++; in ethoc_update_tx_stats()
507 netdev->stats.collisions += (bd->stat >> 4) & 0xf; in ethoc_update_tx_stats()
508 netdev->stats.tx_bytes += bd->stat >> 16; in ethoc_update_tx_stats()
509 netdev->stats.tx_packets++; in ethoc_update_tx_stats()
521 entry = priv->dty_tx & (priv->num_tx-1); in ethoc_tx()
525 if (bd.stat & TX_BD_READY || (priv->dty_tx == priv->cur_tx)) { in ethoc_tx()
536 (priv->dty_tx == priv->cur_tx)) in ethoc_tx()
541 priv->dty_tx++; in ethoc_tx()
544 if ((priv->cur_tx - priv->dty_tx) <= (priv->num_tx / 2)) in ethoc_tx()
558 * The tricky bit here is that the interrupt source bits get in ethoc_interrupt()
576 dev_dbg(&dev->dev, "packet dropped\n"); in ethoc_interrupt()
577 dev->stats.rx_dropped++; in ethoc_interrupt()
583 napi_schedule(&priv->napi); in ethoc_interrupt()
614 rx_work_done = ethoc_rx(priv->netdev, budget); in ethoc_poll()
615 tx_work_done = ethoc_tx(priv->netdev, budget); in ethoc_poll()
627 struct ethoc *priv = bus->priv; in ethoc_mdio_read()
644 return -EBUSY; in ethoc_mdio_read()
649 struct ethoc *priv = bus->priv; in ethoc_mdio_write()
666 return -EBUSY; in ethoc_mdio_write()
672 struct phy_device *phydev = dev->phydev; in ethoc_mdio_poll()
674 u32 mode; in ethoc_mdio_poll() local
676 if (priv->old_link != phydev->link) { in ethoc_mdio_poll()
678 priv->old_link = phydev->link; in ethoc_mdio_poll()
681 if (priv->old_duplex != phydev->duplex) { in ethoc_mdio_poll()
683 priv->old_duplex = phydev->duplex; in ethoc_mdio_poll()
689 mode = ethoc_read(priv, MODER); in ethoc_mdio_poll()
690 if (phydev->duplex == DUPLEX_FULL) in ethoc_mdio_poll()
691 mode |= MODER_FULLD; in ethoc_mdio_poll()
693 mode &= ~MODER_FULLD; in ethoc_mdio_poll()
694 ethoc_write(priv, MODER, mode); in ethoc_mdio_poll()
705 if (priv->phy_id != -1) in ethoc_mdio_probe()
706 phy = mdiobus_get_phy(priv->mdio, priv->phy_id); in ethoc_mdio_probe()
708 phy = phy_find_first(priv->mdio); in ethoc_mdio_probe()
711 dev_err(&dev->dev, "no PHY found\n"); in ethoc_mdio_probe()
712 return -ENXIO; in ethoc_mdio_probe()
715 priv->old_duplex = -1; in ethoc_mdio_probe()
716 priv->old_link = -1; in ethoc_mdio_probe()
721 dev_err(&dev->dev, "could not attach to PHY\n"); in ethoc_mdio_probe()
735 ret = request_irq(dev->irq, ethoc_interrupt, IRQF_SHARED, in ethoc_open()
736 dev->name, dev); in ethoc_open()
740 napi_enable(&priv->napi); in ethoc_open()
742 ethoc_init_ring(priv, dev->mem_start); in ethoc_open()
746 dev_dbg(&dev->dev, " resuming queue\n"); in ethoc_open()
749 dev_dbg(&dev->dev, " starting queue\n"); in ethoc_open()
753 priv->old_link = -1; in ethoc_open()
754 priv->old_duplex = -1; in ethoc_open()
756 phy_start(dev->phydev); in ethoc_open()
759 dev_info(&dev->dev, "I/O: %08lx Memory: %08lx-%08lx\n", in ethoc_open()
760 dev->base_addr, dev->mem_start, dev->mem_end); in ethoc_open()
770 napi_disable(&priv->napi); in ethoc_stop()
772 if (dev->phydev) in ethoc_stop()
773 phy_stop(dev->phydev); in ethoc_stop()
776 free_irq(dev->irq, dev); in ethoc_stop()
791 return -EINVAL; in ethoc_ioctl()
794 if (mdio->phy_id >= PHY_MAX_ADDR) in ethoc_ioctl()
795 return -ERANGE; in ethoc_ioctl()
797 phy = mdiobus_get_phy(priv->mdio, mdio->phy_id); in ethoc_ioctl()
799 return -ENODEV; in ethoc_ioctl()
801 phy = dev->phydev; in ethoc_ioctl()
810 unsigned char *mac = dev->dev_addr; in ethoc_do_set_mac_address()
821 if (!is_valid_ether_addr(addr->sa_data)) in ethoc_set_mac_address()
822 return -EADDRNOTAVAIL; in ethoc_set_mac_address()
823 memcpy(dev->dev_addr, addr->sa_data, ETH_ALEN); in ethoc_set_mac_address()
831 u32 mode = ethoc_read(priv, MODER); in ethoc_set_multicast_list() local
835 /* set loopback mode if requested */ in ethoc_set_multicast_list()
836 if (dev->flags & IFF_LOOPBACK) in ethoc_set_multicast_list()
837 mode |= MODER_LOOP; in ethoc_set_multicast_list()
839 mode &= ~MODER_LOOP; in ethoc_set_multicast_list()
842 if (dev->flags & IFF_BROADCAST) in ethoc_set_multicast_list()
843 mode &= ~MODER_BRO; in ethoc_set_multicast_list()
845 mode |= MODER_BRO; in ethoc_set_multicast_list()
847 /* enable promiscuous mode if requested */ in ethoc_set_multicast_list()
848 if (dev->flags & IFF_PROMISC) in ethoc_set_multicast_list()
849 mode |= MODER_PRO; in ethoc_set_multicast_list()
851 mode &= ~MODER_PRO; in ethoc_set_multicast_list()
853 ethoc_write(priv, MODER, mode); in ethoc_set_multicast_list()
856 if (dev->flags & IFF_ALLMULTI) { in ethoc_set_multicast_list()
861 u32 crc = ether_crc(ETH_ALEN, ha->addr); in ethoc_set_multicast_list()
862 int bit = (crc >> 26) & 0x3f; in ethoc_set_multicast_list() local
863 hash[bit >> 5] |= 1 << (bit & 0x1f); in ethoc_set_multicast_list()
873 return -ENOSYS; in ethoc_change_mtu()
881 ethoc_interrupt(dev->irq, dev); in ethoc_tx_timeout()
892 dev->stats.tx_errors++; in ethoc_start_xmit()
896 if (unlikely(skb->len > ETHOC_BUFSIZ)) { in ethoc_start_xmit()
897 dev->stats.tx_errors++; in ethoc_start_xmit()
901 entry = priv->cur_tx % priv->num_tx; in ethoc_start_xmit()
902 spin_lock_irq(&priv->lock); in ethoc_start_xmit()
903 priv->cur_tx++; in ethoc_start_xmit()
906 if (unlikely(skb->len < ETHOC_ZLEN)) in ethoc_start_xmit()
911 dest = priv->vma[entry]; in ethoc_start_xmit()
912 memcpy_toio(dest, skb->data, skb->len); in ethoc_start_xmit()
915 bd.stat |= TX_BD_LEN(skb->len); in ethoc_start_xmit()
921 if (priv->cur_tx == (priv->dty_tx + priv->num_tx)) { in ethoc_start_xmit()
922 dev_dbg(&dev->dev, "stopping queue\n"); in ethoc_start_xmit()
926 spin_unlock_irq(&priv->lock); in ethoc_start_xmit()
946 regs->version = 0; in ethoc_get_regs()
956 ring->rx_max_pending = priv->num_bd - 1; in ethoc_get_ringparam()
957 ring->rx_mini_max_pending = 0; in ethoc_get_ringparam()
958 ring->rx_jumbo_max_pending = 0; in ethoc_get_ringparam()
959 ring->tx_max_pending = priv->num_bd - 1; in ethoc_get_ringparam()
961 ring->rx_pending = priv->num_rx; in ethoc_get_ringparam()
962 ring->rx_mini_pending = 0; in ethoc_get_ringparam()
963 ring->rx_jumbo_pending = 0; in ethoc_get_ringparam()
964 ring->tx_pending = priv->num_tx; in ethoc_get_ringparam()
972 if (ring->tx_pending < 1 || ring->rx_pending < 1 || in ethoc_set_ringparam()
973 ring->tx_pending + ring->rx_pending > priv->num_bd) in ethoc_set_ringparam()
974 return -EINVAL; in ethoc_set_ringparam()
975 if (ring->rx_mini_pending || ring->rx_jumbo_pending) in ethoc_set_ringparam()
976 return -EINVAL; in ethoc_set_ringparam()
982 synchronize_irq(dev->irq); in ethoc_set_ringparam()
985 priv->num_tx = rounddown_pow_of_two(ring->tx_pending); in ethoc_set_ringparam()
986 priv->num_rx = ring->rx_pending; in ethoc_set_ringparam()
987 ethoc_init_ring(priv, dev->mem_start); in ethoc_set_ringparam()
1021 * ethoc_probe - initialize OpenCores ethernet MAC
1033 struct ethoc_platform_data *pdata = dev_get_platdata(&pdev->dev); in ethoc_probe()
1034 u32 eth_clkfreq = pdata ? pdata->eth_clkfreq : 0; in ethoc_probe()
1039 ret = -ENOMEM; in ethoc_probe()
1043 SET_NETDEV_DEV(netdev, &pdev->dev); in ethoc_probe()
1049 dev_err(&pdev->dev, "cannot obtain I/O memory space\n"); in ethoc_probe()
1050 ret = -ENXIO; in ethoc_probe()
1054 mmio = devm_request_mem_region(&pdev->dev, res->start, in ethoc_probe()
1055 resource_size(res), res->name); in ethoc_probe()
1057 dev_err(&pdev->dev, "cannot request I/O memory space\n"); in ethoc_probe()
1058 ret = -ENXIO; in ethoc_probe()
1062 netdev->base_addr = mmio->start; in ethoc_probe()
1067 mem = devm_request_mem_region(&pdev->dev, res->start, in ethoc_probe()
1068 resource_size(res), res->name); in ethoc_probe()
1070 dev_err(&pdev->dev, "cannot request memory space\n"); in ethoc_probe()
1071 ret = -ENXIO; in ethoc_probe()
1075 netdev->mem_start = mem->start; in ethoc_probe()
1076 netdev->mem_end = mem->end; in ethoc_probe()
1083 dev_err(&pdev->dev, "cannot obtain IRQ\n"); in ethoc_probe()
1084 ret = -ENXIO; in ethoc_probe()
1088 netdev->irq = res->start; in ethoc_probe()
1090 /* setup driver-private data */ in ethoc_probe()
1092 priv->netdev = netdev; in ethoc_probe()
1094 priv->iobase = devm_ioremap(&pdev->dev, netdev->base_addr, in ethoc_probe()
1096 if (!priv->iobase) { in ethoc_probe()
1097 dev_err(&pdev->dev, "cannot remap I/O memory space\n"); in ethoc_probe()
1098 ret = -ENXIO; in ethoc_probe()
1102 if (netdev->mem_end) { in ethoc_probe()
1103 priv->membase = devm_ioremap(&pdev->dev, in ethoc_probe()
1104 netdev->mem_start, resource_size(mem)); in ethoc_probe()
1105 if (!priv->membase) { in ethoc_probe()
1106 dev_err(&pdev->dev, "cannot remap memory space\n"); in ethoc_probe()
1107 ret = -ENXIO; in ethoc_probe()
1112 priv->membase = dmam_alloc_coherent(&pdev->dev, in ethoc_probe()
1113 buffer_size, (void *)&netdev->mem_start, in ethoc_probe()
1115 if (!priv->membase) { in ethoc_probe()
1116 dev_err(&pdev->dev, "cannot allocate %dB buffer\n", in ethoc_probe()
1118 ret = -ENOMEM; in ethoc_probe()
1121 netdev->mem_end = netdev->mem_start + buffer_size; in ethoc_probe()
1124 priv->big_endian = pdata ? pdata->big_endian : in ethoc_probe()
1125 of_device_is_big_endian(pdev->dev.of_node); in ethoc_probe()
1129 128, (netdev->mem_end - netdev->mem_start + 1) / ETHOC_BUFSIZ); in ethoc_probe()
1131 ret = -ENODEV; in ethoc_probe()
1134 priv->num_bd = num_bd; in ethoc_probe()
1136 priv->num_tx = rounddown_pow_of_two(num_bd >> 1); in ethoc_probe()
1137 priv->num_rx = num_bd - priv->num_tx; in ethoc_probe()
1139 dev_dbg(&pdev->dev, "ethoc: num_tx: %d num_rx: %d\n", in ethoc_probe()
1140 priv->num_tx, priv->num_rx); in ethoc_probe()
1142 priv->vma = devm_kcalloc(&pdev->dev, num_bd, sizeof(void *), in ethoc_probe()
1144 if (!priv->vma) { in ethoc_probe()
1145 ret = -ENOMEM; in ethoc_probe()
1151 ether_addr_copy(netdev->dev_addr, pdata->hwaddr); in ethoc_probe()
1152 priv->phy_id = pdata->phy_id; in ethoc_probe()
1156 mac = of_get_mac_address(pdev->dev.of_node); in ethoc_probe()
1158 ether_addr_copy(netdev->dev_addr, mac); in ethoc_probe()
1159 priv->phy_id = -1; in ethoc_probe()
1165 if (!is_valid_ether_addr(netdev->dev_addr)) in ethoc_probe()
1166 ethoc_get_mac_address(netdev, netdev->dev_addr); in ethoc_probe()
1171 if (!is_valid_ether_addr(netdev->dev_addr)) in ethoc_probe()
1178 struct clk *clk = devm_clk_get(&pdev->dev, NULL); in ethoc_probe()
1181 priv->clk = clk; in ethoc_probe()
1187 u32 clkdiv = MIIMODER_CLKDIV(eth_clkfreq / 2500000 + 1); in ethoc_probe() local
1189 if (!clkdiv) in ethoc_probe()
1190 clkdiv = 2; in ethoc_probe()
1191 dev_dbg(&pdev->dev, "setting MII clkdiv to %u\n", clkdiv); in ethoc_probe()
1194 clkdiv); in ethoc_probe()
1198 priv->mdio = mdiobus_alloc(); in ethoc_probe()
1199 if (!priv->mdio) { in ethoc_probe()
1200 ret = -ENOMEM; in ethoc_probe()
1204 priv->mdio->name = "ethoc-mdio"; in ethoc_probe()
1205 snprintf(priv->mdio->id, MII_BUS_ID_SIZE, "%s-%d", in ethoc_probe()
1206 priv->mdio->name, pdev->id); in ethoc_probe()
1207 priv->mdio->read = ethoc_mdio_read; in ethoc_probe()
1208 priv->mdio->write = ethoc_mdio_write; in ethoc_probe()
1209 priv->mdio->priv = priv; in ethoc_probe()
1211 ret = mdiobus_register(priv->mdio); in ethoc_probe()
1213 dev_err(&netdev->dev, "failed to register MDIO bus\n"); in ethoc_probe()
1219 dev_err(&netdev->dev, "failed to probe MDIO bus\n"); in ethoc_probe()
1224 netdev->netdev_ops = ðoc_netdev_ops; in ethoc_probe()
1225 netdev->watchdog_timeo = ETHOC_TIMEOUT; in ethoc_probe()
1226 netdev->features |= 0; in ethoc_probe()
1227 netdev->ethtool_ops = ðoc_ethtool_ops; in ethoc_probe()
1230 netif_napi_add(netdev, &priv->napi, ethoc_poll, 64); in ethoc_probe()
1232 spin_lock_init(&priv->lock); in ethoc_probe()
1236 dev_err(&netdev->dev, "failed to register interface\n"); in ethoc_probe()
1243 netif_napi_del(&priv->napi); in ethoc_probe()
1245 mdiobus_unregister(priv->mdio); in ethoc_probe()
1247 mdiobus_free(priv->mdio); in ethoc_probe()
1249 clk_disable_unprepare(priv->clk); in ethoc_probe()
1257 * ethoc_remove - shutdown OpenCores ethernet MAC
1266 netif_napi_del(&priv->napi); in ethoc_remove()
1267 phy_disconnect(netdev->phydev); in ethoc_remove()
1269 if (priv->mdio) { in ethoc_remove()
1270 mdiobus_unregister(priv->mdio); in ethoc_remove()
1271 mdiobus_free(priv->mdio); in ethoc_remove()
1273 clk_disable_unprepare(priv->clk); in ethoc_remove()
1284 return -ENOSYS; in ethoc_suspend()
1289 return -ENOSYS; in ethoc_resume()
1315 MODULE_AUTHOR("Thierry Reding <thierry.reding@avionic-design.de>");