Lines Matching +full:port +full:- +full:mapping
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;
86 * struct gmac_queue_page - page buffer per-page info
88 * @mapping: the dma address handle
92 dma_addr_t mapping; member
156 spinlock_t irq_lock; /* Locks IRQ-related registers */
227 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_update_config0_reg() local
231 spin_lock_irqsave(&port->config_lock, flags); in gmac_update_config0_reg()
233 reg = readl(port->gmac_base + GMAC_CONFIG0); in gmac_update_config0_reg()
235 writel(reg, port->gmac_base + GMAC_CONFIG0); in gmac_update_config0_reg()
237 spin_unlock_irqrestore(&port->config_lock, flags); in gmac_update_config0_reg()
242 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_enable_tx_rx() local
246 spin_lock_irqsave(&port->config_lock, flags); in gmac_enable_tx_rx()
248 reg = readl(port->gmac_base + GMAC_CONFIG0); in gmac_enable_tx_rx()
250 writel(reg, port->gmac_base + GMAC_CONFIG0); in gmac_enable_tx_rx()
252 spin_unlock_irqrestore(&port->config_lock, flags); in gmac_enable_tx_rx()
257 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_disable_tx_rx() local
261 spin_lock_irqsave(&port->config_lock, flags); in gmac_disable_tx_rx()
263 val = readl(port->gmac_base + GMAC_CONFIG0); in gmac_disable_tx_rx()
265 writel(val, port->gmac_base + GMAC_CONFIG0); in gmac_disable_tx_rx()
267 spin_unlock_irqrestore(&port->config_lock, flags); in gmac_disable_tx_rx()
274 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_set_flow_control() local
278 spin_lock_irqsave(&port->config_lock, flags); in gmac_set_flow_control()
280 val = readl(port->gmac_base + GMAC_CONFIG0); in gmac_set_flow_control()
286 writel(val, port->gmac_base + GMAC_CONFIG0); in gmac_set_flow_control()
288 spin_unlock_irqrestore(&port->config_lock, flags); in gmac_set_flow_control()
293 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_adjust_link() local
294 struct phy_device *phydev = netdev->phydev; in gmac_adjust_link()
299 status.bits32 = readl(port->gmac_base + GMAC_STATUS); in gmac_adjust_link()
301 status.bits.link = phydev->link; in gmac_adjust_link()
302 status.bits.duplex = phydev->duplex; in gmac_adjust_link()
304 switch (phydev->speed) { in gmac_adjust_link()
307 if (phy_interface_mode_is_rgmii(phydev->interface)) in gmac_adjust_link()
314 if (phy_interface_mode_is_rgmii(phydev->interface)) in gmac_adjust_link()
321 if (phy_interface_mode_is_rgmii(phydev->interface)) in gmac_adjust_link()
328 phydev->speed, phydev_name(phydev)); in gmac_adjust_link()
331 if (phydev->duplex == DUPLEX_FULL) { in gmac_adjust_link()
342 if (netif_msg_link(port)) { in gmac_adjust_link()
345 phydev->pause in gmac_adjust_link()
346 ? (phydev->asym_pause ? "tx" : "both") in gmac_adjust_link()
347 : (phydev->asym_pause ? "rx" : "none") in gmac_adjust_link()
352 writel(status.bits32, port->gmac_base + GMAC_STATUS); in gmac_adjust_link()
358 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_setup_phy() local
360 struct device *dev = port->dev; in gmac_setup_phy()
364 dev->of_node, in gmac_setup_phy()
367 return -ENODEV; in gmac_setup_phy()
368 netdev->phydev = phy; in gmac_setup_phy()
374 switch (phy->interface) { in gmac_setup_phy()
396 netdev->phydev = NULL; in gmac_setup_phy()
397 return -EINVAL; in gmac_setup_phy()
399 writel(status.bits32, port->gmac_base + GMAC_STATUS); in gmac_setup_phy()
401 if (netif_msg_link(port)) in gmac_setup_phy()
453 if (maxtot <= maxlen->max_l3_len) in gmac_pick_rx_max_len()
454 return maxlen->val; in gmac_pick_rx_max_len()
457 return -1; in gmac_pick_rx_max_len()
462 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_init() local
512 config0.bits.max_len = gmac_pick_rx_max_len(netdev->mtu); in gmac_init()
513 tmp.bits32 = readl(port->gmac_base + GMAC_CONFIG0); in gmac_init()
515 writel(config0.bits32, port->gmac_base + GMAC_CONFIG0); in gmac_init()
516 writel(config1.bits32, port->gmac_base + GMAC_CONFIG1); in gmac_init()
517 writel(config2.bits32, port->gmac_base + GMAC_CONFIG2); in gmac_init()
518 writel(config3.bits32, port->gmac_base + GMAC_CONFIG3); in gmac_init()
520 readl(port->dma_base + GMAC_AHB_WEIGHT_REG); in gmac_init()
521 writel(ahb_weight.bits32, port->dma_base + GMAC_AHB_WEIGHT_REG); in gmac_init()
524 port->dma_base + GMAC_TX_WEIGHTING_CTRL_0_REG); in gmac_init()
526 port->dma_base + GMAC_TX_WEIGHTING_CTRL_1_REG); in gmac_init()
528 port->rxq_order = DEFAULT_GMAC_RXQ_ORDER; in gmac_init()
529 port->txq_order = DEFAULT_GMAC_TXQ_ORDER; in gmac_init()
530 port->rx_coalesce_nsecs = DEFAULT_RX_COALESCE_NSECS; in gmac_init()
535 port->irq_every_tx_packets = 1 << (port->txq_order - 2); in gmac_init()
542 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_setup_txqs() local
543 unsigned int n_txq = netdev->num_tx_queues; in gmac_setup_txqs()
544 struct gemini_ethernet *geth = port->geth; in gmac_setup_txqs()
545 size_t entries = 1 << port->txq_order; in gmac_setup_txqs()
546 struct gmac_txq *txq = port->txq; in gmac_setup_txqs()
554 rwptr_reg = port->dma_base + GMAC_SW_TX_QUEUE0_PTR_REG; in gmac_setup_txqs()
558 return -ENOMEM; in gmac_setup_txqs()
560 desc_ring = dma_alloc_coherent(geth->dev, len * sizeof(*desc_ring), in gmac_setup_txqs()
561 &port->txq_dma_base, GFP_KERNEL); in gmac_setup_txqs()
565 return -ENOMEM; in gmac_setup_txqs()
568 if (port->txq_dma_base & ~DMA_Q_BASE_MASK) { in gmac_setup_txqs()
569 dev_warn(geth->dev, "TX queue base is not aligned\n"); in gmac_setup_txqs()
570 dma_free_coherent(geth->dev, len * sizeof(*desc_ring), in gmac_setup_txqs()
571 desc_ring, port->txq_dma_base); in gmac_setup_txqs()
573 return -ENOMEM; in gmac_setup_txqs()
576 writel(port->txq_dma_base | port->txq_order, in gmac_setup_txqs()
577 port->dma_base + GMAC_SW_TX_QUEUE_BASE_REG); in gmac_setup_txqs()
580 txq->ring = desc_ring; in gmac_setup_txqs()
581 txq->skb = skb_tab; in gmac_setup_txqs()
582 txq->noirq_packets = 0; in gmac_setup_txqs()
588 txq->cptr = r; in gmac_setup_txqs()
601 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_clean_txq() local
602 unsigned int m = (1 << port->txq_order) - 1; in gmac_clean_txq()
603 struct gemini_ethernet *geth = port->geth; in gmac_clean_txq()
604 unsigned int c = txq->cptr; in gmac_clean_txq()
614 dma_addr_t mapping; in gmac_clean_txq() local
620 txd = txq->ring + c; in gmac_clean_txq()
621 word0 = txd->word0; in gmac_clean_txq()
622 word1 = txd->word1; in gmac_clean_txq()
623 mapping = txd->word2.buf_adr; in gmac_clean_txq()
624 word3 = txd->word3.bits32; in gmac_clean_txq()
626 dma_unmap_single(geth->dev, mapping, in gmac_clean_txq()
630 dev_kfree_skb(txq->skb[c]); in gmac_clean_txq()
644 bytes += txd->word1.bits.byte_count; in gmac_clean_txq()
649 nfrags = word0.bits.desc_count - 1; in gmac_clean_txq()
652 nfrags = TX_MAX_FRAGS - 1; in gmac_clean_txq()
654 u64_stats_update_begin(&port->tx_stats_syncp); in gmac_clean_txq()
655 port->tx_frag_stats[nfrags]++; in gmac_clean_txq()
656 u64_stats_update_end(&port->tx_stats_syncp); in gmac_clean_txq()
660 u64_stats_update_begin(&port->ir_stats_syncp); in gmac_clean_txq()
661 port->stats.tx_errors += errs; in gmac_clean_txq()
662 port->stats.tx_packets += pkts; in gmac_clean_txq()
663 port->stats.tx_bytes += bytes; in gmac_clean_txq()
664 port->tx_hw_csummed += hwchksum; in gmac_clean_txq()
665 u64_stats_update_end(&port->ir_stats_syncp); in gmac_clean_txq()
667 txq->cptr = c; in gmac_clean_txq()
672 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_cleanup_txqs() local
673 unsigned int n_txq = netdev->num_tx_queues; in gmac_cleanup_txqs()
674 struct gemini_ethernet *geth = port->geth; in gmac_cleanup_txqs()
678 rwptr_reg = port->dma_base + GMAC_SW_TX_QUEUE0_PTR_REG; in gmac_cleanup_txqs()
686 gmac_clean_txq(netdev, port->txq + i, r); in gmac_cleanup_txqs()
688 writel(0, port->dma_base + GMAC_SW_TX_QUEUE_BASE_REG); in gmac_cleanup_txqs()
690 kfree(port->txq->skb); in gmac_cleanup_txqs()
691 dma_free_coherent(geth->dev, in gmac_cleanup_txqs()
692 n_txq * sizeof(*port->txq->ring) << port->txq_order, in gmac_cleanup_txqs()
693 port->txq->ring, port->txq_dma_base); in gmac_cleanup_txqs()
698 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_setup_rxq() local
699 struct gemini_ethernet *geth = port->geth; in gmac_setup_rxq()
702 qhdr = geth->base + TOE_DEFAULT_Q_HDR_BASE(netdev->dev_id); in gmac_setup_rxq()
703 port->rxq_rwptr = &qhdr->word1; in gmac_setup_rxq()
706 port->rxq_ring = dma_alloc_coherent(geth->dev, in gmac_setup_rxq()
707 sizeof(*port->rxq_ring) << port->rxq_order, in gmac_setup_rxq()
708 &port->rxq_dma_base, GFP_KERNEL); in gmac_setup_rxq()
709 if (!port->rxq_ring) in gmac_setup_rxq()
710 return -ENOMEM; in gmac_setup_rxq()
711 if (port->rxq_dma_base & ~NONTOE_QHDR0_BASE_MASK) { in gmac_setup_rxq()
712 dev_warn(geth->dev, "RX queue base is not aligned\n"); in gmac_setup_rxq()
713 return -ENOMEM; in gmac_setup_rxq()
716 writel(port->rxq_dma_base | port->rxq_order, &qhdr->word0); in gmac_setup_rxq()
717 writel(0, port->rxq_rwptr); in gmac_setup_rxq()
723 struct gemini_ethernet_port *port, in gmac_get_queue_page() argument
727 dma_addr_t mapping; in gmac_get_queue_page() local
731 mapping = addr & PAGE_MASK; in gmac_get_queue_page()
733 if (!geth->freeq_pages) { in gmac_get_queue_page()
734 dev_err(geth->dev, "try to get page with no page list\n"); in gmac_get_queue_page()
738 /* Look up a ring buffer page from virtual mapping */ in gmac_get_queue_page()
739 for (i = 0; i < geth->num_freeq_pages; i++) { in gmac_get_queue_page()
740 gpage = &geth->freeq_pages[i]; in gmac_get_queue_page()
741 if (gpage->mapping == mapping) in gmac_get_queue_page()
750 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_cleanup_rxq() local
751 struct gemini_ethernet *geth = port->geth; in gmac_cleanup_rxq()
752 struct gmac_rxdesc *rxd = port->rxq_ring; in gmac_cleanup_rxq()
757 dma_addr_t mapping; in gmac_cleanup_rxq() local
761 qhdr = geth->base + in gmac_cleanup_rxq()
762 TOE_DEFAULT_Q_HDR_BASE(netdev->dev_id); in gmac_cleanup_rxq()
763 dma_reg = &qhdr->word0; in gmac_cleanup_rxq()
764 ptr_reg = &qhdr->word1; in gmac_cleanup_rxq()
777 mapping = rxd[r].word2.buf_adr; in gmac_cleanup_rxq()
779 r &= ((1 << port->rxq_order) - 1); in gmac_cleanup_rxq()
781 if (!mapping) in gmac_cleanup_rxq()
785 gpage = gmac_get_queue_page(geth, port, mapping + PAGE_SIZE); in gmac_cleanup_rxq()
787 dev_err(geth->dev, "could not find page\n"); in gmac_cleanup_rxq()
791 put_page(gpage->page); in gmac_cleanup_rxq()
794 dma_free_coherent(geth->dev, sizeof(*port->rxq_ring) << port->rxq_order, in gmac_cleanup_rxq()
795 port->rxq_ring, port->rxq_dma_base); in gmac_cleanup_rxq()
805 dma_addr_t mapping; in geth_freeq_alloc_map_page() local
814 mapping = dma_map_single(geth->dev, page_address(page), in geth_freeq_alloc_map_page()
816 if (dma_mapping_error(geth->dev, mapping)) { in geth_freeq_alloc_map_page()
821 /* The assign the page mapping (physical address) to the buffer address in geth_freeq_alloc_map_page()
827 frag_len = 1 << geth->freeq_frag_order; /* Usually 2048 */ in geth_freeq_alloc_map_page()
828 fpp_order = PAGE_SHIFT - geth->freeq_frag_order; in geth_freeq_alloc_map_page()
829 freeq_entry = geth->freeq_ring + (pn << fpp_order); in geth_freeq_alloc_map_page()
830 dev_dbg(geth->dev, "allocate page %d fragment length %d fragments per page %d, freeq entry %p\n", in geth_freeq_alloc_map_page()
832 for (i = (1 << fpp_order); i > 0; i--) { in geth_freeq_alloc_map_page()
833 freeq_entry->word2.buf_adr = mapping; in geth_freeq_alloc_map_page()
835 mapping += frag_len; in geth_freeq_alloc_map_page()
839 gpage = &geth->freeq_pages[pn]; in geth_freeq_alloc_map_page()
840 if (gpage->page) { in geth_freeq_alloc_map_page()
841 mapping = geth->freeq_ring[pn << fpp_order].word2.buf_adr; in geth_freeq_alloc_map_page()
842 dma_unmap_single(geth->dev, mapping, frag_len, DMA_FROM_DEVICE); in geth_freeq_alloc_map_page()
846 put_page(gpage->page); in geth_freeq_alloc_map_page()
849 /* Then put our new mapping into the page table */ in geth_freeq_alloc_map_page()
850 dev_dbg(geth->dev, "page %d, DMA addr: %08x, page %p\n", in geth_freeq_alloc_map_page()
851 pn, (unsigned int)mapping, page); in geth_freeq_alloc_map_page()
852 gpage->mapping = mapping; in geth_freeq_alloc_map_page()
853 gpage->page = page; in geth_freeq_alloc_map_page()
859 * geth_fill_freeq() - Fill the freeq with empty fragments to use
867 unsigned int fpp_order = PAGE_SHIFT - geth->freeq_frag_order; in geth_fill_freeq()
875 m_pn = (1 << (geth->freeq_order - fpp_order)) - 1; in geth_fill_freeq()
877 spin_lock_irqsave(&geth->freeq_lock, flags); in geth_fill_freeq()
879 rw.bits32 = readl(geth->base + GLOBAL_SWFQ_RWPTR_REG); in geth_fill_freeq()
881 epn = (rw.bits.rptr >> fpp_order) - 1; in geth_fill_freeq()
889 gpage = &geth->freeq_pages[pn]; in geth_fill_freeq()
890 page = gpage->page; in geth_fill_freeq()
892 dev_dbg(geth->dev, "fill entry %d page ref count %d add %d refs\n", in geth_fill_freeq()
896 unsigned int fl = (pn - epn) & m_pn; in geth_fill_freeq()
913 writew(pn << fpp_order, geth->base + GLOBAL_SWFQ_RWPTR_REG + 2); in geth_fill_freeq()
915 spin_unlock_irqrestore(&geth->freeq_lock, flags); in geth_fill_freeq()
922 unsigned int fpp_order = PAGE_SHIFT - geth->freeq_frag_order; in geth_setup_freeq()
923 unsigned int frag_len = 1 << geth->freeq_frag_order; in geth_setup_freeq()
924 unsigned int len = 1 << geth->freeq_order; in geth_setup_freeq()
931 geth->freeq_ring = dma_alloc_coherent(geth->dev, in geth_setup_freeq()
932 sizeof(*geth->freeq_ring) << geth->freeq_order, in geth_setup_freeq()
933 &geth->freeq_dma_base, GFP_KERNEL); in geth_setup_freeq()
934 if (!geth->freeq_ring) in geth_setup_freeq()
935 return -ENOMEM; in geth_setup_freeq()
936 if (geth->freeq_dma_base & ~DMA_Q_BASE_MASK) { in geth_setup_freeq()
937 dev_warn(geth->dev, "queue ring base is not aligned\n"); in geth_setup_freeq()
941 /* Allocate a mapping to page look-up index */ in geth_setup_freeq()
942 geth->freeq_pages = kcalloc(pages, sizeof(*geth->freeq_pages), in geth_setup_freeq()
944 if (!geth->freeq_pages) in geth_setup_freeq()
946 geth->num_freeq_pages = pages; in geth_setup_freeq()
948 dev_info(geth->dev, "allocate %d pages for queue\n", pages); in geth_setup_freeq()
957 qt.bits32 = readl(geth->base + GLOBAL_QUEUE_THRESHOLD_REG); in geth_setup_freeq()
959 writel(qt.bits32, geth->base + GLOBAL_QUEUE_THRESHOLD_REG); in geth_setup_freeq()
961 skbsz.bits.sw_skb_size = 1 << geth->freeq_frag_order; in geth_setup_freeq()
962 writel(skbsz.bits32, geth->base + GLOBAL_DMA_SKB_SIZE_REG); in geth_setup_freeq()
963 writel(geth->freeq_dma_base | geth->freeq_order, in geth_setup_freeq()
964 geth->base + GLOBAL_SW_FREEQ_BASE_SIZE_REG); in geth_setup_freeq()
971 dma_addr_t mapping; in geth_setup_freeq() local
973 --pn; in geth_setup_freeq()
974 mapping = geth->freeq_ring[pn << fpp_order].word2.buf_adr; in geth_setup_freeq()
975 dma_unmap_single(geth->dev, mapping, frag_len, DMA_FROM_DEVICE); in geth_setup_freeq()
976 gpage = &geth->freeq_pages[pn]; in geth_setup_freeq()
977 put_page(gpage->page); in geth_setup_freeq()
980 kfree(geth->freeq_pages); in geth_setup_freeq()
982 dma_free_coherent(geth->dev, in geth_setup_freeq()
983 sizeof(*geth->freeq_ring) << geth->freeq_order, in geth_setup_freeq()
984 geth->freeq_ring, geth->freeq_dma_base); in geth_setup_freeq()
985 geth->freeq_ring = NULL; in geth_setup_freeq()
986 return -ENOMEM; in geth_setup_freeq()
990 * geth_cleanup_freeq() - cleanup the DMA mappings and free the queue
995 unsigned int fpp_order = PAGE_SHIFT - geth->freeq_frag_order; in geth_cleanup_freeq()
996 unsigned int frag_len = 1 << geth->freeq_frag_order; in geth_cleanup_freeq()
997 unsigned int len = 1 << geth->freeq_order; in geth_cleanup_freeq()
1001 writew(readw(geth->base + GLOBAL_SWFQ_RWPTR_REG), in geth_cleanup_freeq()
1002 geth->base + GLOBAL_SWFQ_RWPTR_REG + 2); in geth_cleanup_freeq()
1003 writel(0, geth->base + GLOBAL_SW_FREEQ_BASE_SIZE_REG); in geth_cleanup_freeq()
1007 dma_addr_t mapping; in geth_cleanup_freeq() local
1009 mapping = geth->freeq_ring[pn << fpp_order].word2.buf_adr; in geth_cleanup_freeq()
1010 dma_unmap_single(geth->dev, mapping, frag_len, DMA_FROM_DEVICE); in geth_cleanup_freeq()
1012 gpage = &geth->freeq_pages[pn]; in geth_cleanup_freeq()
1013 while (page_ref_count(gpage->page) > 0) in geth_cleanup_freeq()
1014 put_page(gpage->page); in geth_cleanup_freeq()
1017 kfree(geth->freeq_pages); in geth_cleanup_freeq()
1019 dma_free_coherent(geth->dev, in geth_cleanup_freeq()
1020 sizeof(*geth->freeq_ring) << geth->freeq_order, in geth_cleanup_freeq()
1021 geth->freeq_ring, geth->freeq_dma_base); in geth_cleanup_freeq()
1025 * geth_resize_freeq() - resize the software queue depth
1026 * @port: the port requesting the change
1033 static int geth_resize_freeq(struct gemini_ethernet_port *port) in geth_resize_freeq() argument
1035 struct gemini_ethernet *geth = port->geth; in geth_resize_freeq()
1036 struct net_device *netdev = port->netdev; in geth_resize_freeq()
1045 if (netdev->dev_id == 0) in geth_resize_freeq()
1046 other_netdev = geth->port1->netdev; in geth_resize_freeq()
1048 other_netdev = geth->port0->netdev; in geth_resize_freeq()
1051 return -EBUSY; in geth_resize_freeq()
1053 new_size = 1 << (port->rxq_order + 1); in geth_resize_freeq()
1054 netdev_dbg(netdev, "port %d size: %d order %d\n", in geth_resize_freeq()
1055 netdev->dev_id, in geth_resize_freeq()
1057 port->rxq_order); in geth_resize_freeq()
1060 new_size += 1 << (other_port->rxq_order + 1); in geth_resize_freeq()
1061 netdev_dbg(other_netdev, "port %d size: %d order %d\n", in geth_resize_freeq()
1062 other_netdev->dev_id, in geth_resize_freeq()
1063 (1 << (other_port->rxq_order + 1)), in geth_resize_freeq()
1064 other_port->rxq_order); in geth_resize_freeq()
1067 new_order = min(15, ilog2(new_size - 1) + 1); in geth_resize_freeq()
1068 dev_dbg(geth->dev, "set shared queue to size %d order %d\n", in geth_resize_freeq()
1070 if (geth->freeq_order == new_order) in geth_resize_freeq()
1073 spin_lock_irqsave(&geth->irq_lock, flags); in geth_resize_freeq()
1076 en = readl(geth->base + GLOBAL_INTERRUPT_ENABLE_4_REG); in geth_resize_freeq()
1078 writel(en, geth->base + GLOBAL_INTERRUPT_ENABLE_4_REG); in geth_resize_freeq()
1079 spin_unlock_irqrestore(&geth->irq_lock, flags); in geth_resize_freeq()
1082 if (geth->freeq_ring) in geth_resize_freeq()
1086 geth->freeq_order = new_order; in geth_resize_freeq()
1089 /* Restart the interrupts - NOTE if this is the first resize in geth_resize_freeq()
1093 spin_lock_irqsave(&geth->irq_lock, flags); in geth_resize_freeq()
1095 writel(en, geth->base + GLOBAL_INTERRUPT_ENABLE_4_REG); in geth_resize_freeq()
1096 spin_unlock_irqrestore(&geth->irq_lock, flags); in geth_resize_freeq()
1104 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_tx_irq_enable() local
1105 struct gemini_ethernet *geth = port->geth; in gmac_tx_irq_enable()
1109 netdev_dbg(netdev, "%s device %d\n", __func__, netdev->dev_id); in gmac_tx_irq_enable()
1111 spin_lock_irqsave(&geth->irq_lock, flags); in gmac_tx_irq_enable()
1113 mask = GMAC0_IRQ0_TXQ0_INTS << (6 * netdev->dev_id + txq); in gmac_tx_irq_enable()
1116 writel(mask, geth->base + GLOBAL_INTERRUPT_STATUS_0_REG); in gmac_tx_irq_enable()
1118 val = readl(geth->base + GLOBAL_INTERRUPT_ENABLE_0_REG); in gmac_tx_irq_enable()
1120 writel(val, geth->base + GLOBAL_INTERRUPT_ENABLE_0_REG); in gmac_tx_irq_enable()
1122 spin_unlock_irqrestore(&geth->irq_lock, flags); in gmac_tx_irq_enable()
1136 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_map_tx_bufs() local
1138 unsigned short m = (1 << port->txq_order) - 1; in gmac_map_tx_bufs()
1139 short frag, last_frag = skb_si->nr_frags - 1; in gmac_map_tx_bufs()
1140 struct gemini_ethernet *geth = port->geth; in gmac_map_tx_bufs()
1145 dma_addr_t mapping; in gmac_map_tx_bufs() local
1150 word1 = skb->len; in gmac_map_tx_bufs()
1153 mss = skb_shinfo(skb)->gso_size; in gmac_map_tx_bufs()
1155 /* This means we are dealing with TCP and skb->len is the in gmac_map_tx_bufs()
1162 mss, skb->len); in gmac_map_tx_bufs()
1165 } else if (skb->len >= ETH_FRAME_LEN) { in gmac_map_tx_bufs()
1174 if (skb->ip_summed == CHECKSUM_PARTIAL) { in gmac_map_tx_bufs()
1182 if (skb->ip_summed == CHECKSUM_PARTIAL) { in gmac_map_tx_bufs()
1191 if (skb->protocol == htons(ETH_P_IP)) { in gmac_map_tx_bufs()
1193 tcp = ip_hdr(skb)->protocol == IPPROTO_TCP; in gmac_map_tx_bufs()
1196 tcp = ipv6_hdr(skb)->nexthdr == IPPROTO_TCP; in gmac_map_tx_bufs()
1202 frag = -1; in gmac_map_tx_bufs()
1204 if (frag == -1) { in gmac_map_tx_bufs()
1205 buffer = skb->data; in gmac_map_tx_bufs()
1208 skb_frag = skb_si->frags + frag; in gmac_map_tx_bufs()
1215 txq->skb[w] = skb; in gmac_map_tx_bufs()
1218 mapping = dma_map_single(geth->dev, buffer, buflen, in gmac_map_tx_bufs()
1220 if (dma_mapping_error(geth->dev, mapping)) in gmac_map_tx_bufs()
1223 txd = txq->ring + w; in gmac_map_tx_bufs()
1224 txd->word0.bits32 = buflen; in gmac_map_tx_bufs()
1225 txd->word1.bits32 = word1; in gmac_map_tx_bufs()
1226 txd->word2.buf_adr = mapping; in gmac_map_tx_bufs()
1227 txd->word3.bits32 = word3; in gmac_map_tx_bufs()
1240 w--; in gmac_map_tx_bufs()
1243 dma_unmap_page(geth->dev, txq->ring[w].word2.buf_adr, in gmac_map_tx_bufs()
1244 txq->ring[w].word0.bits.buffer_size, in gmac_map_tx_bufs()
1247 return -ENOMEM; in gmac_map_tx_bufs()
1253 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_start_xmit() local
1254 unsigned short m = (1 << port->txq_order) - 1; in gmac_start_xmit()
1262 if (skb->len >= 0x10000) in gmac_start_xmit()
1266 ptr_reg = port->dma_base + GMAC_SW_TX_QUEUE_PTR_REG(txq_num); in gmac_start_xmit()
1267 txq = &port->txq[txq_num]; in gmac_start_xmit()
1269 nfrags = skb_shinfo(skb)->nr_frags; in gmac_start_xmit()
1275 d = txq->cptr - w - 1; in gmac_start_xmit()
1280 d = txq->cptr - w - 1; in gmac_start_xmit()
1286 d = txq->cptr + nfrags + 16; in gmac_start_xmit()
1288 txq->ring[d].word3.bits.eofie = 1; in gmac_start_xmit()
1291 u64_stats_update_begin(&port->tx_stats_syncp); in gmac_start_xmit()
1292 netdev->stats.tx_fifo_errors++; in gmac_start_xmit()
1293 u64_stats_update_end(&port->tx_stats_syncp); in gmac_start_xmit()
1302 u64_stats_update_begin(&port->tx_stats_syncp); in gmac_start_xmit()
1303 port->tx_frags_linearized++; in gmac_start_xmit()
1304 u64_stats_update_end(&port->tx_stats_syncp); in gmac_start_xmit()
1318 u64_stats_update_begin(&port->tx_stats_syncp); in gmac_start_xmit()
1319 port->stats.tx_dropped++; in gmac_start_xmit()
1320 u64_stats_update_end(&port->tx_stats_syncp); in gmac_start_xmit()
1332 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_enable_irq() local
1333 struct gemini_ethernet *geth = port->geth; in gmac_enable_irq()
1338 netdev->dev_id, enable ? "enable" : "disable"); in gmac_enable_irq()
1339 spin_lock_irqsave(&geth->irq_lock, flags); in gmac_enable_irq()
1341 mask = GMAC0_IRQ0_2 << (netdev->dev_id * 2); in gmac_enable_irq()
1342 val = readl(geth->base + GLOBAL_INTERRUPT_ENABLE_0_REG); in gmac_enable_irq()
1344 writel(val, geth->base + GLOBAL_INTERRUPT_ENABLE_0_REG); in gmac_enable_irq()
1346 mask = DEFAULT_Q0_INT_BIT << netdev->dev_id; in gmac_enable_irq()
1347 val = readl(geth->base + GLOBAL_INTERRUPT_ENABLE_1_REG); in gmac_enable_irq()
1349 writel(val, geth->base + GLOBAL_INTERRUPT_ENABLE_1_REG); in gmac_enable_irq()
1351 mask = GMAC0_IRQ4_8 << (netdev->dev_id * 8); in gmac_enable_irq()
1352 val = readl(geth->base + GLOBAL_INTERRUPT_ENABLE_4_REG); in gmac_enable_irq()
1354 writel(val, geth->base + GLOBAL_INTERRUPT_ENABLE_4_REG); in gmac_enable_irq()
1356 spin_unlock_irqrestore(&geth->irq_lock, flags); in gmac_enable_irq()
1361 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_enable_rx_irq() local
1362 struct gemini_ethernet *geth = port->geth; in gmac_enable_rx_irq()
1366 netdev_dbg(netdev, "%s device %d %s\n", __func__, netdev->dev_id, in gmac_enable_rx_irq()
1368 spin_lock_irqsave(&geth->irq_lock, flags); in gmac_enable_rx_irq()
1369 mask = DEFAULT_Q0_INT_BIT << netdev->dev_id; in gmac_enable_rx_irq()
1371 val = readl(geth->base + GLOBAL_INTERRUPT_ENABLE_1_REG); in gmac_enable_rx_irq()
1373 writel(val, geth->base + GLOBAL_INTERRUPT_ENABLE_1_REG); in gmac_enable_rx_irq()
1375 spin_unlock_irqrestore(&geth->irq_lock, flags); in gmac_enable_rx_irq()
1378 static struct sk_buff *gmac_skb_if_good_frame(struct gemini_ethernet_port *port, in gmac_skb_if_good_frame() argument
1386 port->rx_stats[rx_status]++; in gmac_skb_if_good_frame()
1387 port->rx_csum_stats[rx_csum]++; in gmac_skb_if_good_frame()
1392 port->stats.rx_errors++; in gmac_skb_if_good_frame()
1395 port->stats.rx_length_errors++; in gmac_skb_if_good_frame()
1397 port->stats.rx_over_errors++; in gmac_skb_if_good_frame()
1399 port->stats.rx_crc_errors++; in gmac_skb_if_good_frame()
1401 port->stats.rx_frame_errors++; in gmac_skb_if_good_frame()
1405 skb = napi_get_frags(&port->napi); in gmac_skb_if_good_frame()
1410 skb->ip_summed = CHECKSUM_UNNECESSARY; in gmac_skb_if_good_frame()
1413 port->stats.rx_bytes += frame_len; in gmac_skb_if_good_frame()
1414 port->stats.rx_packets++; in gmac_skb_if_good_frame()
1420 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_rx() local
1421 unsigned short m = (1 << port->rxq_order) - 1; in gmac_rx()
1422 struct gemini_ethernet *geth = port->geth; in gmac_rx()
1423 void __iomem *ptr_reg = port->rxq_rwptr; in gmac_rx()
1436 dma_addr_t mapping; in gmac_rx() local
1439 spin_lock_irqsave(&geth->irq_lock, flags); in gmac_rx()
1442 writel(DEFAULT_Q0_INT_BIT << netdev->dev_id, in gmac_rx()
1443 geth->base + GLOBAL_INTERRUPT_STATUS_1_REG); in gmac_rx()
1444 spin_unlock_irqrestore(&geth->irq_lock, flags); in gmac_rx()
1450 rx = port->rxq_ring + r; in gmac_rx()
1451 word0 = rx->word0; in gmac_rx()
1452 word1 = rx->word1; in gmac_rx()
1453 mapping = rx->word2.buf_adr; in gmac_rx()
1454 word3 = rx->word3; in gmac_rx()
1461 page_offs = mapping & ~PAGE_MASK; in gmac_rx()
1463 if (!mapping) { in gmac_rx()
1470 gpage = gmac_get_queue_page(geth, port, mapping + PAGE_SIZE); in gmac_rx()
1472 dev_err(geth->dev, "could not find mapping\n"); in gmac_rx()
1475 page = gpage->page; in gmac_rx()
1479 napi_free_frags(&port->napi); in gmac_rx()
1480 port->stats.rx_dropped++; in gmac_rx()
1483 skb = gmac_skb_if_good_frame(port, word0, frame_len); in gmac_rx()
1488 frag_len -= NET_IP_ALIGN; in gmac_rx()
1497 frag_len = frame_len - skb->len; in gmac_rx()
1507 skb->len += frag_len; in gmac_rx()
1508 skb->data_len += frag_len; in gmac_rx()
1509 skb->truesize += frag_len; in gmac_rx()
1513 napi_gro_frags(&port->napi); in gmac_rx()
1515 --budget; in gmac_rx()
1521 napi_free_frags(&port->napi); in gmac_rx()
1525 if (mapping) in gmac_rx()
1528 port->stats.rx_dropped++; in gmac_rx()
1537 struct gemini_ethernet_port *port = netdev_priv(napi->dev); in gmac_napi_poll() local
1538 struct gemini_ethernet *geth = port->geth; in gmac_napi_poll()
1542 freeq_threshold = 1 << (geth->freeq_order - 1); in gmac_napi_poll()
1543 u64_stats_update_begin(&port->rx_stats_syncp); in gmac_napi_poll()
1545 received = gmac_rx(napi->dev, budget); in gmac_napi_poll()
1549 gmac_enable_rx_irq(napi->dev, 1); in gmac_napi_poll()
1550 ++port->rx_napi_exits; in gmac_napi_poll()
1553 port->freeq_refill += (budget - received); in gmac_napi_poll()
1554 if (port->freeq_refill > freeq_threshold) { in gmac_napi_poll()
1555 port->freeq_refill -= freeq_threshold; in gmac_napi_poll()
1559 u64_stats_update_end(&port->rx_stats_syncp); in gmac_napi_poll()
1565 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_dump_dma_state() local
1566 struct gemini_ethernet *geth = port->geth; in gmac_dump_dma_state()
1571 reg[0] = readl(geth->base + GLOBAL_INTERRUPT_STATUS_0_REG); in gmac_dump_dma_state()
1572 reg[1] = readl(geth->base + GLOBAL_INTERRUPT_STATUS_1_REG); in gmac_dump_dma_state()
1573 reg[2] = readl(geth->base + GLOBAL_INTERRUPT_STATUS_2_REG); in gmac_dump_dma_state()
1574 reg[3] = readl(geth->base + GLOBAL_INTERRUPT_STATUS_3_REG); in gmac_dump_dma_state()
1575 reg[4] = readl(geth->base + GLOBAL_INTERRUPT_STATUS_4_REG); in gmac_dump_dma_state()
1580 reg[0] = readl(geth->base + GLOBAL_INTERRUPT_ENABLE_0_REG); in gmac_dump_dma_state()
1581 reg[1] = readl(geth->base + GLOBAL_INTERRUPT_ENABLE_1_REG); in gmac_dump_dma_state()
1582 reg[2] = readl(geth->base + GLOBAL_INTERRUPT_ENABLE_2_REG); in gmac_dump_dma_state()
1583 reg[3] = readl(geth->base + GLOBAL_INTERRUPT_ENABLE_3_REG); in gmac_dump_dma_state()
1584 reg[4] = readl(geth->base + GLOBAL_INTERRUPT_ENABLE_4_REG); in gmac_dump_dma_state()
1589 reg[0] = readl(port->dma_base + GMAC_DMA_RX_FIRST_DESC_REG); in gmac_dump_dma_state()
1590 reg[1] = readl(port->dma_base + GMAC_DMA_RX_CURR_DESC_REG); in gmac_dump_dma_state()
1591 reg[2] = GET_RPTR(port->rxq_rwptr); in gmac_dump_dma_state()
1592 reg[3] = GET_WPTR(port->rxq_rwptr); in gmac_dump_dma_state()
1596 reg[0] = readl(port->dma_base + GMAC_DMA_RX_DESC_WORD0_REG); in gmac_dump_dma_state()
1597 reg[1] = readl(port->dma_base + GMAC_DMA_RX_DESC_WORD1_REG); in gmac_dump_dma_state()
1598 reg[2] = readl(port->dma_base + GMAC_DMA_RX_DESC_WORD2_REG); in gmac_dump_dma_state()
1599 reg[3] = readl(port->dma_base + GMAC_DMA_RX_DESC_WORD3_REG); in gmac_dump_dma_state()
1604 ptr_reg = port->dma_base + GMAC_SW_TX_QUEUE0_PTR_REG; in gmac_dump_dma_state()
1606 reg[0] = readl(port->dma_base + GMAC_DMA_TX_FIRST_DESC_REG); in gmac_dump_dma_state()
1607 reg[1] = readl(port->dma_base + GMAC_DMA_TX_CURR_DESC_REG); in gmac_dump_dma_state()
1613 reg[0] = readl(port->dma_base + GMAC_DMA_TX_DESC_WORD0_REG); in gmac_dump_dma_state()
1614 reg[1] = readl(port->dma_base + GMAC_DMA_TX_DESC_WORD1_REG); in gmac_dump_dma_state()
1615 reg[2] = readl(port->dma_base + GMAC_DMA_TX_DESC_WORD2_REG); in gmac_dump_dma_state()
1616 reg[3] = readl(port->dma_base + GMAC_DMA_TX_DESC_WORD3_REG); in gmac_dump_dma_state()
1621 ptr_reg = geth->base + GLOBAL_SWFQ_RWPTR_REG; in gmac_dump_dma_state()
1626 ptr_reg = geth->base + GLOBAL_HWFQ_RWPTR_REG; in gmac_dump_dma_state()
1636 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_update_hw_stats() local
1638 struct gemini_ethernet *geth = port->geth; in gmac_update_hw_stats()
1641 spin_lock_irqsave(&geth->irq_lock, flags); in gmac_update_hw_stats()
1642 u64_stats_update_begin(&port->ir_stats_syncp); in gmac_update_hw_stats()
1644 rx_discards = readl(port->gmac_base + GMAC_IN_DISCARDS); in gmac_update_hw_stats()
1645 port->hw_stats[0] += rx_discards; in gmac_update_hw_stats()
1646 port->hw_stats[1] += readl(port->gmac_base + GMAC_IN_ERRORS); in gmac_update_hw_stats()
1647 rx_mcast = readl(port->gmac_base + GMAC_IN_MCAST); in gmac_update_hw_stats()
1648 port->hw_stats[2] += rx_mcast; in gmac_update_hw_stats()
1649 rx_bcast = readl(port->gmac_base + GMAC_IN_BCAST); in gmac_update_hw_stats()
1650 port->hw_stats[3] += rx_bcast; in gmac_update_hw_stats()
1651 port->hw_stats[4] += readl(port->gmac_base + GMAC_IN_MAC1); in gmac_update_hw_stats()
1652 port->hw_stats[5] += readl(port->gmac_base + GMAC_IN_MAC2); in gmac_update_hw_stats()
1654 port->stats.rx_missed_errors += rx_discards; in gmac_update_hw_stats()
1655 port->stats.multicast += rx_mcast; in gmac_update_hw_stats()
1656 port->stats.multicast += rx_bcast; in gmac_update_hw_stats()
1658 writel(GMAC0_MIB_INT_BIT << (netdev->dev_id * 8), in gmac_update_hw_stats()
1659 geth->base + GLOBAL_INTERRUPT_STATUS_4_REG); in gmac_update_hw_stats()
1661 u64_stats_update_end(&port->ir_stats_syncp); in gmac_update_hw_stats()
1662 spin_unlock_irqrestore(&geth->irq_lock, flags); in gmac_update_hw_stats()
1666 * gmac_get_intr_flags() - get interrupt status flags for a port from
1667 * @netdev: the net device for the port to get flags from
1672 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_get_intr_flags() local
1673 struct gemini_ethernet *geth = port->geth; in gmac_get_intr_flags()
1678 offs = i * (GLOBAL_INTERRUPT_STATUS_1_REG - in gmac_get_intr_flags()
1681 irqif_reg = geth->base + GLOBAL_INTERRUPT_STATUS_0_REG + offs; in gmac_get_intr_flags()
1682 irqen_reg = geth->base + GLOBAL_INTERRUPT_ENABLE_0_REG + offs; in gmac_get_intr_flags()
1690 struct gemini_ethernet_port *port = in gmac_coalesce_delay_expired() local
1694 napi_schedule(&port->napi); in gmac_coalesce_delay_expired()
1700 struct gemini_ethernet_port *port; in gmac_irq() local
1705 port = netdev_priv(netdev); in gmac_irq()
1706 geth = port->geth; in gmac_irq()
1711 if (val & (GMAC0_IRQ0_2 << (netdev->dev_id * 2))) { in gmac_irq()
1721 if (val & (GMAC0_IRQ0_TXQ0_INTS << (netdev->dev_id * 6))) in gmac_irq()
1727 if (val & (DEFAULT_Q0_INT_BIT << netdev->dev_id)) { in gmac_irq()
1730 if (!port->rx_coalesce_nsecs) { in gmac_irq()
1731 napi_schedule(&port->napi); in gmac_irq()
1735 ktime = ktime_set(0, port->rx_coalesce_nsecs); in gmac_irq()
1736 hrtimer_start(&port->rx_coalesce_timer, ktime, in gmac_irq()
1744 if (val & (GMAC0_MIB_INT_BIT << (netdev->dev_id * 8))) in gmac_irq()
1747 if (val & (GMAC0_RX_OVERRUN_INT_BIT << (netdev->dev_id * 8))) { in gmac_irq()
1748 spin_lock(&geth->irq_lock); in gmac_irq()
1749 writel(GMAC0_RXDERR_INT_BIT << (netdev->dev_id * 8), in gmac_irq()
1750 geth->base + GLOBAL_INTERRUPT_STATUS_4_REG); in gmac_irq()
1751 u64_stats_update_begin(&port->ir_stats_syncp); in gmac_irq()
1752 ++port->stats.rx_fifo_errors; in gmac_irq()
1753 u64_stats_update_end(&port->ir_stats_syncp); in gmac_irq()
1754 spin_unlock(&geth->irq_lock); in gmac_irq()
1760 static void gmac_start_dma(struct gemini_ethernet_port *port) in gmac_start_dma() argument
1762 void __iomem *dma_ctrl_reg = port->dma_base + GMAC_DMA_CTRL_REG; in gmac_start_dma()
1781 static void gmac_stop_dma(struct gemini_ethernet_port *port) in gmac_stop_dma() argument
1783 void __iomem *dma_ctrl_reg = port->dma_base + GMAC_DMA_CTRL_REG; in gmac_stop_dma()
1794 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_open() local
1797 err = request_irq(netdev->irq, gmac_irq, in gmac_open()
1798 IRQF_SHARED, netdev->name, netdev); in gmac_open()
1805 phy_start(netdev->phydev); in gmac_open()
1807 err = geth_resize_freeq(port); in gmac_open()
1808 /* It's fine if it's just busy, the other port has set up in gmac_open()
1811 if (err && (err != -EBUSY)) { in gmac_open()
1829 napi_enable(&port->napi); in gmac_open()
1831 gmac_start_dma(port); in gmac_open()
1836 hrtimer_init(&port->rx_coalesce_timer, CLOCK_MONOTONIC, in gmac_open()
1838 port->rx_coalesce_timer.function = &gmac_coalesce_delay_expired; in gmac_open()
1845 phy_stop(netdev->phydev); in gmac_open()
1846 free_irq(netdev->irq, netdev); in gmac_open()
1852 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_stop() local
1854 hrtimer_cancel(&port->rx_coalesce_timer); in gmac_stop()
1857 gmac_stop_dma(port); in gmac_stop()
1858 napi_disable(&port->napi); in gmac_stop()
1864 phy_stop(netdev->phydev); in gmac_stop()
1865 free_irq(netdev->irq, netdev); in gmac_stop()
1873 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_set_rx_mode() local
1886 if (netdev->flags & IFF_PROMISC) { in gmac_set_rx_mode()
1891 } else if (netdev->flags & IFF_ALLMULTI) { in gmac_set_rx_mode()
1896 bit_nr = ~crc32_le(~0, ha->addr, ETH_ALEN) & 0x3f; in gmac_set_rx_mode()
1901 writel(mc_filter[0], port->gmac_base + GMAC_MCAST_FIL0); in gmac_set_rx_mode()
1902 writel(mc_filter[1], port->gmac_base + GMAC_MCAST_FIL1); in gmac_set_rx_mode()
1903 writel(filter.bits32, port->gmac_base + GMAC_RX_FLTR); in gmac_set_rx_mode()
1908 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_write_mac_address() local
1912 memcpy(addr, netdev->dev_addr, ETH_ALEN); in gmac_write_mac_address()
1914 writel(le32_to_cpu(addr[0]), port->gmac_base + GMAC_STA_ADD0); in gmac_write_mac_address()
1915 writel(le32_to_cpu(addr[1]), port->gmac_base + GMAC_STA_ADD1); in gmac_write_mac_address()
1916 writel(le32_to_cpu(addr[2]), port->gmac_base + GMAC_STA_ADD2); in gmac_write_mac_address()
1923 eth_hw_addr_set(netdev, sa->sa_data); in gmac_set_mac_address()
1931 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_clear_hw_stats() local
1933 readl(port->gmac_base + GMAC_IN_DISCARDS); in gmac_clear_hw_stats()
1934 readl(port->gmac_base + GMAC_IN_ERRORS); in gmac_clear_hw_stats()
1935 readl(port->gmac_base + GMAC_IN_MCAST); in gmac_clear_hw_stats()
1936 readl(port->gmac_base + GMAC_IN_BCAST); in gmac_clear_hw_stats()
1937 readl(port->gmac_base + GMAC_IN_MAC1); in gmac_clear_hw_stats()
1938 readl(port->gmac_base + GMAC_IN_MAC2); in gmac_clear_hw_stats()
1944 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_get_stats64() local
1951 start = u64_stats_fetch_begin(&port->rx_stats_syncp); in gmac_get_stats64()
1953 stats->rx_packets = port->stats.rx_packets; in gmac_get_stats64()
1954 stats->rx_bytes = port->stats.rx_bytes; in gmac_get_stats64()
1955 stats->rx_errors = port->stats.rx_errors; in gmac_get_stats64()
1956 stats->rx_dropped = port->stats.rx_dropped; in gmac_get_stats64()
1958 stats->rx_length_errors = port->stats.rx_length_errors; in gmac_get_stats64()
1959 stats->rx_over_errors = port->stats.rx_over_errors; in gmac_get_stats64()
1960 stats->rx_crc_errors = port->stats.rx_crc_errors; in gmac_get_stats64()
1961 stats->rx_frame_errors = port->stats.rx_frame_errors; in gmac_get_stats64()
1963 } while (u64_stats_fetch_retry(&port->rx_stats_syncp, start)); in gmac_get_stats64()
1967 start = u64_stats_fetch_begin(&port->ir_stats_syncp); in gmac_get_stats64()
1969 stats->tx_errors = port->stats.tx_errors; in gmac_get_stats64()
1970 stats->tx_packets = port->stats.tx_packets; in gmac_get_stats64()
1971 stats->tx_bytes = port->stats.tx_bytes; in gmac_get_stats64()
1973 stats->multicast = port->stats.multicast; in gmac_get_stats64()
1974 stats->rx_missed_errors = port->stats.rx_missed_errors; in gmac_get_stats64()
1975 stats->rx_fifo_errors = port->stats.rx_fifo_errors; in gmac_get_stats64()
1977 } while (u64_stats_fetch_retry(&port->ir_stats_syncp, start)); in gmac_get_stats64()
1981 start = u64_stats_fetch_begin(&port->tx_stats_syncp); in gmac_get_stats64()
1983 stats->tx_dropped = port->stats.tx_dropped; in gmac_get_stats64()
1985 } while (u64_stats_fetch_retry(&port->tx_stats_syncp, start)); in gmac_get_stats64()
1987 stats->rx_dropped += stats->rx_missed_errors; in gmac_get_stats64()
1995 return -EINVAL; in gmac_change_mtu()
1999 WRITE_ONCE(netdev->mtu, new_mtu); in gmac_change_mtu()
2013 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_set_features() local
2018 spin_lock_irqsave(&port->config_lock, flags); in gmac_set_features()
2020 reg = readl(port->gmac_base + GMAC_CONFIG0); in gmac_set_features()
2022 writel(reg, port->gmac_base + GMAC_CONFIG0); in gmac_set_features()
2024 spin_unlock_irqrestore(&port->config_lock, flags); in gmac_set_features()
2044 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_get_ethtool_stats() local
2054 start = u64_stats_fetch_begin(&port->ir_stats_syncp); in gmac_get_ethtool_stats()
2057 *p++ = port->hw_stats[i]; in gmac_get_ethtool_stats()
2059 } while (u64_stats_fetch_retry(&port->ir_stats_syncp, start)); in gmac_get_ethtool_stats()
2065 start = u64_stats_fetch_begin(&port->rx_stats_syncp); in gmac_get_ethtool_stats()
2068 *p++ = port->rx_stats[i]; in gmac_get_ethtool_stats()
2070 *p++ = port->rx_csum_stats[i]; in gmac_get_ethtool_stats()
2071 *p++ = port->rx_napi_exits; in gmac_get_ethtool_stats()
2073 } while (u64_stats_fetch_retry(&port->rx_stats_syncp, start)); in gmac_get_ethtool_stats()
2079 start = u64_stats_fetch_begin(&port->tx_stats_syncp); in gmac_get_ethtool_stats()
2082 *values++ = port->tx_frag_stats[i]; in gmac_get_ethtool_stats()
2083 port->tx_frag_stats[i] = 0; in gmac_get_ethtool_stats()
2085 *values++ = port->tx_frags_linearized; in gmac_get_ethtool_stats()
2086 *values++ = port->tx_hw_csummed; in gmac_get_ethtool_stats()
2088 } while (u64_stats_fetch_retry(&port->tx_stats_syncp, start)); in gmac_get_ethtool_stats()
2094 if (!netdev->phydev) in gmac_get_ksettings()
2095 return -ENXIO; in gmac_get_ksettings()
2096 phy_ethtool_ksettings_get(netdev->phydev, cmd); in gmac_get_ksettings()
2104 if (!netdev->phydev) in gmac_set_ksettings()
2105 return -ENXIO; in gmac_set_ksettings()
2106 return phy_ethtool_ksettings_set(netdev->phydev, cmd); in gmac_set_ksettings()
2111 if (!netdev->phydev) in gmac_nway_reset()
2112 return -ENXIO; in gmac_nway_reset()
2113 return phy_start_aneg(netdev->phydev); in gmac_nway_reset()
2119 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_get_pauseparam() local
2122 config0.bits32 = readl(port->gmac_base + GMAC_CONFIG0); in gmac_get_pauseparam()
2124 pparam->rx_pause = config0.bits.rx_fc_en; in gmac_get_pauseparam()
2125 pparam->tx_pause = config0.bits.tx_fc_en; in gmac_get_pauseparam()
2126 pparam->autoneg = true; in gmac_get_pauseparam()
2132 struct phy_device *phydev = netdev->phydev; in gmac_set_pauseparam()
2134 if (!pparam->autoneg) in gmac_set_pauseparam()
2135 return -EOPNOTSUPP; in gmac_set_pauseparam()
2137 phy_set_asym_pause(phydev, pparam->rx_pause, pparam->tx_pause); in gmac_set_pauseparam()
2147 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_get_ringparam() local
2149 readl(port->gmac_base + GMAC_CONFIG0); in gmac_get_ringparam()
2151 rp->rx_max_pending = 1 << 15; in gmac_get_ringparam()
2152 rp->rx_mini_max_pending = 0; in gmac_get_ringparam()
2153 rp->rx_jumbo_max_pending = 0; in gmac_get_ringparam()
2154 rp->tx_max_pending = 1 << 15; in gmac_get_ringparam()
2156 rp->rx_pending = 1 << port->rxq_order; in gmac_get_ringparam()
2157 rp->rx_mini_pending = 0; in gmac_get_ringparam()
2158 rp->rx_jumbo_pending = 0; in gmac_get_ringparam()
2159 rp->tx_pending = 1 << port->txq_order; in gmac_get_ringparam()
2167 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_set_ringparam() local
2171 return -EBUSY; in gmac_set_ringparam()
2173 if (rp->rx_pending) { in gmac_set_ringparam()
2174 port->rxq_order = min(15, ilog2(rp->rx_pending - 1) + 1); in gmac_set_ringparam()
2175 err = geth_resize_freeq(port); in gmac_set_ringparam()
2177 if (rp->tx_pending) { in gmac_set_ringparam()
2178 port->txq_order = min(15, ilog2(rp->tx_pending - 1) + 1); in gmac_set_ringparam()
2179 port->irq_every_tx_packets = 1 << (port->txq_order - 2); in gmac_set_ringparam()
2190 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_get_coalesce() local
2192 ecmd->rx_max_coalesced_frames = 1; in gmac_get_coalesce()
2193 ecmd->tx_max_coalesced_frames = port->irq_every_tx_packets; in gmac_get_coalesce()
2194 ecmd->rx_coalesce_usecs = port->rx_coalesce_nsecs / 1000; in gmac_get_coalesce()
2204 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_set_coalesce() local
2206 if (ecmd->tx_max_coalesced_frames < 1) in gmac_set_coalesce()
2207 return -EINVAL; in gmac_set_coalesce()
2208 if (ecmd->tx_max_coalesced_frames >= 1 << port->txq_order) in gmac_set_coalesce()
2209 return -EINVAL; in gmac_set_coalesce()
2211 port->irq_every_tx_packets = ecmd->tx_max_coalesced_frames; in gmac_set_coalesce()
2212 port->rx_coalesce_nsecs = ecmd->rx_coalesce_usecs * 1000; in gmac_set_coalesce()
2219 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_get_msglevel() local
2221 return port->msg_enable; in gmac_get_msglevel()
2226 struct gemini_ethernet_port *port = netdev_priv(netdev); in gmac_set_msglevel() local
2228 port->msg_enable = level; in gmac_set_msglevel()
2234 strcpy(info->driver, DRV_NAME); in gmac_get_drvinfo()
2235 strcpy(info->bus_info, netdev->dev_id ? "1" : "0"); in gmac_get_drvinfo()
2275 struct gemini_ethernet_port *port = data; in gemini_port_irq_thread() local
2279 geth = port->geth; in gemini_port_irq_thread()
2283 spin_lock_irqsave(&geth->irq_lock, flags); in gemini_port_irq_thread()
2285 writel(irqmask, geth->base + GLOBAL_INTERRUPT_STATUS_4_REG); in gemini_port_irq_thread()
2287 irqmask |= readl(geth->base + GLOBAL_INTERRUPT_ENABLE_4_REG); in gemini_port_irq_thread()
2288 writel(irqmask, geth->base + GLOBAL_INTERRUPT_ENABLE_4_REG); in gemini_port_irq_thread()
2289 spin_unlock_irqrestore(&geth->irq_lock, flags); in gemini_port_irq_thread()
2296 struct gemini_ethernet_port *port = data; in gemini_port_irq() local
2301 geth = port->geth; in gemini_port_irq()
2302 spin_lock(&geth->irq_lock); in gemini_port_irq()
2304 val = readl(geth->base + GLOBAL_INTERRUPT_STATUS_4_REG); in gemini_port_irq()
2305 en = readl(geth->base + GLOBAL_INTERRUPT_ENABLE_4_REG); in gemini_port_irq()
2314 writel(en, geth->base + GLOBAL_INTERRUPT_ENABLE_4_REG); in gemini_port_irq()
2318 spin_unlock(&geth->irq_lock); in gemini_port_irq()
2323 static void gemini_port_remove(struct gemini_ethernet_port *port) in gemini_port_remove() argument
2325 if (port->netdev) { in gemini_port_remove()
2326 phy_disconnect(port->netdev->phydev); in gemini_port_remove()
2327 unregister_netdev(port->netdev); in gemini_port_remove()
2329 clk_disable_unprepare(port->pclk); in gemini_port_remove()
2330 geth_cleanup_freeq(port->geth); in gemini_port_remove()
2336 if (geth->initialized) in gemini_ethernet_init()
2338 if (geth->port0 && geth->port1) in gemini_ethernet_init()
2339 geth->initialized = true; in gemini_ethernet_init()
2343 writel(0, geth->base + GLOBAL_INTERRUPT_ENABLE_0_REG); in gemini_ethernet_init()
2344 writel(0, geth->base + GLOBAL_INTERRUPT_ENABLE_1_REG); in gemini_ethernet_init()
2345 writel(0, geth->base + GLOBAL_INTERRUPT_ENABLE_2_REG); in gemini_ethernet_init()
2346 writel(0, geth->base + GLOBAL_INTERRUPT_ENABLE_3_REG); in gemini_ethernet_init()
2347 writel(0, geth->base + GLOBAL_INTERRUPT_ENABLE_4_REG); in gemini_ethernet_init()
2351 * GMAC0 intr bits ------> int0 ----> eth0 in gemini_ethernet_init()
2352 * GMAC1 intr bits ------> int1 ----> eth1 in gemini_ethernet_init()
2353 * TOE intr -------------> int1 ----> eth1 in gemini_ethernet_init()
2354 * Classification Intr --> int0 ----> eth0 in gemini_ethernet_init()
2355 * Default Q0 -----------> int0 ----> eth0 in gemini_ethernet_init()
2356 * Default Q1 -----------> int1 ----> eth1 in gemini_ethernet_init()
2357 * FreeQ intr -----------> int1 ----> eth1 in gemini_ethernet_init()
2359 writel(0xCCFC0FC0, geth->base + GLOBAL_INTERRUPT_SELECT_0_REG); in gemini_ethernet_init()
2360 writel(0x00F00002, geth->base + GLOBAL_INTERRUPT_SELECT_1_REG); in gemini_ethernet_init()
2361 writel(0xFFFFFFFF, geth->base + GLOBAL_INTERRUPT_SELECT_2_REG); in gemini_ethernet_init()
2362 writel(0xFFFFFFFF, geth->base + GLOBAL_INTERRUPT_SELECT_3_REG); in gemini_ethernet_init()
2363 writel(0xFF000003, geth->base + GLOBAL_INTERRUPT_SELECT_4_REG); in gemini_ethernet_init()
2365 /* edge-triggered interrupts packed to level-triggered one... */ in gemini_ethernet_init()
2366 writel(~0, geth->base + GLOBAL_INTERRUPT_STATUS_0_REG); in gemini_ethernet_init()
2367 writel(~0, geth->base + GLOBAL_INTERRUPT_STATUS_1_REG); in gemini_ethernet_init()
2368 writel(~0, geth->base + GLOBAL_INTERRUPT_STATUS_2_REG); in gemini_ethernet_init()
2369 writel(~0, geth->base + GLOBAL_INTERRUPT_STATUS_3_REG); in gemini_ethernet_init()
2370 writel(~0, geth->base + GLOBAL_INTERRUPT_STATUS_4_REG); in gemini_ethernet_init()
2373 writel(0, geth->base + GLOBAL_SW_FREEQ_BASE_SIZE_REG); in gemini_ethernet_init()
2374 writel(0, geth->base + GLOBAL_HW_FREEQ_BASE_SIZE_REG); in gemini_ethernet_init()
2375 writel(0, geth->base + GLOBAL_SWFQ_RWPTR_REG); in gemini_ethernet_init()
2376 writel(0, geth->base + GLOBAL_HWFQ_RWPTR_REG); in gemini_ethernet_init()
2378 geth->freeq_frag_order = DEFAULT_RX_BUF_ORDER; in gemini_ethernet_init()
2382 geth->freeq_order = 1; in gemini_ethernet_init()
2385 static void gemini_port_save_mac_addr(struct gemini_ethernet_port *port) in gemini_port_save_mac_addr() argument
2387 port->mac_addr[0] = in gemini_port_save_mac_addr()
2388 cpu_to_le32(readl(port->gmac_base + GMAC_STA_ADD0)); in gemini_port_save_mac_addr()
2389 port->mac_addr[1] = in gemini_port_save_mac_addr()
2390 cpu_to_le32(readl(port->gmac_base + GMAC_STA_ADD1)); in gemini_port_save_mac_addr()
2391 port->mac_addr[2] = in gemini_port_save_mac_addr()
2392 cpu_to_le32(readl(port->gmac_base + GMAC_STA_ADD2)); in gemini_port_save_mac_addr()
2398 struct device_node *np = pdev->dev.of_node; in gemini_ethernet_port_probe()
2399 struct gemini_ethernet_port *port; in gemini_ethernet_port_probe() local
2400 struct device *dev = &pdev->dev; in gemini_ethernet_port_probe()
2409 parent = dev->parent; in gemini_ethernet_port_probe()
2412 if (!strcmp(dev_name(dev), "60008000.ethernet-port")) in gemini_ethernet_port_probe()
2414 else if (!strcmp(dev_name(dev), "6000c000.ethernet-port")) in gemini_ethernet_port_probe()
2417 return -ENODEV; in gemini_ethernet_port_probe()
2421 netdev = devm_alloc_etherdev_mqs(dev, sizeof(*port), TX_QUEUE_NUM, TX_QUEUE_NUM); in gemini_ethernet_port_probe()
2424 return -ENOMEM; in gemini_ethernet_port_probe()
2427 port = netdev_priv(netdev); in gemini_ethernet_port_probe()
2429 port->netdev = netdev; in gemini_ethernet_port_probe()
2430 port->id = id; in gemini_ethernet_port_probe()
2431 port->geth = geth; in gemini_ethernet_port_probe()
2432 port->dev = dev; in gemini_ethernet_port_probe()
2433 port->msg_enable = netif_msg_init(debug, DEFAULT_MSG_ENABLE); in gemini_ethernet_port_probe()
2436 port->dma_base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL); in gemini_ethernet_port_probe()
2437 if (IS_ERR(port->dma_base)) { in gemini_ethernet_port_probe()
2439 return PTR_ERR(port->dma_base); in gemini_ethernet_port_probe()
2443 port->gmac_base = devm_platform_get_and_ioremap_resource(pdev, 1, NULL); in gemini_ethernet_port_probe()
2444 if (IS_ERR(port->gmac_base)) { in gemini_ethernet_port_probe()
2446 return PTR_ERR(port->gmac_base); in gemini_ethernet_port_probe()
2453 port->irq = irq; in gemini_ethernet_port_probe()
2455 /* Clock the port */ in gemini_ethernet_port_probe()
2456 port->pclk = devm_clk_get(dev, "PCLK"); in gemini_ethernet_port_probe()
2457 if (IS_ERR(port->pclk)) { in gemini_ethernet_port_probe()
2459 return PTR_ERR(port->pclk); in gemini_ethernet_port_probe()
2461 ret = clk_prepare_enable(port->pclk); in gemini_ethernet_port_probe()
2466 gemini_port_save_mac_addr(port); in gemini_ethernet_port_probe()
2468 /* Reset the port */ in gemini_ethernet_port_probe()
2469 port->reset = devm_reset_control_get_exclusive(dev, NULL); in gemini_ethernet_port_probe()
2470 if (IS_ERR(port->reset)) { in gemini_ethernet_port_probe()
2472 ret = PTR_ERR(port->reset); in gemini_ethernet_port_probe()
2475 reset_control_reset(port->reset); in gemini_ethernet_port_probe()
2480 geth->port0 = port; in gemini_ethernet_port_probe()
2482 geth->port1 = port; in gemini_ethernet_port_probe()
2487 platform_set_drvdata(pdev, port); in gemini_ethernet_port_probe()
2490 netdev->dev_id = port->id; in gemini_ethernet_port_probe()
2491 netdev->irq = irq; in gemini_ethernet_port_probe()
2492 netdev->netdev_ops = &gmac_351x_ops; in gemini_ethernet_port_probe()
2493 netdev->ethtool_ops = &gmac_351x_ethtool_ops; in gemini_ethernet_port_probe()
2495 spin_lock_init(&port->config_lock); in gemini_ethernet_port_probe()
2498 netdev->hw_features = GMAC_OFFLOAD_FEATURES; in gemini_ethernet_port_probe()
2499 netdev->features |= GMAC_OFFLOAD_FEATURES | NETIF_F_GRO; in gemini_ethernet_port_probe()
2504 netdev->min_mtu = ETH_MIN_MTU; in gemini_ethernet_port_probe()
2505 netdev->max_mtu = MTU_SIZE_BIT_MASK - VLAN_ETH_HLEN; in gemini_ethernet_port_probe()
2507 port->freeq_refill = 0; in gemini_ethernet_port_probe()
2508 netif_napi_add(netdev, &port->napi, gmac_napi_poll); in gemini_ethernet_port_probe()
2513 memcpy(port->mac_addr, mac, ETH_ALEN); in gemini_ethernet_port_probe()
2516 if (is_valid_ether_addr((void *)port->mac_addr)) { in gemini_ethernet_port_probe()
2517 eth_hw_addr_set(netdev, (u8 *)port->mac_addr); in gemini_ethernet_port_probe()
2520 port->mac_addr[0], port->mac_addr[1], in gemini_ethernet_port_probe()
2521 port->mac_addr[2]); in gemini_ethernet_port_probe()
2527 ret = devm_request_threaded_irq(port->dev, in gemini_ethernet_port_probe()
2528 port->irq, in gemini_ethernet_port_probe()
2532 port_names[port->id], in gemini_ethernet_port_probe()
2533 port); in gemini_ethernet_port_probe()
2551 clk_disable_unprepare(port->pclk); in gemini_ethernet_port_probe()
2557 struct gemini_ethernet_port *port = platform_get_drvdata(pdev); in gemini_ethernet_port_remove() local
2559 gemini_port_remove(port); in gemini_ethernet_port_remove()
2564 .compatible = "cortina,gemini-ethernet-port",
2572 .name = "gemini-ethernet-port",
2581 struct device *dev = &pdev->dev; in gemini_ethernet_probe()
2589 return -ENOMEM; in gemini_ethernet_probe()
2590 geth->base = devm_platform_get_and_ioremap_resource(pdev, 0, NULL); in gemini_ethernet_probe()
2591 if (IS_ERR(geth->base)) in gemini_ethernet_probe()
2592 return PTR_ERR(geth->base); in gemini_ethernet_probe()
2593 geth->dev = dev; in gemini_ethernet_probe()
2598 val = readl(geth->base + GLOBAL_TOE_VERSION_REG); in gemini_ethernet_probe()
2600 } while (!val && --retry); in gemini_ethernet_probe()
2603 return -EIO; in gemini_ethernet_probe()
2608 spin_lock_init(&geth->irq_lock); in gemini_ethernet_probe()
2609 spin_lock_init(&geth->freeq_lock); in gemini_ethernet_probe()
2623 geth->initialized = false; in gemini_ethernet_remove()
2628 .compatible = "cortina,gemini-ethernet",