Lines Matching +full:speed +full:- +full:map
1 // SPDX-License-Identifier: GPL-2.0-or-later
155 #define TX_NEXT(N) (((N) + 1) & (TX_DESC_NUM-1))
156 #define RX_NEXT(N) (((N) + 1) & (RX_DESC_NUM-1))
165 #define DRV_NAME "hip04-ether"
218 unsigned int speed; member
244 struct regmap *map; member
253 return (head - tail) % TX_DESC_NUM; in tx_count()
256 static void hip04_config_port(struct net_device *ndev, u32 speed, u32 duplex) in hip04_config_port() argument
261 priv->speed = speed; in hip04_config_port()
262 priv->duplex = duplex; in hip04_config_port()
264 switch (priv->phy_mode) { in hip04_config_port()
266 if (speed == SPEED_1000) in hip04_config_port()
268 else if (speed == SPEED_100) in hip04_config_port()
274 if (speed == SPEED_100) in hip04_config_port()
284 writel_relaxed(val, priv->base + GE_PORT_MODE); in hip04_config_port()
287 writel_relaxed(val, priv->base + GE_DUPLEX_TYPE); in hip04_config_port()
290 writel_relaxed(val, priv->base + GE_MODE_CHANGE_REG); in hip04_config_port()
296 writel_relaxed(RESET_DREQ_ALL, priv->sysctrl_base + SC_PPE_RESET_DREQ); in hip04_reset_dreq()
305 regmap_read(priv->map, priv->port * 4 + PPE_CURR_BUF_CNT, &val); in hip04_reset_ppe()
306 regmap_read(priv->map, priv->port * 4 + PPE_CFG_RX_ADDR, &tmp); in hip04_reset_ppe()
316 val = readl_relaxed(priv->base + PPE_CFG_STS_MODE); in hip04_config_fifo()
318 writel_relaxed(val, priv->base + PPE_CFG_STS_MODE); in hip04_config_fifo()
320 val = BIT(priv->group); in hip04_config_fifo()
321 regmap_write(priv->map, priv->port * 4 + PPE_CFG_POOL_GRP, val); in hip04_config_fifo()
323 val = priv->group << PPE_CFG_QOS_VMID_GRP_SHIFT; in hip04_config_fifo()
325 writel_relaxed(val, priv->base + PPE_CFG_QOS_VMID_GEN); in hip04_config_fifo()
328 regmap_write(priv->map, priv->port * 4 + PPE_CFG_RX_BUF_SIZE, val); in hip04_config_fifo()
332 val |= priv->chan << PPE_CFG_RX_START_SHIFT; in hip04_config_fifo()
333 regmap_write(priv->map, priv->port * 4 + PPE_CFG_RX_FIFO_SIZE, val); in hip04_config_fifo()
336 writel_relaxed(val, priv->base + PPE_CFG_RX_CTRL_REG); in hip04_config_fifo()
339 writel_relaxed(val, priv->base + PPE_CFG_RX_PKT_MODE_REG); in hip04_config_fifo()
342 writel_relaxed(val, priv->base + PPE_CFG_BUS_CTRL_REG); in hip04_config_fifo()
345 writel_relaxed(val, priv->base + PPE_CFG_MAX_FRAME_LEN_REG); in hip04_config_fifo()
348 writel_relaxed(val, priv->base + GE_MAX_FRM_SIZE_REG); in hip04_config_fifo()
351 writel_relaxed(val, priv->base + GE_SHORT_RUNTS_THR_REG); in hip04_config_fifo()
353 val = readl_relaxed(priv->base + GE_TRANSMIT_CONTROL_REG); in hip04_config_fifo()
355 writel_relaxed(val, priv->base + GE_TRANSMIT_CONTROL_REG); in hip04_config_fifo()
358 writel_relaxed(val, priv->base + GE_CF_CRC_STRIP_REG); in hip04_config_fifo()
360 val = readl_relaxed(priv->base + GE_RECV_CONTROL_REG); in hip04_config_fifo()
362 writel_relaxed(val, priv->base + GE_RECV_CONTROL_REG); in hip04_config_fifo()
366 writel_relaxed(val, priv->base + GE_TX_LOCAL_PAGE_REG); in hip04_config_fifo()
376 val = readl_relaxed(priv->base + GE_PORT_EN); in hip04_mac_enable()
378 writel_relaxed(val, priv->base + GE_PORT_EN); in hip04_mac_enable()
382 writel_relaxed(val, priv->base + PPE_RINT); in hip04_mac_enable()
386 writel_relaxed(val, priv->base + PPE_CFG_RX_PKT_INT); in hip04_mac_enable()
389 priv->reg_inten = DEF_INT_MASK; in hip04_mac_enable()
390 writel_relaxed(priv->reg_inten, priv->base + PPE_INTEN); in hip04_mac_enable()
399 priv->reg_inten &= ~(DEF_INT_MASK); in hip04_mac_disable()
400 writel_relaxed(priv->reg_inten, priv->base + PPE_INTEN); in hip04_mac_disable()
403 val = readl_relaxed(priv->base + GE_PORT_EN); in hip04_mac_disable()
405 writel_relaxed(val, priv->base + GE_PORT_EN); in hip04_mac_disable()
413 writel(val, priv->base + PPE_CFG_CPU_ADD_ADDR); in hip04_set_xmit_desc()
421 regmap_write(priv->map, priv->port * 4 + PPE_CFG_RX_ADDR, val); in hip04_set_recv_desc()
426 return readl(priv->base + PPE_HIS_RX_PKT_CNT); in hip04_recv_cnt()
433 writel_relaxed(((ndev->dev_addr[0] << 8) | (ndev->dev_addr[1])), in hip04_update_mac_address()
434 priv->base + GE_STATION_MAC_ADDRESS); in hip04_update_mac_address()
435 writel_relaxed(((ndev->dev_addr[2] << 24) | (ndev->dev_addr[3] << 16) | in hip04_update_mac_address()
436 (ndev->dev_addr[4] << 8) | (ndev->dev_addr[5])), in hip04_update_mac_address()
437 priv->base + GE_STATION_MAC_ADDRESS + 4); in hip04_update_mac_address()
450 unsigned tx_tail = priv->tx_tail; in hip04_tx_reclaim()
456 count = tx_count(READ_ONCE(priv->tx_head), tx_tail); in hip04_tx_reclaim()
461 desc = &priv->tx_desc[tx_tail]; in hip04_tx_reclaim()
462 if (desc->send_addr != 0) { in hip04_tx_reclaim()
464 desc->send_addr = 0; in hip04_tx_reclaim()
469 if (priv->tx_phys[tx_tail]) { in hip04_tx_reclaim()
470 dma_unmap_single(priv->dev, priv->tx_phys[tx_tail], in hip04_tx_reclaim()
471 priv->tx_skb[tx_tail]->len, in hip04_tx_reclaim()
473 priv->tx_phys[tx_tail] = 0; in hip04_tx_reclaim()
476 bytes_compl += priv->tx_skb[tx_tail]->len; in hip04_tx_reclaim()
477 dev_kfree_skb(priv->tx_skb[tx_tail]); in hip04_tx_reclaim()
478 priv->tx_skb[tx_tail] = NULL; in hip04_tx_reclaim()
480 count--; in hip04_tx_reclaim()
483 priv->tx_tail = tx_tail; in hip04_tx_reclaim()
490 if (unlikely(netif_queue_stopped(ndev)) && (count < (TX_DESC_NUM - 1))) in hip04_tx_reclaim()
498 unsigned long ns = priv->tx_coalesce_usecs * NSEC_PER_USEC / 2; in hip04_start_tx_timer()
501 hrtimer_start_range_ns(&priv->tx_coalesce_timer, ns_to_ktime(ns), in hip04_start_tx_timer()
509 struct net_device_stats *stats = &ndev->stats; in hip04_mac_start_xmit()
510 unsigned int tx_head = priv->tx_head, count; in hip04_mac_start_xmit()
511 struct tx_desc *desc = &priv->tx_desc[tx_head]; in hip04_mac_start_xmit()
515 count = tx_count(tx_head, READ_ONCE(priv->tx_tail)); in hip04_mac_start_xmit()
516 if (count == (TX_DESC_NUM - 1)) { in hip04_mac_start_xmit()
521 phys = dma_map_single(priv->dev, skb->data, skb->len, DMA_TO_DEVICE); in hip04_mac_start_xmit()
522 if (dma_mapping_error(priv->dev, phys)) { in hip04_mac_start_xmit()
527 priv->tx_skb[tx_head] = skb; in hip04_mac_start_xmit()
528 priv->tx_phys[tx_head] = phys; in hip04_mac_start_xmit()
530 desc->send_size = (__force u32)cpu_to_be32(skb->len); in hip04_mac_start_xmit()
532 desc->cfg = (__force u32)cpu_to_be32(TX_CLEAR_WB | TX_FINISH_CACHE_INV in hip04_mac_start_xmit()
533 | TX_RELEASE_TO_PPE | priv->port << TX_POOL_SHIFT); in hip04_mac_start_xmit()
534 desc->data_offset = (__force u32)cpu_to_be32(phys & SOC_CACHE_LINE_MASK); in hip04_mac_start_xmit()
535 desc->send_addr = (__force u32)cpu_to_be32(phys & ~SOC_CACHE_LINE_MASK); in hip04_mac_start_xmit()
537 desc->cfg = (__force u32)cpu_to_be32(TX_CLEAR_WB | TX_FINISH_CACHE_INV); in hip04_mac_start_xmit()
538 desc->send_addr = (__force u32)cpu_to_be32(phys); in hip04_mac_start_xmit()
540 phys = priv->tx_desc_dma + tx_head * sizeof(struct tx_desc); in hip04_mac_start_xmit()
541 desc->wb_addr = (__force u32)cpu_to_be32(phys + in hip04_mac_start_xmit()
547 netdev_sent_queue(ndev, skb->len); in hip04_mac_start_xmit()
548 priv->tx_head = TX_NEXT(tx_head); in hip04_mac_start_xmit()
550 stats->tx_bytes += skb->len; in hip04_mac_start_xmit()
551 stats->tx_packets++; in hip04_mac_start_xmit()
557 if (count >= priv->tx_coalesce_frames) { in hip04_mac_start_xmit()
558 if (napi_schedule_prep(&priv->napi)) { in hip04_mac_start_xmit()
560 priv->reg_inten &= ~(RCV_INT); in hip04_mac_start_xmit()
562 priv->base + PPE_INTEN); in hip04_mac_start_xmit()
563 hrtimer_cancel(&priv->tx_coalesce_timer); in hip04_mac_start_xmit()
564 __napi_schedule(&priv->napi); in hip04_mac_start_xmit()
566 } else if (!hrtimer_is_queued(&priv->tx_coalesce_timer)) { in hip04_mac_start_xmit()
577 struct net_device *ndev = priv->ndev; in hip04_rx_poll()
578 struct net_device_stats *stats = &ndev->stats; in hip04_rx_poll()
591 priv->rx_cnt_remaining += hip04_recv_cnt(priv); in hip04_rx_poll()
592 while (priv->rx_cnt_remaining && !last) { in hip04_rx_poll()
593 buf = priv->rx_buf[priv->rx_head]; in hip04_rx_poll()
594 skb = build_skb(buf, priv->rx_buf_size); in hip04_rx_poll()
600 dma_unmap_single(priv->dev, priv->rx_phys[priv->rx_head], in hip04_rx_poll()
602 priv->rx_phys[priv->rx_head] = 0; in hip04_rx_poll()
604 desc = (struct rx_desc *)skb->data; in hip04_rx_poll()
605 len = be16_to_cpu((__force __be16)desc->pkt_len); in hip04_rx_poll()
606 err = be32_to_cpu((__force __be32)desc->pkt_err); in hip04_rx_poll()
613 stats->rx_dropped++; in hip04_rx_poll()
614 stats->rx_errors++; in hip04_rx_poll()
618 skb->protocol = eth_type_trans(skb, ndev); in hip04_rx_poll()
619 napi_gro_receive(&priv->napi, skb); in hip04_rx_poll()
620 stats->rx_packets++; in hip04_rx_poll()
621 stats->rx_bytes += len; in hip04_rx_poll()
626 buf = netdev_alloc_frag(priv->rx_buf_size); in hip04_rx_poll()
629 phys = dma_map_single(priv->dev, buf, in hip04_rx_poll()
631 if (dma_mapping_error(priv->dev, phys)) in hip04_rx_poll()
633 priv->rx_buf[priv->rx_head] = buf; in hip04_rx_poll()
634 priv->rx_phys[priv->rx_head] = phys; in hip04_rx_poll()
637 priv->rx_head = RX_NEXT(priv->rx_head); in hip04_rx_poll()
639 --priv->rx_cnt_remaining; in hip04_rx_poll()
643 if (--priv->rx_cnt_remaining == 0) in hip04_rx_poll()
644 priv->rx_cnt_remaining += hip04_recv_cnt(priv); in hip04_rx_poll()
647 if (!(priv->reg_inten & RCV_INT)) { in hip04_rx_poll()
649 priv->reg_inten |= RCV_INT; in hip04_rx_poll()
650 writel_relaxed(priv->reg_inten, priv->base + PPE_INTEN); in hip04_rx_poll()
665 struct net_device_stats *stats = &ndev->stats; in hip04_mac_interrupt()
666 u32 ists = readl_relaxed(priv->base + PPE_INTSTS); in hip04_mac_interrupt()
671 writel_relaxed(DEF_INT_MASK, priv->base + PPE_RINT); in hip04_mac_interrupt()
675 stats->rx_errors++; in hip04_mac_interrupt()
676 stats->rx_dropped++; in hip04_mac_interrupt()
680 stats->tx_dropped++; in hip04_mac_interrupt()
685 if (ists & RCV_INT && napi_schedule_prep(&priv->napi)) { in hip04_mac_interrupt()
687 priv->reg_inten &= ~(RCV_INT); in hip04_mac_interrupt()
688 writel_relaxed(DEF_INT_MASK & ~RCV_INT, priv->base + PPE_INTEN); in hip04_mac_interrupt()
689 hrtimer_cancel(&priv->tx_coalesce_timer); in hip04_mac_interrupt()
690 __napi_schedule(&priv->napi); in hip04_mac_interrupt()
702 if (napi_schedule_prep(&priv->napi)) { in tx_done()
704 priv->reg_inten &= ~(RCV_INT); in tx_done()
705 writel_relaxed(DEF_INT_MASK & ~RCV_INT, priv->base + PPE_INTEN); in tx_done()
706 __napi_schedule(&priv->napi); in tx_done()
715 struct phy_device *phy = priv->phy; in hip04_adjust_link()
717 if ((priv->speed != phy->speed) || (priv->duplex != phy->duplex)) { in hip04_adjust_link()
718 hip04_config_port(ndev, phy->speed, phy->duplex); in hip04_adjust_link()
728 priv->rx_head = 0; in hip04_mac_open()
729 priv->rx_cnt_remaining = 0; in hip04_mac_open()
730 priv->tx_head = 0; in hip04_mac_open()
731 priv->tx_tail = 0; in hip04_mac_open()
737 phys = dma_map_single(priv->dev, priv->rx_buf[i], in hip04_mac_open()
739 if (dma_mapping_error(priv->dev, phys)) in hip04_mac_open()
740 return -EIO; in hip04_mac_open()
742 priv->rx_phys[i] = phys; in hip04_mac_open()
746 if (priv->phy) in hip04_mac_open()
747 phy_start(priv->phy); in hip04_mac_open()
752 napi_enable(&priv->napi); in hip04_mac_open()
762 napi_disable(&priv->napi); in hip04_mac_stop()
768 if (priv->phy) in hip04_mac_stop()
769 phy_stop(priv->phy); in hip04_mac_stop()
772 if (priv->rx_phys[i]) { in hip04_mac_stop()
773 dma_unmap_single(priv->dev, priv->rx_phys[i], in hip04_mac_stop()
775 priv->rx_phys[i] = 0; in hip04_mac_stop()
786 schedule_work(&priv->tx_timeout_task); in hip04_timeout()
794 hip04_mac_stop(priv->ndev); in hip04_tx_timeout_task()
795 hip04_mac_open(priv->ndev); in hip04_tx_timeout_task()
805 ec->tx_coalesce_usecs = priv->tx_coalesce_usecs; in hip04_get_coalesce()
806 ec->tx_max_coalesced_frames = priv->tx_coalesce_frames; in hip04_get_coalesce()
818 if ((ec->tx_coalesce_usecs > HIP04_MAX_TX_COALESCE_USECS || in hip04_set_coalesce()
819 ec->tx_coalesce_usecs < HIP04_MIN_TX_COALESCE_USECS) || in hip04_set_coalesce()
820 (ec->tx_max_coalesced_frames > HIP04_MAX_TX_COALESCE_FRAMES || in hip04_set_coalesce()
821 ec->tx_max_coalesced_frames < HIP04_MIN_TX_COALESCE_FRAMES)) in hip04_set_coalesce()
822 return -EINVAL; in hip04_set_coalesce()
824 priv->tx_coalesce_usecs = ec->tx_coalesce_usecs; in hip04_set_coalesce()
825 priv->tx_coalesce_frames = ec->tx_max_coalesced_frames; in hip04_set_coalesce()
833 strscpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver)); in hip04_get_drvinfo()
834 strscpy(drvinfo->version, DRV_VERSION, sizeof(drvinfo->version)); in hip04_get_drvinfo()
859 priv->tx_desc = dma_alloc_coherent(d, in hip04_alloc_ring()
861 &priv->tx_desc_dma, GFP_KERNEL); in hip04_alloc_ring()
862 if (!priv->tx_desc) in hip04_alloc_ring()
863 return -ENOMEM; in hip04_alloc_ring()
865 priv->rx_buf_size = RX_BUF_SIZE + in hip04_alloc_ring()
868 priv->rx_buf[i] = netdev_alloc_frag(priv->rx_buf_size); in hip04_alloc_ring()
869 if (!priv->rx_buf[i]) in hip04_alloc_ring()
870 return -ENOMEM; in hip04_alloc_ring()
882 if (priv->rx_buf[i]) in hip04_free_ring()
883 skb_free_frag(priv->rx_buf[i]); in hip04_free_ring()
886 if (priv->tx_skb[i]) in hip04_free_ring()
887 dev_kfree_skb_any(priv->tx_skb[i]); in hip04_free_ring()
890 priv->tx_desc, priv->tx_desc_dma); in hip04_free_ring()
895 struct device *d = &pdev->dev; in hip04_mac_probe()
896 struct device_node *node = d->of_node; in hip04_mac_probe()
905 return -ENOMEM; in hip04_mac_probe()
908 priv->dev = d; in hip04_mac_probe()
909 priv->ndev = ndev; in hip04_mac_probe()
911 SET_NETDEV_DEV(ndev, &pdev->dev); in hip04_mac_probe()
913 priv->base = devm_platform_ioremap_resource(pdev, 0); in hip04_mac_probe()
914 if (IS_ERR(priv->base)) { in hip04_mac_probe()
915 ret = PTR_ERR(priv->base); in hip04_mac_probe()
920 priv->sysctrl_base = devm_platform_ioremap_resource(pdev, 1); in hip04_mac_probe()
921 if (IS_ERR(priv->sysctrl_base)) { in hip04_mac_probe()
922 ret = PTR_ERR(priv->sysctrl_base); in hip04_mac_probe()
927 ret = of_parse_phandle_with_fixed_args(node, "port-handle", 3, 0, &arg); in hip04_mac_probe()
929 dev_warn(d, "no port-handle\n"); in hip04_mac_probe()
933 priv->port = arg.args[0]; in hip04_mac_probe()
934 priv->chan = arg.args[1] * RX_DESC_NUM; in hip04_mac_probe()
935 priv->group = arg.args[2]; in hip04_mac_probe()
937 hrtimer_init(&priv->tx_coalesce_timer, CLOCK_MONOTONIC, HRTIMER_MODE_REL); in hip04_mac_probe()
945 priv->tx_coalesce_frames = TX_DESC_NUM * 3 / 4; in hip04_mac_probe()
946 priv->tx_coalesce_usecs = 200; in hip04_mac_probe()
947 priv->tx_coalesce_timer.function = tx_done; in hip04_mac_probe()
949 priv->map = syscon_node_to_regmap(arg.np); in hip04_mac_probe()
951 if (IS_ERR(priv->map)) { in hip04_mac_probe()
952 dev_warn(d, "no syscon hisilicon,hip04-ppe\n"); in hip04_mac_probe()
953 ret = PTR_ERR(priv->map); in hip04_mac_probe()
957 ret = of_get_phy_mode(node, &priv->phy_mode); in hip04_mac_probe()
959 dev_warn(d, "not find phy-mode\n"); in hip04_mac_probe()
970 0, pdev->name, ndev); in hip04_mac_probe()
976 priv->phy_node = of_parse_phandle(node, "phy-handle", 0); in hip04_mac_probe()
977 if (priv->phy_node) { in hip04_mac_probe()
978 priv->phy = of_phy_connect(ndev, priv->phy_node, in hip04_mac_probe()
980 0, priv->phy_mode); in hip04_mac_probe()
981 if (!priv->phy) { in hip04_mac_probe()
982 ret = -EPROBE_DEFER; in hip04_mac_probe()
987 INIT_WORK(&priv->tx_timeout_task, hip04_tx_timeout_task); in hip04_mac_probe()
989 ndev->netdev_ops = &hip04_netdev_ops; in hip04_mac_probe()
990 ndev->ethtool_ops = &hip04_ethtool_ops; in hip04_mac_probe()
991 ndev->watchdog_timeo = TX_TIMEOUT; in hip04_mac_probe()
992 ndev->priv_flags |= IFF_UNICAST_FLT; in hip04_mac_probe()
993 ndev->irq = irq; in hip04_mac_probe()
994 netif_napi_add(ndev, &priv->napi, hip04_rx_poll); in hip04_mac_probe()
998 if (priv->phy_mode == PHY_INTERFACE_MODE_MII) in hip04_mac_probe()
1020 of_node_put(priv->phy_node); in hip04_mac_probe()
1029 struct device *d = &pdev->dev; in hip04_remove()
1031 if (priv->phy) in hip04_remove()
1032 phy_disconnect(priv->phy); in hip04_remove()
1036 of_node_put(priv->phy_node); in hip04_remove()
1037 cancel_work_sync(&priv->tx_timeout_task); in hip04_remove()
1042 { .compatible = "hisilicon,hip04-mac" },