Lines Matching +full:mac +full:- +full:clk +full:- +full:rx
1 // SPDX-License-Identifier: GPL-2.0-or-later
5 * (C) Copyright 2009-2011 Faraday Technology
6 * Po-Yu Chuang <ratbert@faraday-tech.com>
11 #include <linux/clk.h>
12 #include <linux/dma-mapping.h>
58 /* Rx ring */
79 /* Scratch page to use when rx skb alloc fails */
90 struct clk *clk; member
93 struct clk *rclk;
116 struct net_device *netdev = priv->netdev; in ftgmac100_reset_mac()
120 iowrite32(maccr, priv->base + FTGMAC100_OFFSET_MACCR); in ftgmac100_reset_mac()
122 priv->base + FTGMAC100_OFFSET_MACCR); in ftgmac100_reset_mac()
126 maccr = ioread32(priv->base + FTGMAC100_OFFSET_MACCR); in ftgmac100_reset_mac()
134 return -EIO; in ftgmac100_reset_mac()
141 switch (priv->cur_speed) { in ftgmac100_reset_and_config_mac()
154 netdev_err(priv->netdev, "Unknown speed %d !\n", in ftgmac100_reset_and_config_mac()
155 priv->cur_speed); in ftgmac100_reset_and_config_mac()
160 priv->rx_pointer = 0; in ftgmac100_reset_and_config_mac()
161 priv->tx_clean_pointer = 0; in ftgmac100_reset_and_config_mac()
162 priv->tx_pointer = 0; in ftgmac100_reset_and_config_mac()
166 return -EIO; in ftgmac100_reset_and_config_mac()
171 static void ftgmac100_write_mac_addr(struct ftgmac100 *priv, const u8 *mac) in ftgmac100_write_mac_addr() argument
173 unsigned int maddr = mac[0] << 8 | mac[1]; in ftgmac100_write_mac_addr()
174 unsigned int laddr = mac[2] << 24 | mac[3] << 16 | mac[4] << 8 | mac[5]; in ftgmac100_write_mac_addr()
176 iowrite32(maddr, priv->base + FTGMAC100_OFFSET_MAC_MADR); in ftgmac100_write_mac_addr()
177 iowrite32(laddr, priv->base + FTGMAC100_OFFSET_MAC_LADR); in ftgmac100_write_mac_addr()
182 u8 mac[ETH_ALEN]; in ftgmac100_initial_mac() local
187 err = of_get_ethdev_address(priv->dev->of_node, priv->netdev); in ftgmac100_initial_mac()
188 if (err == -EPROBE_DEFER) in ftgmac100_initial_mac()
191 dev_info(priv->dev, "Read MAC address %pM from device tree\n", in ftgmac100_initial_mac()
192 priv->netdev->dev_addr); in ftgmac100_initial_mac()
196 m = ioread32(priv->base + FTGMAC100_OFFSET_MAC_MADR); in ftgmac100_initial_mac()
197 l = ioread32(priv->base + FTGMAC100_OFFSET_MAC_LADR); in ftgmac100_initial_mac()
199 mac[0] = (m >> 8) & 0xff; in ftgmac100_initial_mac()
200 mac[1] = m & 0xff; in ftgmac100_initial_mac()
201 mac[2] = (l >> 24) & 0xff; in ftgmac100_initial_mac()
202 mac[3] = (l >> 16) & 0xff; in ftgmac100_initial_mac()
203 mac[4] = (l >> 8) & 0xff; in ftgmac100_initial_mac()
204 mac[5] = l & 0xff; in ftgmac100_initial_mac()
206 if (is_valid_ether_addr(mac)) { in ftgmac100_initial_mac()
207 eth_hw_addr_set(priv->netdev, mac); in ftgmac100_initial_mac()
208 dev_info(priv->dev, "Read MAC address %pM from chip\n", mac); in ftgmac100_initial_mac()
210 eth_hw_addr_random(priv->netdev); in ftgmac100_initial_mac()
211 dev_info(priv->dev, "Generated random MAC address %pM\n", in ftgmac100_initial_mac()
212 priv->netdev->dev_addr); in ftgmac100_initial_mac()
227 ftgmac100_write_mac_addr(netdev_priv(dev), dev->dev_addr); in ftgmac100_set_mac_addr()
237 if (priv->rx_pause) in ftgmac100_config_pause()
240 /* Enables sending pause frames when the RX queue is past a in ftgmac100_config_pause()
243 if (priv->tx_pause) in ftgmac100_config_pause()
246 iowrite32(fcr, priv->base + FTGMAC100_OFFSET_FCR); in ftgmac100_config_pause()
254 reg = ioread32(priv->base + FTGMAC100_OFFSET_ISR); in ftgmac100_init_hw()
255 iowrite32(reg, priv->base + FTGMAC100_OFFSET_ISR); in ftgmac100_init_hw()
257 /* Setup RX ring buffer base */ in ftgmac100_init_hw()
258 iowrite32(priv->rxdes_dma, priv->base + FTGMAC100_OFFSET_RXR_BADR); in ftgmac100_init_hw()
261 iowrite32(priv->txdes_dma, priv->base + FTGMAC100_OFFSET_NPTXR_BADR); in ftgmac100_init_hw()
263 /* Configure RX buffer size */ in ftgmac100_init_hw()
265 priv->base + FTGMAC100_OFFSET_RBSR); in ftgmac100_init_hw()
267 /* Set RX descriptor autopoll */ in ftgmac100_init_hw()
269 priv->base + FTGMAC100_OFFSET_APTC); in ftgmac100_init_hw()
271 /* Write MAC address */ in ftgmac100_init_hw()
272 ftgmac100_write_mac_addr(priv, priv->netdev->dev_addr); in ftgmac100_init_hw()
275 iowrite32(priv->maht0, priv->base + FTGMAC100_OFFSET_MAHT0); in ftgmac100_init_hw()
276 iowrite32(priv->maht1, priv->base + FTGMAC100_OFFSET_MAHT1); in ftgmac100_init_hw()
283 iowrite32(FTGMAC100_DBLAC_RXDES_SIZE(2) | /* 2*8 bytes RX descs */ in ftgmac100_init_hw()
285 FTGMAC100_DBLAC_RXBURST_SIZE(3) | /* 512 bytes max RX bursts */ in ftgmac100_init_hw()
290 priv->base + FTGMAC100_OFFSET_DBLAC); in ftgmac100_init_hw()
298 priv->base + FTGMAC100_OFFSET_ITC); in ftgmac100_init_hw()
301 reg = ioread32(priv->base + FTGMAC100_OFFSET_FEAR); in ftgmac100_init_hw()
304 reg = ioread32(priv->base + FTGMAC100_OFFSET_TPAFCR); in ftgmac100_init_hw()
308 iowrite32(reg, priv->base + FTGMAC100_OFFSET_TPAFCR); in ftgmac100_init_hw()
313 u32 maccr = ioread32(priv->base + FTGMAC100_OFFSET_MACCR); in ftgmac100_start_hw()
329 if (priv->cur_duplex == DUPLEX_FULL) in ftgmac100_start_hw()
331 if (priv->netdev->flags & IFF_PROMISC) in ftgmac100_start_hw()
333 if (priv->netdev->flags & IFF_ALLMULTI) in ftgmac100_start_hw()
335 else if (netdev_mc_count(priv->netdev)) in ftgmac100_start_hw()
339 if (priv->netdev->features & NETIF_F_HW_VLAN_CTAG_RX) in ftgmac100_start_hw()
343 iowrite32(maccr, priv->base + FTGMAC100_OFFSET_MACCR); in ftgmac100_start_hw()
348 iowrite32(0, priv->base + FTGMAC100_OFFSET_MACCR); in ftgmac100_stop_hw()
355 priv->maht1 = 0; in ftgmac100_calc_mc_hash()
356 priv->maht0 = 0; in ftgmac100_calc_mc_hash()
357 netdev_for_each_mc_addr(ha, priv->netdev) { in ftgmac100_calc_mc_hash()
358 u32 crc_val = ether_crc_le(ETH_ALEN, ha->addr); in ftgmac100_calc_mc_hash()
362 priv->maht1 |= 1ul << (crc_val - 32); in ftgmac100_calc_mc_hash()
364 priv->maht0 |= 1ul << (crc_val); in ftgmac100_calc_mc_hash()
380 iowrite32(priv->maht0, priv->base + FTGMAC100_OFFSET_MAHT0); in ftgmac100_set_rx_mode()
381 iowrite32(priv->maht1, priv->base + FTGMAC100_OFFSET_MAHT1); in ftgmac100_set_rx_mode()
390 struct net_device *netdev = priv->netdev; in ftgmac100_alloc_rx_buf()
398 netdev_warn(netdev, "failed to allocate rx skb\n"); in ftgmac100_alloc_rx_buf()
399 err = -ENOMEM; in ftgmac100_alloc_rx_buf()
400 map = priv->rx_scratch_dma; in ftgmac100_alloc_rx_buf()
402 map = dma_map_single(priv->dev, skb->data, RX_BUF_SIZE, in ftgmac100_alloc_rx_buf()
404 if (unlikely(dma_mapping_error(priv->dev, map))) { in ftgmac100_alloc_rx_buf()
406 netdev_err(netdev, "failed to map rx page\n"); in ftgmac100_alloc_rx_buf()
408 map = priv->rx_scratch_dma; in ftgmac100_alloc_rx_buf()
410 err = -ENOMEM; in ftgmac100_alloc_rx_buf()
415 priv->rx_skbs[entry] = skb; in ftgmac100_alloc_rx_buf()
417 /* Store DMA address into RX desc */ in ftgmac100_alloc_rx_buf()
418 rxdes->rxdes3 = cpu_to_le32(map); in ftgmac100_alloc_rx_buf()
424 if (entry == (priv->rx_q_entries - 1)) in ftgmac100_alloc_rx_buf()
425 rxdes->rxdes0 = cpu_to_le32(priv->rxdes0_edorr_mask); in ftgmac100_alloc_rx_buf()
427 rxdes->rxdes0 = 0; in ftgmac100_alloc_rx_buf()
435 return (pointer + 1) & (priv->rx_q_entries - 1); in ftgmac100_next_rx_pointer()
440 struct net_device *netdev = priv->netdev; in ftgmac100_rx_packet_error()
443 netdev->stats.rx_errors++; in ftgmac100_rx_packet_error()
446 netdev->stats.rx_crc_errors++; in ftgmac100_rx_packet_error()
451 netdev->stats.rx_length_errors++; in ftgmac100_rx_packet_error()
456 struct net_device *netdev = priv->netdev; in ftgmac100_rx_packet()
463 /* Grab next RX descriptor */ in ftgmac100_rx_packet()
464 pointer = priv->rx_pointer; in ftgmac100_rx_packet()
465 rxdes = &priv->rxdes[pointer]; in ftgmac100_rx_packet()
468 status = le32_to_cpu(rxdes->rxdes0); in ftgmac100_rx_packet()
477 /* We don't cope with fragmented RX packets */ in ftgmac100_rx_packet()
484 csum_vlan = le32_to_cpu(rxdes->rxdes1); in ftgmac100_rx_packet()
508 skb = priv->rx_skbs[pointer]; in ftgmac100_rx_packet()
515 netdev->stats.multicast++; in ftgmac100_rx_packet()
523 if (netdev->features & NETIF_F_RXCSUM) { in ftgmac100_rx_packet()
529 skb->ip_summed = CHECKSUM_NONE; in ftgmac100_rx_packet()
531 skb->ip_summed = CHECKSUM_UNNECESSARY; in ftgmac100_rx_packet()
538 if ((netdev->features & NETIF_F_HW_VLAN_CTAG_RX) && in ftgmac100_rx_packet()
544 map = le32_to_cpu(rxdes->rxdes3); in ftgmac100_rx_packet()
551 dma_unmap_single(priv->dev, map, size, DMA_FROM_DEVICE); in ftgmac100_rx_packet()
553 dma_unmap_single(priv->dev, map, RX_BUF_SIZE, DMA_FROM_DEVICE); in ftgmac100_rx_packet()
557 /* Resplenish rx ring */ in ftgmac100_rx_packet()
559 priv->rx_pointer = ftgmac100_next_rx_pointer(priv, pointer); in ftgmac100_rx_packet()
561 skb->protocol = eth_type_trans(skb, netdev); in ftgmac100_rx_packet()
563 netdev->stats.rx_packets++; in ftgmac100_rx_packet()
564 netdev->stats.rx_bytes += size; in ftgmac100_rx_packet()
567 if (skb->ip_summed == CHECKSUM_NONE) in ftgmac100_rx_packet()
570 napi_gro_receive(&priv->napi, skb); in ftgmac100_rx_packet()
577 rxdes->rxdes0 = cpu_to_le32(status & priv->rxdes0_edorr_mask); in ftgmac100_rx_packet()
578 priv->rx_pointer = ftgmac100_next_rx_pointer(priv, pointer); in ftgmac100_rx_packet()
579 netdev->stats.rx_dropped++; in ftgmac100_rx_packet()
586 if (index == (priv->tx_q_entries - 1)) in ftgmac100_base_tx_ctlstat()
587 return priv->txdes0_edotr_mask; in ftgmac100_base_tx_ctlstat()
595 return (pointer + 1) & (priv->tx_q_entries - 1); in ftgmac100_next_tx_pointer()
606 return (priv->tx_clean_pointer - priv->tx_pointer - 1) & in ftgmac100_tx_buf_avail()
607 (priv->tx_q_entries - 1); in ftgmac100_tx_buf_avail()
612 return priv->tx_pointer != priv->tx_clean_pointer; in ftgmac100_tx_buf_cleanable()
621 dma_addr_t map = le32_to_cpu(txdes->txdes3); in ftgmac100_free_tx_packet()
626 dma_unmap_single(priv->dev, map, len, DMA_TO_DEVICE); in ftgmac100_free_tx_packet()
629 dma_unmap_page(priv->dev, map, len, DMA_TO_DEVICE); in ftgmac100_free_tx_packet()
635 priv->tx_skbs[pointer] = NULL; in ftgmac100_free_tx_packet()
640 struct net_device *netdev = priv->netdev; in ftgmac100_tx_complete_packet()
646 pointer = priv->tx_clean_pointer; in ftgmac100_tx_complete_packet()
647 txdes = &priv->txdes[pointer]; in ftgmac100_tx_complete_packet()
649 ctl_stat = le32_to_cpu(txdes->txdes0); in ftgmac100_tx_complete_packet()
653 skb = priv->tx_skbs[pointer]; in ftgmac100_tx_complete_packet()
654 netdev->stats.tx_packets++; in ftgmac100_tx_complete_packet()
655 netdev->stats.tx_bytes += skb->len; in ftgmac100_tx_complete_packet()
657 txdes->txdes0 = cpu_to_le32(ctl_stat & priv->txdes0_edotr_mask); in ftgmac100_tx_complete_packet()
659 priv->tx_clean_pointer = ftgmac100_next_tx_pointer(priv, pointer); in ftgmac100_tx_complete_packet()
666 struct net_device *netdev = priv->netdev; in ftgmac100_tx_complete()
690 if (skb->protocol == cpu_to_be16(ETH_P_IP)) { in ftgmac100_prep_tx_csum()
691 u8 ip_proto = ip_hdr(skb)->protocol; in ftgmac100_prep_tx_csum()
719 netdev->stats.tx_dropped++; in ftgmac100_hard_start_xmit()
724 if (unlikely(skb->len > MAX_PKT_SIZE)) { in ftgmac100_hard_start_xmit()
733 nfrags = skb_shinfo(skb)->nr_frags; in ftgmac100_hard_start_xmit()
737 if (skb->ip_summed == CHECKSUM_PARTIAL && in ftgmac100_hard_start_xmit()
751 map = dma_map_single(priv->dev, skb->data, len, DMA_TO_DEVICE); in ftgmac100_hard_start_xmit()
752 if (dma_mapping_error(priv->dev, map)) { in ftgmac100_hard_start_xmit()
759 pointer = priv->tx_pointer; in ftgmac100_hard_start_xmit()
760 txdes = first = &priv->txdes[pointer]; in ftgmac100_hard_start_xmit()
765 priv->tx_skbs[pointer] = skb; in ftgmac100_hard_start_xmit()
772 txdes->txdes3 = cpu_to_le32(map); in ftgmac100_hard_start_xmit()
773 txdes->txdes1 = cpu_to_le32(csum_vlan); in ftgmac100_hard_start_xmit()
780 skb_frag_t *frag = &skb_shinfo(skb)->frags[i]; in ftgmac100_hard_start_xmit()
785 map = skb_frag_dma_map(priv->dev, frag, 0, len, in ftgmac100_hard_start_xmit()
787 if (dma_mapping_error(priv->dev, map)) in ftgmac100_hard_start_xmit()
791 priv->tx_skbs[pointer] = skb; in ftgmac100_hard_start_xmit()
792 txdes = &priv->txdes[pointer]; in ftgmac100_hard_start_xmit()
796 if (i == (nfrags - 1)) in ftgmac100_hard_start_xmit()
798 txdes->txdes0 = cpu_to_le32(ctl_stat); in ftgmac100_hard_start_xmit()
799 txdes->txdes1 = 0; in ftgmac100_hard_start_xmit()
800 txdes->txdes3 = cpu_to_le32(map); in ftgmac100_hard_start_xmit()
810 first->txdes0 = cpu_to_le32(f_ctl_stat); in ftgmac100_hard_start_xmit()
813 priv->tx_pointer = pointer; in ftgmac100_hard_start_xmit()
828 iowrite32(1, priv->base + FTGMAC100_OFFSET_NPTXPD); in ftgmac100_hard_start_xmit()
837 pointer = priv->tx_pointer; in ftgmac100_hard_start_xmit()
839 first->txdes0 = cpu_to_le32(f_ctl_stat & priv->txdes0_edotr_mask); in ftgmac100_hard_start_xmit()
844 txdes = &priv->txdes[pointer]; in ftgmac100_hard_start_xmit()
845 ctl_stat = le32_to_cpu(txdes->txdes0); in ftgmac100_hard_start_xmit()
847 txdes->txdes0 = cpu_to_le32(ctl_stat & priv->txdes0_edotr_mask); in ftgmac100_hard_start_xmit()
857 netdev->stats.tx_dropped++; in ftgmac100_hard_start_xmit()
866 /* Free all RX buffers */ in ftgmac100_free_buffers()
867 for (i = 0; i < priv->rx_q_entries; i++) { in ftgmac100_free_buffers()
868 struct ftgmac100_rxdes *rxdes = &priv->rxdes[i]; in ftgmac100_free_buffers()
869 struct sk_buff *skb = priv->rx_skbs[i]; in ftgmac100_free_buffers()
870 dma_addr_t map = le32_to_cpu(rxdes->rxdes3); in ftgmac100_free_buffers()
875 priv->rx_skbs[i] = NULL; in ftgmac100_free_buffers()
876 dma_unmap_single(priv->dev, map, RX_BUF_SIZE, DMA_FROM_DEVICE); in ftgmac100_free_buffers()
881 for (i = 0; i < priv->tx_q_entries; i++) { in ftgmac100_free_buffers()
882 struct ftgmac100_txdes *txdes = &priv->txdes[i]; in ftgmac100_free_buffers()
883 struct sk_buff *skb = priv->tx_skbs[i]; in ftgmac100_free_buffers()
888 le32_to_cpu(txdes->txdes0)); in ftgmac100_free_buffers()
895 kfree(priv->rx_skbs); in ftgmac100_free_rings()
896 kfree(priv->tx_skbs); in ftgmac100_free_rings()
899 if (priv->rxdes) in ftgmac100_free_rings()
900 dma_free_coherent(priv->dev, MAX_RX_QUEUE_ENTRIES * in ftgmac100_free_rings()
902 priv->rxdes, priv->rxdes_dma); in ftgmac100_free_rings()
903 priv->rxdes = NULL; in ftgmac100_free_rings()
905 if (priv->txdes) in ftgmac100_free_rings()
906 dma_free_coherent(priv->dev, MAX_TX_QUEUE_ENTRIES * in ftgmac100_free_rings()
908 priv->txdes, priv->txdes_dma); in ftgmac100_free_rings()
909 priv->txdes = NULL; in ftgmac100_free_rings()
912 if (priv->rx_scratch) in ftgmac100_free_rings()
913 dma_free_coherent(priv->dev, RX_BUF_SIZE, in ftgmac100_free_rings()
914 priv->rx_scratch, priv->rx_scratch_dma); in ftgmac100_free_rings()
920 priv->rx_skbs = kcalloc(MAX_RX_QUEUE_ENTRIES, sizeof(void *), in ftgmac100_alloc_rings()
922 if (!priv->rx_skbs) in ftgmac100_alloc_rings()
923 return -ENOMEM; in ftgmac100_alloc_rings()
924 priv->tx_skbs = kcalloc(MAX_TX_QUEUE_ENTRIES, sizeof(void *), in ftgmac100_alloc_rings()
926 if (!priv->tx_skbs) in ftgmac100_alloc_rings()
927 return -ENOMEM; in ftgmac100_alloc_rings()
930 priv->rxdes = dma_alloc_coherent(priv->dev, in ftgmac100_alloc_rings()
932 &priv->rxdes_dma, GFP_KERNEL); in ftgmac100_alloc_rings()
933 if (!priv->rxdes) in ftgmac100_alloc_rings()
934 return -ENOMEM; in ftgmac100_alloc_rings()
935 priv->txdes = dma_alloc_coherent(priv->dev, in ftgmac100_alloc_rings()
937 &priv->txdes_dma, GFP_KERNEL); in ftgmac100_alloc_rings()
938 if (!priv->txdes) in ftgmac100_alloc_rings()
939 return -ENOMEM; in ftgmac100_alloc_rings()
942 priv->rx_scratch = dma_alloc_coherent(priv->dev, in ftgmac100_alloc_rings()
944 &priv->rx_scratch_dma, in ftgmac100_alloc_rings()
946 if (!priv->rx_scratch) in ftgmac100_alloc_rings()
947 return -ENOMEM; in ftgmac100_alloc_rings()
959 priv->rx_q_entries = priv->new_rx_q_entries; in ftgmac100_init_rings()
960 priv->tx_q_entries = priv->new_tx_q_entries; in ftgmac100_init_rings()
962 if (WARN_ON(priv->rx_q_entries < MIN_RX_QUEUE_ENTRIES)) in ftgmac100_init_rings()
965 /* Initialize RX ring */ in ftgmac100_init_rings()
966 for (i = 0; i < priv->rx_q_entries; i++) { in ftgmac100_init_rings()
967 rxdes = &priv->rxdes[i]; in ftgmac100_init_rings()
968 rxdes->rxdes0 = 0; in ftgmac100_init_rings()
969 rxdes->rxdes3 = cpu_to_le32(priv->rx_scratch_dma); in ftgmac100_init_rings()
972 rxdes->rxdes0 |= cpu_to_le32(priv->rxdes0_edorr_mask); in ftgmac100_init_rings()
974 if (WARN_ON(priv->tx_q_entries < MIN_RX_QUEUE_ENTRIES)) in ftgmac100_init_rings()
978 for (i = 0; i < priv->tx_q_entries; i++) { in ftgmac100_init_rings()
979 txdes = &priv->txdes[i]; in ftgmac100_init_rings()
980 txdes->txdes0 = 0; in ftgmac100_init_rings()
982 txdes->txdes0 |= cpu_to_le32(priv->txdes0_edotr_mask); in ftgmac100_init_rings()
989 for (i = 0; i < priv->rx_q_entries; i++) { in ftgmac100_alloc_rx_buffers()
990 struct ftgmac100_rxdes *rxdes = &priv->rxdes[i]; in ftgmac100_alloc_rx_buffers()
993 return -ENOMEM; in ftgmac100_alloc_rx_buffers()
1000 struct net_device *netdev = bus->priv; in ftgmac100_mdiobus_read()
1005 phycr = ioread32(priv->base + FTGMAC100_OFFSET_PHYCR); in ftgmac100_mdiobus_read()
1014 iowrite32(phycr, priv->base + FTGMAC100_OFFSET_PHYCR); in ftgmac100_mdiobus_read()
1017 phycr = ioread32(priv->base + FTGMAC100_OFFSET_PHYCR); in ftgmac100_mdiobus_read()
1022 data = ioread32(priv->base + FTGMAC100_OFFSET_PHYDATA); in ftgmac100_mdiobus_read()
1030 return -EIO; in ftgmac100_mdiobus_read()
1036 struct net_device *netdev = bus->priv; in ftgmac100_mdiobus_write()
1042 phycr = ioread32(priv->base + FTGMAC100_OFFSET_PHYCR); in ftgmac100_mdiobus_write()
1053 iowrite32(data, priv->base + FTGMAC100_OFFSET_PHYDATA); in ftgmac100_mdiobus_write()
1054 iowrite32(phycr, priv->base + FTGMAC100_OFFSET_PHYCR); in ftgmac100_mdiobus_write()
1057 phycr = ioread32(priv->base + FTGMAC100_OFFSET_PHYCR); in ftgmac100_mdiobus_write()
1066 return -EIO; in ftgmac100_mdiobus_write()
1072 strscpy(info->driver, DRV_NAME, sizeof(info->driver)); in ftgmac100_get_drvinfo()
1073 strscpy(info->bus_info, dev_name(&netdev->dev), sizeof(info->bus_info)); in ftgmac100_get_drvinfo()
1085 ering->rx_max_pending = MAX_RX_QUEUE_ENTRIES; in ftgmac100_get_ringparam()
1086 ering->tx_max_pending = MAX_TX_QUEUE_ENTRIES; in ftgmac100_get_ringparam()
1087 ering->rx_pending = priv->rx_q_entries; in ftgmac100_get_ringparam()
1088 ering->tx_pending = priv->tx_q_entries; in ftgmac100_get_ringparam()
1099 if (ering->rx_pending > MAX_RX_QUEUE_ENTRIES || in ftgmac100_set_ringparam()
1100 ering->tx_pending > MAX_TX_QUEUE_ENTRIES || in ftgmac100_set_ringparam()
1101 ering->rx_pending < MIN_RX_QUEUE_ENTRIES || in ftgmac100_set_ringparam()
1102 ering->tx_pending < MIN_TX_QUEUE_ENTRIES || in ftgmac100_set_ringparam()
1103 !is_power_of_2(ering->rx_pending) || in ftgmac100_set_ringparam()
1104 !is_power_of_2(ering->tx_pending)) in ftgmac100_set_ringparam()
1105 return -EINVAL; in ftgmac100_set_ringparam()
1107 priv->new_rx_q_entries = ering->rx_pending; in ftgmac100_set_ringparam()
1108 priv->new_tx_q_entries = ering->tx_pending; in ftgmac100_set_ringparam()
1110 schedule_work(&priv->reset_task); in ftgmac100_set_ringparam()
1120 pause->autoneg = priv->aneg_pause; in ftgmac100_get_pauseparam()
1121 pause->tx_pause = priv->tx_pause; in ftgmac100_get_pauseparam()
1122 pause->rx_pause = priv->rx_pause; in ftgmac100_get_pauseparam()
1129 struct phy_device *phydev = netdev->phydev; in ftgmac100_set_pauseparam()
1131 priv->aneg_pause = pause->autoneg; in ftgmac100_set_pauseparam()
1132 priv->tx_pause = pause->tx_pause; in ftgmac100_set_pauseparam()
1133 priv->rx_pause = pause->rx_pause; in ftgmac100_set_pauseparam()
1136 phy_set_asym_pause(phydev, pause->rx_pause, pause->tx_pause); in ftgmac100_set_pauseparam()
1139 if (!(phydev && priv->aneg_pause)) in ftgmac100_set_pauseparam()
1165 status = ioread32(priv->base + FTGMAC100_OFFSET_ISR); in ftgmac100_interrupt()
1166 iowrite32(status, priv->base + FTGMAC100_OFFSET_ISR); in ftgmac100_interrupt()
1169 /* RX buffer unavailable */ in ftgmac100_interrupt()
1171 netdev->stats.rx_over_errors++; in ftgmac100_interrupt()
1173 /* received packet lost due to RX FIFO full */ in ftgmac100_interrupt()
1175 netdev->stats.rx_fifo_errors++; in ftgmac100_interrupt()
1179 netdev->stats.tx_fifo_errors++; in ftgmac100_interrupt()
1181 /* AHB error -> Reset the chip */ in ftgmac100_interrupt()
1186 iowrite32(0, priv->base + FTGMAC100_OFFSET_IER); in ftgmac100_interrupt()
1187 schedule_work(&priv->reset_task); in ftgmac100_interrupt()
1191 /* We may need to restart the MAC after such errors, delay in ftgmac100_interrupt()
1192 * this until after we have freed some Rx buffers though in ftgmac100_interrupt()
1194 priv->need_mac_restart = true; in ftgmac100_interrupt()
1201 iowrite32(new_mask, priv->base + FTGMAC100_OFFSET_IER); in ftgmac100_interrupt()
1204 napi_schedule_irqoff(&priv->napi); in ftgmac100_interrupt()
1211 struct ftgmac100_rxdes *rxdes = &priv->rxdes[priv->rx_pointer]; in ftgmac100_check_rx()
1214 return !!(rxdes->rxdes0 & cpu_to_le32(FTGMAC100_RXDES0_RXPKT_RDY)); in ftgmac100_check_rx()
1227 /* Handle RX packets */ in ftgmac100_poll()
1233 /* The interrupt is telling us to kick the MAC back to life in ftgmac100_poll()
1234 * after an RX overflow in ftgmac100_poll()
1236 if (unlikely(priv->need_mac_restart)) { in ftgmac100_poll()
1238 priv->need_mac_restart = false; in ftgmac100_poll()
1240 /* Re-enable "bad" interrupts */ in ftgmac100_poll()
1242 priv->base + FTGMAC100_OFFSET_IER); in ftgmac100_poll()
1252 /* We are about to re-enable all interrupts. However in ftgmac100_poll()
1253 * the HW has been latching RX/TX packet interrupts while in ftgmac100_poll()
1255 * to re-check if there's something to process in ftgmac100_poll()
1258 priv->base + FTGMAC100_OFFSET_ISR); in ftgmac100_poll()
1263 ioread32(priv->base + FTGMAC100_OFFSET_ISR); in ftgmac100_poll()
1265 /* Check RX and TX descriptors for more work to do */ in ftgmac100_poll()
1275 priv->base + FTGMAC100_OFFSET_IER); in ftgmac100_poll()
1285 /* Re-init descriptors (adjust queue sizes) */ in ftgmac100_init_all()
1288 /* Realloc rx descriptors */ in ftgmac100_init_all()
1298 /* Re-enable the device */ in ftgmac100_init_all()
1299 napi_enable(&priv->napi); in ftgmac100_init_all()
1300 netif_start_queue(priv->netdev); in ftgmac100_init_all()
1303 iowrite32(FTGMAC100_INT_ALL, priv->base + FTGMAC100_OFFSET_IER); in ftgmac100_init_all()
1310 struct net_device *netdev = priv->netdev; in ftgmac100_reset()
1317 if (netdev->phydev) in ftgmac100_reset()
1318 mutex_lock(&netdev->phydev->lock); in ftgmac100_reset()
1319 if (priv->mii_bus) in ftgmac100_reset()
1320 mutex_lock(&priv->mii_bus->mdio_lock); in ftgmac100_reset()
1329 napi_disable(&priv->napi); in ftgmac100_reset()
1332 /* Stop and reset the MAC */ in ftgmac100_reset()
1340 /* Free all rx and tx buffers */ in ftgmac100_reset()
1348 if (priv->mii_bus) in ftgmac100_reset()
1349 mutex_unlock(&priv->mii_bus->mdio_lock); in ftgmac100_reset()
1350 if (netdev->phydev) in ftgmac100_reset()
1351 mutex_unlock(&netdev->phydev->lock); in ftgmac100_reset()
1366 struct phy_device *phydev = netdev->phydev; in ftgmac100_adjust_link()
1371 if (!phydev->link) in ftgmac100_adjust_link()
1374 new_speed = phydev->speed; in ftgmac100_adjust_link()
1377 if (priv->aneg_pause) { in ftgmac100_adjust_link()
1378 rx_pause = tx_pause = phydev->pause; in ftgmac100_adjust_link()
1379 if (phydev->asym_pause) in ftgmac100_adjust_link()
1382 rx_pause = priv->rx_pause; in ftgmac100_adjust_link()
1383 tx_pause = priv->tx_pause; in ftgmac100_adjust_link()
1387 if (phydev->speed == priv->cur_speed && in ftgmac100_adjust_link()
1388 phydev->duplex == priv->cur_duplex && in ftgmac100_adjust_link()
1389 rx_pause == priv->rx_pause && in ftgmac100_adjust_link()
1390 tx_pause == priv->tx_pause) in ftgmac100_adjust_link()
1396 if (new_speed || priv->cur_speed) in ftgmac100_adjust_link()
1399 priv->cur_speed = new_speed; in ftgmac100_adjust_link()
1400 priv->cur_duplex = phydev->duplex; in ftgmac100_adjust_link()
1401 priv->rx_pause = rx_pause; in ftgmac100_adjust_link()
1402 priv->tx_pause = tx_pause; in ftgmac100_adjust_link()
1409 iowrite32(0, priv->base + FTGMAC100_OFFSET_IER); in ftgmac100_adjust_link()
1414 if (netdev->phydev) in ftgmac100_adjust_link()
1415 mutex_unlock(&netdev->phydev->lock); in ftgmac100_adjust_link()
1419 if (netdev->phydev) in ftgmac100_adjust_link()
1420 mutex_lock(&netdev->phydev->lock); in ftgmac100_adjust_link()
1427 struct platform_device *pdev = to_platform_device(priv->dev); in ftgmac100_mii_probe()
1428 struct device_node *np = pdev->dev.of_node; in ftgmac100_mii_probe()
1448 * those SoC specific bits and assume the device-tree is in ftgmac100_mii_probe()
1452 if (priv->is_aspeed && !(phy_interface_mode_is_rgmii(phy_intf))) { in ftgmac100_mii_probe()
1458 phydev = phy_find_first(priv->mii_bus); in ftgmac100_mii_probe()
1460 netdev_info(netdev, "%s: no PHY found\n", netdev->name); in ftgmac100_mii_probe()
1461 return -ENODEV; in ftgmac100_mii_probe()
1468 netdev_err(netdev, "%s: Could not attach to PHY\n", netdev->name); in ftgmac100_mii_probe()
1495 /* When using NC-SI we force the speed to 100Mbit/s full duplex, in ftgmac100_open()
1501 if (priv->use_ncsi) { in ftgmac100_open()
1502 priv->cur_duplex = DUPLEX_FULL; in ftgmac100_open()
1503 priv->cur_speed = SPEED_100; in ftgmac100_open()
1505 priv->cur_duplex = 0; in ftgmac100_open()
1506 priv->cur_speed = 0; in ftgmac100_open()
1515 netif_napi_add(netdev, &priv->napi, ftgmac100_poll); in ftgmac100_open()
1518 err = request_irq(netdev->irq, ftgmac100_interrupt, 0, netdev->name, netdev); in ftgmac100_open()
1520 netdev_err(netdev, "failed to request irq %d\n", netdev->irq); in ftgmac100_open()
1531 if (netdev->phydev) { in ftgmac100_open()
1533 phy_start(netdev->phydev); in ftgmac100_open()
1534 } else if (priv->use_ncsi) { in ftgmac100_open()
1535 /* If using NC-SI, set our carrier on and start the stack */ in ftgmac100_open()
1539 err = ncsi_start_dev(priv->ndev); in ftgmac100_open()
1547 napi_disable(&priv->napi); in ftgmac100_open()
1551 free_irq(netdev->irq, netdev); in ftgmac100_open()
1553 netif_napi_del(&priv->napi); in ftgmac100_open()
1555 iowrite32(0, priv->base + FTGMAC100_OFFSET_IER); in ftgmac100_open()
1573 iowrite32(0, priv->base + FTGMAC100_OFFSET_IER); in ftgmac100_stop()
1576 napi_disable(&priv->napi); in ftgmac100_stop()
1577 netif_napi_del(&priv->napi); in ftgmac100_stop()
1578 if (netdev->phydev) in ftgmac100_stop()
1579 phy_stop(netdev->phydev); in ftgmac100_stop()
1580 else if (priv->use_ncsi) in ftgmac100_stop()
1581 ncsi_stop_dev(priv->ndev); in ftgmac100_stop()
1584 free_irq(netdev->irq, netdev); in ftgmac100_stop()
1596 iowrite32(0, priv->base + FTGMAC100_OFFSET_IER); in ftgmac100_tx_timeout()
1599 schedule_work(&priv->reset_task); in ftgmac100_tx_timeout()
1606 netdev_features_t changed = netdev->features ^ features; in ftgmac100_set_features()
1615 maccr = ioread32(priv->base + FTGMAC100_OFFSET_MACCR); in ftgmac100_set_features()
1616 if (priv->netdev->features & NETIF_F_HW_VLAN_CTAG_RX) in ftgmac100_set_features()
1620 iowrite32(maccr, priv->base + FTGMAC100_OFFSET_MACCR); in ftgmac100_set_features()
1632 ftgmac100_interrupt(netdev->irq, netdev); in ftgmac100_poll_controller()
1657 struct platform_device *pdev = to_platform_device(priv->dev); in ftgmac100_setup_mdio()
1658 struct device_node *np = pdev->dev.of_node; in ftgmac100_setup_mdio()
1664 priv->mii_bus = mdiobus_alloc(); in ftgmac100_setup_mdio()
1665 if (!priv->mii_bus) in ftgmac100_setup_mdio()
1666 return -EIO; in ftgmac100_setup_mdio()
1668 if (of_device_is_compatible(np, "aspeed,ast2400-mac") || in ftgmac100_setup_mdio()
1669 of_device_is_compatible(np, "aspeed,ast2500-mac")) { in ftgmac100_setup_mdio()
1675 reg = ioread32(priv->base + FTGMAC100_OFFSET_REVR); in ftgmac100_setup_mdio()
1677 iowrite32(reg, priv->base + FTGMAC100_OFFSET_REVR); in ftgmac100_setup_mdio()
1680 priv->mii_bus->name = "ftgmac100_mdio"; in ftgmac100_setup_mdio()
1681 snprintf(priv->mii_bus->id, MII_BUS_ID_SIZE, "%s-%d", in ftgmac100_setup_mdio()
1682 pdev->name, pdev->id); in ftgmac100_setup_mdio()
1683 priv->mii_bus->parent = priv->dev; in ftgmac100_setup_mdio()
1684 priv->mii_bus->priv = priv->netdev; in ftgmac100_setup_mdio()
1685 priv->mii_bus->read = ftgmac100_mdiobus_read; in ftgmac100_setup_mdio()
1686 priv->mii_bus->write = ftgmac100_mdiobus_write; in ftgmac100_setup_mdio()
1689 priv->mii_bus->irq[i] = PHY_POLL; in ftgmac100_setup_mdio()
1693 err = of_mdiobus_register(priv->mii_bus, mdio_np); in ftgmac100_setup_mdio()
1695 dev_err(priv->dev, "Cannot register MDIO bus!\n"); in ftgmac100_setup_mdio()
1704 mdiobus_free(priv->mii_bus); in ftgmac100_setup_mdio()
1712 if (!netdev->phydev) in ftgmac100_phy_disconnect()
1715 phy_disconnect(netdev->phydev); in ftgmac100_phy_disconnect()
1716 if (of_phy_is_fixed_link(priv->dev->of_node)) in ftgmac100_phy_disconnect()
1717 of_phy_deregister_fixed_link(priv->dev->of_node); in ftgmac100_phy_disconnect()
1724 if (!priv->mii_bus) in ftgmac100_destroy_mdio()
1727 mdiobus_unregister(priv->mii_bus); in ftgmac100_destroy_mdio()
1728 mdiobus_free(priv->mii_bus); in ftgmac100_destroy_mdio()
1733 if (unlikely(nd->state != ncsi_dev_state_functional)) in ftgmac100_ncsi_handler()
1736 netdev_dbg(nd->dev, "NCSI interface %s\n", in ftgmac100_ncsi_handler()
1737 nd->link_up ? "up" : "down"); in ftgmac100_ncsi_handler()
1742 struct clk *clk; in ftgmac100_setup_clk() local
1745 clk = devm_clk_get(priv->dev, NULL /* MACCLK */); in ftgmac100_setup_clk()
1746 if (IS_ERR(clk)) in ftgmac100_setup_clk()
1747 return PTR_ERR(clk); in ftgmac100_setup_clk()
1748 priv->clk = clk; in ftgmac100_setup_clk()
1749 rc = clk_prepare_enable(priv->clk); in ftgmac100_setup_clk()
1757 rc = clk_set_rate(priv->clk, priv->use_ncsi ? FTGMAC_25MHZ : in ftgmac100_setup_clk()
1763 * necessary if it's the AST2400 MAC, or the MAC is configured for in ftgmac100_setup_clk()
1764 * RGMII, or the controller is not an ASPEED-based controller. in ftgmac100_setup_clk()
1766 priv->rclk = devm_clk_get_optional(priv->dev, "RCLK"); in ftgmac100_setup_clk()
1767 rc = clk_prepare_enable(priv->rclk); in ftgmac100_setup_clk()
1772 clk_disable_unprepare(priv->clk); in ftgmac100_setup_clk()
1801 return -ENXIO; in ftgmac100_probe()
1810 err = -ENOMEM; in ftgmac100_probe()
1814 SET_NETDEV_DEV(netdev, &pdev->dev); in ftgmac100_probe()
1816 netdev->ethtool_ops = &ftgmac100_ethtool_ops; in ftgmac100_probe()
1817 netdev->netdev_ops = &ftgmac100_netdev_ops; in ftgmac100_probe()
1818 netdev->watchdog_timeo = 5 * HZ; in ftgmac100_probe()
1824 priv->netdev = netdev; in ftgmac100_probe()
1825 priv->dev = &pdev->dev; in ftgmac100_probe()
1826 INIT_WORK(&priv->reset_task, ftgmac100_reset_task); in ftgmac100_probe()
1829 priv->res = request_mem_region(res->start, resource_size(res), in ftgmac100_probe()
1830 dev_name(&pdev->dev)); in ftgmac100_probe()
1831 if (!priv->res) { in ftgmac100_probe()
1832 dev_err(&pdev->dev, "Could not reserve memory region\n"); in ftgmac100_probe()
1833 err = -ENOMEM; in ftgmac100_probe()
1837 priv->base = ioremap(res->start, resource_size(res)); in ftgmac100_probe()
1838 if (!priv->base) { in ftgmac100_probe()
1839 dev_err(&pdev->dev, "Failed to ioremap ethernet registers\n"); in ftgmac100_probe()
1840 err = -EIO; in ftgmac100_probe()
1844 netdev->irq = irq; in ftgmac100_probe()
1847 priv->tx_pause = true; in ftgmac100_probe()
1848 priv->rx_pause = true; in ftgmac100_probe()
1849 priv->aneg_pause = true; in ftgmac100_probe()
1851 /* MAC address from chip or random one */ in ftgmac100_probe()
1856 np = pdev->dev.of_node; in ftgmac100_probe()
1857 if (np && (of_device_is_compatible(np, "aspeed,ast2400-mac") || in ftgmac100_probe()
1858 of_device_is_compatible(np, "aspeed,ast2500-mac") || in ftgmac100_probe()
1859 of_device_is_compatible(np, "aspeed,ast2600-mac"))) { in ftgmac100_probe()
1860 priv->rxdes0_edorr_mask = BIT(30); in ftgmac100_probe()
1861 priv->txdes0_edotr_mask = BIT(30); in ftgmac100_probe()
1862 priv->is_aspeed = true; in ftgmac100_probe()
1864 priv->rxdes0_edorr_mask = BIT(15); in ftgmac100_probe()
1865 priv->txdes0_edotr_mask = BIT(15); in ftgmac100_probe()
1868 if (np && of_get_property(np, "use-ncsi", NULL)) { in ftgmac100_probe()
1870 dev_err(&pdev->dev, "NCSI stack not enabled\n"); in ftgmac100_probe()
1871 err = -EINVAL; in ftgmac100_probe()
1875 dev_info(&pdev->dev, "Using NCSI interface\n"); in ftgmac100_probe()
1876 priv->use_ncsi = true; in ftgmac100_probe()
1877 priv->ndev = ncsi_register_dev(netdev, ftgmac100_ncsi_handler); in ftgmac100_probe()
1878 if (!priv->ndev) { in ftgmac100_probe()
1879 err = -EINVAL; in ftgmac100_probe()
1887 dev_err(&pdev->dev, "Failed to register fixed PHY\n"); in ftgmac100_probe()
1891 phy = of_phy_get_and_connect(priv->netdev, np, in ftgmac100_probe()
1894 dev_err(&pdev->dev, "Failed to connect to fixed PHY\n"); in ftgmac100_probe()
1896 err = -EINVAL; in ftgmac100_probe()
1902 } else if (np && of_get_property(np, "phy-handle", NULL)) { in ftgmac100_probe()
1909 if (of_device_is_compatible(np, "aspeed,ast2400-mac") || in ftgmac100_probe()
1910 of_device_is_compatible(np, "aspeed,ast2500-mac")) { in ftgmac100_probe()
1916 phy = of_phy_get_and_connect(priv->netdev, np, in ftgmac100_probe()
1919 dev_err(&pdev->dev, "Failed to connect to phy\n"); in ftgmac100_probe()
1920 err = -EINVAL; in ftgmac100_probe()
1933 * MAC with an embedded MDIO controller but have no "mdio" in ftgmac100_probe()
1937 priv->use_ncsi = false; in ftgmac100_probe()
1944 dev_err(priv->dev, "MII probe failed!\n"); in ftgmac100_probe()
1950 if (priv->is_aspeed) { in ftgmac100_probe()
1956 if (of_device_is_compatible(np, "aspeed,ast2600-mac")) in ftgmac100_probe()
1958 priv->base + FTGMAC100_OFFSET_TM); in ftgmac100_probe()
1962 priv->rx_q_entries = priv->new_rx_q_entries = DEF_RX_QUEUE_ENTRIES; in ftgmac100_probe()
1963 priv->tx_q_entries = priv->new_tx_q_entries = DEF_TX_QUEUE_ENTRIES; in ftgmac100_probe()
1966 netdev->hw_features = NETIF_F_RXCSUM | NETIF_F_HW_CSUM | in ftgmac100_probe()
1970 if (priv->use_ncsi) in ftgmac100_probe()
1971 netdev->hw_features |= NETIF_F_HW_VLAN_CTAG_FILTER; in ftgmac100_probe()
1974 if (np && (of_device_is_compatible(np, "aspeed,ast2400-mac"))) in ftgmac100_probe()
1975 netdev->hw_features &= ~NETIF_F_HW_CSUM; in ftgmac100_probe()
1978 if (priv->use_ncsi && of_device_is_compatible(np, "aspeed,ast2600-mac")) in ftgmac100_probe()
1979 netdev->hw_features &= ~NETIF_F_HW_CSUM; in ftgmac100_probe()
1981 if (np && of_get_property(np, "no-hw-checksum", NULL)) in ftgmac100_probe()
1982 netdev->hw_features &= ~(NETIF_F_HW_CSUM | NETIF_F_RXCSUM); in ftgmac100_probe()
1983 netdev->features |= netdev->hw_features; in ftgmac100_probe()
1988 dev_err(&pdev->dev, "Failed to register netdev\n"); in ftgmac100_probe()
1992 netdev_info(netdev, "irq %d, mapped at %p\n", netdev->irq, priv->base); in ftgmac100_probe()
1997 clk_disable_unprepare(priv->rclk); in ftgmac100_probe()
1998 clk_disable_unprepare(priv->clk); in ftgmac100_probe()
2002 if (priv->ndev) in ftgmac100_probe()
2003 ncsi_unregister_dev(priv->ndev); in ftgmac100_probe()
2006 iounmap(priv->base); in ftgmac100_probe()
2008 release_resource(priv->res); in ftgmac100_probe()
2023 if (priv->ndev) in ftgmac100_remove()
2024 ncsi_unregister_dev(priv->ndev); in ftgmac100_remove()
2027 clk_disable_unprepare(priv->rclk); in ftgmac100_remove()
2028 clk_disable_unprepare(priv->clk); in ftgmac100_remove()
2030 /* There's a small chance the reset task will have been re-queued, in ftgmac100_remove()
2033 cancel_work_sync(&priv->reset_task); in ftgmac100_remove()
2038 iounmap(priv->base); in ftgmac100_remove()
2039 release_resource(priv->res); in ftgmac100_remove()
2041 netif_napi_del(&priv->napi); in ftgmac100_remove()
2061 MODULE_AUTHOR("Po-Yu Chuang <ratbert@faraday-tech.com>");