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