1262 lines · c
1// SPDX-License-Identifier: GPL-2.0-or-later2/*3 * Faraday FTMAC100 10/100 Ethernet4 *5 * (C) Copyright 2009-2011 Faraday Technology6 * Po-Yu Chuang <ratbert@faraday-tech.com>7 */8 9#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt10 11#include <linux/dma-mapping.h>12#include <linux/etherdevice.h>13#include <linux/ethtool.h>14#include <linux/if_ether.h>15#include <linux/if_vlan.h>16#include <linux/init.h>17#include <linux/interrupt.h>18#include <linux/io.h>19#include <linux/mii.h>20#include <linux/module.h>21#include <linux/mod_devicetable.h>22#include <linux/netdevice.h>23#include <linux/platform_device.h>24 25#include "ftmac100.h"26 27#define DRV_NAME "ftmac100"28 29#define RX_QUEUE_ENTRIES 128 /* must be power of 2 */30#define TX_QUEUE_ENTRIES 16 /* must be power of 2 */31 32#define RX_BUF_SIZE 2044 /* must be smaller than 0x7ff */33#define MAX_PKT_SIZE RX_BUF_SIZE /* multi-segment not supported */34 35#if MAX_PKT_SIZE > 0x7ff36#error invalid MAX_PKT_SIZE37#endif38 39#if RX_BUF_SIZE > 0x7ff || RX_BUF_SIZE > PAGE_SIZE40#error invalid RX_BUF_SIZE41#endif42 43/******************************************************************************44 * private data45 *****************************************************************************/46struct ftmac100_descs {47 struct ftmac100_rxdes rxdes[RX_QUEUE_ENTRIES];48 struct ftmac100_txdes txdes[TX_QUEUE_ENTRIES];49};50 51struct ftmac100 {52 struct resource *res;53 void __iomem *base;54 int irq;55 56 struct ftmac100_descs *descs;57 dma_addr_t descs_dma_addr;58 59 unsigned int rx_pointer;60 unsigned int tx_clean_pointer;61 unsigned int tx_pointer;62 unsigned int tx_pending;63 64 spinlock_t tx_lock;65 66 struct net_device *netdev;67 struct device *dev;68 struct napi_struct napi;69 70 struct mii_if_info mii;71};72 73static int ftmac100_alloc_rx_page(struct ftmac100 *priv,74 struct ftmac100_rxdes *rxdes, gfp_t gfp);75 76/******************************************************************************77 * internal functions (hardware register access)78 *****************************************************************************/79#define INT_MASK_ALL_ENABLED (FTMAC100_INT_RPKT_FINISH | \80 FTMAC100_INT_NORXBUF | \81 FTMAC100_INT_XPKT_OK | \82 FTMAC100_INT_XPKT_LOST | \83 FTMAC100_INT_RPKT_LOST | \84 FTMAC100_INT_AHB_ERR | \85 FTMAC100_INT_PHYSTS_CHG)86 87#define INT_MASK_ALL_DISABLED 088 89static void ftmac100_enable_all_int(struct ftmac100 *priv)90{91 iowrite32(INT_MASK_ALL_ENABLED, priv->base + FTMAC100_OFFSET_IMR);92}93 94static void ftmac100_disable_all_int(struct ftmac100 *priv)95{96 iowrite32(INT_MASK_ALL_DISABLED, priv->base + FTMAC100_OFFSET_IMR);97}98 99static void ftmac100_set_rx_ring_base(struct ftmac100 *priv, dma_addr_t addr)100{101 iowrite32(addr, priv->base + FTMAC100_OFFSET_RXR_BADR);102}103 104static void ftmac100_set_tx_ring_base(struct ftmac100 *priv, dma_addr_t addr)105{106 iowrite32(addr, priv->base + FTMAC100_OFFSET_TXR_BADR);107}108 109static void ftmac100_txdma_start_polling(struct ftmac100 *priv)110{111 iowrite32(1, priv->base + FTMAC100_OFFSET_TXPD);112}113 114static int ftmac100_reset(struct ftmac100 *priv)115{116 struct net_device *netdev = priv->netdev;117 int i;118 119 /* NOTE: reset clears all registers */120 iowrite32(FTMAC100_MACCR_SW_RST, priv->base + FTMAC100_OFFSET_MACCR);121 122 for (i = 0; i < 5; i++) {123 unsigned int maccr;124 125 maccr = ioread32(priv->base + FTMAC100_OFFSET_MACCR);126 if (!(maccr & FTMAC100_MACCR_SW_RST)) {127 /*128 * FTMAC100_MACCR_SW_RST cleared does not indicate129 * that hardware reset completed (what the f*ck).130 * We still need to wait for a while.131 */132 udelay(500);133 return 0;134 }135 136 udelay(1000);137 }138 139 netdev_err(netdev, "software reset failed\n");140 return -EIO;141}142 143static void ftmac100_set_mac(struct ftmac100 *priv, const unsigned char *mac)144{145 unsigned int maddr = mac[0] << 8 | mac[1];146 unsigned int laddr = mac[2] << 24 | mac[3] << 16 | mac[4] << 8 | mac[5];147 148 iowrite32(maddr, priv->base + FTMAC100_OFFSET_MAC_MADR);149 iowrite32(laddr, priv->base + FTMAC100_OFFSET_MAC_LADR);150}151 152static void ftmac100_setup_mc_ht(struct ftmac100 *priv)153{154 struct netdev_hw_addr *ha;155 u64 maht = 0; /* Multicast Address Hash Table */156 157 netdev_for_each_mc_addr(ha, priv->netdev) {158 u32 hash = ether_crc(ETH_ALEN, ha->addr) >> 26;159 160 maht |= BIT_ULL(hash);161 }162 163 iowrite32(lower_32_bits(maht), priv->base + FTMAC100_OFFSET_MAHT0);164 iowrite32(upper_32_bits(maht), priv->base + FTMAC100_OFFSET_MAHT1);165}166 167static void ftmac100_set_rx_bits(struct ftmac100 *priv, unsigned int *maccr)168{169 struct net_device *netdev = priv->netdev;170 171 /* Clear all */172 *maccr &= ~(FTMAC100_MACCR_RCV_ALL | FTMAC100_MACCR_RX_MULTIPKT |173 FTMAC100_MACCR_HT_MULTI_EN);174 175 /* Set the requested bits */176 if (netdev->flags & IFF_PROMISC)177 *maccr |= FTMAC100_MACCR_RCV_ALL;178 if (netdev->flags & IFF_ALLMULTI)179 *maccr |= FTMAC100_MACCR_RX_MULTIPKT;180 else if (netdev_mc_count(netdev)) {181 *maccr |= FTMAC100_MACCR_HT_MULTI_EN;182 ftmac100_setup_mc_ht(priv);183 }184}185 186#define MACCR_ENABLE_ALL (FTMAC100_MACCR_XMT_EN | \187 FTMAC100_MACCR_RCV_EN | \188 FTMAC100_MACCR_XDMA_EN | \189 FTMAC100_MACCR_RDMA_EN | \190 FTMAC100_MACCR_CRC_APD | \191 FTMAC100_MACCR_FULLDUP | \192 FTMAC100_MACCR_RX_RUNT | \193 FTMAC100_MACCR_RX_BROADPKT)194 195static int ftmac100_start_hw(struct ftmac100 *priv)196{197 struct net_device *netdev = priv->netdev;198 unsigned int maccr = MACCR_ENABLE_ALL;199 200 if (ftmac100_reset(priv))201 return -EIO;202 203 /* setup ring buffer base registers */204 ftmac100_set_rx_ring_base(priv,205 priv->descs_dma_addr +206 offsetof(struct ftmac100_descs, rxdes));207 ftmac100_set_tx_ring_base(priv,208 priv->descs_dma_addr +209 offsetof(struct ftmac100_descs, txdes));210 211 iowrite32(FTMAC100_APTC_RXPOLL_CNT(1), priv->base + FTMAC100_OFFSET_APTC);212 213 ftmac100_set_mac(priv, netdev->dev_addr);214 215 /* See ftmac100_change_mtu() */216 if (netdev->mtu > ETH_DATA_LEN)217 maccr |= FTMAC100_MACCR_RX_FTL;218 219 ftmac100_set_rx_bits(priv, &maccr);220 221 iowrite32(maccr, priv->base + FTMAC100_OFFSET_MACCR);222 return 0;223}224 225static void ftmac100_stop_hw(struct ftmac100 *priv)226{227 iowrite32(0, priv->base + FTMAC100_OFFSET_MACCR);228}229 230/******************************************************************************231 * internal functions (receive descriptor)232 *****************************************************************************/233static bool ftmac100_rxdes_first_segment(struct ftmac100_rxdes *rxdes)234{235 return rxdes->rxdes0 & cpu_to_le32(FTMAC100_RXDES0_FRS);236}237 238static bool ftmac100_rxdes_last_segment(struct ftmac100_rxdes *rxdes)239{240 return rxdes->rxdes0 & cpu_to_le32(FTMAC100_RXDES0_LRS);241}242 243static bool ftmac100_rxdes_owned_by_dma(struct ftmac100_rxdes *rxdes)244{245 return rxdes->rxdes0 & cpu_to_le32(FTMAC100_RXDES0_RXDMA_OWN);246}247 248static void ftmac100_rxdes_set_dma_own(struct ftmac100_rxdes *rxdes)249{250 /* clear status bits */251 rxdes->rxdes0 = cpu_to_le32(FTMAC100_RXDES0_RXDMA_OWN);252}253 254static bool ftmac100_rxdes_rx_error(struct ftmac100_rxdes *rxdes)255{256 return rxdes->rxdes0 & cpu_to_le32(FTMAC100_RXDES0_RX_ERR);257}258 259static bool ftmac100_rxdes_crc_error(struct ftmac100_rxdes *rxdes)260{261 return rxdes->rxdes0 & cpu_to_le32(FTMAC100_RXDES0_CRC_ERR);262}263 264static bool ftmac100_rxdes_runt(struct ftmac100_rxdes *rxdes)265{266 return rxdes->rxdes0 & cpu_to_le32(FTMAC100_RXDES0_RUNT);267}268 269static bool ftmac100_rxdes_odd_nibble(struct ftmac100_rxdes *rxdes)270{271 return rxdes->rxdes0 & cpu_to_le32(FTMAC100_RXDES0_RX_ODD_NB);272}273 274static unsigned int ftmac100_rxdes_frame_length(struct ftmac100_rxdes *rxdes)275{276 return le32_to_cpu(rxdes->rxdes0) & FTMAC100_RXDES0_RFL;277}278 279static bool ftmac100_rxdes_multicast(struct ftmac100_rxdes *rxdes)280{281 return rxdes->rxdes0 & cpu_to_le32(FTMAC100_RXDES0_MULTICAST);282}283 284static void ftmac100_rxdes_set_buffer_size(struct ftmac100_rxdes *rxdes,285 unsigned int size)286{287 rxdes->rxdes1 &= cpu_to_le32(FTMAC100_RXDES1_EDORR);288 rxdes->rxdes1 |= cpu_to_le32(FTMAC100_RXDES1_RXBUF_SIZE(size));289}290 291static void ftmac100_rxdes_set_end_of_ring(struct ftmac100_rxdes *rxdes)292{293 rxdes->rxdes1 |= cpu_to_le32(FTMAC100_RXDES1_EDORR);294}295 296static void ftmac100_rxdes_set_dma_addr(struct ftmac100_rxdes *rxdes,297 dma_addr_t addr)298{299 rxdes->rxdes2 = cpu_to_le32(addr);300}301 302static dma_addr_t ftmac100_rxdes_get_dma_addr(struct ftmac100_rxdes *rxdes)303{304 return le32_to_cpu(rxdes->rxdes2);305}306 307/*308 * rxdes3 is not used by hardware. We use it to keep track of page.309 * Since hardware does not touch it, we can skip cpu_to_le32()/le32_to_cpu().310 */311static void ftmac100_rxdes_set_page(struct ftmac100_rxdes *rxdes, struct page *page)312{313 rxdes->rxdes3 = (unsigned int)page;314}315 316static struct page *ftmac100_rxdes_get_page(struct ftmac100_rxdes *rxdes)317{318 return (struct page *)rxdes->rxdes3;319}320 321/******************************************************************************322 * internal functions (receive)323 *****************************************************************************/324static int ftmac100_next_rx_pointer(int pointer)325{326 return (pointer + 1) & (RX_QUEUE_ENTRIES - 1);327}328 329static void ftmac100_rx_pointer_advance(struct ftmac100 *priv)330{331 priv->rx_pointer = ftmac100_next_rx_pointer(priv->rx_pointer);332}333 334static struct ftmac100_rxdes *ftmac100_current_rxdes(struct ftmac100 *priv)335{336 return &priv->descs->rxdes[priv->rx_pointer];337}338 339static struct ftmac100_rxdes *340ftmac100_rx_locate_first_segment(struct ftmac100 *priv)341{342 struct ftmac100_rxdes *rxdes = ftmac100_current_rxdes(priv);343 344 while (!ftmac100_rxdes_owned_by_dma(rxdes)) {345 if (ftmac100_rxdes_first_segment(rxdes))346 return rxdes;347 348 ftmac100_rxdes_set_dma_own(rxdes);349 ftmac100_rx_pointer_advance(priv);350 rxdes = ftmac100_current_rxdes(priv);351 }352 353 return NULL;354}355 356static bool ftmac100_rx_packet_error(struct ftmac100 *priv,357 struct ftmac100_rxdes *rxdes)358{359 struct net_device *netdev = priv->netdev;360 bool error = false;361 362 if (unlikely(ftmac100_rxdes_rx_error(rxdes))) {363 if (net_ratelimit())364 netdev_info(netdev, "rx err\n");365 366 netdev->stats.rx_errors++;367 error = true;368 }369 370 if (unlikely(ftmac100_rxdes_crc_error(rxdes))) {371 if (net_ratelimit())372 netdev_info(netdev, "rx crc err\n");373 374 netdev->stats.rx_crc_errors++;375 error = true;376 }377 378 if (unlikely(ftmac100_rxdes_runt(rxdes))) {379 if (net_ratelimit())380 netdev_info(netdev, "rx runt\n");381 382 netdev->stats.rx_length_errors++;383 error = true;384 } else if (unlikely(ftmac100_rxdes_odd_nibble(rxdes))) {385 if (net_ratelimit())386 netdev_info(netdev, "rx odd nibble\n");387 388 netdev->stats.rx_length_errors++;389 error = true;390 }391 /*392 * FTMAC100_RXDES0_FTL is not an error, it just indicates that the393 * frame is longer than 1518 octets. Receiving these is possible when394 * we told the hardware not to drop them, via FTMAC100_MACCR_RX_FTL.395 */396 397 return error;398}399 400static void ftmac100_rx_drop_packet(struct ftmac100 *priv)401{402 struct net_device *netdev = priv->netdev;403 struct ftmac100_rxdes *rxdes = ftmac100_current_rxdes(priv);404 bool done = false;405 406 if (net_ratelimit())407 netdev_dbg(netdev, "drop packet %p\n", rxdes);408 409 do {410 if (ftmac100_rxdes_last_segment(rxdes))411 done = true;412 413 ftmac100_rxdes_set_dma_own(rxdes);414 ftmac100_rx_pointer_advance(priv);415 rxdes = ftmac100_current_rxdes(priv);416 } while (!done && !ftmac100_rxdes_owned_by_dma(rxdes));417 418 netdev->stats.rx_dropped++;419}420 421static bool ftmac100_rx_packet(struct ftmac100 *priv, int *processed)422{423 struct net_device *netdev = priv->netdev;424 struct ftmac100_rxdes *rxdes;425 struct sk_buff *skb;426 struct page *page;427 dma_addr_t map;428 int length;429 bool ret;430 431 rxdes = ftmac100_rx_locate_first_segment(priv);432 if (!rxdes)433 return false;434 435 if (unlikely(ftmac100_rx_packet_error(priv, rxdes))) {436 ftmac100_rx_drop_packet(priv);437 return true;438 }439 440 /* We don't support multi-segment packets for now, so drop them. */441 ret = ftmac100_rxdes_last_segment(rxdes);442 if (unlikely(!ret)) {443 netdev->stats.rx_length_errors++;444 ftmac100_rx_drop_packet(priv);445 return true;446 }447 448 /* start processing */449 skb = netdev_alloc_skb_ip_align(netdev, 128);450 if (unlikely(!skb)) {451 if (net_ratelimit())452 netdev_err(netdev, "rx skb alloc failed\n");453 454 ftmac100_rx_drop_packet(priv);455 return true;456 }457 458 if (unlikely(ftmac100_rxdes_multicast(rxdes)))459 netdev->stats.multicast++;460 461 map = ftmac100_rxdes_get_dma_addr(rxdes);462 dma_unmap_page(priv->dev, map, RX_BUF_SIZE, DMA_FROM_DEVICE);463 464 length = ftmac100_rxdes_frame_length(rxdes);465 page = ftmac100_rxdes_get_page(rxdes);466 skb_fill_page_desc(skb, 0, page, 0, length);467 skb->len += length;468 skb->data_len += length;469 470 if (length > 128) {471 skb->truesize += PAGE_SIZE;472 /* We pull the minimum amount into linear part */473 __pskb_pull_tail(skb, ETH_HLEN);474 } else {475 /* Small frames are copied into linear part to free one page */476 __pskb_pull_tail(skb, length);477 }478 ftmac100_alloc_rx_page(priv, rxdes, GFP_ATOMIC);479 480 ftmac100_rx_pointer_advance(priv);481 482 skb->protocol = eth_type_trans(skb, netdev);483 484 netdev->stats.rx_packets++;485 netdev->stats.rx_bytes += skb->len;486 487 /* push packet to protocol stack */488 netif_receive_skb(skb);489 490 (*processed)++;491 return true;492}493 494/******************************************************************************495 * internal functions (transmit descriptor)496 *****************************************************************************/497static void ftmac100_txdes_reset(struct ftmac100_txdes *txdes)498{499 /* clear all except end of ring bit */500 txdes->txdes0 = 0;501 txdes->txdes1 &= cpu_to_le32(FTMAC100_TXDES1_EDOTR);502 txdes->txdes2 = 0;503 txdes->txdes3 = 0;504}505 506static bool ftmac100_txdes_owned_by_dma(struct ftmac100_txdes *txdes)507{508 return txdes->txdes0 & cpu_to_le32(FTMAC100_TXDES0_TXDMA_OWN);509}510 511static void ftmac100_txdes_set_dma_own(struct ftmac100_txdes *txdes)512{513 /*514 * Make sure dma own bit will not be set before any other515 * descriptor fields.516 */517 wmb();518 txdes->txdes0 |= cpu_to_le32(FTMAC100_TXDES0_TXDMA_OWN);519}520 521static bool ftmac100_txdes_excessive_collision(struct ftmac100_txdes *txdes)522{523 return txdes->txdes0 & cpu_to_le32(FTMAC100_TXDES0_TXPKT_EXSCOL);524}525 526static bool ftmac100_txdes_late_collision(struct ftmac100_txdes *txdes)527{528 return txdes->txdes0 & cpu_to_le32(FTMAC100_TXDES0_TXPKT_LATECOL);529}530 531static void ftmac100_txdes_set_end_of_ring(struct ftmac100_txdes *txdes)532{533 txdes->txdes1 |= cpu_to_le32(FTMAC100_TXDES1_EDOTR);534}535 536static void ftmac100_txdes_set_first_segment(struct ftmac100_txdes *txdes)537{538 txdes->txdes1 |= cpu_to_le32(FTMAC100_TXDES1_FTS);539}540 541static void ftmac100_txdes_set_last_segment(struct ftmac100_txdes *txdes)542{543 txdes->txdes1 |= cpu_to_le32(FTMAC100_TXDES1_LTS);544}545 546static void ftmac100_txdes_set_txint(struct ftmac100_txdes *txdes)547{548 txdes->txdes1 |= cpu_to_le32(FTMAC100_TXDES1_TXIC);549}550 551static void ftmac100_txdes_set_buffer_size(struct ftmac100_txdes *txdes,552 unsigned int len)553{554 txdes->txdes1 |= cpu_to_le32(FTMAC100_TXDES1_TXBUF_SIZE(len));555}556 557static void ftmac100_txdes_set_dma_addr(struct ftmac100_txdes *txdes,558 dma_addr_t addr)559{560 txdes->txdes2 = cpu_to_le32(addr);561}562 563static dma_addr_t ftmac100_txdes_get_dma_addr(struct ftmac100_txdes *txdes)564{565 return le32_to_cpu(txdes->txdes2);566}567 568/*569 * txdes3 is not used by hardware. We use it to keep track of socket buffer.570 * Since hardware does not touch it, we can skip cpu_to_le32()/le32_to_cpu().571 */572static void ftmac100_txdes_set_skb(struct ftmac100_txdes *txdes, struct sk_buff *skb)573{574 txdes->txdes3 = (unsigned int)skb;575}576 577static struct sk_buff *ftmac100_txdes_get_skb(struct ftmac100_txdes *txdes)578{579 return (struct sk_buff *)txdes->txdes3;580}581 582/******************************************************************************583 * internal functions (transmit)584 *****************************************************************************/585static int ftmac100_next_tx_pointer(int pointer)586{587 return (pointer + 1) & (TX_QUEUE_ENTRIES - 1);588}589 590static void ftmac100_tx_pointer_advance(struct ftmac100 *priv)591{592 priv->tx_pointer = ftmac100_next_tx_pointer(priv->tx_pointer);593}594 595static void ftmac100_tx_clean_pointer_advance(struct ftmac100 *priv)596{597 priv->tx_clean_pointer = ftmac100_next_tx_pointer(priv->tx_clean_pointer);598}599 600static struct ftmac100_txdes *ftmac100_current_txdes(struct ftmac100 *priv)601{602 return &priv->descs->txdes[priv->tx_pointer];603}604 605static struct ftmac100_txdes *ftmac100_current_clean_txdes(struct ftmac100 *priv)606{607 return &priv->descs->txdes[priv->tx_clean_pointer];608}609 610static bool ftmac100_tx_complete_packet(struct ftmac100 *priv)611{612 struct net_device *netdev = priv->netdev;613 struct ftmac100_txdes *txdes;614 struct sk_buff *skb;615 dma_addr_t map;616 617 if (priv->tx_pending == 0)618 return false;619 620 txdes = ftmac100_current_clean_txdes(priv);621 622 if (ftmac100_txdes_owned_by_dma(txdes))623 return false;624 625 skb = ftmac100_txdes_get_skb(txdes);626 map = ftmac100_txdes_get_dma_addr(txdes);627 628 if (unlikely(ftmac100_txdes_excessive_collision(txdes) ||629 ftmac100_txdes_late_collision(txdes))) {630 /*631 * packet transmitted to ethernet lost due to late collision632 * or excessive collision633 */634 netdev->stats.tx_aborted_errors++;635 } else {636 netdev->stats.tx_packets++;637 netdev->stats.tx_bytes += skb->len;638 }639 640 dma_unmap_single(priv->dev, map, skb_headlen(skb), DMA_TO_DEVICE);641 dev_kfree_skb(skb);642 643 ftmac100_txdes_reset(txdes);644 645 ftmac100_tx_clean_pointer_advance(priv);646 647 spin_lock(&priv->tx_lock);648 priv->tx_pending--;649 spin_unlock(&priv->tx_lock);650 netif_wake_queue(netdev);651 652 return true;653}654 655static void ftmac100_tx_complete(struct ftmac100 *priv)656{657 while (ftmac100_tx_complete_packet(priv))658 ;659}660 661static netdev_tx_t ftmac100_xmit(struct ftmac100 *priv, struct sk_buff *skb,662 dma_addr_t map)663{664 struct net_device *netdev = priv->netdev;665 struct ftmac100_txdes *txdes;666 unsigned int len = (skb->len < ETH_ZLEN) ? ETH_ZLEN : skb->len;667 668 txdes = ftmac100_current_txdes(priv);669 ftmac100_tx_pointer_advance(priv);670 671 /* setup TX descriptor */672 ftmac100_txdes_set_skb(txdes, skb);673 ftmac100_txdes_set_dma_addr(txdes, map);674 675 ftmac100_txdes_set_first_segment(txdes);676 ftmac100_txdes_set_last_segment(txdes);677 ftmac100_txdes_set_txint(txdes);678 ftmac100_txdes_set_buffer_size(txdes, len);679 680 spin_lock(&priv->tx_lock);681 priv->tx_pending++;682 if (priv->tx_pending == TX_QUEUE_ENTRIES)683 netif_stop_queue(netdev);684 685 /* start transmit */686 ftmac100_txdes_set_dma_own(txdes);687 spin_unlock(&priv->tx_lock);688 689 ftmac100_txdma_start_polling(priv);690 return NETDEV_TX_OK;691}692 693/******************************************************************************694 * internal functions (buffer)695 *****************************************************************************/696static int ftmac100_alloc_rx_page(struct ftmac100 *priv,697 struct ftmac100_rxdes *rxdes, gfp_t gfp)698{699 struct net_device *netdev = priv->netdev;700 struct page *page;701 dma_addr_t map;702 703 page = alloc_page(gfp);704 if (!page) {705 if (net_ratelimit())706 netdev_err(netdev, "failed to allocate rx page\n");707 return -ENOMEM;708 }709 710 map = dma_map_page(priv->dev, page, 0, RX_BUF_SIZE, DMA_FROM_DEVICE);711 if (unlikely(dma_mapping_error(priv->dev, map))) {712 if (net_ratelimit())713 netdev_err(netdev, "failed to map rx page\n");714 __free_page(page);715 return -ENOMEM;716 }717 718 ftmac100_rxdes_set_page(rxdes, page);719 ftmac100_rxdes_set_dma_addr(rxdes, map);720 ftmac100_rxdes_set_buffer_size(rxdes, RX_BUF_SIZE);721 ftmac100_rxdes_set_dma_own(rxdes);722 return 0;723}724 725static void ftmac100_free_buffers(struct ftmac100 *priv)726{727 int i;728 729 for (i = 0; i < RX_QUEUE_ENTRIES; i++) {730 struct ftmac100_rxdes *rxdes = &priv->descs->rxdes[i];731 struct page *page = ftmac100_rxdes_get_page(rxdes);732 dma_addr_t map = ftmac100_rxdes_get_dma_addr(rxdes);733 734 if (!page)735 continue;736 737 dma_unmap_page(priv->dev, map, RX_BUF_SIZE, DMA_FROM_DEVICE);738 __free_page(page);739 }740 741 for (i = 0; i < TX_QUEUE_ENTRIES; i++) {742 struct ftmac100_txdes *txdes = &priv->descs->txdes[i];743 struct sk_buff *skb = ftmac100_txdes_get_skb(txdes);744 dma_addr_t map = ftmac100_txdes_get_dma_addr(txdes);745 746 if (!skb)747 continue;748 749 dma_unmap_single(priv->dev, map, skb_headlen(skb), DMA_TO_DEVICE);750 dev_kfree_skb(skb);751 }752 753 dma_free_coherent(priv->dev, sizeof(struct ftmac100_descs),754 priv->descs, priv->descs_dma_addr);755}756 757static int ftmac100_alloc_buffers(struct ftmac100 *priv)758{759 int i;760 761 priv->descs = dma_alloc_coherent(priv->dev,762 sizeof(struct ftmac100_descs),763 &priv->descs_dma_addr, GFP_KERNEL);764 if (!priv->descs)765 return -ENOMEM;766 767 /* initialize RX ring */768 ftmac100_rxdes_set_end_of_ring(&priv->descs->rxdes[RX_QUEUE_ENTRIES - 1]);769 770 for (i = 0; i < RX_QUEUE_ENTRIES; i++) {771 struct ftmac100_rxdes *rxdes = &priv->descs->rxdes[i];772 773 if (ftmac100_alloc_rx_page(priv, rxdes, GFP_KERNEL))774 goto err;775 }776 777 /* initialize TX ring */778 ftmac100_txdes_set_end_of_ring(&priv->descs->txdes[TX_QUEUE_ENTRIES - 1]);779 return 0;780 781err:782 ftmac100_free_buffers(priv);783 return -ENOMEM;784}785 786/******************************************************************************787 * struct mii_if_info functions788 *****************************************************************************/789static int ftmac100_mdio_read(struct net_device *netdev, int phy_id, int reg)790{791 struct ftmac100 *priv = netdev_priv(netdev);792 unsigned int phycr;793 int i;794 795 phycr = FTMAC100_PHYCR_PHYAD(phy_id) |796 FTMAC100_PHYCR_REGAD(reg) |797 FTMAC100_PHYCR_MIIRD;798 799 iowrite32(phycr, priv->base + FTMAC100_OFFSET_PHYCR);800 801 for (i = 0; i < 10; i++) {802 phycr = ioread32(priv->base + FTMAC100_OFFSET_PHYCR);803 804 if ((phycr & FTMAC100_PHYCR_MIIRD) == 0)805 return phycr & FTMAC100_PHYCR_MIIRDATA;806 807 udelay(100);808 }809 810 netdev_err(netdev, "mdio read timed out\n");811 return 0;812}813 814static void ftmac100_mdio_write(struct net_device *netdev, int phy_id, int reg,815 int data)816{817 struct ftmac100 *priv = netdev_priv(netdev);818 unsigned int phycr;819 int i;820 821 phycr = FTMAC100_PHYCR_PHYAD(phy_id) |822 FTMAC100_PHYCR_REGAD(reg) |823 FTMAC100_PHYCR_MIIWR;824 825 data = FTMAC100_PHYWDATA_MIIWDATA(data);826 827 iowrite32(data, priv->base + FTMAC100_OFFSET_PHYWDATA);828 iowrite32(phycr, priv->base + FTMAC100_OFFSET_PHYCR);829 830 for (i = 0; i < 10; i++) {831 phycr = ioread32(priv->base + FTMAC100_OFFSET_PHYCR);832 833 if ((phycr & FTMAC100_PHYCR_MIIWR) == 0)834 return;835 836 udelay(100);837 }838 839 netdev_err(netdev, "mdio write timed out\n");840}841 842/******************************************************************************843 * struct ethtool_ops functions844 *****************************************************************************/845static void ftmac100_get_drvinfo(struct net_device *netdev,846 struct ethtool_drvinfo *info)847{848 strscpy(info->driver, DRV_NAME, sizeof(info->driver));849 strscpy(info->bus_info, dev_name(&netdev->dev), sizeof(info->bus_info));850}851 852static int ftmac100_get_link_ksettings(struct net_device *netdev,853 struct ethtool_link_ksettings *cmd)854{855 struct ftmac100 *priv = netdev_priv(netdev);856 857 mii_ethtool_get_link_ksettings(&priv->mii, cmd);858 859 return 0;860}861 862static int ftmac100_set_link_ksettings(struct net_device *netdev,863 const struct ethtool_link_ksettings *cmd)864{865 struct ftmac100 *priv = netdev_priv(netdev);866 return mii_ethtool_set_link_ksettings(&priv->mii, cmd);867}868 869static int ftmac100_nway_reset(struct net_device *netdev)870{871 struct ftmac100 *priv = netdev_priv(netdev);872 return mii_nway_restart(&priv->mii);873}874 875static u32 ftmac100_get_link(struct net_device *netdev)876{877 struct ftmac100 *priv = netdev_priv(netdev);878 return mii_link_ok(&priv->mii);879}880 881static const struct ethtool_ops ftmac100_ethtool_ops = {882 .get_drvinfo = ftmac100_get_drvinfo,883 .nway_reset = ftmac100_nway_reset,884 .get_link = ftmac100_get_link,885 .get_link_ksettings = ftmac100_get_link_ksettings,886 .set_link_ksettings = ftmac100_set_link_ksettings,887};888 889/******************************************************************************890 * interrupt handler891 *****************************************************************************/892static irqreturn_t ftmac100_interrupt(int irq, void *dev_id)893{894 struct net_device *netdev = dev_id;895 struct ftmac100 *priv = netdev_priv(netdev);896 897 /* Disable interrupts for polling */898 ftmac100_disable_all_int(priv);899 if (likely(netif_running(netdev)))900 napi_schedule(&priv->napi);901 902 return IRQ_HANDLED;903}904 905/******************************************************************************906 * struct napi_struct functions907 *****************************************************************************/908static int ftmac100_poll(struct napi_struct *napi, int budget)909{910 struct ftmac100 *priv = container_of(napi, struct ftmac100, napi);911 struct net_device *netdev = priv->netdev;912 unsigned int status;913 bool completed = true;914 int rx = 0;915 916 status = ioread32(priv->base + FTMAC100_OFFSET_ISR);917 918 if (status & (FTMAC100_INT_RPKT_FINISH | FTMAC100_INT_NORXBUF)) {919 /*920 * FTMAC100_INT_RPKT_FINISH:921 * RX DMA has received packets into RX buffer successfully922 *923 * FTMAC100_INT_NORXBUF:924 * RX buffer unavailable925 */926 bool retry;927 928 do {929 retry = ftmac100_rx_packet(priv, &rx);930 } while (retry && rx < budget);931 932 if (retry && rx == budget)933 completed = false;934 }935 936 if (status & (FTMAC100_INT_XPKT_OK | FTMAC100_INT_XPKT_LOST)) {937 /*938 * FTMAC100_INT_XPKT_OK:939 * packet transmitted to ethernet successfully940 *941 * FTMAC100_INT_XPKT_LOST:942 * packet transmitted to ethernet lost due to late943 * collision or excessive collision944 */945 ftmac100_tx_complete(priv);946 }947 948 if (status & (FTMAC100_INT_NORXBUF | FTMAC100_INT_RPKT_LOST |949 FTMAC100_INT_AHB_ERR | FTMAC100_INT_PHYSTS_CHG)) {950 if (net_ratelimit())951 netdev_info(netdev, "[ISR] = 0x%x: %s%s%s%s\n", status,952 status & FTMAC100_INT_NORXBUF ? "NORXBUF " : "",953 status & FTMAC100_INT_RPKT_LOST ? "RPKT_LOST " : "",954 status & FTMAC100_INT_AHB_ERR ? "AHB_ERR " : "",955 status & FTMAC100_INT_PHYSTS_CHG ? "PHYSTS_CHG" : "");956 957 if (status & FTMAC100_INT_NORXBUF) {958 /* RX buffer unavailable */959 netdev->stats.rx_over_errors++;960 }961 962 if (status & FTMAC100_INT_RPKT_LOST) {963 /* received packet lost due to RX FIFO full */964 netdev->stats.rx_fifo_errors++;965 }966 967 if (status & FTMAC100_INT_PHYSTS_CHG) {968 /* PHY link status change */969 mii_check_link(&priv->mii);970 }971 }972 973 if (completed) {974 /* stop polling */975 napi_complete(napi);976 ftmac100_enable_all_int(priv);977 }978 979 return rx;980}981 982/******************************************************************************983 * struct net_device_ops functions984 *****************************************************************************/985static int ftmac100_open(struct net_device *netdev)986{987 struct ftmac100 *priv = netdev_priv(netdev);988 int err;989 990 err = ftmac100_alloc_buffers(priv);991 if (err) {992 netdev_err(netdev, "failed to allocate buffers\n");993 goto err_alloc;994 }995 996 err = request_irq(priv->irq, ftmac100_interrupt, 0, netdev->name, netdev);997 if (err) {998 netdev_err(netdev, "failed to request irq %d\n", priv->irq);999 goto err_irq;1000 }1001 1002 priv->rx_pointer = 0;1003 priv->tx_clean_pointer = 0;1004 priv->tx_pointer = 0;1005 priv->tx_pending = 0;1006 1007 err = ftmac100_start_hw(priv);1008 if (err)1009 goto err_hw;1010 1011 napi_enable(&priv->napi);1012 netif_start_queue(netdev);1013 1014 ftmac100_enable_all_int(priv);1015 1016 return 0;1017 1018err_hw:1019 free_irq(priv->irq, netdev);1020err_irq:1021 ftmac100_free_buffers(priv);1022err_alloc:1023 return err;1024}1025 1026static int ftmac100_stop(struct net_device *netdev)1027{1028 struct ftmac100 *priv = netdev_priv(netdev);1029 1030 ftmac100_disable_all_int(priv);1031 netif_stop_queue(netdev);1032 napi_disable(&priv->napi);1033 ftmac100_stop_hw(priv);1034 free_irq(priv->irq, netdev);1035 ftmac100_free_buffers(priv);1036 1037 return 0;1038}1039 1040static netdev_tx_t1041ftmac100_hard_start_xmit(struct sk_buff *skb, struct net_device *netdev)1042{1043 struct ftmac100 *priv = netdev_priv(netdev);1044 dma_addr_t map;1045 1046 if (unlikely(skb->len > MAX_PKT_SIZE)) {1047 if (net_ratelimit())1048 netdev_dbg(netdev, "tx packet too big\n");1049 1050 netdev->stats.tx_dropped++;1051 dev_kfree_skb(skb);1052 return NETDEV_TX_OK;1053 }1054 1055 map = dma_map_single(priv->dev, skb->data, skb_headlen(skb), DMA_TO_DEVICE);1056 if (unlikely(dma_mapping_error(priv->dev, map))) {1057 /* drop packet */1058 if (net_ratelimit())1059 netdev_err(netdev, "map socket buffer failed\n");1060 1061 netdev->stats.tx_dropped++;1062 dev_kfree_skb(skb);1063 return NETDEV_TX_OK;1064 }1065 1066 return ftmac100_xmit(priv, skb, map);1067}1068 1069/* optional */1070static int ftmac100_do_ioctl(struct net_device *netdev, struct ifreq *ifr, int cmd)1071{1072 struct ftmac100 *priv = netdev_priv(netdev);1073 struct mii_ioctl_data *data = if_mii(ifr);1074 1075 return generic_mii_ioctl(&priv->mii, data, cmd, NULL);1076}1077 1078static int ftmac100_change_mtu(struct net_device *netdev, int mtu)1079{1080 struct ftmac100 *priv = netdev_priv(netdev);1081 unsigned int maccr;1082 1083 maccr = ioread32(priv->base + FTMAC100_OFFSET_MACCR);1084 if (mtu > ETH_DATA_LEN) {1085 /* process long packets in the driver */1086 maccr |= FTMAC100_MACCR_RX_FTL;1087 } else {1088 /* Let the controller drop incoming packets greater1089 * than 1518 (that is 1500 + 14 Ethernet + 4 FCS).1090 */1091 maccr &= ~FTMAC100_MACCR_RX_FTL;1092 }1093 iowrite32(maccr, priv->base + FTMAC100_OFFSET_MACCR);1094 1095 WRITE_ONCE(netdev->mtu, mtu);1096 1097 return 0;1098}1099 1100static void ftmac100_set_rx_mode(struct net_device *netdev)1101{1102 struct ftmac100 *priv = netdev_priv(netdev);1103 unsigned int maccr = ioread32(priv->base + FTMAC100_OFFSET_MACCR);1104 1105 ftmac100_set_rx_bits(priv, &maccr);1106 iowrite32(maccr, priv->base + FTMAC100_OFFSET_MACCR);1107}1108 1109static const struct net_device_ops ftmac100_netdev_ops = {1110 .ndo_open = ftmac100_open,1111 .ndo_stop = ftmac100_stop,1112 .ndo_start_xmit = ftmac100_hard_start_xmit,1113 .ndo_set_mac_address = eth_mac_addr,1114 .ndo_validate_addr = eth_validate_addr,1115 .ndo_eth_ioctl = ftmac100_do_ioctl,1116 .ndo_change_mtu = ftmac100_change_mtu,1117 .ndo_set_rx_mode = ftmac100_set_rx_mode,1118};1119 1120/******************************************************************************1121 * struct platform_driver functions1122 *****************************************************************************/1123static int ftmac100_probe(struct platform_device *pdev)1124{1125 struct resource *res;1126 int irq;1127 struct net_device *netdev;1128 struct ftmac100 *priv;1129 int err;1130 1131 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);1132 if (!res)1133 return -ENXIO;1134 1135 irq = platform_get_irq(pdev, 0);1136 if (irq < 0)1137 return irq;1138 1139 /* setup net_device */1140 netdev = alloc_etherdev(sizeof(*priv));1141 if (!netdev) {1142 err = -ENOMEM;1143 goto err_alloc_etherdev;1144 }1145 1146 SET_NETDEV_DEV(netdev, &pdev->dev);1147 netdev->ethtool_ops = &ftmac100_ethtool_ops;1148 netdev->netdev_ops = &ftmac100_netdev_ops;1149 netdev->max_mtu = MAX_PKT_SIZE - VLAN_ETH_HLEN;1150 1151 err = platform_get_ethdev_address(&pdev->dev, netdev);1152 if (err == -EPROBE_DEFER)1153 goto defer_get_mac;1154 1155 platform_set_drvdata(pdev, netdev);1156 1157 /* setup private data */1158 priv = netdev_priv(netdev);1159 priv->netdev = netdev;1160 priv->dev = &pdev->dev;1161 1162 spin_lock_init(&priv->tx_lock);1163 1164 /* initialize NAPI */1165 netif_napi_add(netdev, &priv->napi, ftmac100_poll);1166 1167 /* map io memory */1168 priv->res = request_mem_region(res->start, resource_size(res),1169 dev_name(&pdev->dev));1170 if (!priv->res) {1171 dev_err(&pdev->dev, "Could not reserve memory region\n");1172 err = -ENOMEM;1173 goto err_req_mem;1174 }1175 1176 priv->base = ioremap(res->start, resource_size(res));1177 if (!priv->base) {1178 dev_err(&pdev->dev, "Failed to ioremap ethernet registers\n");1179 err = -EIO;1180 goto err_ioremap;1181 }1182 1183 priv->irq = irq;1184 1185 /* initialize struct mii_if_info */1186 priv->mii.phy_id = 0;1187 priv->mii.phy_id_mask = 0x1f;1188 priv->mii.reg_num_mask = 0x1f;1189 priv->mii.dev = netdev;1190 priv->mii.mdio_read = ftmac100_mdio_read;1191 priv->mii.mdio_write = ftmac100_mdio_write;1192 1193 /* register network device */1194 err = register_netdev(netdev);1195 if (err) {1196 dev_err(&pdev->dev, "Failed to register netdev\n");1197 goto err_register_netdev;1198 }1199 1200 netdev_info(netdev, "irq %d, mapped at %p\n", priv->irq, priv->base);1201 1202 if (!is_valid_ether_addr(netdev->dev_addr)) {1203 eth_hw_addr_random(netdev);1204 netdev_info(netdev, "generated random MAC address %pM\n",1205 netdev->dev_addr);1206 }1207 1208 return 0;1209 1210err_register_netdev:1211 iounmap(priv->base);1212err_ioremap:1213 release_resource(priv->res);1214err_req_mem:1215 netif_napi_del(&priv->napi);1216defer_get_mac:1217 free_netdev(netdev);1218err_alloc_etherdev:1219 return err;1220}1221 1222static void ftmac100_remove(struct platform_device *pdev)1223{1224 struct net_device *netdev;1225 struct ftmac100 *priv;1226 1227 netdev = platform_get_drvdata(pdev);1228 priv = netdev_priv(netdev);1229 1230 unregister_netdev(netdev);1231 1232 iounmap(priv->base);1233 release_resource(priv->res);1234 1235 netif_napi_del(&priv->napi);1236 free_netdev(netdev);1237}1238 1239static const struct of_device_id ftmac100_of_ids[] = {1240 { .compatible = "andestech,atmac100" },1241 { }1242};1243 1244static struct platform_driver ftmac100_driver = {1245 .probe = ftmac100_probe,1246 .remove_new = ftmac100_remove,1247 .driver = {1248 .name = DRV_NAME,1249 .of_match_table = ftmac100_of_ids1250 },1251};1252 1253/******************************************************************************1254 * initialization / finalization1255 *****************************************************************************/1256module_platform_driver(ftmac100_driver);1257 1258MODULE_AUTHOR("Po-Yu Chuang <ratbert@faraday-tech.com>");1259MODULE_DESCRIPTION("FTMAC100 driver");1260MODULE_LICENSE("GPL");1261MODULE_DEVICE_TABLE(of, ftmac100_of_ids);1262