brintos

brintos / linux-shallow public Read only

0
0
Text · 32.1 KiB · 1047c80 Raw
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