Lines Matching +full:ast2600 +full:- +full:mdio
1 // SPDX-License-Identifier: GPL-2.0-or-later
5 * (C) Copyright 2009-2011 Faraday Technology
6 * Po-Yu Chuang <ratbert@faraday-tech.com>
13 #include <linux/dma-mapping.h>
55 /* For NC-SI to register a fixed-link phy device */
103 /* AST2500/AST2600 RMII ref clock gate */
129 struct net_device *netdev = priv->netdev; in ftgmac100_reset_mac()
133 iowrite32(maccr, priv->base + FTGMAC100_OFFSET_MACCR); in ftgmac100_reset_mac()
135 priv->base + FTGMAC100_OFFSET_MACCR); in ftgmac100_reset_mac()
139 maccr = ioread32(priv->base + FTGMAC100_OFFSET_MACCR); in ftgmac100_reset_mac()
147 return -EIO; in ftgmac100_reset_mac()
155 if (priv->is_aspeed && priv->netdev->phydev->interface == PHY_INTERFACE_MODE_RMII) { in ftgmac100_reset_and_config_mac()
158 err = reset_control_assert(priv->rst); in ftgmac100_reset_and_config_mac()
160 dev_err(priv->dev, "Failed to reset mac (%d)\n", err); in ftgmac100_reset_and_config_mac()
164 err = reset_control_deassert(priv->rst); in ftgmac100_reset_and_config_mac()
166 dev_err(priv->dev, "Failed to deassert mac reset (%d)\n", err); in ftgmac100_reset_and_config_mac()
171 switch (priv->cur_speed) { in ftgmac100_reset_and_config_mac()
184 netdev_err(priv->netdev, "Unknown speed %d !\n", in ftgmac100_reset_and_config_mac()
185 priv->cur_speed); in ftgmac100_reset_and_config_mac()
190 priv->rx_pointer = 0; in ftgmac100_reset_and_config_mac()
191 priv->tx_clean_pointer = 0; in ftgmac100_reset_and_config_mac()
192 priv->tx_pointer = 0; in ftgmac100_reset_and_config_mac()
196 return -EIO; in ftgmac100_reset_and_config_mac()
206 iowrite32(maddr, priv->base + FTGMAC100_OFFSET_MAC_MADR); in ftgmac100_write_mac_addr()
207 iowrite32(laddr, priv->base + FTGMAC100_OFFSET_MAC_LADR); in ftgmac100_write_mac_addr()
217 err = of_get_ethdev_address(priv->dev->of_node, priv->netdev); in ftgmac100_initial_mac()
218 if (err == -EPROBE_DEFER) in ftgmac100_initial_mac()
221 dev_info(priv->dev, "Read MAC address %pM from device tree\n", in ftgmac100_initial_mac()
222 priv->netdev->dev_addr); in ftgmac100_initial_mac()
226 m = ioread32(priv->base + FTGMAC100_OFFSET_MAC_MADR); in ftgmac100_initial_mac()
227 l = ioread32(priv->base + FTGMAC100_OFFSET_MAC_LADR); in ftgmac100_initial_mac()
237 eth_hw_addr_set(priv->netdev, mac); in ftgmac100_initial_mac()
238 dev_info(priv->dev, "Read MAC address %pM from chip\n", mac); in ftgmac100_initial_mac()
240 eth_hw_addr_random(priv->netdev); in ftgmac100_initial_mac()
241 dev_info(priv->dev, "Generated random MAC address %pM\n", in ftgmac100_initial_mac()
242 priv->netdev->dev_addr); in ftgmac100_initial_mac()
257 ftgmac100_write_mac_addr(netdev_priv(dev), dev->dev_addr); in ftgmac100_set_mac_addr()
267 if (priv->rx_pause) in ftgmac100_config_pause()
273 if (priv->tx_pause) in ftgmac100_config_pause()
276 iowrite32(fcr, priv->base + FTGMAC100_OFFSET_FCR); in ftgmac100_config_pause()
284 reg = ioread32(priv->base + FTGMAC100_OFFSET_ISR); in ftgmac100_init_hw()
285 iowrite32(reg, priv->base + FTGMAC100_OFFSET_ISR); in ftgmac100_init_hw()
288 iowrite32(priv->rxdes_dma, priv->base + FTGMAC100_OFFSET_RXR_BADR); in ftgmac100_init_hw()
291 iowrite32(priv->txdes_dma, priv->base + FTGMAC100_OFFSET_NPTXR_BADR); in ftgmac100_init_hw()
295 priv->base + FTGMAC100_OFFSET_RBSR); in ftgmac100_init_hw()
299 priv->base + FTGMAC100_OFFSET_APTC); in ftgmac100_init_hw()
302 ftgmac100_write_mac_addr(priv, priv->netdev->dev_addr); in ftgmac100_init_hw()
305 iowrite32(priv->maht0, priv->base + FTGMAC100_OFFSET_MAHT0); in ftgmac100_init_hw()
306 iowrite32(priv->maht1, priv->base + FTGMAC100_OFFSET_MAHT1); in ftgmac100_init_hw()
320 priv->base + FTGMAC100_OFFSET_DBLAC); in ftgmac100_init_hw()
328 priv->base + FTGMAC100_OFFSET_ITC); in ftgmac100_init_hw()
331 reg = ioread32(priv->base + FTGMAC100_OFFSET_FEAR); in ftgmac100_init_hw()
334 reg = ioread32(priv->base + FTGMAC100_OFFSET_TPAFCR); in ftgmac100_init_hw()
338 iowrite32(reg, priv->base + FTGMAC100_OFFSET_TPAFCR); in ftgmac100_init_hw()
343 u32 maccr = ioread32(priv->base + FTGMAC100_OFFSET_MACCR); in ftgmac100_start_hw()
359 if (priv->cur_duplex == DUPLEX_FULL) in ftgmac100_start_hw()
361 if (priv->netdev->flags & IFF_PROMISC) in ftgmac100_start_hw()
363 if (priv->netdev->flags & IFF_ALLMULTI) in ftgmac100_start_hw()
365 else if (netdev_mc_count(priv->netdev)) in ftgmac100_start_hw()
369 if (priv->netdev->features & NETIF_F_HW_VLAN_CTAG_RX) in ftgmac100_start_hw()
373 iowrite32(maccr, priv->base + FTGMAC100_OFFSET_MACCR); in ftgmac100_start_hw()
378 iowrite32(0, priv->base + FTGMAC100_OFFSET_MACCR); in ftgmac100_stop_hw()
385 priv->maht1 = 0; in ftgmac100_calc_mc_hash()
386 priv->maht0 = 0; in ftgmac100_calc_mc_hash()
387 netdev_for_each_mc_addr(ha, priv->netdev) { in ftgmac100_calc_mc_hash()
388 u32 crc_val = ether_crc_le(ETH_ALEN, ha->addr); in ftgmac100_calc_mc_hash()
392 priv->maht1 |= 1ul << (crc_val - 32); in ftgmac100_calc_mc_hash()
394 priv->maht0 |= 1ul << (crc_val); in ftgmac100_calc_mc_hash()
410 iowrite32(priv->maht0, priv->base + FTGMAC100_OFFSET_MAHT0); in ftgmac100_set_rx_mode()
411 iowrite32(priv->maht1, priv->base + FTGMAC100_OFFSET_MAHT1); in ftgmac100_set_rx_mode()
420 struct net_device *netdev = priv->netdev; in ftgmac100_alloc_rx_buf()
429 err = -ENOMEM; in ftgmac100_alloc_rx_buf()
430 map = priv->rx_scratch_dma; in ftgmac100_alloc_rx_buf()
432 map = dma_map_single(priv->dev, skb->data, RX_BUF_SIZE, in ftgmac100_alloc_rx_buf()
434 if (unlikely(dma_mapping_error(priv->dev, map))) { in ftgmac100_alloc_rx_buf()
438 map = priv->rx_scratch_dma; in ftgmac100_alloc_rx_buf()
440 err = -ENOMEM; in ftgmac100_alloc_rx_buf()
445 priv->rx_skbs[entry] = skb; in ftgmac100_alloc_rx_buf()
448 rxdes->rxdes3 = cpu_to_le32(map); in ftgmac100_alloc_rx_buf()
454 if (entry == (priv->rx_q_entries - 1)) in ftgmac100_alloc_rx_buf()
455 rxdes->rxdes0 = cpu_to_le32(priv->rxdes0_edorr_mask); in ftgmac100_alloc_rx_buf()
457 rxdes->rxdes0 = 0; in ftgmac100_alloc_rx_buf()
465 return (pointer + 1) & (priv->rx_q_entries - 1); in ftgmac100_next_rx_pointer()
470 struct net_device *netdev = priv->netdev; in ftgmac100_rx_packet_error()
473 netdev->stats.rx_errors++; in ftgmac100_rx_packet_error()
476 netdev->stats.rx_crc_errors++; in ftgmac100_rx_packet_error()
481 netdev->stats.rx_length_errors++; in ftgmac100_rx_packet_error()
486 struct net_device *netdev = priv->netdev; in ftgmac100_rx_packet()
494 pointer = priv->rx_pointer; in ftgmac100_rx_packet()
495 rxdes = &priv->rxdes[pointer]; in ftgmac100_rx_packet()
498 status = le32_to_cpu(rxdes->rxdes0); in ftgmac100_rx_packet()
514 csum_vlan = le32_to_cpu(rxdes->rxdes1); in ftgmac100_rx_packet()
538 skb = priv->rx_skbs[pointer]; in ftgmac100_rx_packet()
545 netdev->stats.multicast++; in ftgmac100_rx_packet()
553 if (netdev->features & NETIF_F_RXCSUM) { in ftgmac100_rx_packet()
559 skb->ip_summed = CHECKSUM_NONE; in ftgmac100_rx_packet()
561 skb->ip_summed = CHECKSUM_UNNECESSARY; in ftgmac100_rx_packet()
568 if ((netdev->features & NETIF_F_HW_VLAN_CTAG_RX) && in ftgmac100_rx_packet()
574 map = le32_to_cpu(rxdes->rxdes3); in ftgmac100_rx_packet()
581 dma_unmap_single(priv->dev, map, size, DMA_FROM_DEVICE); in ftgmac100_rx_packet()
583 dma_unmap_single(priv->dev, map, RX_BUF_SIZE, DMA_FROM_DEVICE); in ftgmac100_rx_packet()
589 priv->rx_pointer = ftgmac100_next_rx_pointer(priv, pointer); in ftgmac100_rx_packet()
591 skb->protocol = eth_type_trans(skb, netdev); in ftgmac100_rx_packet()
593 netdev->stats.rx_packets++; in ftgmac100_rx_packet()
594 netdev->stats.rx_bytes += size; in ftgmac100_rx_packet()
597 if (skb->ip_summed == CHECKSUM_NONE) in ftgmac100_rx_packet()
600 napi_gro_receive(&priv->napi, skb); in ftgmac100_rx_packet()
607 rxdes->rxdes0 = cpu_to_le32(status & priv->rxdes0_edorr_mask); in ftgmac100_rx_packet()
608 priv->rx_pointer = ftgmac100_next_rx_pointer(priv, pointer); in ftgmac100_rx_packet()
609 netdev->stats.rx_dropped++; in ftgmac100_rx_packet()
616 if (index == (priv->tx_q_entries - 1)) in ftgmac100_base_tx_ctlstat()
617 return priv->txdes0_edotr_mask; in ftgmac100_base_tx_ctlstat()
625 return (pointer + 1) & (priv->tx_q_entries - 1); in ftgmac100_next_tx_pointer()
636 return (priv->tx_clean_pointer - priv->tx_pointer - 1) & in ftgmac100_tx_buf_avail()
637 (priv->tx_q_entries - 1); in ftgmac100_tx_buf_avail()
642 return priv->tx_pointer != priv->tx_clean_pointer; in ftgmac100_tx_buf_cleanable()
651 dma_addr_t map = le32_to_cpu(txdes->txdes3); in ftgmac100_free_tx_packet()
656 dma_unmap_single(priv->dev, map, len, DMA_TO_DEVICE); in ftgmac100_free_tx_packet()
659 dma_unmap_page(priv->dev, map, len, DMA_TO_DEVICE); in ftgmac100_free_tx_packet()
665 priv->tx_skbs[pointer] = NULL; in ftgmac100_free_tx_packet()
670 struct net_device *netdev = priv->netdev; in ftgmac100_tx_complete_packet()
676 pointer = priv->tx_clean_pointer; in ftgmac100_tx_complete_packet()
677 txdes = &priv->txdes[pointer]; in ftgmac100_tx_complete_packet()
679 ctl_stat = le32_to_cpu(txdes->txdes0); in ftgmac100_tx_complete_packet()
683 skb = priv->tx_skbs[pointer]; in ftgmac100_tx_complete_packet()
684 netdev->stats.tx_packets++; in ftgmac100_tx_complete_packet()
685 netdev->stats.tx_bytes += skb->len; in ftgmac100_tx_complete_packet()
687 txdes->txdes0 = cpu_to_le32(ctl_stat & priv->txdes0_edotr_mask); in ftgmac100_tx_complete_packet()
694 priv->tx_clean_pointer = ftgmac100_next_tx_pointer(priv, pointer); in ftgmac100_tx_complete_packet()
701 struct net_device *netdev = priv->netdev; in ftgmac100_tx_complete()
725 if (skb->protocol == cpu_to_be16(ETH_P_IP)) { in ftgmac100_prep_tx_csum()
726 u8 ip_proto = ip_hdr(skb)->protocol; in ftgmac100_prep_tx_csum()
754 netdev->stats.tx_dropped++; in ftgmac100_hard_start_xmit()
759 if (unlikely(skb->len > MAX_PKT_SIZE)) { in ftgmac100_hard_start_xmit()
768 nfrags = skb_shinfo(skb)->nr_frags; in ftgmac100_hard_start_xmit()
772 if (skb->ip_summed == CHECKSUM_PARTIAL && in ftgmac100_hard_start_xmit()
786 map = dma_map_single(priv->dev, skb->data, len, DMA_TO_DEVICE); in ftgmac100_hard_start_xmit()
787 if (dma_mapping_error(priv->dev, map)) { in ftgmac100_hard_start_xmit()
794 pointer = priv->tx_pointer; in ftgmac100_hard_start_xmit()
795 txdes = first = &priv->txdes[pointer]; in ftgmac100_hard_start_xmit()
800 priv->tx_skbs[pointer] = skb; in ftgmac100_hard_start_xmit()
807 txdes->txdes3 = cpu_to_le32(map); in ftgmac100_hard_start_xmit()
808 txdes->txdes1 = cpu_to_le32(csum_vlan); in ftgmac100_hard_start_xmit()
815 skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; in ftgmac100_hard_start_xmit()
820 map = skb_frag_dma_map(priv->dev, frag, 0, len, in ftgmac100_hard_start_xmit()
822 if (dma_mapping_error(priv->dev, map)) in ftgmac100_hard_start_xmit()
826 priv->tx_skbs[pointer] = skb; in ftgmac100_hard_start_xmit()
827 txdes = &priv->txdes[pointer]; in ftgmac100_hard_start_xmit()
831 if (i == (nfrags - 1)) in ftgmac100_hard_start_xmit()
833 txdes->txdes0 = cpu_to_le32(ctl_stat); in ftgmac100_hard_start_xmit()
834 txdes->txdes1 = 0; in ftgmac100_hard_start_xmit()
835 txdes->txdes3 = cpu_to_le32(map); in ftgmac100_hard_start_xmit()
845 first->txdes0 = cpu_to_le32(f_ctl_stat); in ftgmac100_hard_start_xmit()
853 priv->tx_pointer = pointer; in ftgmac100_hard_start_xmit()
868 iowrite32(1, priv->base + FTGMAC100_OFFSET_NPTXPD); in ftgmac100_hard_start_xmit()
877 pointer = priv->tx_pointer; in ftgmac100_hard_start_xmit()
879 first->txdes0 = cpu_to_le32(f_ctl_stat & priv->txdes0_edotr_mask); in ftgmac100_hard_start_xmit()
884 txdes = &priv->txdes[pointer]; in ftgmac100_hard_start_xmit()
885 ctl_stat = le32_to_cpu(txdes->txdes0); in ftgmac100_hard_start_xmit()
887 txdes->txdes0 = cpu_to_le32(ctl_stat & priv->txdes0_edotr_mask); in ftgmac100_hard_start_xmit()
897 netdev->stats.tx_dropped++; in ftgmac100_hard_start_xmit()
907 for (i = 0; i < priv->rx_q_entries; i++) { in ftgmac100_free_buffers()
908 struct ftgmac100_rxdes *rxdes = &priv->rxdes[i]; in ftgmac100_free_buffers()
909 struct sk_buff *skb = priv->rx_skbs[i]; in ftgmac100_free_buffers()
910 dma_addr_t map = le32_to_cpu(rxdes->rxdes3); in ftgmac100_free_buffers()
915 priv->rx_skbs[i] = NULL; in ftgmac100_free_buffers()
916 dma_unmap_single(priv->dev, map, RX_BUF_SIZE, DMA_FROM_DEVICE); in ftgmac100_free_buffers()
921 for (i = 0; i < priv->tx_q_entries; i++) { in ftgmac100_free_buffers()
922 struct ftgmac100_txdes *txdes = &priv->txdes[i]; in ftgmac100_free_buffers()
923 struct sk_buff *skb = priv->tx_skbs[i]; in ftgmac100_free_buffers()
928 le32_to_cpu(txdes->txdes0)); in ftgmac100_free_buffers()
935 kfree(priv->rx_skbs); in ftgmac100_free_rings()
936 kfree(priv->tx_skbs); in ftgmac100_free_rings()
939 if (priv->rxdes) in ftgmac100_free_rings()
940 dma_free_coherent(priv->dev, MAX_RX_QUEUE_ENTRIES * in ftgmac100_free_rings()
942 priv->rxdes, priv->rxdes_dma); in ftgmac100_free_rings()
943 priv->rxdes = NULL; in ftgmac100_free_rings()
945 if (priv->txdes) in ftgmac100_free_rings()
946 dma_free_coherent(priv->dev, MAX_TX_QUEUE_ENTRIES * in ftgmac100_free_rings()
948 priv->txdes, priv->txdes_dma); in ftgmac100_free_rings()
949 priv->txdes = NULL; in ftgmac100_free_rings()
952 if (priv->rx_scratch) in ftgmac100_free_rings()
953 dma_free_coherent(priv->dev, RX_BUF_SIZE, in ftgmac100_free_rings()
954 priv->rx_scratch, priv->rx_scratch_dma); in ftgmac100_free_rings()
960 priv->rx_skbs = kcalloc(MAX_RX_QUEUE_ENTRIES, sizeof(void *), in ftgmac100_alloc_rings()
962 if (!priv->rx_skbs) in ftgmac100_alloc_rings()
963 return -ENOMEM; in ftgmac100_alloc_rings()
964 priv->tx_skbs = kcalloc(MAX_TX_QUEUE_ENTRIES, sizeof(void *), in ftgmac100_alloc_rings()
966 if (!priv->tx_skbs) in ftgmac100_alloc_rings()
967 return -ENOMEM; in ftgmac100_alloc_rings()
970 priv->rxdes = dma_alloc_coherent(priv->dev, in ftgmac100_alloc_rings()
972 &priv->rxdes_dma, GFP_KERNEL); in ftgmac100_alloc_rings()
973 if (!priv->rxdes) in ftgmac100_alloc_rings()
974 return -ENOMEM; in ftgmac100_alloc_rings()
975 priv->txdes = dma_alloc_coherent(priv->dev, in ftgmac100_alloc_rings()
977 &priv->txdes_dma, GFP_KERNEL); in ftgmac100_alloc_rings()
978 if (!priv->txdes) in ftgmac100_alloc_rings()
979 return -ENOMEM; in ftgmac100_alloc_rings()
982 priv->rx_scratch = dma_alloc_coherent(priv->dev, in ftgmac100_alloc_rings()
984 &priv->rx_scratch_dma, in ftgmac100_alloc_rings()
986 if (!priv->rx_scratch) in ftgmac100_alloc_rings()
987 return -ENOMEM; in ftgmac100_alloc_rings()
999 priv->rx_q_entries = priv->new_rx_q_entries; in ftgmac100_init_rings()
1000 priv->tx_q_entries = priv->new_tx_q_entries; in ftgmac100_init_rings()
1002 if (WARN_ON(priv->rx_q_entries < MIN_RX_QUEUE_ENTRIES)) in ftgmac100_init_rings()
1006 for (i = 0; i < priv->rx_q_entries; i++) { in ftgmac100_init_rings()
1007 rxdes = &priv->rxdes[i]; in ftgmac100_init_rings()
1008 rxdes->rxdes0 = 0; in ftgmac100_init_rings()
1009 rxdes->rxdes3 = cpu_to_le32(priv->rx_scratch_dma); in ftgmac100_init_rings()
1012 rxdes->rxdes0 |= cpu_to_le32(priv->rxdes0_edorr_mask); in ftgmac100_init_rings()
1014 if (WARN_ON(priv->tx_q_entries < MIN_RX_QUEUE_ENTRIES)) in ftgmac100_init_rings()
1018 for (i = 0; i < priv->tx_q_entries; i++) { in ftgmac100_init_rings()
1019 txdes = &priv->txdes[i]; in ftgmac100_init_rings()
1020 txdes->txdes0 = 0; in ftgmac100_init_rings()
1022 txdes->txdes0 |= cpu_to_le32(priv->txdes0_edotr_mask); in ftgmac100_init_rings()
1029 for (i = 0; i < priv->rx_q_entries; i++) { in ftgmac100_alloc_rx_buffers()
1030 struct ftgmac100_rxdes *rxdes = &priv->rxdes[i]; in ftgmac100_alloc_rx_buffers()
1033 return -ENOMEM; in ftgmac100_alloc_rx_buffers()
1040 struct net_device *netdev = bus->priv; in ftgmac100_mdiobus_read()
1045 phycr = ioread32(priv->base + FTGMAC100_OFFSET_PHYCR); in ftgmac100_mdiobus_read()
1054 iowrite32(phycr, priv->base + FTGMAC100_OFFSET_PHYCR); in ftgmac100_mdiobus_read()
1057 phycr = ioread32(priv->base + FTGMAC100_OFFSET_PHYCR); in ftgmac100_mdiobus_read()
1062 data = ioread32(priv->base + FTGMAC100_OFFSET_PHYDATA); in ftgmac100_mdiobus_read()
1069 netdev_err(netdev, "mdio read timed out\n"); in ftgmac100_mdiobus_read()
1070 return -EIO; in ftgmac100_mdiobus_read()
1076 struct net_device *netdev = bus->priv; in ftgmac100_mdiobus_write()
1082 phycr = ioread32(priv->base + FTGMAC100_OFFSET_PHYCR); in ftgmac100_mdiobus_write()
1093 iowrite32(data, priv->base + FTGMAC100_OFFSET_PHYDATA); in ftgmac100_mdiobus_write()
1094 iowrite32(phycr, priv->base + FTGMAC100_OFFSET_PHYCR); in ftgmac100_mdiobus_write()
1097 phycr = ioread32(priv->base + FTGMAC100_OFFSET_PHYCR); in ftgmac100_mdiobus_write()
1105 netdev_err(netdev, "mdio write timed out\n"); in ftgmac100_mdiobus_write()
1106 return -EIO; in ftgmac100_mdiobus_write()
1112 strscpy(info->driver, DRV_NAME, sizeof(info->driver)); in ftgmac100_get_drvinfo()
1113 strscpy(info->bus_info, dev_name(&netdev->dev), sizeof(info->bus_info)); in ftgmac100_get_drvinfo()
1125 ering->rx_max_pending = MAX_RX_QUEUE_ENTRIES; in ftgmac100_get_ringparam()
1126 ering->tx_max_pending = MAX_TX_QUEUE_ENTRIES; in ftgmac100_get_ringparam()
1127 ering->rx_pending = priv->rx_q_entries; in ftgmac100_get_ringparam()
1128 ering->tx_pending = priv->tx_q_entries; in ftgmac100_get_ringparam()
1139 if (ering->rx_pending > MAX_RX_QUEUE_ENTRIES || in ftgmac100_set_ringparam()
1140 ering->tx_pending > MAX_TX_QUEUE_ENTRIES || in ftgmac100_set_ringparam()
1141 ering->rx_pending < MIN_RX_QUEUE_ENTRIES || in ftgmac100_set_ringparam()
1142 ering->tx_pending < MIN_TX_QUEUE_ENTRIES || in ftgmac100_set_ringparam()
1143 !is_power_of_2(ering->rx_pending) || in ftgmac100_set_ringparam()
1144 !is_power_of_2(ering->tx_pending)) in ftgmac100_set_ringparam()
1145 return -EINVAL; in ftgmac100_set_ringparam()
1147 priv->new_rx_q_entries = ering->rx_pending; in ftgmac100_set_ringparam()
1148 priv->new_tx_q_entries = ering->tx_pending; in ftgmac100_set_ringparam()
1150 schedule_work(&priv->reset_task); in ftgmac100_set_ringparam()
1160 pause->autoneg = priv->aneg_pause; in ftgmac100_get_pauseparam()
1161 pause->tx_pause = priv->tx_pause; in ftgmac100_get_pauseparam()
1162 pause->rx_pause = priv->rx_pause; in ftgmac100_get_pauseparam()
1169 struct phy_device *phydev = netdev->phydev; in ftgmac100_set_pauseparam()
1171 priv->aneg_pause = pause->autoneg; in ftgmac100_set_pauseparam()
1172 priv->tx_pause = pause->tx_pause; in ftgmac100_set_pauseparam()
1173 priv->rx_pause = pause->rx_pause; in ftgmac100_set_pauseparam()
1176 phy_set_asym_pause(phydev, pause->rx_pause, pause->tx_pause); in ftgmac100_set_pauseparam()
1179 if (!(phydev && priv->aneg_pause)) in ftgmac100_set_pauseparam()
1205 status = ioread32(priv->base + FTGMAC100_OFFSET_ISR); in ftgmac100_interrupt()
1206 iowrite32(status, priv->base + FTGMAC100_OFFSET_ISR); in ftgmac100_interrupt()
1211 netdev->stats.rx_over_errors++; in ftgmac100_interrupt()
1215 netdev->stats.rx_fifo_errors++; in ftgmac100_interrupt()
1219 netdev->stats.tx_fifo_errors++; in ftgmac100_interrupt()
1221 /* AHB error -> Reset the chip */ in ftgmac100_interrupt()
1226 iowrite32(0, priv->base + FTGMAC100_OFFSET_IER); in ftgmac100_interrupt()
1227 schedule_work(&priv->reset_task); in ftgmac100_interrupt()
1234 priv->need_mac_restart = true; in ftgmac100_interrupt()
1241 iowrite32(new_mask, priv->base + FTGMAC100_OFFSET_IER); in ftgmac100_interrupt()
1244 napi_schedule_irqoff(&priv->napi); in ftgmac100_interrupt()
1251 struct ftgmac100_rxdes *rxdes = &priv->rxdes[priv->rx_pointer]; in ftgmac100_check_rx()
1254 return !!(rxdes->rxdes0 & cpu_to_le32(FTGMAC100_RXDES0_RXPKT_RDY)); in ftgmac100_check_rx()
1276 if (unlikely(priv->need_mac_restart)) { in ftgmac100_poll()
1278 priv->need_mac_restart = false; in ftgmac100_poll()
1280 /* Re-enable "bad" interrupts */ in ftgmac100_poll()
1282 priv->base + FTGMAC100_OFFSET_IER); in ftgmac100_poll()
1292 /* We are about to re-enable all interrupts. However in ftgmac100_poll()
1295 * to re-check if there's something to process in ftgmac100_poll()
1298 priv->base + FTGMAC100_OFFSET_ISR); in ftgmac100_poll()
1303 ioread32(priv->base + FTGMAC100_OFFSET_ISR); in ftgmac100_poll()
1315 priv->base + FTGMAC100_OFFSET_IER); in ftgmac100_poll()
1325 /* Re-init descriptors (adjust queue sizes) */ in ftgmac100_init_all()
1338 /* Re-enable the device */ in ftgmac100_init_all()
1339 napi_enable(&priv->napi); in ftgmac100_init_all()
1340 netif_start_queue(priv->netdev); in ftgmac100_init_all()
1343 iowrite32(FTGMAC100_INT_ALL, priv->base + FTGMAC100_OFFSET_IER); in ftgmac100_init_all()
1350 struct net_device *netdev = priv->netdev; in ftgmac100_reset()
1357 if (netdev->phydev) in ftgmac100_reset()
1358 mutex_lock(&netdev->phydev->lock); in ftgmac100_reset()
1359 if (priv->mii_bus) in ftgmac100_reset()
1360 mutex_lock(&priv->mii_bus->mdio_lock); in ftgmac100_reset()
1369 napi_disable(&priv->napi); in ftgmac100_reset()
1388 if (priv->mii_bus) in ftgmac100_reset()
1389 mutex_unlock(&priv->mii_bus->mdio_lock); in ftgmac100_reset()
1390 if (netdev->phydev) in ftgmac100_reset()
1391 mutex_unlock(&netdev->phydev->lock); in ftgmac100_reset()
1406 struct phy_device *phydev = netdev->phydev; in ftgmac100_adjust_link()
1411 if (!phydev->link) in ftgmac100_adjust_link()
1414 new_speed = phydev->speed; in ftgmac100_adjust_link()
1417 if (priv->aneg_pause) { in ftgmac100_adjust_link()
1418 rx_pause = tx_pause = phydev->pause; in ftgmac100_adjust_link()
1419 if (phydev->asym_pause) in ftgmac100_adjust_link()
1422 rx_pause = priv->rx_pause; in ftgmac100_adjust_link()
1423 tx_pause = priv->tx_pause; in ftgmac100_adjust_link()
1427 if (phydev->speed == priv->cur_speed && in ftgmac100_adjust_link()
1428 phydev->duplex == priv->cur_duplex && in ftgmac100_adjust_link()
1429 rx_pause == priv->rx_pause && in ftgmac100_adjust_link()
1430 tx_pause == priv->tx_pause) in ftgmac100_adjust_link()
1436 if (new_speed || priv->cur_speed) in ftgmac100_adjust_link()
1439 priv->cur_speed = new_speed; in ftgmac100_adjust_link()
1440 priv->cur_duplex = phydev->duplex; in ftgmac100_adjust_link()
1441 priv->rx_pause = rx_pause; in ftgmac100_adjust_link()
1442 priv->tx_pause = tx_pause; in ftgmac100_adjust_link()
1449 iowrite32(0, priv->base + FTGMAC100_OFFSET_IER); in ftgmac100_adjust_link()
1454 if (netdev->phydev) in ftgmac100_adjust_link()
1455 mutex_unlock(&netdev->phydev->lock); in ftgmac100_adjust_link()
1459 if (netdev->phydev) in ftgmac100_adjust_link()
1460 mutex_lock(&netdev->phydev->lock); in ftgmac100_adjust_link()
1467 struct platform_device *pdev = to_platform_device(priv->dev); in ftgmac100_mii_probe()
1468 struct device_node *np = pdev->dev.of_node; in ftgmac100_mii_probe()
1488 * those SoC specific bits and assume the device-tree is in ftgmac100_mii_probe()
1492 if (priv->is_aspeed && !(phy_interface_mode_is_rgmii(phy_intf))) { in ftgmac100_mii_probe()
1498 phydev = phy_find_first(priv->mii_bus); in ftgmac100_mii_probe()
1500 netdev_info(netdev, "%s: no PHY found\n", netdev->name); in ftgmac100_mii_probe()
1501 return -ENODEV; in ftgmac100_mii_probe()
1508 netdev_err(netdev, "%s: Could not attach to PHY\n", netdev->name); in ftgmac100_mii_probe()
1535 /* When using NC-SI we force the speed to 100Mbit/s full duplex, in ftgmac100_open()
1541 if (priv->use_ncsi) { in ftgmac100_open()
1542 priv->cur_duplex = DUPLEX_FULL; in ftgmac100_open()
1543 priv->cur_speed = SPEED_100; in ftgmac100_open()
1545 priv->cur_duplex = 0; in ftgmac100_open()
1546 priv->cur_speed = 0; in ftgmac100_open()
1555 netif_napi_add(netdev, &priv->napi, ftgmac100_poll); in ftgmac100_open()
1558 err = request_irq(netdev->irq, ftgmac100_interrupt, 0, netdev->name, netdev); in ftgmac100_open()
1560 netdev_err(netdev, "failed to request irq %d\n", netdev->irq); in ftgmac100_open()
1571 if (netdev->phydev) { in ftgmac100_open()
1573 phy_start(netdev->phydev); in ftgmac100_open()
1575 if (priv->use_ncsi) { in ftgmac100_open()
1576 /* If using NC-SI, set our carrier on and start the stack */ in ftgmac100_open()
1580 err = ncsi_start_dev(priv->ndev); in ftgmac100_open()
1588 phy_stop(netdev->phydev); in ftgmac100_open()
1589 napi_disable(&priv->napi); in ftgmac100_open()
1593 free_irq(netdev->irq, netdev); in ftgmac100_open()
1595 netif_napi_del(&priv->napi); in ftgmac100_open()
1597 iowrite32(0, priv->base + FTGMAC100_OFFSET_IER); in ftgmac100_open()
1615 iowrite32(0, priv->base + FTGMAC100_OFFSET_IER); in ftgmac100_stop()
1618 napi_disable(&priv->napi); in ftgmac100_stop()
1619 netif_napi_del(&priv->napi); in ftgmac100_stop()
1620 if (netdev->phydev) in ftgmac100_stop()
1621 phy_stop(netdev->phydev); in ftgmac100_stop()
1622 if (priv->use_ncsi) in ftgmac100_stop()
1623 ncsi_stop_dev(priv->ndev); in ftgmac100_stop()
1626 free_irq(netdev->irq, netdev); in ftgmac100_stop()
1638 iowrite32(0, priv->base + FTGMAC100_OFFSET_IER); in ftgmac100_tx_timeout()
1641 schedule_work(&priv->reset_task); in ftgmac100_tx_timeout()
1648 netdev_features_t changed = netdev->features ^ features; in ftgmac100_set_features()
1657 maccr = ioread32(priv->base + FTGMAC100_OFFSET_MACCR); in ftgmac100_set_features()
1658 if (priv->netdev->features & NETIF_F_HW_VLAN_CTAG_RX) in ftgmac100_set_features()
1662 iowrite32(maccr, priv->base + FTGMAC100_OFFSET_MACCR); in ftgmac100_set_features()
1674 ftgmac100_interrupt(netdev->irq, netdev); in ftgmac100_poll_controller()
1699 struct platform_device *pdev = to_platform_device(priv->dev); in ftgmac100_setup_mdio()
1700 struct device_node *np = pdev->dev.of_node; in ftgmac100_setup_mdio()
1705 /* initialize mdio bus */ in ftgmac100_setup_mdio()
1706 priv->mii_bus = mdiobus_alloc(); in ftgmac100_setup_mdio()
1707 if (!priv->mii_bus) in ftgmac100_setup_mdio()
1708 return -EIO; in ftgmac100_setup_mdio()
1710 if (of_device_is_compatible(np, "aspeed,ast2400-mac") || in ftgmac100_setup_mdio()
1711 of_device_is_compatible(np, "aspeed,ast2500-mac")) { in ftgmac100_setup_mdio()
1712 /* The AST2600 has a separate MDIO controller */ in ftgmac100_setup_mdio()
1715 * old MDIO interface in ftgmac100_setup_mdio()
1717 reg = ioread32(priv->base + FTGMAC100_OFFSET_REVR); in ftgmac100_setup_mdio()
1719 iowrite32(reg, priv->base + FTGMAC100_OFFSET_REVR); in ftgmac100_setup_mdio()
1722 priv->mii_bus->name = "ftgmac100_mdio"; in ftgmac100_setup_mdio()
1723 snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "%s-%d", in ftgmac100_setup_mdio()
1724 pdev->name, pdev->id); in ftgmac100_setup_mdio()
1725 priv->mii_bus->parent = priv->dev; in ftgmac100_setup_mdio()
1726 priv->mii_bus->priv = priv->netdev; in ftgmac100_setup_mdio()
1727 priv->mii_bus->read = ftgmac100_mdiobus_read; in ftgmac100_setup_mdio()
1728 priv->mii_bus->write = ftgmac100_mdiobus_write; in ftgmac100_setup_mdio()
1731 priv->mii_bus->irq[i] = PHY_POLL; in ftgmac100_setup_mdio()
1733 mdio_np = of_get_child_by_name(np, "mdio"); in ftgmac100_setup_mdio()
1735 err = of_mdiobus_register(priv->mii_bus, mdio_np); in ftgmac100_setup_mdio()
1737 dev_err(priv->dev, "Cannot register MDIO bus!\n"); in ftgmac100_setup_mdio()
1746 mdiobus_free(priv->mii_bus); in ftgmac100_setup_mdio()
1754 if (!netdev->phydev) in ftgmac100_phy_disconnect()
1757 phy_disconnect(netdev->phydev); in ftgmac100_phy_disconnect()
1758 if (of_phy_is_fixed_link(priv->dev->of_node)) in ftgmac100_phy_disconnect()
1759 of_phy_deregister_fixed_link(priv->dev->of_node); in ftgmac100_phy_disconnect()
1761 if (priv->use_ncsi) in ftgmac100_phy_disconnect()
1762 fixed_phy_unregister(netdev->phydev); in ftgmac100_phy_disconnect()
1769 if (!priv->mii_bus) in ftgmac100_destroy_mdio()
1772 mdiobus_unregister(priv->mii_bus); in ftgmac100_destroy_mdio()
1773 mdiobus_free(priv->mii_bus); in ftgmac100_destroy_mdio()
1778 if (unlikely(nd->state != ncsi_dev_state_functional)) in ftgmac100_ncsi_handler()
1781 netdev_dbg(nd->dev, "NCSI interface %s\n", in ftgmac100_ncsi_handler()
1782 nd->link_up ? "up" : "down"); in ftgmac100_ncsi_handler()
1790 clk = devm_clk_get(priv->dev, NULL /* MACCLK */); in ftgmac100_setup_clk()
1793 priv->clk = clk; in ftgmac100_setup_clk()
1794 rc = clk_prepare_enable(priv->clk); in ftgmac100_setup_clk()
1802 rc = clk_set_rate(priv->clk, priv->use_ncsi ? FTGMAC_25MHZ : in ftgmac100_setup_clk()
1809 * RGMII, or the controller is not an ASPEED-based controller. in ftgmac100_setup_clk()
1811 priv->rclk = devm_clk_get_optional(priv->dev, "RCLK"); in ftgmac100_setup_clk()
1812 rc = clk_prepare_enable(priv->rclk); in ftgmac100_setup_clk()
1817 clk_disable_unprepare(priv->clk); in ftgmac100_setup_clk()
1847 return -ENXIO; in ftgmac100_probe()
1856 err = -ENOMEM; in ftgmac100_probe()
1860 SET_NETDEV_DEV(netdev, &pdev->dev); in ftgmac100_probe()
1862 netdev->ethtool_ops = &ftgmac100_ethtool_ops; in ftgmac100_probe()
1863 netdev->netdev_ops = &ftgmac100_netdev_ops; in ftgmac100_probe()
1864 netdev->watchdog_timeo = 5 * HZ; in ftgmac100_probe()
1870 priv->netdev = netdev; in ftgmac100_probe()
1871 priv->dev = &pdev->dev; in ftgmac100_probe()
1872 INIT_WORK(&priv->reset_task, ftgmac100_reset_task); in ftgmac100_probe()
1875 priv->res = request_mem_region(res->start, resource_size(res), in ftgmac100_probe()
1876 dev_name(&pdev->dev)); in ftgmac100_probe()
1877 if (!priv->res) { in ftgmac100_probe()
1878 dev_err(&pdev->dev, "Could not reserve memory region\n"); in ftgmac100_probe()
1879 err = -ENOMEM; in ftgmac100_probe()
1883 priv->base = ioremap(res->start, resource_size(res)); in ftgmac100_probe()
1884 if (!priv->base) { in ftgmac100_probe()
1885 dev_err(&pdev->dev, "Failed to ioremap ethernet registers\n"); in ftgmac100_probe()
1886 err = -EIO; in ftgmac100_probe()
1890 netdev->irq = irq; in ftgmac100_probe()
1893 priv->tx_pause = true; in ftgmac100_probe()
1894 priv->rx_pause = true; in ftgmac100_probe()
1895 priv->aneg_pause = true; in ftgmac100_probe()
1902 np = pdev->dev.of_node; in ftgmac100_probe()
1903 if (np && (of_device_is_compatible(np, "aspeed,ast2400-mac") || in ftgmac100_probe()
1904 of_device_is_compatible(np, "aspeed,ast2500-mac") || in ftgmac100_probe()
1905 of_device_is_compatible(np, "aspeed,ast2600-mac"))) { in ftgmac100_probe()
1906 priv->rxdes0_edorr_mask = BIT(30); in ftgmac100_probe()
1907 priv->txdes0_edotr_mask = BIT(30); in ftgmac100_probe()
1908 priv->is_aspeed = true; in ftgmac100_probe()
1910 priv->rxdes0_edorr_mask = BIT(15); in ftgmac100_probe()
1911 priv->txdes0_edotr_mask = BIT(15); in ftgmac100_probe()
1914 if (np && of_get_property(np, "use-ncsi", NULL)) { in ftgmac100_probe()
1916 dev_err(&pdev->dev, "NCSI stack not enabled\n"); in ftgmac100_probe()
1917 err = -EINVAL; in ftgmac100_probe()
1921 dev_info(&pdev->dev, "Using NCSI interface\n"); in ftgmac100_probe()
1922 priv->use_ncsi = true; in ftgmac100_probe()
1923 priv->ndev = ncsi_register_dev(netdev, ftgmac100_ncsi_handler); in ftgmac100_probe()
1924 if (!priv->ndev) { in ftgmac100_probe()
1925 err = -EINVAL; in ftgmac100_probe()
1931 dev_err(&pdev->dev, "failed to register fixed PHY device\n"); in ftgmac100_probe()
1938 dev_err(&pdev->dev, "Connecting PHY failed\n"); in ftgmac100_probe()
1942 of_get_property(np, "phy-handle", NULL))) { in ftgmac100_probe()
1945 /* Support "mdio"/"phy" child nodes for ast2400/2500 with in ftgmac100_probe()
1946 * an embedded MDIO controller. Automatically scan the DTS for in ftgmac100_probe()
1949 if (of_get_property(np, "phy-handle", NULL) && in ftgmac100_probe()
1950 (of_device_is_compatible(np, "aspeed,ast2400-mac") || in ftgmac100_probe()
1951 of_device_is_compatible(np, "aspeed,ast2500-mac"))) { in ftgmac100_probe()
1957 phy = of_phy_get_and_connect(priv->netdev, np, in ftgmac100_probe()
1960 dev_err(&pdev->dev, "Failed to connect to phy\n"); in ftgmac100_probe()
1961 err = -EINVAL; in ftgmac100_probe()
1972 } else if (np && !ftgmac100_has_child_node(np, "mdio")) { in ftgmac100_probe()
1974 * MAC with an embedded MDIO controller but have no "mdio" in ftgmac100_probe()
1975 * child node. Automatically scan the MDIO bus for available in ftgmac100_probe()
1978 priv->use_ncsi = false; in ftgmac100_probe()
1985 dev_err(priv->dev, "MII probe failed!\n"); in ftgmac100_probe()
1991 priv->rst = devm_reset_control_get_optional_exclusive(priv->dev, NULL); in ftgmac100_probe()
1992 if (IS_ERR(priv->rst)) { in ftgmac100_probe()
1993 err = PTR_ERR(priv->rst); in ftgmac100_probe()
1997 if (priv->is_aspeed) { in ftgmac100_probe()
2002 /* Disable ast2600 problematic HW arbitration */ in ftgmac100_probe()
2003 if (of_device_is_compatible(np, "aspeed,ast2600-mac")) in ftgmac100_probe()
2005 priv->base + FTGMAC100_OFFSET_TM); in ftgmac100_probe()
2009 priv->rx_q_entries = priv->new_rx_q_entries = DEF_RX_QUEUE_ENTRIES; in ftgmac100_probe()
2010 priv->tx_q_entries = priv->new_tx_q_entries = DEF_TX_QUEUE_ENTRIES; in ftgmac100_probe()
2013 netdev->hw_features = NETIF_F_RXCSUM | NETIF_F_HW_CSUM | in ftgmac100_probe()
2017 if (priv->use_ncsi) in ftgmac100_probe()
2018 netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_FILTER; in ftgmac100_probe()
2021 if (np && (of_device_is_compatible(np, "aspeed,ast2400-mac"))) in ftgmac100_probe()
2022 netdev->hw_features &= ~NETIF_F_HW_CSUM; in ftgmac100_probe()
2024 /* AST2600 tx checksum with NCSI is broken */ in ftgmac100_probe()
2025 if (priv->use_ncsi && of_device_is_compatible(np, "aspeed,ast2600-mac")) in ftgmac100_probe()
2026 netdev->hw_features &= ~NETIF_F_HW_CSUM; in ftgmac100_probe()
2028 if (np && of_get_property(np, "no-hw-checksum", NULL)) in ftgmac100_probe()
2029 netdev->hw_features &= ~(NETIF_F_HW_CSUM | NETIF_F_RXCSUM); in ftgmac100_probe()
2030 netdev->features |= netdev->hw_features; in ftgmac100_probe()
2035 dev_err(&pdev->dev, "Failed to register netdev\n"); in ftgmac100_probe()
2039 netdev_info(netdev, "irq %d, mapped at %p\n", netdev->irq, priv->base); in ftgmac100_probe()
2044 clk_disable_unprepare(priv->rclk); in ftgmac100_probe()
2045 clk_disable_unprepare(priv->clk); in ftgmac100_probe()
2049 if (priv->ndev) in ftgmac100_probe()
2050 ncsi_unregister_dev(priv->ndev); in ftgmac100_probe()
2053 iounmap(priv->base); in ftgmac100_probe()
2055 release_resource(priv->res); in ftgmac100_probe()
2070 if (priv->ndev) in ftgmac100_remove()
2071 ncsi_unregister_dev(priv->ndev); in ftgmac100_remove()
2074 clk_disable_unprepare(priv->rclk); in ftgmac100_remove()
2075 clk_disable_unprepare(priv->clk); in ftgmac100_remove()
2077 /* There's a small chance the reset task will have been re-queued, in ftgmac100_remove()
2080 cancel_work_sync(&priv->reset_task); in ftgmac100_remove()
2085 iounmap(priv->base); in ftgmac100_remove()
2086 release_resource(priv->res); in ftgmac100_remove()
2088 netif_napi_del(&priv->napi); in ftgmac100_remove()
2108 MODULE_AUTHOR("Po-Yu Chuang <ratbert@faraday-tech.com>");