Lines Matching +full:port +full:- +full:base
1 // SPDX-License-Identifier: GPL-2.0
11 * Michał Mirosław <mirq-linux@rere.qmqm.pl>
22 #include <linux/dma-mapping.h>
46 #define DRV_NAME "gmac-gemini"
49 static int debug = -1;
85 * struct gmac_queue_page - page buffer per-page info
150 void __iomem *base; member
155 spinlock_t irq_lock; /* Locks IRQ-related registers */
226 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_update_config0_reg() local
230 spin_lock_irqsave(&port->config_lock, flags); in gmac_update_config0_reg()
232 reg = readl(port->gmac_base + GMAC_CONFIG0); in gmac_update_config0_reg()
234 writel(reg, port->gmac_base + GMAC_CONFIG0); in gmac_update_config0_reg()
236 spin_unlock_irqrestore(&port->config_lock, flags); in gmac_update_config0_reg()
241 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_enable_tx_rx() local
245 spin_lock_irqsave(&port->config_lock, flags); in gmac_enable_tx_rx()
247 reg = readl(port->gmac_base + GMAC_CONFIG0); in gmac_enable_tx_rx()
249 writel(reg, port->gmac_base + GMAC_CONFIG0); in gmac_enable_tx_rx()
251 spin_unlock_irqrestore(&port->config_lock, flags); in gmac_enable_tx_rx()
256 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_disable_tx_rx() local
260 spin_lock_irqsave(&port->config_lock, flags); in gmac_disable_tx_rx()
262 val = readl(port->gmac_base + GMAC_CONFIG0); in gmac_disable_tx_rx()
264 writel(val, port->gmac_base + GMAC_CONFIG0); in gmac_disable_tx_rx()
266 spin_unlock_irqrestore(&port->config_lock, flags); in gmac_disable_tx_rx()
273 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_set_flow_control() local
277 spin_lock_irqsave(&port->config_lock, flags); in gmac_set_flow_control()
279 val = readl(port->gmac_base + GMAC_CONFIG0); in gmac_set_flow_control()
285 writel(val, port->gmac_base + GMAC_CONFIG0); in gmac_set_flow_control()
287 spin_unlock_irqrestore(&port->config_lock, flags); in gmac_set_flow_control()
292 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_speed_set() local
293 struct phy_device *phydev = netdev->phydev; in gmac_speed_set()
298 status.bits32 = readl(port->gmac_base + GMAC_STATUS); in gmac_speed_set()
300 status.bits.link = phydev->link; in gmac_speed_set()
301 status.bits.duplex = phydev->duplex; in gmac_speed_set()
303 switch (phydev->speed) { in gmac_speed_set()
306 if (phy_interface_mode_is_rgmii(phydev->interface)) in gmac_speed_set()
313 if (phy_interface_mode_is_rgmii(phydev->interface)) in gmac_speed_set()
320 if (phy_interface_mode_is_rgmii(phydev->interface)) in gmac_speed_set()
327 phydev->speed, phydev_name(phydev)); in gmac_speed_set()
330 if (phydev->duplex == DUPLEX_FULL) { in gmac_speed_set()
346 if (netif_msg_link(port)) { in gmac_speed_set()
349 phydev->pause in gmac_speed_set()
350 ? (phydev->asym_pause ? "tx" : "both") in gmac_speed_set()
351 : (phydev->asym_pause ? "rx" : "none") in gmac_speed_set()
356 writel(status.bits32, port->gmac_base + GMAC_STATUS); in gmac_speed_set()
362 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_setup_phy() local
364 struct device *dev = port->dev; in gmac_setup_phy()
368 dev->of_node, in gmac_setup_phy()
371 return -ENODEV; in gmac_setup_phy()
372 netdev->phydev = phy; in gmac_setup_phy()
378 switch (phy->interface) { in gmac_setup_phy()
400 netdev->phydev = NULL; in gmac_setup_phy()
401 return -EINVAL; in gmac_setup_phy()
403 writel(status.bits32, port->gmac_base + GMAC_STATUS); in gmac_setup_phy()
405 if (netif_msg_link(port)) in gmac_setup_phy()
457 if (maxtot <= maxlen->max_l3_len) in gmac_pick_rx_max_len()
458 return maxlen->val; in gmac_pick_rx_max_len()
461 return -1; in gmac_pick_rx_max_len()
466 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_init() local
516 config0.bits.max_len = gmac_pick_rx_max_len(netdev->mtu); in gmac_init()
517 tmp.bits32 = readl(port->gmac_base + GMAC_CONFIG0); in gmac_init()
519 writel(config0.bits32, port->gmac_base + GMAC_CONFIG0); in gmac_init()
520 writel(config1.bits32, port->gmac_base + GMAC_CONFIG1); in gmac_init()
521 writel(config2.bits32, port->gmac_base + GMAC_CONFIG2); in gmac_init()
522 writel(config3.bits32, port->gmac_base + GMAC_CONFIG3); in gmac_init()
524 readl(port->dma_base + GMAC_AHB_WEIGHT_REG); in gmac_init()
525 writel(ahb_weight.bits32, port->dma_base + GMAC_AHB_WEIGHT_REG); in gmac_init()
528 port->dma_base + GMAC_TX_WEIGHTING_CTRL_0_REG); in gmac_init()
530 port->dma_base + GMAC_TX_WEIGHTING_CTRL_1_REG); in gmac_init()
532 port->rxq_order = DEFAULT_GMAC_RXQ_ORDER; in gmac_init()
533 port->txq_order = DEFAULT_GMAC_TXQ_ORDER; in gmac_init()
534 port->rx_coalesce_nsecs = DEFAULT_RX_COALESCE_NSECS; in gmac_init()
539 port->irq_every_tx_packets = 1 << (port->txq_order - 2); in gmac_init()
546 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_setup_txqs() local
547 unsigned int n_txq = netdev->num_tx_queues; in gmac_setup_txqs()
548 struct gemini_ethernet *geth = port->geth; in gmac_setup_txqs()
549 size_t entries = 1 << port->txq_order; in gmac_setup_txqs()
550 struct gmac_txq *txq = port->txq; in gmac_setup_txqs()
558 rwptr_reg = port->dma_base + GMAC_SW_TX_QUEUE0_PTR_REG; in gmac_setup_txqs()
562 return -ENOMEM; in gmac_setup_txqs()
564 desc_ring = dma_alloc_coherent(geth->dev, len * sizeof(*desc_ring), in gmac_setup_txqs()
565 &port->txq_dma_base, GFP_KERNEL); in gmac_setup_txqs()
569 return -ENOMEM; in gmac_setup_txqs()
572 if (port->txq_dma_base & ~DMA_Q_BASE_MASK) { in gmac_setup_txqs()
573 dev_warn(geth->dev, "TX queue base is not aligned\n"); in gmac_setup_txqs()
574 dma_free_coherent(geth->dev, len * sizeof(*desc_ring), in gmac_setup_txqs()
575 desc_ring, port->txq_dma_base); in gmac_setup_txqs()
577 return -ENOMEM; in gmac_setup_txqs()
580 writel(port->txq_dma_base | port->txq_order, in gmac_setup_txqs()
581 port->dma_base + GMAC_SW_TX_QUEUE_BASE_REG); in gmac_setup_txqs()
584 txq->ring = desc_ring; in gmac_setup_txqs()
585 txq->skb = skb_tab; in gmac_setup_txqs()
586 txq->noirq_packets = 0; in gmac_setup_txqs()
592 txq->cptr = r; in gmac_setup_txqs()
605 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_clean_txq() local
606 unsigned int m = (1 << port->txq_order) - 1; in gmac_clean_txq()
607 struct gemini_ethernet *geth = port->geth; in gmac_clean_txq()
608 unsigned int c = txq->cptr; in gmac_clean_txq()
624 txd = txq->ring + c; in gmac_clean_txq()
625 word0 = txd->word0; in gmac_clean_txq()
626 word1 = txd->word1; in gmac_clean_txq()
627 mapping = txd->word2.buf_adr; in gmac_clean_txq()
628 word3 = txd->word3.bits32; in gmac_clean_txq()
630 dma_unmap_single(geth->dev, mapping, in gmac_clean_txq()
634 dev_kfree_skb(txq->skb[c]); in gmac_clean_txq()
648 bytes += txd->word1.bits.byte_count; in gmac_clean_txq()
653 nfrags = word0.bits.desc_count - 1; in gmac_clean_txq()
656 nfrags = TX_MAX_FRAGS - 1; in gmac_clean_txq()
658 u64_stats_update_begin(&port->tx_stats_syncp); in gmac_clean_txq()
659 port->tx_frag_stats[nfrags]++; in gmac_clean_txq()
660 u64_stats_update_end(&port->tx_stats_syncp); in gmac_clean_txq()
664 u64_stats_update_begin(&port->ir_stats_syncp); in gmac_clean_txq()
665 port->stats.tx_errors += errs; in gmac_clean_txq()
666 port->stats.tx_packets += pkts; in gmac_clean_txq()
667 port->stats.tx_bytes += bytes; in gmac_clean_txq()
668 port->tx_hw_csummed += hwchksum; in gmac_clean_txq()
669 u64_stats_update_end(&port->ir_stats_syncp); in gmac_clean_txq()
671 txq->cptr = c; in gmac_clean_txq()
676 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_cleanup_txqs() local
677 unsigned int n_txq = netdev->num_tx_queues; in gmac_cleanup_txqs()
678 struct gemini_ethernet *geth = port->geth; in gmac_cleanup_txqs()
682 rwptr_reg = port->dma_base + GMAC_SW_TX_QUEUE0_PTR_REG; in gmac_cleanup_txqs()
690 gmac_clean_txq(netdev, port->txq + i, r); in gmac_cleanup_txqs()
692 writel(0, port->dma_base + GMAC_SW_TX_QUEUE_BASE_REG); in gmac_cleanup_txqs()
694 kfree(port->txq->skb); in gmac_cleanup_txqs()
695 dma_free_coherent(geth->dev, in gmac_cleanup_txqs()
696 n_txq * sizeof(*port->txq->ring) << port->txq_order, in gmac_cleanup_txqs()
697 port->txq->ring, port->txq_dma_base); in gmac_cleanup_txqs()
702 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_setup_rxq() local
703 struct gemini_ethernet *geth = port->geth; in gmac_setup_rxq()
706 qhdr = geth->base + TOE_DEFAULT_Q_HDR_BASE(netdev->dev_id); in gmac_setup_rxq()
707 port->rxq_rwptr = &qhdr->word1; in gmac_setup_rxq()
710 port->rxq_ring = dma_alloc_coherent(geth->dev, in gmac_setup_rxq()
711 sizeof(*port->rxq_ring) << port->rxq_order, in gmac_setup_rxq()
712 &port->rxq_dma_base, GFP_KERNEL); in gmac_setup_rxq()
713 if (!port->rxq_ring) in gmac_setup_rxq()
714 return -ENOMEM; in gmac_setup_rxq()
715 if (port->rxq_dma_base & ~NONTOE_QHDR0_BASE_MASK) { in gmac_setup_rxq()
716 dev_warn(geth->dev, "RX queue base is not aligned\n"); in gmac_setup_rxq()
717 return -ENOMEM; in gmac_setup_rxq()
720 writel(port->rxq_dma_base | port->rxq_order, &qhdr->word0); in gmac_setup_rxq()
721 writel(0, port->rxq_rwptr); in gmac_setup_rxq()
727 struct gemini_ethernet_port *port, in gmac_get_queue_page() argument
737 if (!geth->freeq_pages) { in gmac_get_queue_page()
738 dev_err(geth->dev, "try to get page with no page list\n"); in gmac_get_queue_page()
743 for (i = 0; i < geth->num_freeq_pages; i++) { in gmac_get_queue_page()
744 gpage = &geth->freeq_pages[i]; in gmac_get_queue_page()
745 if (gpage->mapping == mapping) in gmac_get_queue_page()
754 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_cleanup_rxq() local
755 struct gemini_ethernet *geth = port->geth; in gmac_cleanup_rxq()
756 struct gmac_rxdesc *rxd = port->rxq_ring; in gmac_cleanup_rxq()
765 qhdr = geth->base + in gmac_cleanup_rxq()
766 TOE_DEFAULT_Q_HDR_BASE(netdev->dev_id); in gmac_cleanup_rxq()
767 dma_reg = &qhdr->word0; in gmac_cleanup_rxq()
768 ptr_reg = &qhdr->word1; in gmac_cleanup_rxq()
783 r &= ((1 << port->rxq_order) - 1); in gmac_cleanup_rxq()
789 gpage = gmac_get_queue_page(geth, port, mapping + PAGE_SIZE); in gmac_cleanup_rxq()
791 dev_err(geth->dev, "could not find page\n"); in gmac_cleanup_rxq()
795 put_page(gpage->page); in gmac_cleanup_rxq()
798 dma_free_coherent(geth->dev, sizeof(*port->rxq_ring) << port->rxq_order, in gmac_cleanup_rxq()
799 port->rxq_ring, port->rxq_dma_base); in gmac_cleanup_rxq()
818 mapping = dma_map_single(geth->dev, page_address(page), in geth_freeq_alloc_map_page()
820 if (dma_mapping_error(geth->dev, mapping)) { in geth_freeq_alloc_map_page()
831 frag_len = 1 << geth->freeq_frag_order; /* Usually 2048 */ in geth_freeq_alloc_map_page()
832 fpp_order = PAGE_SHIFT - geth->freeq_frag_order; in geth_freeq_alloc_map_page()
833 freeq_entry = geth->freeq_ring + (pn << fpp_order); in geth_freeq_alloc_map_page()
834 dev_dbg(geth->dev, "allocate page %d fragment length %d fragments per page %d, freeq entry %p\n", in geth_freeq_alloc_map_page()
836 for (i = (1 << fpp_order); i > 0; i--) { in geth_freeq_alloc_map_page()
837 freeq_entry->word2.buf_adr = mapping; in geth_freeq_alloc_map_page()
843 gpage = &geth->freeq_pages[pn]; in geth_freeq_alloc_map_page()
844 if (gpage->page) { in geth_freeq_alloc_map_page()
845 mapping = geth->freeq_ring[pn << fpp_order].word2.buf_adr; in geth_freeq_alloc_map_page()
846 dma_unmap_single(geth->dev, mapping, frag_len, DMA_FROM_DEVICE); in geth_freeq_alloc_map_page()
850 put_page(gpage->page); in geth_freeq_alloc_map_page()
854 dev_dbg(geth->dev, "page %d, DMA addr: %08x, page %p\n", in geth_freeq_alloc_map_page()
856 gpage->mapping = mapping; in geth_freeq_alloc_map_page()
857 gpage->page = page; in geth_freeq_alloc_map_page()
863 * geth_fill_freeq() - Fill the freeq with empty fragments to use
871 unsigned int fpp_order = PAGE_SHIFT - geth->freeq_frag_order; in geth_fill_freeq()
879 m_pn = (1 << (geth->freeq_order - fpp_order)) - 1; in geth_fill_freeq()
881 spin_lock_irqsave(&geth->freeq_lock, flags); in geth_fill_freeq()
883 rw.bits32 = readl(geth->base + GLOBAL_SWFQ_RWPTR_REG); in geth_fill_freeq()
885 epn = (rw.bits.rptr >> fpp_order) - 1; in geth_fill_freeq()
893 gpage = &geth->freeq_pages[pn]; in geth_fill_freeq()
894 page = gpage->page; in geth_fill_freeq()
896 dev_dbg(geth->dev, "fill entry %d page ref count %d add %d refs\n", in geth_fill_freeq()
900 unsigned int fl = (pn - epn) & m_pn; in geth_fill_freeq()
917 writew(pn << fpp_order, geth->base + GLOBAL_SWFQ_RWPTR_REG + 2); in geth_fill_freeq()
919 spin_unlock_irqrestore(&geth->freeq_lock, flags); in geth_fill_freeq()
926 unsigned int fpp_order = PAGE_SHIFT - geth->freeq_frag_order; in geth_setup_freeq()
927 unsigned int frag_len = 1 << geth->freeq_frag_order; in geth_setup_freeq()
928 unsigned int len = 1 << geth->freeq_order; in geth_setup_freeq()
935 geth->freeq_ring = dma_alloc_coherent(geth->dev, in geth_setup_freeq()
936 sizeof(*geth->freeq_ring) << geth->freeq_order, in geth_setup_freeq()
937 &geth->freeq_dma_base, GFP_KERNEL); in geth_setup_freeq()
938 if (!geth->freeq_ring) in geth_setup_freeq()
939 return -ENOMEM; in geth_setup_freeq()
940 if (geth->freeq_dma_base & ~DMA_Q_BASE_MASK) { in geth_setup_freeq()
941 dev_warn(geth->dev, "queue ring base is not aligned\n"); in geth_setup_freeq()
945 /* Allocate a mapping to page look-up index */ in geth_setup_freeq()
946 geth->freeq_pages = kcalloc(pages, sizeof(*geth->freeq_pages), in geth_setup_freeq()
948 if (!geth->freeq_pages) in geth_setup_freeq()
950 geth->num_freeq_pages = pages; in geth_setup_freeq()
952 dev_info(geth->dev, "allocate %d pages for queue\n", pages); in geth_setup_freeq()
961 qt.bits32 = readl(geth->base + GLOBAL_QUEUE_THRESHOLD_REG); in geth_setup_freeq()
963 writel(qt.bits32, geth->base + GLOBAL_QUEUE_THRESHOLD_REG); in geth_setup_freeq()
965 skbsz.bits.sw_skb_size = 1 << geth->freeq_frag_order; in geth_setup_freeq()
966 writel(skbsz.bits32, geth->base + GLOBAL_DMA_SKB_SIZE_REG); in geth_setup_freeq()
967 writel(geth->freeq_dma_base | geth->freeq_order, in geth_setup_freeq()
968 geth->base + GLOBAL_SW_FREEQ_BASE_SIZE_REG); in geth_setup_freeq()
977 --pn; in geth_setup_freeq()
978 mapping = geth->freeq_ring[pn << fpp_order].word2.buf_adr; in geth_setup_freeq()
979 dma_unmap_single(geth->dev, mapping, frag_len, DMA_FROM_DEVICE); in geth_setup_freeq()
980 gpage = &geth->freeq_pages[pn]; in geth_setup_freeq()
981 put_page(gpage->page); in geth_setup_freeq()
984 kfree(geth->freeq_pages); in geth_setup_freeq()
986 dma_free_coherent(geth->dev, in geth_setup_freeq()
987 sizeof(*geth->freeq_ring) << geth->freeq_order, in geth_setup_freeq()
988 geth->freeq_ring, geth->freeq_dma_base); in geth_setup_freeq()
989 geth->freeq_ring = NULL; in geth_setup_freeq()
990 return -ENOMEM; in geth_setup_freeq()
994 * geth_cleanup_freeq() - cleanup the DMA mappings and free the queue
999 unsigned int fpp_order = PAGE_SHIFT - geth->freeq_frag_order; in geth_cleanup_freeq()
1000 unsigned int frag_len = 1 << geth->freeq_frag_order; in geth_cleanup_freeq()
1001 unsigned int len = 1 << geth->freeq_order; in geth_cleanup_freeq()
1005 writew(readw(geth->base + GLOBAL_SWFQ_RWPTR_REG), in geth_cleanup_freeq()
1006 geth->base + GLOBAL_SWFQ_RWPTR_REG + 2); in geth_cleanup_freeq()
1007 writel(0, geth->base + GLOBAL_SW_FREEQ_BASE_SIZE_REG); in geth_cleanup_freeq()
1013 mapping = geth->freeq_ring[pn << fpp_order].word2.buf_adr; in geth_cleanup_freeq()
1014 dma_unmap_single(geth->dev, mapping, frag_len, DMA_FROM_DEVICE); in geth_cleanup_freeq()
1016 gpage = &geth->freeq_pages[pn]; in geth_cleanup_freeq()
1017 while (page_ref_count(gpage->page) > 0) in geth_cleanup_freeq()
1018 put_page(gpage->page); in geth_cleanup_freeq()
1021 kfree(geth->freeq_pages); in geth_cleanup_freeq()
1023 dma_free_coherent(geth->dev, in geth_cleanup_freeq()
1024 sizeof(*geth->freeq_ring) << geth->freeq_order, in geth_cleanup_freeq()
1025 geth->freeq_ring, geth->freeq_dma_base); in geth_cleanup_freeq()
1029 * geth_resize_freeq() - resize the software queue depth
1030 * @port: the port requesting the change
1037 static int geth_resize_freeq(struct gemini_ethernet_port *port) in geth_resize_freeq() argument
1039 struct gemini_ethernet *geth = port->geth; in geth_resize_freeq()
1040 struct net_device *netdev = port->netdev; in geth_resize_freeq()
1049 if (netdev->dev_id == 0) in geth_resize_freeq()
1050 other_netdev = geth->port1->netdev; in geth_resize_freeq()
1052 other_netdev = geth->port0->netdev; in geth_resize_freeq()
1055 return -EBUSY; in geth_resize_freeq()
1057 new_size = 1 << (port->rxq_order + 1); in geth_resize_freeq()
1058 netdev_dbg(netdev, "port %d size: %d order %d\n", in geth_resize_freeq()
1059 netdev->dev_id, in geth_resize_freeq()
1061 port->rxq_order); in geth_resize_freeq()
1064 new_size += 1 << (other_port->rxq_order + 1); in geth_resize_freeq()
1065 netdev_dbg(other_netdev, "port %d size: %d order %d\n", in geth_resize_freeq()
1066 other_netdev->dev_id, in geth_resize_freeq()
1067 (1 << (other_port->rxq_order + 1)), in geth_resize_freeq()
1068 other_port->rxq_order); in geth_resize_freeq()
1071 new_order = min(15, ilog2(new_size - 1) + 1); in geth_resize_freeq()
1072 dev_dbg(geth->dev, "set shared queue to size %d order %d\n", in geth_resize_freeq()
1074 if (geth->freeq_order == new_order) in geth_resize_freeq()
1077 spin_lock_irqsave(&geth->irq_lock, flags); in geth_resize_freeq()
1080 en = readl(geth->base + GLOBAL_INTERRUPT_ENABLE_4_REG); in geth_resize_freeq()
1082 writel(en, geth->base + GLOBAL_INTERRUPT_ENABLE_4_REG); in geth_resize_freeq()
1083 spin_unlock_irqrestore(&geth->irq_lock, flags); in geth_resize_freeq()
1086 if (geth->freeq_ring) in geth_resize_freeq()
1090 geth->freeq_order = new_order; in geth_resize_freeq()
1093 /* Restart the interrupts - NOTE if this is the first resize in geth_resize_freeq()
1097 spin_lock_irqsave(&geth->irq_lock, flags); in geth_resize_freeq()
1099 writel(en, geth->base + GLOBAL_INTERRUPT_ENABLE_4_REG); in geth_resize_freeq()
1100 spin_unlock_irqrestore(&geth->irq_lock, flags); in geth_resize_freeq()
1108 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_tx_irq_enable() local
1109 struct gemini_ethernet *geth = port->geth; in gmac_tx_irq_enable()
1112 netdev_dbg(netdev, "%s device %d\n", __func__, netdev->dev_id); in gmac_tx_irq_enable()
1114 mask = GMAC0_IRQ0_TXQ0_INTS << (6 * netdev->dev_id + txq); in gmac_tx_irq_enable()
1117 writel(mask, geth->base + GLOBAL_INTERRUPT_STATUS_0_REG); in gmac_tx_irq_enable()
1119 val = readl(geth->base + GLOBAL_INTERRUPT_ENABLE_0_REG); in gmac_tx_irq_enable()
1121 writel(val, geth->base + GLOBAL_INTERRUPT_ENABLE_0_REG); in gmac_tx_irq_enable()
1135 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_map_tx_bufs() local
1137 unsigned short m = (1 << port->txq_order) - 1; in gmac_map_tx_bufs()
1138 short frag, last_frag = skb_si->nr_frags - 1; in gmac_map_tx_bufs()
1139 struct gemini_ethernet *geth = port->geth; in gmac_map_tx_bufs()
1149 word1 = skb->len; in gmac_map_tx_bufs()
1152 if (skb->len >= ETH_FRAME_LEN) { in gmac_map_tx_bufs()
1161 if (skb->ip_summed == CHECKSUM_PARTIAL) { in gmac_map_tx_bufs()
1167 } else if (skb->ip_summed == CHECKSUM_PARTIAL) { in gmac_map_tx_bufs()
1176 if (skb->protocol == htons(ETH_P_IP)) { in gmac_map_tx_bufs()
1178 tcp = ip_hdr(skb)->protocol == IPPROTO_TCP; in gmac_map_tx_bufs()
1181 tcp = ipv6_hdr(skb)->nexthdr == IPPROTO_TCP; in gmac_map_tx_bufs()
1187 frag = -1; in gmac_map_tx_bufs()
1189 if (frag == -1) { in gmac_map_tx_bufs()
1190 buffer = skb->data; in gmac_map_tx_bufs()
1193 skb_frag = skb_si->frags + frag; in gmac_map_tx_bufs()
1200 txq->skb[w] = skb; in gmac_map_tx_bufs()
1203 mapping = dma_map_single(geth->dev, buffer, buflen, in gmac_map_tx_bufs()
1205 if (dma_mapping_error(geth->dev, mapping)) in gmac_map_tx_bufs()
1208 txd = txq->ring + w; in gmac_map_tx_bufs()
1209 txd->word0.bits32 = buflen; in gmac_map_tx_bufs()
1210 txd->word1.bits32 = word1; in gmac_map_tx_bufs()
1211 txd->word2.buf_adr = mapping; in gmac_map_tx_bufs()
1212 txd->word3.bits32 = word3; in gmac_map_tx_bufs()
1225 w--; in gmac_map_tx_bufs()
1228 dma_unmap_page(geth->dev, txq->ring[w].word2.buf_adr, in gmac_map_tx_bufs()
1229 txq->ring[w].word0.bits.buffer_size, in gmac_map_tx_bufs()
1232 return -ENOMEM; in gmac_map_tx_bufs()
1238 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_start_xmit() local
1239 unsigned short m = (1 << port->txq_order) - 1; in gmac_start_xmit()
1247 if (skb->len >= 0x10000) in gmac_start_xmit()
1251 ptr_reg = port->dma_base + GMAC_SW_TX_QUEUE_PTR_REG(txq_num); in gmac_start_xmit()
1252 txq = &port->txq[txq_num]; in gmac_start_xmit()
1254 nfrags = skb_shinfo(skb)->nr_frags; in gmac_start_xmit()
1260 d = txq->cptr - w - 1; in gmac_start_xmit()
1265 d = txq->cptr - w - 1; in gmac_start_xmit()
1271 d = txq->cptr + nfrags + 16; in gmac_start_xmit()
1273 txq->ring[d].word3.bits.eofie = 1; in gmac_start_xmit()
1276 u64_stats_update_begin(&port->tx_stats_syncp); in gmac_start_xmit()
1277 netdev->stats.tx_fifo_errors++; in gmac_start_xmit()
1278 u64_stats_update_end(&port->tx_stats_syncp); in gmac_start_xmit()
1287 u64_stats_update_begin(&port->tx_stats_syncp); in gmac_start_xmit()
1288 port->tx_frags_linearized++; in gmac_start_xmit()
1289 u64_stats_update_end(&port->tx_stats_syncp); in gmac_start_xmit()
1303 u64_stats_update_begin(&port->tx_stats_syncp); in gmac_start_xmit()
1304 port->stats.tx_dropped++; in gmac_start_xmit()
1305 u64_stats_update_end(&port->tx_stats_syncp); in gmac_start_xmit()
1317 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_enable_irq() local
1318 struct gemini_ethernet *geth = port->geth; in gmac_enable_irq()
1323 netdev->dev_id, enable ? "enable" : "disable"); in gmac_enable_irq()
1324 spin_lock_irqsave(&geth->irq_lock, flags); in gmac_enable_irq()
1326 mask = GMAC0_IRQ0_2 << (netdev->dev_id * 2); in gmac_enable_irq()
1327 val = readl(geth->base + GLOBAL_INTERRUPT_ENABLE_0_REG); in gmac_enable_irq()
1329 writel(val, geth->base + GLOBAL_INTERRUPT_ENABLE_0_REG); in gmac_enable_irq()
1331 mask = DEFAULT_Q0_INT_BIT << netdev->dev_id; in gmac_enable_irq()
1332 val = readl(geth->base + GLOBAL_INTERRUPT_ENABLE_1_REG); in gmac_enable_irq()
1334 writel(val, geth->base + GLOBAL_INTERRUPT_ENABLE_1_REG); in gmac_enable_irq()
1336 mask = GMAC0_IRQ4_8 << (netdev->dev_id * 8); in gmac_enable_irq()
1337 val = readl(geth->base + GLOBAL_INTERRUPT_ENABLE_4_REG); in gmac_enable_irq()
1339 writel(val, geth->base + GLOBAL_INTERRUPT_ENABLE_4_REG); in gmac_enable_irq()
1341 spin_unlock_irqrestore(&geth->irq_lock, flags); in gmac_enable_irq()
1346 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_enable_rx_irq() local
1347 struct gemini_ethernet *geth = port->geth; in gmac_enable_rx_irq()
1351 netdev_dbg(netdev, "%s device %d %s\n", __func__, netdev->dev_id, in gmac_enable_rx_irq()
1353 spin_lock_irqsave(&geth->irq_lock, flags); in gmac_enable_rx_irq()
1354 mask = DEFAULT_Q0_INT_BIT << netdev->dev_id; in gmac_enable_rx_irq()
1356 val = readl(geth->base + GLOBAL_INTERRUPT_ENABLE_1_REG); in gmac_enable_rx_irq()
1358 writel(val, geth->base + GLOBAL_INTERRUPT_ENABLE_1_REG); in gmac_enable_rx_irq()
1360 spin_unlock_irqrestore(&geth->irq_lock, flags); in gmac_enable_rx_irq()
1363 static struct sk_buff *gmac_skb_if_good_frame(struct gemini_ethernet_port *port, in gmac_skb_if_good_frame() argument
1371 port->rx_stats[rx_status]++; in gmac_skb_if_good_frame()
1372 port->rx_csum_stats[rx_csum]++; in gmac_skb_if_good_frame()
1377 port->stats.rx_errors++; in gmac_skb_if_good_frame()
1380 port->stats.rx_length_errors++; in gmac_skb_if_good_frame()
1382 port->stats.rx_over_errors++; in gmac_skb_if_good_frame()
1384 port->stats.rx_crc_errors++; in gmac_skb_if_good_frame()
1386 port->stats.rx_frame_errors++; in gmac_skb_if_good_frame()
1390 skb = napi_get_frags(&port->napi); in gmac_skb_if_good_frame()
1395 skb->ip_summed = CHECKSUM_UNNECESSARY; in gmac_skb_if_good_frame()
1398 port->stats.rx_bytes += frame_len; in gmac_skb_if_good_frame()
1399 port->stats.rx_packets++; in gmac_skb_if_good_frame()
1405 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_rx() local
1406 unsigned short m = (1 << port->rxq_order) - 1; in gmac_rx()
1407 struct gemini_ethernet *geth = port->geth; in gmac_rx()
1408 void __iomem *ptr_reg = port->rxq_rwptr; in gmac_rx()
1425 writel(DEFAULT_Q0_INT_BIT << netdev->dev_id, in gmac_rx()
1426 geth->base + GLOBAL_INTERRUPT_STATUS_1_REG); in gmac_rx()
1431 rx = port->rxq_ring + r; in gmac_rx()
1432 word0 = rx->word0; in gmac_rx()
1433 word1 = rx->word1; in gmac_rx()
1434 mapping = rx->word2.buf_adr; in gmac_rx()
1435 word3 = rx->word3; in gmac_rx()
1451 gpage = gmac_get_queue_page(geth, port, mapping + PAGE_SIZE); in gmac_rx()
1453 dev_err(geth->dev, "could not find mapping\n"); in gmac_rx()
1456 page = gpage->page; in gmac_rx()
1460 napi_free_frags(&port->napi); in gmac_rx()
1461 port->stats.rx_dropped++; in gmac_rx()
1464 skb = gmac_skb_if_good_frame(port, word0, frame_len); in gmac_rx()
1469 frag_len -= NET_IP_ALIGN; in gmac_rx()
1478 frag_len = frame_len - skb->len; in gmac_rx()
1488 skb->len += frag_len; in gmac_rx()
1489 skb->data_len += frag_len; in gmac_rx()
1490 skb->truesize += frag_len; in gmac_rx()
1494 napi_gro_frags(&port->napi); in gmac_rx()
1496 --budget; in gmac_rx()
1502 napi_free_frags(&port->napi); in gmac_rx()
1509 port->stats.rx_dropped++; in gmac_rx()
1518 struct gemini_ethernet_port *port = netdev_priv(napi->dev); in gmac_napi_poll() local
1519 struct gemini_ethernet *geth = port->geth; in gmac_napi_poll()
1523 freeq_threshold = 1 << (geth->freeq_order - 1); in gmac_napi_poll()
1524 u64_stats_update_begin(&port->rx_stats_syncp); in gmac_napi_poll()
1526 received = gmac_rx(napi->dev, budget); in gmac_napi_poll()
1530 gmac_enable_rx_irq(napi->dev, 1); in gmac_napi_poll()
1531 ++port->rx_napi_exits; in gmac_napi_poll()
1534 port->freeq_refill += (budget - received); in gmac_napi_poll()
1535 if (port->freeq_refill > freeq_threshold) { in gmac_napi_poll()
1536 port->freeq_refill -= freeq_threshold; in gmac_napi_poll()
1540 u64_stats_update_end(&port->rx_stats_syncp); in gmac_napi_poll()
1546 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_dump_dma_state() local
1547 struct gemini_ethernet *geth = port->geth; in gmac_dump_dma_state()
1552 reg[0] = readl(geth->base + GLOBAL_INTERRUPT_STATUS_0_REG); in gmac_dump_dma_state()
1553 reg[1] = readl(geth->base + GLOBAL_INTERRUPT_STATUS_1_REG); in gmac_dump_dma_state()
1554 reg[2] = readl(geth->base + GLOBAL_INTERRUPT_STATUS_2_REG); in gmac_dump_dma_state()
1555 reg[3] = readl(geth->base + GLOBAL_INTERRUPT_STATUS_3_REG); in gmac_dump_dma_state()
1556 reg[4] = readl(geth->base + GLOBAL_INTERRUPT_STATUS_4_REG); in gmac_dump_dma_state()
1561 reg[0] = readl(geth->base + GLOBAL_INTERRUPT_ENABLE_0_REG); in gmac_dump_dma_state()
1562 reg[1] = readl(geth->base + GLOBAL_INTERRUPT_ENABLE_1_REG); in gmac_dump_dma_state()
1563 reg[2] = readl(geth->base + GLOBAL_INTERRUPT_ENABLE_2_REG); in gmac_dump_dma_state()
1564 reg[3] = readl(geth->base + GLOBAL_INTERRUPT_ENABLE_3_REG); in gmac_dump_dma_state()
1565 reg[4] = readl(geth->base + GLOBAL_INTERRUPT_ENABLE_4_REG); in gmac_dump_dma_state()
1570 reg[0] = readl(port->dma_base + GMAC_DMA_RX_FIRST_DESC_REG); in gmac_dump_dma_state()
1571 reg[1] = readl(port->dma_base + GMAC_DMA_RX_CURR_DESC_REG); in gmac_dump_dma_state()
1572 reg[2] = GET_RPTR(port->rxq_rwptr); in gmac_dump_dma_state()
1573 reg[3] = GET_WPTR(port->rxq_rwptr); in gmac_dump_dma_state()
1577 reg[0] = readl(port->dma_base + GMAC_DMA_RX_DESC_WORD0_REG); in gmac_dump_dma_state()
1578 reg[1] = readl(port->dma_base + GMAC_DMA_RX_DESC_WORD1_REG); in gmac_dump_dma_state()
1579 reg[2] = readl(port->dma_base + GMAC_DMA_RX_DESC_WORD2_REG); in gmac_dump_dma_state()
1580 reg[3] = readl(port->dma_base + GMAC_DMA_RX_DESC_WORD3_REG); in gmac_dump_dma_state()
1585 ptr_reg = port->dma_base + GMAC_SW_TX_QUEUE0_PTR_REG; in gmac_dump_dma_state()
1587 reg[0] = readl(port->dma_base + GMAC_DMA_TX_FIRST_DESC_REG); in gmac_dump_dma_state()
1588 reg[1] = readl(port->dma_base + GMAC_DMA_TX_CURR_DESC_REG); in gmac_dump_dma_state()
1594 reg[0] = readl(port->dma_base + GMAC_DMA_TX_DESC_WORD0_REG); in gmac_dump_dma_state()
1595 reg[1] = readl(port->dma_base + GMAC_DMA_TX_DESC_WORD1_REG); in gmac_dump_dma_state()
1596 reg[2] = readl(port->dma_base + GMAC_DMA_TX_DESC_WORD2_REG); in gmac_dump_dma_state()
1597 reg[3] = readl(port->dma_base + GMAC_DMA_TX_DESC_WORD3_REG); in gmac_dump_dma_state()
1602 ptr_reg = geth->base + GLOBAL_SWFQ_RWPTR_REG; in gmac_dump_dma_state()
1607 ptr_reg = geth->base + GLOBAL_HWFQ_RWPTR_REG; in gmac_dump_dma_state()
1617 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_update_hw_stats() local
1619 struct gemini_ethernet *geth = port->geth; in gmac_update_hw_stats()
1622 spin_lock_irqsave(&geth->irq_lock, flags); in gmac_update_hw_stats()
1623 u64_stats_update_begin(&port->ir_stats_syncp); in gmac_update_hw_stats()
1625 rx_discards = readl(port->gmac_base + GMAC_IN_DISCARDS); in gmac_update_hw_stats()
1626 port->hw_stats[0] += rx_discards; in gmac_update_hw_stats()
1627 port->hw_stats[1] += readl(port->gmac_base + GMAC_IN_ERRORS); in gmac_update_hw_stats()
1628 rx_mcast = readl(port->gmac_base + GMAC_IN_MCAST); in gmac_update_hw_stats()
1629 port->hw_stats[2] += rx_mcast; in gmac_update_hw_stats()
1630 rx_bcast = readl(port->gmac_base + GMAC_IN_BCAST); in gmac_update_hw_stats()
1631 port->hw_stats[3] += rx_bcast; in gmac_update_hw_stats()
1632 port->hw_stats[4] += readl(port->gmac_base + GMAC_IN_MAC1); in gmac_update_hw_stats()
1633 port->hw_stats[5] += readl(port->gmac_base + GMAC_IN_MAC2); in gmac_update_hw_stats()
1635 port->stats.rx_missed_errors += rx_discards; in gmac_update_hw_stats()
1636 port->stats.multicast += rx_mcast; in gmac_update_hw_stats()
1637 port->stats.multicast += rx_bcast; in gmac_update_hw_stats()
1639 writel(GMAC0_MIB_INT_BIT << (netdev->dev_id * 8), in gmac_update_hw_stats()
1640 geth->base + GLOBAL_INTERRUPT_STATUS_4_REG); in gmac_update_hw_stats()
1642 u64_stats_update_end(&port->ir_stats_syncp); in gmac_update_hw_stats()
1643 spin_unlock_irqrestore(&geth->irq_lock, flags); in gmac_update_hw_stats()
1647 * gmac_get_intr_flags() - get interrupt status flags for a port from
1648 * @netdev: the net device for the port to get flags from
1653 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_get_intr_flags() local
1654 struct gemini_ethernet *geth = port->geth; in gmac_get_intr_flags()
1659 offs = i * (GLOBAL_INTERRUPT_STATUS_1_REG - in gmac_get_intr_flags()
1662 irqif_reg = geth->base + GLOBAL_INTERRUPT_STATUS_0_REG + offs; in gmac_get_intr_flags()
1663 irqen_reg = geth->base + GLOBAL_INTERRUPT_ENABLE_0_REG + offs; in gmac_get_intr_flags()
1671 struct gemini_ethernet_port *port = in gmac_coalesce_delay_expired() local
1675 napi_schedule(&port->napi); in gmac_coalesce_delay_expired()
1681 struct gemini_ethernet_port *port; in gmac_irq() local
1686 port = netdev_priv(netdev); in gmac_irq()
1687 geth = port->geth; in gmac_irq()
1692 if (val & (GMAC0_IRQ0_2 << (netdev->dev_id * 2))) { in gmac_irq()
1702 if (val & (GMAC0_IRQ0_TXQ0_INTS << (netdev->dev_id * 6))) in gmac_irq()
1708 if (val & (DEFAULT_Q0_INT_BIT << netdev->dev_id)) { in gmac_irq()
1711 if (!port->rx_coalesce_nsecs) { in gmac_irq()
1712 napi_schedule(&port->napi); in gmac_irq()
1716 ktime = ktime_set(0, port->rx_coalesce_nsecs); in gmac_irq()
1717 hrtimer_start(&port->rx_coalesce_timer, ktime, in gmac_irq()
1725 if (val & (GMAC0_MIB_INT_BIT << (netdev->dev_id * 8))) in gmac_irq()
1728 if (val & (GMAC0_RX_OVERRUN_INT_BIT << (netdev->dev_id * 8))) { in gmac_irq()
1729 writel(GMAC0_RXDERR_INT_BIT << (netdev->dev_id * 8), in gmac_irq()
1730 geth->base + GLOBAL_INTERRUPT_STATUS_4_REG); in gmac_irq()
1732 spin_lock(&geth->irq_lock); in gmac_irq()
1733 u64_stats_update_begin(&port->ir_stats_syncp); in gmac_irq()
1734 ++port->stats.rx_fifo_errors; in gmac_irq()
1735 u64_stats_update_end(&port->ir_stats_syncp); in gmac_irq()
1736 spin_unlock(&geth->irq_lock); in gmac_irq()
1742 static void gmac_start_dma(struct gemini_ethernet_port *port) in gmac_start_dma() argument
1744 void __iomem *dma_ctrl_reg = port->dma_base + GMAC_DMA_CTRL_REG; in gmac_start_dma()
1763 static void gmac_stop_dma(struct gemini_ethernet_port *port) in gmac_stop_dma() argument
1765 void __iomem *dma_ctrl_reg = port->dma_base + GMAC_DMA_CTRL_REG; in gmac_stop_dma()
1776 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_open() local
1779 err = request_irq(netdev->irq, gmac_irq, in gmac_open()
1780 IRQF_SHARED, netdev->name, netdev); in gmac_open()
1787 phy_start(netdev->phydev); in gmac_open()
1789 err = geth_resize_freeq(port); in gmac_open()
1790 /* It's fine if it's just busy, the other port has set up in gmac_open()
1793 if (err && (err != -EBUSY)) { in gmac_open()
1811 napi_enable(&port->napi); in gmac_open()
1813 gmac_start_dma(port); in gmac_open()
1818 hrtimer_init(&port->rx_coalesce_timer, CLOCK_MONOTONIC, in gmac_open()
1820 port->rx_coalesce_timer.function = &gmac_coalesce_delay_expired; in gmac_open()
1827 phy_stop(netdev->phydev); in gmac_open()
1828 free_irq(netdev->irq, netdev); in gmac_open()
1834 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_stop() local
1836 hrtimer_cancel(&port->rx_coalesce_timer); in gmac_stop()
1839 gmac_stop_dma(port); in gmac_stop()
1840 napi_disable(&port->napi); in gmac_stop()
1846 phy_stop(netdev->phydev); in gmac_stop()
1847 free_irq(netdev->irq, netdev); in gmac_stop()
1855 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_set_rx_mode() local
1868 if (netdev->flags & IFF_PROMISC) { in gmac_set_rx_mode()
1873 } else if (netdev->flags & IFF_ALLMULTI) { in gmac_set_rx_mode()
1878 bit_nr = ~crc32_le(~0, ha->addr, ETH_ALEN) & 0x3f; in gmac_set_rx_mode()
1883 writel(mc_filter[0], port->gmac_base + GMAC_MCAST_FIL0); in gmac_set_rx_mode()
1884 writel(mc_filter[1], port->gmac_base + GMAC_MCAST_FIL1); in gmac_set_rx_mode()
1885 writel(filter.bits32, port->gmac_base + GMAC_RX_FLTR); in gmac_set_rx_mode()
1890 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_write_mac_address() local
1894 memcpy(addr, netdev->dev_addr, ETH_ALEN); in gmac_write_mac_address()
1896 writel(le32_to_cpu(addr[0]), port->gmac_base + GMAC_STA_ADD0); in gmac_write_mac_address()
1897 writel(le32_to_cpu(addr[1]), port->gmac_base + GMAC_STA_ADD1); in gmac_write_mac_address()
1898 writel(le32_to_cpu(addr[2]), port->gmac_base + GMAC_STA_ADD2); in gmac_write_mac_address()
1905 eth_hw_addr_set(netdev, sa->sa_data); in gmac_set_mac_address()
1913 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_clear_hw_stats() local
1915 readl(port->gmac_base + GMAC_IN_DISCARDS); in gmac_clear_hw_stats()
1916 readl(port->gmac_base + GMAC_IN_ERRORS); in gmac_clear_hw_stats()
1917 readl(port->gmac_base + GMAC_IN_MCAST); in gmac_clear_hw_stats()
1918 readl(port->gmac_base + GMAC_IN_BCAST); in gmac_clear_hw_stats()
1919 readl(port->gmac_base + GMAC_IN_MAC1); in gmac_clear_hw_stats()
1920 readl(port->gmac_base + GMAC_IN_MAC2); in gmac_clear_hw_stats()
1926 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_get_stats64() local
1933 start = u64_stats_fetch_begin(&port->rx_stats_syncp); in gmac_get_stats64()
1935 stats->rx_packets = port->stats.rx_packets; in gmac_get_stats64()
1936 stats->rx_bytes = port->stats.rx_bytes; in gmac_get_stats64()
1937 stats->rx_errors = port->stats.rx_errors; in gmac_get_stats64()
1938 stats->rx_dropped = port->stats.rx_dropped; in gmac_get_stats64()
1940 stats->rx_length_errors = port->stats.rx_length_errors; in gmac_get_stats64()
1941 stats->rx_over_errors = port->stats.rx_over_errors; in gmac_get_stats64()
1942 stats->rx_crc_errors = port->stats.rx_crc_errors; in gmac_get_stats64()
1943 stats->rx_frame_errors = port->stats.rx_frame_errors; in gmac_get_stats64()
1945 } while (u64_stats_fetch_retry(&port->rx_stats_syncp, start)); in gmac_get_stats64()
1949 start = u64_stats_fetch_begin(&port->ir_stats_syncp); in gmac_get_stats64()
1951 stats->tx_errors = port->stats.tx_errors; in gmac_get_stats64()
1952 stats->tx_packets = port->stats.tx_packets; in gmac_get_stats64()
1953 stats->tx_bytes = port->stats.tx_bytes; in gmac_get_stats64()
1955 stats->multicast = port->stats.multicast; in gmac_get_stats64()
1956 stats->rx_missed_errors = port->stats.rx_missed_errors; in gmac_get_stats64()
1957 stats->rx_fifo_errors = port->stats.rx_fifo_errors; in gmac_get_stats64()
1959 } while (u64_stats_fetch_retry(&port->ir_stats_syncp, start)); in gmac_get_stats64()
1963 start = u64_stats_fetch_begin(&port->tx_stats_syncp); in gmac_get_stats64()
1965 stats->tx_dropped = port->stats.tx_dropped; in gmac_get_stats64()
1967 } while (u64_stats_fetch_retry(&port->tx_stats_syncp, start)); in gmac_get_stats64()
1969 stats->rx_dropped += stats->rx_missed_errors; in gmac_get_stats64()
1977 return -EINVAL; in gmac_change_mtu()
1981 netdev->mtu = new_mtu; in gmac_change_mtu()
1995 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_set_features() local
2000 spin_lock_irqsave(&port->config_lock, flags); in gmac_set_features()
2002 reg = readl(port->gmac_base + GMAC_CONFIG0); in gmac_set_features()
2004 writel(reg, port->gmac_base + GMAC_CONFIG0); in gmac_set_features()
2006 spin_unlock_irqrestore(&port->config_lock, flags); in gmac_set_features()
2026 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_get_ethtool_stats() local
2036 start = u64_stats_fetch_begin(&port->ir_stats_syncp); in gmac_get_ethtool_stats()
2039 *p++ = port->hw_stats[i]; in gmac_get_ethtool_stats()
2041 } while (u64_stats_fetch_retry(&port->ir_stats_syncp, start)); in gmac_get_ethtool_stats()
2047 start = u64_stats_fetch_begin(&port->rx_stats_syncp); in gmac_get_ethtool_stats()
2050 *p++ = port->rx_stats[i]; in gmac_get_ethtool_stats()
2052 *p++ = port->rx_csum_stats[i]; in gmac_get_ethtool_stats()
2053 *p++ = port->rx_napi_exits; in gmac_get_ethtool_stats()
2055 } while (u64_stats_fetch_retry(&port->rx_stats_syncp, start)); in gmac_get_ethtool_stats()
2061 start = u64_stats_fetch_begin(&port->tx_stats_syncp); in gmac_get_ethtool_stats()
2064 *values++ = port->tx_frag_stats[i]; in gmac_get_ethtool_stats()
2065 port->tx_frag_stats[i] = 0; in gmac_get_ethtool_stats()
2067 *values++ = port->tx_frags_linearized; in gmac_get_ethtool_stats()
2068 *values++ = port->tx_hw_csummed; in gmac_get_ethtool_stats()
2070 } while (u64_stats_fetch_retry(&port->tx_stats_syncp, start)); in gmac_get_ethtool_stats()
2076 if (!netdev->phydev) in gmac_get_ksettings()
2077 return -ENXIO; in gmac_get_ksettings()
2078 phy_ethtool_ksettings_get(netdev->phydev, cmd); in gmac_get_ksettings()
2086 if (!netdev->phydev) in gmac_set_ksettings()
2087 return -ENXIO; in gmac_set_ksettings()
2088 return phy_ethtool_ksettings_set(netdev->phydev, cmd); in gmac_set_ksettings()
2093 if (!netdev->phydev) in gmac_nway_reset()
2094 return -ENXIO; in gmac_nway_reset()
2095 return phy_start_aneg(netdev->phydev); in gmac_nway_reset()
2101 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_get_pauseparam() local
2104 config0.bits32 = readl(port->gmac_base + GMAC_CONFIG0); in gmac_get_pauseparam()
2106 pparam->rx_pause = config0.bits.rx_fc_en; in gmac_get_pauseparam()
2107 pparam->tx_pause = config0.bits.tx_fc_en; in gmac_get_pauseparam()
2108 pparam->autoneg = true; in gmac_get_pauseparam()
2116 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_get_ringparam() local
2118 readl(port->gmac_base + GMAC_CONFIG0); in gmac_get_ringparam()
2120 rp->rx_max_pending = 1 << 15; in gmac_get_ringparam()
2121 rp->rx_mini_max_pending = 0; in gmac_get_ringparam()
2122 rp->rx_jumbo_max_pending = 0; in gmac_get_ringparam()
2123 rp->tx_max_pending = 1 << 15; in gmac_get_ringparam()
2125 rp->rx_pending = 1 << port->rxq_order; in gmac_get_ringparam()
2126 rp->rx_mini_pending = 0; in gmac_get_ringparam()
2127 rp->rx_jumbo_pending = 0; in gmac_get_ringparam()
2128 rp->tx_pending = 1 << port->txq_order; in gmac_get_ringparam()
2136 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_set_ringparam() local
2140 return -EBUSY; in gmac_set_ringparam()
2142 if (rp->rx_pending) { in gmac_set_ringparam()
2143 port->rxq_order = min(15, ilog2(rp->rx_pending - 1) + 1); in gmac_set_ringparam()
2144 err = geth_resize_freeq(port); in gmac_set_ringparam()
2146 if (rp->tx_pending) { in gmac_set_ringparam()
2147 port->txq_order = min(15, ilog2(rp->tx_pending - 1) + 1); in gmac_set_ringparam()
2148 port->irq_every_tx_packets = 1 << (port->txq_order - 2); in gmac_set_ringparam()
2159 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_get_coalesce() local
2161 ecmd->rx_max_coalesced_frames = 1; in gmac_get_coalesce()
2162 ecmd->tx_max_coalesced_frames = port->irq_every_tx_packets; in gmac_get_coalesce()
2163 ecmd->rx_coalesce_usecs = port->rx_coalesce_nsecs / 1000; in gmac_get_coalesce()
2173 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_set_coalesce() local
2175 if (ecmd->tx_max_coalesced_frames < 1) in gmac_set_coalesce()
2176 return -EINVAL; in gmac_set_coalesce()
2177 if (ecmd->tx_max_coalesced_frames >= 1 << port->txq_order) in gmac_set_coalesce()
2178 return -EINVAL; in gmac_set_coalesce()
2180 port->irq_every_tx_packets = ecmd->tx_max_coalesced_frames; in gmac_set_coalesce()
2181 port->rx_coalesce_nsecs = ecmd->rx_coalesce_usecs * 1000; in gmac_set_coalesce()
2188 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_get_msglevel() local
2190 return port->msg_enable; in gmac_get_msglevel()
2195 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_set_msglevel() local
2197 port->msg_enable = level; in gmac_set_msglevel()
2203 strcpy(info->driver, DRV_NAME); in gmac_get_drvinfo()
2204 strcpy(info->bus_info, netdev->dev_id ? "1" : "0"); in gmac_get_drvinfo()
2243 struct gemini_ethernet_port *port = data; in gemini_port_irq_thread() local
2247 geth = port->geth; in gemini_port_irq_thread()
2251 spin_lock_irqsave(&geth->irq_lock, flags); in gemini_port_irq_thread()
2253 writel(irqmask, geth->base + GLOBAL_INTERRUPT_STATUS_4_REG); in gemini_port_irq_thread()
2255 irqmask |= readl(geth->base + GLOBAL_INTERRUPT_ENABLE_4_REG); in gemini_port_irq_thread()
2256 writel(irqmask, geth->base + GLOBAL_INTERRUPT_ENABLE_4_REG); in gemini_port_irq_thread()
2257 spin_unlock_irqrestore(&geth->irq_lock, flags); in gemini_port_irq_thread()
2264 struct gemini_ethernet_port *port = data; in gemini_port_irq() local
2269 geth = port->geth; in gemini_port_irq()
2270 spin_lock(&geth->irq_lock); in gemini_port_irq()
2272 val = readl(geth->base + GLOBAL_INTERRUPT_STATUS_4_REG); in gemini_port_irq()
2273 en = readl(geth->base + GLOBAL_INTERRUPT_ENABLE_4_REG); in gemini_port_irq()
2282 writel(en, geth->base + GLOBAL_INTERRUPT_ENABLE_4_REG); in gemini_port_irq()
2286 spin_unlock(&geth->irq_lock); in gemini_port_irq()
2291 static void gemini_port_remove(struct gemini_ethernet_port *port) in gemini_port_remove() argument
2293 if (port->netdev) { in gemini_port_remove()
2294 phy_disconnect(port->netdev->phydev); in gemini_port_remove()
2295 unregister_netdev(port->netdev); in gemini_port_remove()
2297 clk_disable_unprepare(port->pclk); in gemini_port_remove()
2298 geth_cleanup_freeq(port->geth); in gemini_port_remove()
2304 if (geth->initialized) in gemini_ethernet_init()
2306 if (geth->port0 && geth->port1) in gemini_ethernet_init()
2307 geth->initialized = true; in gemini_ethernet_init()
2311 writel(0, geth->base + GLOBAL_INTERRUPT_ENABLE_0_REG); in gemini_ethernet_init()
2312 writel(0, geth->base + GLOBAL_INTERRUPT_ENABLE_1_REG); in gemini_ethernet_init()
2313 writel(0, geth->base + GLOBAL_INTERRUPT_ENABLE_2_REG); in gemini_ethernet_init()
2314 writel(0, geth->base + GLOBAL_INTERRUPT_ENABLE_3_REG); in gemini_ethernet_init()
2315 writel(0, geth->base + GLOBAL_INTERRUPT_ENABLE_4_REG); in gemini_ethernet_init()
2319 * GMAC0 intr bits ------> int0 ----> eth0 in gemini_ethernet_init()
2320 * GMAC1 intr bits ------> int1 ----> eth1 in gemini_ethernet_init()
2321 * TOE intr -------------> int1 ----> eth1 in gemini_ethernet_init()
2322 * Classification Intr --> int0 ----> eth0 in gemini_ethernet_init()
2323 * Default Q0 -----------> int0 ----> eth0 in gemini_ethernet_init()
2324 * Default Q1 -----------> int1 ----> eth1 in gemini_ethernet_init()
2325 * FreeQ intr -----------> int1 ----> eth1 in gemini_ethernet_init()
2327 writel(0xCCFC0FC0, geth->base + GLOBAL_INTERRUPT_SELECT_0_REG); in gemini_ethernet_init()
2328 writel(0x00F00002, geth->base + GLOBAL_INTERRUPT_SELECT_1_REG); in gemini_ethernet_init()
2329 writel(0xFFFFFFFF, geth->base + GLOBAL_INTERRUPT_SELECT_2_REG); in gemini_ethernet_init()
2330 writel(0xFFFFFFFF, geth->base + GLOBAL_INTERRUPT_SELECT_3_REG); in gemini_ethernet_init()
2331 writel(0xFF000003, geth->base + GLOBAL_INTERRUPT_SELECT_4_REG); in gemini_ethernet_init()
2333 /* edge-triggered interrupts packed to level-triggered one... */ in gemini_ethernet_init()
2334 writel(~0, geth->base + GLOBAL_INTERRUPT_STATUS_0_REG); in gemini_ethernet_init()
2335 writel(~0, geth->base + GLOBAL_INTERRUPT_STATUS_1_REG); in gemini_ethernet_init()
2336 writel(~0, geth->base + GLOBAL_INTERRUPT_STATUS_2_REG); in gemini_ethernet_init()
2337 writel(~0, geth->base + GLOBAL_INTERRUPT_STATUS_3_REG); in gemini_ethernet_init()
2338 writel(~0, geth->base + GLOBAL_INTERRUPT_STATUS_4_REG); in gemini_ethernet_init()
2341 writel(0, geth->base + GLOBAL_SW_FREEQ_BASE_SIZE_REG); in gemini_ethernet_init()
2342 writel(0, geth->base + GLOBAL_HW_FREEQ_BASE_SIZE_REG); in gemini_ethernet_init()
2343 writel(0, geth->base + GLOBAL_SWFQ_RWPTR_REG); in gemini_ethernet_init()
2344 writel(0, geth->base + GLOBAL_HWFQ_RWPTR_REG); in gemini_ethernet_init()
2346 geth->freeq_frag_order = DEFAULT_RX_BUF_ORDER; in gemini_ethernet_init()
2350 geth->freeq_order = 1; in gemini_ethernet_init()
2353 static void gemini_port_save_mac_addr(struct gemini_ethernet_port *port) in gemini_port_save_mac_addr() argument
2355 port->mac_addr[0] = in gemini_port_save_mac_addr()
2356 cpu_to_le32(readl(port->gmac_base + GMAC_STA_ADD0)); in gemini_port_save_mac_addr()
2357 port->mac_addr[1] = in gemini_port_save_mac_addr()
2358 cpu_to_le32(readl(port->gmac_base + GMAC_STA_ADD1)); in gemini_port_save_mac_addr()
2359 port->mac_addr[2] = in gemini_port_save_mac_addr()
2360 cpu_to_le32(readl(port->gmac_base + GMAC_STA_ADD2)); in gemini_port_save_mac_addr()
2366 struct device_node *np = pdev->dev.of_node; in gemini_ethernet_port_probe()
2367 struct gemini_ethernet_port *port; in gemini_ethernet_port_probe() local
2368 struct device *dev = &pdev->dev; in gemini_ethernet_port_probe()
2377 parent = dev->parent; in gemini_ethernet_port_probe()
2380 if (!strcmp(dev_name(dev), "60008000.ethernet-port")) in gemini_ethernet_port_probe()
2382 else if (!strcmp(dev_name(dev), "6000c000.ethernet-port")) in gemini_ethernet_port_probe()
2385 return -ENODEV; in gemini_ethernet_port_probe()
2389 netdev = devm_alloc_etherdev_mqs(dev, sizeof(*port), TX_QUEUE_NUM, TX_QUEUE_NUM); in gemini_ethernet_port_probe()
2392 return -ENOMEM; in gemini_ethernet_port_probe()
2395 port = netdev_priv(netdev); in gemini_ethernet_port_probe()
2397 port->netdev = netdev; in gemini_ethernet_port_probe()
2398 port->id = id; in gemini_ethernet_port_probe()
2399 port->geth = geth; in gemini_ethernet_port_probe()
2400 port->dev = dev; in gemini_ethernet_port_probe()
2401 port->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE); in gemini_ethernet_port_probe()
2404 port->dma_base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL); in gemini_ethernet_port_probe()
2405 if (IS_ERR(port->dma_base)) { in gemini_ethernet_port_probe()
2407 return PTR_ERR(port->dma_base); in gemini_ethernet_port_probe()
2411 port->gmac_base = devm_platform_get_and_ioremap_resource(pdev, 1, NULL); in gemini_ethernet_port_probe()
2412 if (IS_ERR(port->gmac_base)) { in gemini_ethernet_port_probe()
2414 return PTR_ERR(port->gmac_base); in gemini_ethernet_port_probe()
2421 port->irq = irq; in gemini_ethernet_port_probe()
2423 /* Clock the port */ in gemini_ethernet_port_probe()
2424 port->pclk = devm_clk_get(dev, "PCLK"); in gemini_ethernet_port_probe()
2425 if (IS_ERR(port->pclk)) { in gemini_ethernet_port_probe()
2427 return PTR_ERR(port->pclk); in gemini_ethernet_port_probe()
2429 ret = clk_prepare_enable(port->pclk); in gemini_ethernet_port_probe()
2434 gemini_port_save_mac_addr(port); in gemini_ethernet_port_probe()
2436 /* Reset the port */ in gemini_ethernet_port_probe()
2437 port->reset = devm_reset_control_get_exclusive(dev, NULL); in gemini_ethernet_port_probe()
2438 if (IS_ERR(port->reset)) { in gemini_ethernet_port_probe()
2440 ret = PTR_ERR(port->reset); in gemini_ethernet_port_probe()
2443 reset_control_reset(port->reset); in gemini_ethernet_port_probe()
2448 geth->port0 = port; in gemini_ethernet_port_probe()
2450 geth->port1 = port; in gemini_ethernet_port_probe()
2455 platform_set_drvdata(pdev, port); in gemini_ethernet_port_probe()
2458 netdev->dev_id = port->id; in gemini_ethernet_port_probe()
2459 netdev->irq = irq; in gemini_ethernet_port_probe()
2460 netdev->netdev_ops = &gmac_351x_ops; in gemini_ethernet_port_probe()
2461 netdev->ethtool_ops = &gmac_351x_ethtool_ops; in gemini_ethernet_port_probe()
2463 spin_lock_init(&port->config_lock); in gemini_ethernet_port_probe()
2466 netdev->hw_features = GMAC_OFFLOAD_FEATURES; in gemini_ethernet_port_probe()
2467 netdev->features |= GMAC_OFFLOAD_FEATURES | NETIF_F_GRO; in gemini_ethernet_port_probe()
2472 netdev->min_mtu = ETH_MIN_MTU; in gemini_ethernet_port_probe()
2473 netdev->max_mtu = MTU_SIZE_BIT_MASK - VLAN_ETH_HLEN; in gemini_ethernet_port_probe()
2475 port->freeq_refill = 0; in gemini_ethernet_port_probe()
2476 netif_napi_add(netdev, &port->napi, gmac_napi_poll); in gemini_ethernet_port_probe()
2481 memcpy(port->mac_addr, mac, ETH_ALEN); in gemini_ethernet_port_probe()
2484 if (is_valid_ether_addr((void *)port->mac_addr)) { in gemini_ethernet_port_probe()
2485 eth_hw_addr_set(netdev, (u8 *)port->mac_addr); in gemini_ethernet_port_probe()
2488 port->mac_addr[0], port->mac_addr[1], in gemini_ethernet_port_probe()
2489 port->mac_addr[2]); in gemini_ethernet_port_probe()
2495 ret = devm_request_threaded_irq(port->dev, in gemini_ethernet_port_probe()
2496 port->irq, in gemini_ethernet_port_probe()
2500 port_names[port->id], in gemini_ethernet_port_probe()
2501 port); in gemini_ethernet_port_probe()
2519 clk_disable_unprepare(port->pclk); in gemini_ethernet_port_probe()
2525 struct gemini_ethernet_port *port = platform_get_drvdata(pdev); in gemini_ethernet_port_remove() local
2527 gemini_port_remove(port); in gemini_ethernet_port_remove()
2532 .compatible = "cortina,gemini-ethernet-port",
2540 .name = "gemini-ethernet-port",
2549 struct device *dev = &pdev->dev; in gemini_ethernet_probe()
2557 return -ENOMEM; in gemini_ethernet_probe()
2558 geth->base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL); in gemini_ethernet_probe()
2559 if (IS_ERR(geth->base)) in gemini_ethernet_probe()
2560 return PTR_ERR(geth->base); in gemini_ethernet_probe()
2561 geth->dev = dev; in gemini_ethernet_probe()
2566 val = readl(geth->base + GLOBAL_TOE_VERSION_REG); in gemini_ethernet_probe()
2568 } while (!val && --retry); in gemini_ethernet_probe()
2571 return -EIO; in gemini_ethernet_probe()
2576 spin_lock_init(&geth->irq_lock); in gemini_ethernet_probe()
2577 spin_lock_init(&geth->freeq_lock); in gemini_ethernet_probe()
2591 geth->initialized = false; in gemini_ethernet_remove()
2596 .compatible = "cortina,gemini-ethernet",