xref: /openbmc/linux/drivers/net/ethernet/marvell/pxa168_eth.c (revision ecc23d0a422a3118fcf6e4f0a46e17a6c2047b02)
11ccea77eSThomas Gleixner // SPDX-License-Identifier: GPL-2.0-or-later
2527a6266SJeff Kirsher /*
3527a6266SJeff Kirsher  * PXA168 ethernet driver.
4527a6266SJeff Kirsher  * Most of the code is derived from mv643xx ethernet driver.
5527a6266SJeff Kirsher  *
6527a6266SJeff Kirsher  * Copyright (C) 2010 Marvell International Ltd.
7527a6266SJeff Kirsher  *		Sachin Sanap <ssanap@marvell.com>
8527a6266SJeff Kirsher  *		Zhangfei Gao <zgao6@marvell.com>
9527a6266SJeff Kirsher  *		Philip Rakity <prakity@marvell.com>
10527a6266SJeff Kirsher  *		Mark Brown <markb@marvell.com>
11527a6266SJeff Kirsher  */
12527a6266SJeff Kirsher 
13527a6266SJeff Kirsher #include <linux/bitops.h>
14527a6266SJeff Kirsher #include <linux/clk.h>
15307f6565SAntoine Ténart #include <linux/delay.h>
16307f6565SAntoine Ténart #include <linux/dma-mapping.h>
17307f6565SAntoine Ténart #include <linux/etherdevice.h>
18307f6565SAntoine Ténart #include <linux/ethtool.h>
19307f6565SAntoine Ténart #include <linux/in.h>
208decf868SDavid S. Miller #include <linux/interrupt.h>
21307f6565SAntoine Ténart #include <linux/io.h>
22307f6565SAntoine Ténart #include <linux/ip.h>
23307f6565SAntoine Ténart #include <linux/kernel.h>
24307f6565SAntoine Ténart #include <linux/module.h>
25307f6565SAntoine Ténart #include <linux/of.h>
2678b9b2c4SAntoine Ténart #include <linux/of_net.h>
27307f6565SAntoine Ténart #include <linux/phy.h>
28307f6565SAntoine Ténart #include <linux/platform_device.h>
29307f6565SAntoine Ténart #include <linux/pxa168_eth.h>
30307f6565SAntoine Ténart #include <linux/tcp.h>
31527a6266SJeff Kirsher #include <linux/types.h>
32307f6565SAntoine Ténart #include <linux/udp.h>
33307f6565SAntoine Ténart #include <linux/workqueue.h>
34ca5999fdSMike Rapoport #include <linux/pgtable.h>
3565fddcfcSMike Rapoport 
36527a6266SJeff Kirsher #include <asm/cacheflush.h>
37527a6266SJeff Kirsher 
38527a6266SJeff Kirsher #define DRIVER_NAME	"pxa168-eth"
39527a6266SJeff Kirsher #define DRIVER_VERSION	"0.3"
40527a6266SJeff Kirsher 
41527a6266SJeff Kirsher /*
42527a6266SJeff Kirsher  * Registers
43527a6266SJeff Kirsher  */
44527a6266SJeff Kirsher 
45527a6266SJeff Kirsher #define PHY_ADDRESS		0x0000
46527a6266SJeff Kirsher #define SMI			0x0010
47527a6266SJeff Kirsher #define PORT_CONFIG		0x0400
48527a6266SJeff Kirsher #define PORT_CONFIG_EXT		0x0408
49527a6266SJeff Kirsher #define PORT_COMMAND		0x0410
50527a6266SJeff Kirsher #define PORT_STATUS		0x0418
51527a6266SJeff Kirsher #define HTPR			0x0428
5239830689SAntoine Ténart #define MAC_ADDR_LOW		0x0430
5339830689SAntoine Ténart #define MAC_ADDR_HIGH		0x0438
54527a6266SJeff Kirsher #define SDMA_CONFIG		0x0440
55527a6266SJeff Kirsher #define SDMA_CMD		0x0448
56527a6266SJeff Kirsher #define INT_CAUSE		0x0450
57527a6266SJeff Kirsher #define INT_W_CLEAR		0x0454
58527a6266SJeff Kirsher #define INT_MASK		0x0458
59527a6266SJeff Kirsher #define ETH_F_RX_DESC_0		0x0480
60527a6266SJeff Kirsher #define ETH_C_RX_DESC_0		0x04A0
61527a6266SJeff Kirsher #define ETH_C_TX_DESC_1		0x04E4
62527a6266SJeff Kirsher 
63527a6266SJeff Kirsher /* smi register */
64527a6266SJeff Kirsher #define SMI_BUSY		(1 << 28)	/* 0 - Write, 1 - Read  */
65527a6266SJeff Kirsher #define SMI_R_VALID		(1 << 27)	/* 0 - Write, 1 - Read  */
66527a6266SJeff Kirsher #define SMI_OP_W		(0 << 26)	/* Write operation      */
67527a6266SJeff Kirsher #define SMI_OP_R		(1 << 26)	/* Read operation */
68527a6266SJeff Kirsher 
69527a6266SJeff Kirsher #define PHY_WAIT_ITERATIONS	10
70527a6266SJeff Kirsher 
71527a6266SJeff Kirsher #define PXA168_ETH_PHY_ADDR_DEFAULT	0
72527a6266SJeff Kirsher /* RX & TX descriptor command */
73527a6266SJeff Kirsher #define BUF_OWNED_BY_DMA	(1 << 31)
74527a6266SJeff Kirsher 
75527a6266SJeff Kirsher /* RX descriptor status */
76527a6266SJeff Kirsher #define RX_EN_INT		(1 << 23)
77527a6266SJeff Kirsher #define RX_FIRST_DESC		(1 << 17)
78527a6266SJeff Kirsher #define RX_LAST_DESC		(1 << 16)
79527a6266SJeff Kirsher #define RX_ERROR		(1 << 15)
80527a6266SJeff Kirsher 
81527a6266SJeff Kirsher /* TX descriptor command */
82527a6266SJeff Kirsher #define TX_EN_INT		(1 << 23)
83527a6266SJeff Kirsher #define TX_GEN_CRC		(1 << 22)
84527a6266SJeff Kirsher #define TX_ZERO_PADDING		(1 << 18)
85527a6266SJeff Kirsher #define TX_FIRST_DESC		(1 << 17)
86527a6266SJeff Kirsher #define TX_LAST_DESC		(1 << 16)
87527a6266SJeff Kirsher #define TX_ERROR		(1 << 15)
88527a6266SJeff Kirsher 
89527a6266SJeff Kirsher /* SDMA_CMD */
90527a6266SJeff Kirsher #define SDMA_CMD_AT		(1 << 31)
91527a6266SJeff Kirsher #define SDMA_CMD_TXDL		(1 << 24)
92527a6266SJeff Kirsher #define SDMA_CMD_TXDH		(1 << 23)
93527a6266SJeff Kirsher #define SDMA_CMD_AR		(1 << 15)
94527a6266SJeff Kirsher #define SDMA_CMD_ERD		(1 << 7)
95527a6266SJeff Kirsher 
96527a6266SJeff Kirsher /* Bit definitions of the Port Config Reg */
971a149132SSebastian Hesselbarth #define PCR_DUPLEX_FULL		(1 << 15)
98527a6266SJeff Kirsher #define PCR_HS			(1 << 12)
99527a6266SJeff Kirsher #define PCR_EN			(1 << 7)
100527a6266SJeff Kirsher #define PCR_PM			(1 << 0)
101527a6266SJeff Kirsher 
102527a6266SJeff Kirsher /* Bit definitions of the Port Config Extend Reg */
103527a6266SJeff Kirsher #define PCXR_2BSM		(1 << 28)
104527a6266SJeff Kirsher #define PCXR_DSCP_EN		(1 << 21)
1051a149132SSebastian Hesselbarth #define PCXR_RMII_EN		(1 << 20)
1061a149132SSebastian Hesselbarth #define PCXR_AN_SPEED_DIS	(1 << 19)
1071a149132SSebastian Hesselbarth #define PCXR_SPEED_100		(1 << 18)
108527a6266SJeff Kirsher #define PCXR_MFL_1518		(0 << 14)
109527a6266SJeff Kirsher #define PCXR_MFL_1536		(1 << 14)
110527a6266SJeff Kirsher #define PCXR_MFL_2048		(2 << 14)
111527a6266SJeff Kirsher #define PCXR_MFL_64K		(3 << 14)
1121a149132SSebastian Hesselbarth #define PCXR_FLOWCTL_DIS	(1 << 12)
113527a6266SJeff Kirsher #define PCXR_FLP		(1 << 11)
1141a149132SSebastian Hesselbarth #define PCXR_AN_FLOWCTL_DIS	(1 << 10)
1151a149132SSebastian Hesselbarth #define PCXR_AN_DUPLEX_DIS	(1 << 9)
116527a6266SJeff Kirsher #define PCXR_PRIO_TX_OFF	3
117527a6266SJeff Kirsher #define PCXR_TX_HIGH_PRI	(7 << PCXR_PRIO_TX_OFF)
118527a6266SJeff Kirsher 
119527a6266SJeff Kirsher /* Bit definitions of the SDMA Config Reg */
120527a6266SJeff Kirsher #define SDCR_BSZ_OFF		12
121527a6266SJeff Kirsher #define SDCR_BSZ8		(3 << SDCR_BSZ_OFF)
122527a6266SJeff Kirsher #define SDCR_BSZ4		(2 << SDCR_BSZ_OFF)
123527a6266SJeff Kirsher #define SDCR_BSZ2		(1 << SDCR_BSZ_OFF)
124527a6266SJeff Kirsher #define SDCR_BSZ1		(0 << SDCR_BSZ_OFF)
125527a6266SJeff Kirsher #define SDCR_BLMR		(1 << 6)
126527a6266SJeff Kirsher #define SDCR_BLMT		(1 << 7)
127527a6266SJeff Kirsher #define SDCR_RIFB		(1 << 9)
128527a6266SJeff Kirsher #define SDCR_RC_OFF		2
129527a6266SJeff Kirsher #define SDCR_RC_MAX_RETRANS	(0xf << SDCR_RC_OFF)
130527a6266SJeff Kirsher 
131527a6266SJeff Kirsher /*
132527a6266SJeff Kirsher  * Bit definitions of the Interrupt Cause Reg
133527a6266SJeff Kirsher  * and Interrupt MASK Reg is the same
134527a6266SJeff Kirsher  */
135527a6266SJeff Kirsher #define ICR_RXBUF		(1 << 0)
136527a6266SJeff Kirsher #define ICR_TXBUF_H		(1 << 2)
137527a6266SJeff Kirsher #define ICR_TXBUF_L		(1 << 3)
138527a6266SJeff Kirsher #define ICR_TXEND_H		(1 << 6)
139527a6266SJeff Kirsher #define ICR_TXEND_L		(1 << 7)
140527a6266SJeff Kirsher #define ICR_RXERR		(1 << 8)
141527a6266SJeff Kirsher #define ICR_TXERR_H		(1 << 10)
142527a6266SJeff Kirsher #define ICR_TXERR_L		(1 << 11)
143527a6266SJeff Kirsher #define ICR_TX_UDR		(1 << 13)
144527a6266SJeff Kirsher #define ICR_MII_CH		(1 << 28)
145527a6266SJeff Kirsher 
146527a6266SJeff Kirsher #define ALL_INTS (ICR_TXBUF_H  | ICR_TXBUF_L  | ICR_TX_UDR |\
147527a6266SJeff Kirsher 				ICR_TXERR_H  | ICR_TXERR_L |\
148527a6266SJeff Kirsher 				ICR_TXEND_H  | ICR_TXEND_L |\
149527a6266SJeff Kirsher 				ICR_RXBUF | ICR_RXERR  | ICR_MII_CH)
150527a6266SJeff Kirsher 
151527a6266SJeff Kirsher #define ETH_HW_IP_ALIGN		2	/* hw aligns IP header */
152527a6266SJeff Kirsher 
153527a6266SJeff Kirsher #define NUM_RX_DESCS		64
154527a6266SJeff Kirsher #define NUM_TX_DESCS		64
155527a6266SJeff Kirsher 
156527a6266SJeff Kirsher #define HASH_ADD		0
157527a6266SJeff Kirsher #define HASH_DELETE		1
158527a6266SJeff Kirsher #define HASH_ADDR_TABLE_SIZE	0x4000	/* 16K (1/2K address - PCR_HS == 1) */
159527a6266SJeff Kirsher #define HOP_NUMBER		12
160527a6266SJeff Kirsher 
161527a6266SJeff Kirsher /* Bit definitions for Port status */
162527a6266SJeff Kirsher #define PORT_SPEED_100		(1 << 0)
163527a6266SJeff Kirsher #define FULL_DUPLEX		(1 << 1)
16409f5da1bSAntoine Ténart #define FLOW_CONTROL_DISABLED	(1 << 2)
165527a6266SJeff Kirsher #define LINK_UP			(1 << 3)
166527a6266SJeff Kirsher 
167527a6266SJeff Kirsher /* Bit definitions for work to be done */
168527a6266SJeff Kirsher #define WORK_TX_DONE		(1 << 1)
169527a6266SJeff Kirsher 
170527a6266SJeff Kirsher /*
171527a6266SJeff Kirsher  * Misc definitions.
172527a6266SJeff Kirsher  */
173527a6266SJeff Kirsher #define SKB_DMA_REALIGN		((PAGE_SIZE - NET_SKB_PAD) % SMP_CACHE_BYTES)
174527a6266SJeff Kirsher 
175527a6266SJeff Kirsher struct rx_desc {
176527a6266SJeff Kirsher 	u32 cmd_sts;		/* Descriptor command status            */
177527a6266SJeff Kirsher 	u16 byte_cnt;		/* Descriptor buffer byte count         */
178527a6266SJeff Kirsher 	u16 buf_size;		/* Buffer size                          */
179527a6266SJeff Kirsher 	u32 buf_ptr;		/* Descriptor buffer pointer            */
180527a6266SJeff Kirsher 	u32 next_desc_ptr;	/* Next descriptor pointer              */
181527a6266SJeff Kirsher };
182527a6266SJeff Kirsher 
183527a6266SJeff Kirsher struct tx_desc {
184527a6266SJeff Kirsher 	u32 cmd_sts;		/* Command/status field                 */
185527a6266SJeff Kirsher 	u16 reserved;
186527a6266SJeff Kirsher 	u16 byte_cnt;		/* buffer byte count                    */
187527a6266SJeff Kirsher 	u32 buf_ptr;		/* pointer to buffer for this descriptor */
188527a6266SJeff Kirsher 	u32 next_desc_ptr;	/* Pointer to next descriptor           */
189527a6266SJeff Kirsher };
190527a6266SJeff Kirsher 
191527a6266SJeff Kirsher struct pxa168_eth_private {
192e86b76f6SChristoph Hellwig 	struct platform_device *pdev;
193527a6266SJeff Kirsher 	int port_num;		/* User Ethernet port number    */
19443d3ddf8SAntoine Ténart 	int phy_addr;
1959d8ea73dSSebastian Hesselbarth 	int phy_speed;
1969d8ea73dSSebastian Hesselbarth 	int phy_duplex;
1979d8ea73dSSebastian Hesselbarth 	phy_interface_t phy_intf;
198527a6266SJeff Kirsher 
199527a6266SJeff Kirsher 	int rx_resource_err;	/* Rx ring resource error flag */
200527a6266SJeff Kirsher 
201527a6266SJeff Kirsher 	/* Next available and first returning Rx resource */
202527a6266SJeff Kirsher 	int rx_curr_desc_q, rx_used_desc_q;
203527a6266SJeff Kirsher 
204527a6266SJeff Kirsher 	/* Next available and first returning Tx resource */
205527a6266SJeff Kirsher 	int tx_curr_desc_q, tx_used_desc_q;
206527a6266SJeff Kirsher 
207527a6266SJeff Kirsher 	struct rx_desc *p_rx_desc_area;
208527a6266SJeff Kirsher 	dma_addr_t rx_desc_dma;
209527a6266SJeff Kirsher 	int rx_desc_area_size;
210527a6266SJeff Kirsher 	struct sk_buff **rx_skb;
211527a6266SJeff Kirsher 
212527a6266SJeff Kirsher 	struct tx_desc *p_tx_desc_area;
213527a6266SJeff Kirsher 	dma_addr_t tx_desc_dma;
214527a6266SJeff Kirsher 	int tx_desc_area_size;
215527a6266SJeff Kirsher 	struct sk_buff **tx_skb;
216527a6266SJeff Kirsher 
217527a6266SJeff Kirsher 	struct work_struct tx_timeout_task;
218527a6266SJeff Kirsher 
219527a6266SJeff Kirsher 	struct net_device *dev;
220527a6266SJeff Kirsher 	struct napi_struct napi;
221527a6266SJeff Kirsher 	u8 work_todo;
222527a6266SJeff Kirsher 	int skb_size;
223527a6266SJeff Kirsher 
224527a6266SJeff Kirsher 	/* Size of Tx Ring per queue */
225527a6266SJeff Kirsher 	int tx_ring_size;
226527a6266SJeff Kirsher 	/* Number of tx descriptors in use */
227527a6266SJeff Kirsher 	int tx_desc_count;
228527a6266SJeff Kirsher 	/* Size of Rx Ring per queue */
229527a6266SJeff Kirsher 	int rx_ring_size;
230527a6266SJeff Kirsher 	/* Number of rx descriptors in use */
231527a6266SJeff Kirsher 	int rx_desc_count;
232527a6266SJeff Kirsher 
233527a6266SJeff Kirsher 	/*
234527a6266SJeff Kirsher 	 * Used in case RX Ring is empty, which can occur when
235527a6266SJeff Kirsher 	 * system does not have resources (skb's)
236527a6266SJeff Kirsher 	 */
237527a6266SJeff Kirsher 	struct timer_list timeout;
238527a6266SJeff Kirsher 	struct mii_bus *smi_bus;
239527a6266SJeff Kirsher 
240527a6266SJeff Kirsher 	/* clock */
241527a6266SJeff Kirsher 	struct clk *clk;
242527a6266SJeff Kirsher 	struct pxa168_eth_platform_data *pd;
243527a6266SJeff Kirsher 	/*
244527a6266SJeff Kirsher 	 * Ethernet controller base address.
245527a6266SJeff Kirsher 	 */
246527a6266SJeff Kirsher 	void __iomem *base;
247527a6266SJeff Kirsher 
248527a6266SJeff Kirsher 	/* Pointer to the hardware address filter table */
249527a6266SJeff Kirsher 	void *htpr;
250527a6266SJeff Kirsher 	dma_addr_t htpr_dma;
251527a6266SJeff Kirsher };
252527a6266SJeff Kirsher 
253527a6266SJeff Kirsher struct addr_table_entry {
254527a6266SJeff Kirsher 	__le32 lo;
255527a6266SJeff Kirsher 	__le32 hi;
256527a6266SJeff Kirsher };
257527a6266SJeff Kirsher 
258527a6266SJeff Kirsher /* Bit fields of a Hash Table Entry */
259527a6266SJeff Kirsher enum hash_table_entry {
260527a6266SJeff Kirsher 	HASH_ENTRY_VALID = 1,
261527a6266SJeff Kirsher 	SKIP = 2,
262527a6266SJeff Kirsher 	HASH_ENTRY_RECEIVE_DISCARD = 4,
263527a6266SJeff Kirsher 	HASH_ENTRY_RECEIVE_DISCARD_BIT = 2
264527a6266SJeff Kirsher };
265527a6266SJeff Kirsher 
266527a6266SJeff Kirsher static int pxa168_init_hw(struct pxa168_eth_private *pep);
2671a149132SSebastian Hesselbarth static int pxa168_init_phy(struct net_device *dev);
268527a6266SJeff Kirsher static void eth_port_reset(struct net_device *dev);
269527a6266SJeff Kirsher static void eth_port_start(struct net_device *dev);
270527a6266SJeff Kirsher static int pxa168_eth_open(struct net_device *dev);
271527a6266SJeff Kirsher static int pxa168_eth_stop(struct net_device *dev);
272527a6266SJeff Kirsher 
rdl(struct pxa168_eth_private * pep,int offset)273527a6266SJeff Kirsher static inline u32 rdl(struct pxa168_eth_private *pep, int offset)
274527a6266SJeff Kirsher {
2753ed68782SJisheng Zhang 	return readl_relaxed(pep->base + offset);
276527a6266SJeff Kirsher }
277527a6266SJeff Kirsher 
wrl(struct pxa168_eth_private * pep,int offset,u32 data)278527a6266SJeff Kirsher static inline void wrl(struct pxa168_eth_private *pep, int offset, u32 data)
279527a6266SJeff Kirsher {
2803ed68782SJisheng Zhang 	writel_relaxed(data, pep->base + offset);
281527a6266SJeff Kirsher }
282527a6266SJeff Kirsher 
abort_dma(struct pxa168_eth_private * pep)283527a6266SJeff Kirsher static void abort_dma(struct pxa168_eth_private *pep)
284527a6266SJeff Kirsher {
285527a6266SJeff Kirsher 	int delay;
286527a6266SJeff Kirsher 	int max_retries = 40;
287527a6266SJeff Kirsher 
288527a6266SJeff Kirsher 	do {
289527a6266SJeff Kirsher 		wrl(pep, SDMA_CMD, SDMA_CMD_AR | SDMA_CMD_AT);
290527a6266SJeff Kirsher 		udelay(100);
291527a6266SJeff Kirsher 
292527a6266SJeff Kirsher 		delay = 10;
293527a6266SJeff Kirsher 		while ((rdl(pep, SDMA_CMD) & (SDMA_CMD_AR | SDMA_CMD_AT))
294527a6266SJeff Kirsher 		       && delay-- > 0) {
295527a6266SJeff Kirsher 			udelay(10);
296527a6266SJeff Kirsher 		}
297527a6266SJeff Kirsher 	} while (max_retries-- > 0 && delay <= 0);
298527a6266SJeff Kirsher 
299527a6266SJeff Kirsher 	if (max_retries <= 0)
300307f6565SAntoine Ténart 		netdev_err(pep->dev, "%s : DMA Stuck\n", __func__);
301527a6266SJeff Kirsher }
302527a6266SJeff Kirsher 
rxq_refill(struct net_device * dev)303527a6266SJeff Kirsher static void rxq_refill(struct net_device *dev)
304527a6266SJeff Kirsher {
305527a6266SJeff Kirsher 	struct pxa168_eth_private *pep = netdev_priv(dev);
306527a6266SJeff Kirsher 	struct sk_buff *skb;
307527a6266SJeff Kirsher 	struct rx_desc *p_used_rx_desc;
308527a6266SJeff Kirsher 	int used_rx_desc;
309527a6266SJeff Kirsher 
310527a6266SJeff Kirsher 	while (pep->rx_desc_count < pep->rx_ring_size) {
311527a6266SJeff Kirsher 		int size;
312527a6266SJeff Kirsher 
313c056b734SPradeep A Dalvi 		skb = netdev_alloc_skb(dev, pep->skb_size);
314527a6266SJeff Kirsher 		if (!skb)
315527a6266SJeff Kirsher 			break;
316527a6266SJeff Kirsher 		if (SKB_DMA_REALIGN)
317527a6266SJeff Kirsher 			skb_reserve(skb, SKB_DMA_REALIGN);
318527a6266SJeff Kirsher 		pep->rx_desc_count++;
319527a6266SJeff Kirsher 		/* Get 'used' Rx descriptor */
320527a6266SJeff Kirsher 		used_rx_desc = pep->rx_used_desc_q;
321527a6266SJeff Kirsher 		p_used_rx_desc = &pep->p_rx_desc_area[used_rx_desc];
322511efbbbSIsaku Yamahata 		size = skb_end_pointer(skb) - skb->data;
323e86b76f6SChristoph Hellwig 		p_used_rx_desc->buf_ptr = dma_map_single(&pep->pdev->dev,
324527a6266SJeff Kirsher 							 skb->data,
325527a6266SJeff Kirsher 							 size,
326527a6266SJeff Kirsher 							 DMA_FROM_DEVICE);
327527a6266SJeff Kirsher 		p_used_rx_desc->buf_size = size;
328527a6266SJeff Kirsher 		pep->rx_skb[used_rx_desc] = skb;
329527a6266SJeff Kirsher 
330527a6266SJeff Kirsher 		/* Return the descriptor to DMA ownership */
331b17d1559SJisheng Zhang 		dma_wmb();
332527a6266SJeff Kirsher 		p_used_rx_desc->cmd_sts = BUF_OWNED_BY_DMA | RX_EN_INT;
333b17d1559SJisheng Zhang 		dma_wmb();
334527a6266SJeff Kirsher 
335527a6266SJeff Kirsher 		/* Move the used descriptor pointer to the next descriptor */
336527a6266SJeff Kirsher 		pep->rx_used_desc_q = (used_rx_desc + 1) % pep->rx_ring_size;
337527a6266SJeff Kirsher 
338527a6266SJeff Kirsher 		/* Any Rx return cancels the Rx resource error status */
339527a6266SJeff Kirsher 		pep->rx_resource_err = 0;
340527a6266SJeff Kirsher 
341527a6266SJeff Kirsher 		skb_reserve(skb, ETH_HW_IP_ALIGN);
342527a6266SJeff Kirsher 	}
343527a6266SJeff Kirsher 
344527a6266SJeff Kirsher 	/*
345527a6266SJeff Kirsher 	 * If RX ring is empty of SKB, set a timer to try allocating
346527a6266SJeff Kirsher 	 * again at a later time.
347527a6266SJeff Kirsher 	 */
348527a6266SJeff Kirsher 	if (pep->rx_desc_count == 0) {
349527a6266SJeff Kirsher 		pep->timeout.expires = jiffies + (HZ / 10);
350527a6266SJeff Kirsher 		add_timer(&pep->timeout);
351527a6266SJeff Kirsher 	}
352527a6266SJeff Kirsher }
353527a6266SJeff Kirsher 
rxq_refill_timer_wrapper(struct timer_list * t)354e99e88a9SKees Cook static inline void rxq_refill_timer_wrapper(struct timer_list *t)
355527a6266SJeff Kirsher {
356e99e88a9SKees Cook 	struct pxa168_eth_private *pep = from_timer(pep, t, timeout);
357527a6266SJeff Kirsher 	napi_schedule(&pep->napi);
358527a6266SJeff Kirsher }
359527a6266SJeff Kirsher 
flip_8_bits(u8 x)360527a6266SJeff Kirsher static inline u8 flip_8_bits(u8 x)
361527a6266SJeff Kirsher {
362527a6266SJeff Kirsher 	return (((x) & 0x01) << 3) | (((x) & 0x02) << 1)
363527a6266SJeff Kirsher 	    | (((x) & 0x04) >> 1) | (((x) & 0x08) >> 3)
364527a6266SJeff Kirsher 	    | (((x) & 0x10) << 3) | (((x) & 0x20) << 1)
365527a6266SJeff Kirsher 	    | (((x) & 0x40) >> 1) | (((x) & 0x80) >> 3);
366527a6266SJeff Kirsher }
367527a6266SJeff Kirsher 
nibble_swap_every_byte(unsigned char * mac_addr)368527a6266SJeff Kirsher static void nibble_swap_every_byte(unsigned char *mac_addr)
369527a6266SJeff Kirsher {
370527a6266SJeff Kirsher 	int i;
371527a6266SJeff Kirsher 	for (i = 0; i < ETH_ALEN; i++) {
372527a6266SJeff Kirsher 		mac_addr[i] = ((mac_addr[i] & 0x0f) << 4) |
373527a6266SJeff Kirsher 				((mac_addr[i] & 0xf0) >> 4);
374527a6266SJeff Kirsher 	}
375527a6266SJeff Kirsher }
376527a6266SJeff Kirsher 
inverse_every_nibble(unsigned char * mac_addr)377527a6266SJeff Kirsher static void inverse_every_nibble(unsigned char *mac_addr)
378527a6266SJeff Kirsher {
379527a6266SJeff Kirsher 	int i;
380527a6266SJeff Kirsher 	for (i = 0; i < ETH_ALEN; i++)
381527a6266SJeff Kirsher 		mac_addr[i] = flip_8_bits(mac_addr[i]);
382527a6266SJeff Kirsher }
383527a6266SJeff Kirsher 
384527a6266SJeff Kirsher /*
385527a6266SJeff Kirsher  * ----------------------------------------------------------------------------
386527a6266SJeff Kirsher  * This function will calculate the hash function of the address.
387527a6266SJeff Kirsher  * Inputs
388527a6266SJeff Kirsher  * mac_addr_orig    - MAC address.
389527a6266SJeff Kirsher  * Outputs
390527a6266SJeff Kirsher  * return the calculated entry.
391527a6266SJeff Kirsher  */
hash_function(const unsigned char * mac_addr_orig)39276660757SJakub Kicinski static u32 hash_function(const unsigned char *mac_addr_orig)
393527a6266SJeff Kirsher {
394527a6266SJeff Kirsher 	u32 hash_result;
395527a6266SJeff Kirsher 	u32 addr0;
396527a6266SJeff Kirsher 	u32 addr1;
397527a6266SJeff Kirsher 	u32 addr2;
398527a6266SJeff Kirsher 	u32 addr3;
399527a6266SJeff Kirsher 	unsigned char mac_addr[ETH_ALEN];
400527a6266SJeff Kirsher 
401527a6266SJeff Kirsher 	/* Make a copy of MAC address since we are going to performe bit
402527a6266SJeff Kirsher 	 * operations on it
403527a6266SJeff Kirsher 	 */
404527a6266SJeff Kirsher 	memcpy(mac_addr, mac_addr_orig, ETH_ALEN);
405527a6266SJeff Kirsher 
406527a6266SJeff Kirsher 	nibble_swap_every_byte(mac_addr);
407527a6266SJeff Kirsher 	inverse_every_nibble(mac_addr);
408527a6266SJeff Kirsher 
409527a6266SJeff Kirsher 	addr0 = (mac_addr[5] >> 2) & 0x3f;
410527a6266SJeff Kirsher 	addr1 = (mac_addr[5] & 0x03) | (((mac_addr[4] & 0x7f)) << 2);
411527a6266SJeff Kirsher 	addr2 = ((mac_addr[4] & 0x80) >> 7) | mac_addr[3] << 1;
412527a6266SJeff Kirsher 	addr3 = (mac_addr[2] & 0xff) | ((mac_addr[1] & 1) << 8);
413527a6266SJeff Kirsher 
414527a6266SJeff Kirsher 	hash_result = (addr0 << 9) | (addr1 ^ addr2 ^ addr3);
415527a6266SJeff Kirsher 	hash_result = hash_result & 0x07ff;
416527a6266SJeff Kirsher 	return hash_result;
417527a6266SJeff Kirsher }
418527a6266SJeff Kirsher 
419527a6266SJeff Kirsher /*
420527a6266SJeff Kirsher  * ----------------------------------------------------------------------------
421527a6266SJeff Kirsher  * This function will add/del an entry to the address table.
422527a6266SJeff Kirsher  * Inputs
423527a6266SJeff Kirsher  * pep - ETHERNET .
424527a6266SJeff Kirsher  * mac_addr - MAC address.
425527a6266SJeff Kirsher  * skip - if 1, skip this address.Used in case of deleting an entry which is a
426527a6266SJeff Kirsher  *	  part of chain in the hash table.We can't just delete the entry since
427527a6266SJeff Kirsher  *	  that will break the chain.We need to defragment the tables time to
428527a6266SJeff Kirsher  *	  time.
429527a6266SJeff Kirsher  * rd   - 0 Discard packet upon match.
430527a6266SJeff Kirsher  *	- 1 Receive packet upon match.
431527a6266SJeff Kirsher  * Outputs
432527a6266SJeff Kirsher  * address table entry is added/deleted.
433527a6266SJeff Kirsher  * 0 if success.
434527a6266SJeff Kirsher  * -ENOSPC if table full
435527a6266SJeff Kirsher  */
add_del_hash_entry(struct pxa168_eth_private * pep,const unsigned char * mac_addr,u32 rd,u32 skip,int del)436527a6266SJeff Kirsher static int add_del_hash_entry(struct pxa168_eth_private *pep,
43776660757SJakub Kicinski 			      const unsigned char *mac_addr,
438527a6266SJeff Kirsher 			      u32 rd, u32 skip, int del)
439527a6266SJeff Kirsher {
440527a6266SJeff Kirsher 	struct addr_table_entry *entry, *start;
441527a6266SJeff Kirsher 	u32 new_high;
442527a6266SJeff Kirsher 	u32 new_low;
443527a6266SJeff Kirsher 	u32 i;
444527a6266SJeff Kirsher 
445527a6266SJeff Kirsher 	new_low = (((mac_addr[1] >> 4) & 0xf) << 15)
446527a6266SJeff Kirsher 	    | (((mac_addr[1] >> 0) & 0xf) << 11)
447527a6266SJeff Kirsher 	    | (((mac_addr[0] >> 4) & 0xf) << 7)
448527a6266SJeff Kirsher 	    | (((mac_addr[0] >> 0) & 0xf) << 3)
449527a6266SJeff Kirsher 	    | (((mac_addr[3] >> 4) & 0x1) << 31)
450527a6266SJeff Kirsher 	    | (((mac_addr[3] >> 0) & 0xf) << 27)
451527a6266SJeff Kirsher 	    | (((mac_addr[2] >> 4) & 0xf) << 23)
452527a6266SJeff Kirsher 	    | (((mac_addr[2] >> 0) & 0xf) << 19)
453527a6266SJeff Kirsher 	    | (skip << SKIP) | (rd << HASH_ENTRY_RECEIVE_DISCARD_BIT)
454527a6266SJeff Kirsher 	    | HASH_ENTRY_VALID;
455527a6266SJeff Kirsher 
456527a6266SJeff Kirsher 	new_high = (((mac_addr[5] >> 4) & 0xf) << 15)
457527a6266SJeff Kirsher 	    | (((mac_addr[5] >> 0) & 0xf) << 11)
458527a6266SJeff Kirsher 	    | (((mac_addr[4] >> 4) & 0xf) << 7)
459527a6266SJeff Kirsher 	    | (((mac_addr[4] >> 0) & 0xf) << 3)
460527a6266SJeff Kirsher 	    | (((mac_addr[3] >> 5) & 0x7) << 0);
461527a6266SJeff Kirsher 
462527a6266SJeff Kirsher 	/*
463527a6266SJeff Kirsher 	 * Pick the appropriate table, start scanning for free/reusable
464527a6266SJeff Kirsher 	 * entries at the index obtained by hashing the specified MAC address
465527a6266SJeff Kirsher 	 */
466527a6266SJeff Kirsher 	start = pep->htpr;
467527a6266SJeff Kirsher 	entry = start + hash_function(mac_addr);
468527a6266SJeff Kirsher 	for (i = 0; i < HOP_NUMBER; i++) {
469527a6266SJeff Kirsher 		if (!(le32_to_cpu(entry->lo) & HASH_ENTRY_VALID)) {
470527a6266SJeff Kirsher 			break;
471527a6266SJeff Kirsher 		} else {
472527a6266SJeff Kirsher 			/* if same address put in same position */
473527a6266SJeff Kirsher 			if (((le32_to_cpu(entry->lo) & 0xfffffff8) ==
474527a6266SJeff Kirsher 				(new_low & 0xfffffff8)) &&
475527a6266SJeff Kirsher 				(le32_to_cpu(entry->hi) == new_high)) {
476527a6266SJeff Kirsher 				break;
477527a6266SJeff Kirsher 			}
478527a6266SJeff Kirsher 		}
479527a6266SJeff Kirsher 		if (entry == start + 0x7ff)
480527a6266SJeff Kirsher 			entry = start;
481527a6266SJeff Kirsher 		else
482527a6266SJeff Kirsher 			entry++;
483527a6266SJeff Kirsher 	}
484527a6266SJeff Kirsher 
485527a6266SJeff Kirsher 	if (((le32_to_cpu(entry->lo) & 0xfffffff8) != (new_low & 0xfffffff8)) &&
486527a6266SJeff Kirsher 	    (le32_to_cpu(entry->hi) != new_high) && del)
487527a6266SJeff Kirsher 		return 0;
488527a6266SJeff Kirsher 
489527a6266SJeff Kirsher 	if (i == HOP_NUMBER) {
490527a6266SJeff Kirsher 		if (!del) {
491307f6565SAntoine Ténart 			netdev_info(pep->dev,
492307f6565SAntoine Ténart 				    "%s: table section is full, need to "
493527a6266SJeff Kirsher 				    "move to 16kB implementation?\n",
494527a6266SJeff Kirsher 				    __FILE__);
495527a6266SJeff Kirsher 			return -ENOSPC;
496527a6266SJeff Kirsher 		} else
497527a6266SJeff Kirsher 			return 0;
498527a6266SJeff Kirsher 	}
499527a6266SJeff Kirsher 
500527a6266SJeff Kirsher 	/*
501527a6266SJeff Kirsher 	 * Update the selected entry
502527a6266SJeff Kirsher 	 */
503527a6266SJeff Kirsher 	if (del) {
504527a6266SJeff Kirsher 		entry->hi = 0;
505527a6266SJeff Kirsher 		entry->lo = 0;
506527a6266SJeff Kirsher 	} else {
507527a6266SJeff Kirsher 		entry->hi = cpu_to_le32(new_high);
508527a6266SJeff Kirsher 		entry->lo = cpu_to_le32(new_low);
509527a6266SJeff Kirsher 	}
510527a6266SJeff Kirsher 
511527a6266SJeff Kirsher 	return 0;
512527a6266SJeff Kirsher }
513527a6266SJeff Kirsher 
514527a6266SJeff Kirsher /*
515527a6266SJeff Kirsher  * ----------------------------------------------------------------------------
516527a6266SJeff Kirsher  *  Create an addressTable entry from MAC address info
517527a6266SJeff Kirsher  *  found in the specifed net_device struct
518527a6266SJeff Kirsher  *
519527a6266SJeff Kirsher  *  Input : pointer to ethernet interface network device structure
520527a6266SJeff Kirsher  *  Output : N/A
521527a6266SJeff Kirsher  */
update_hash_table_mac_address(struct pxa168_eth_private * pep,unsigned char * oaddr,const unsigned char * addr)522527a6266SJeff Kirsher static void update_hash_table_mac_address(struct pxa168_eth_private *pep,
523527a6266SJeff Kirsher 					  unsigned char *oaddr,
52476660757SJakub Kicinski 					  const unsigned char *addr)
525527a6266SJeff Kirsher {
526527a6266SJeff Kirsher 	/* Delete old entry */
527527a6266SJeff Kirsher 	if (oaddr)
528527a6266SJeff Kirsher 		add_del_hash_entry(pep, oaddr, 1, 0, HASH_DELETE);
529527a6266SJeff Kirsher 	/* Add new entry */
530527a6266SJeff Kirsher 	add_del_hash_entry(pep, addr, 1, 0, HASH_ADD);
531527a6266SJeff Kirsher }
532527a6266SJeff Kirsher 
init_hash_table(struct pxa168_eth_private * pep)533527a6266SJeff Kirsher static int init_hash_table(struct pxa168_eth_private *pep)
534527a6266SJeff Kirsher {
535527a6266SJeff Kirsher 	/*
536527a6266SJeff Kirsher 	 * Hardware expects CPU to build a hash table based on a predefined
537527a6266SJeff Kirsher 	 * hash function and populate it based on hardware address. The
538527a6266SJeff Kirsher 	 * location of the hash table is identified by 32-bit pointer stored
539527a6266SJeff Kirsher 	 * in HTPR internal register. Two possible sizes exists for the hash
540527a6266SJeff Kirsher 	 * table 8kB (256kB of DRAM required (4 x 64 kB banks)) and 1/2kB
541527a6266SJeff Kirsher 	 * (16kB of DRAM required (4 x 4 kB banks)).We currently only support
542527a6266SJeff Kirsher 	 * 1/2kB.
543527a6266SJeff Kirsher 	 */
544527a6266SJeff Kirsher 	/* TODO: Add support for 8kB hash table and alternative hash
545527a6266SJeff Kirsher 	 * function.Driver can dynamically switch to them if the 1/2kB hash
546527a6266SJeff Kirsher 	 * table is full.
547527a6266SJeff Kirsher 	 */
5488273f0a3SMarkus Elfring 	if (!pep->htpr) {
549750afb08SLuis Chamberlain 		pep->htpr = dma_alloc_coherent(pep->dev->dev.parent,
550527a6266SJeff Kirsher 					       HASH_ADDR_TABLE_SIZE,
551ede23fa8SJoe Perches 					       &pep->htpr_dma, GFP_KERNEL);
5528273f0a3SMarkus Elfring 		if (!pep->htpr)
553527a6266SJeff Kirsher 			return -ENOMEM;
5541f9061d2SJoe Perches 	} else {
555527a6266SJeff Kirsher 		memset(pep->htpr, 0, HASH_ADDR_TABLE_SIZE);
5561f9061d2SJoe Perches 	}
557527a6266SJeff Kirsher 	wrl(pep, HTPR, pep->htpr_dma);
558527a6266SJeff Kirsher 	return 0;
559527a6266SJeff Kirsher }
560527a6266SJeff Kirsher 
pxa168_eth_set_rx_mode(struct net_device * dev)561527a6266SJeff Kirsher static void pxa168_eth_set_rx_mode(struct net_device *dev)
562527a6266SJeff Kirsher {
563527a6266SJeff Kirsher 	struct pxa168_eth_private *pep = netdev_priv(dev);
564527a6266SJeff Kirsher 	struct netdev_hw_addr *ha;
565527a6266SJeff Kirsher 	u32 val;
566527a6266SJeff Kirsher 
567527a6266SJeff Kirsher 	val = rdl(pep, PORT_CONFIG);
568527a6266SJeff Kirsher 	if (dev->flags & IFF_PROMISC)
569527a6266SJeff Kirsher 		val |= PCR_PM;
570527a6266SJeff Kirsher 	else
571527a6266SJeff Kirsher 		val &= ~PCR_PM;
572527a6266SJeff Kirsher 	wrl(pep, PORT_CONFIG, val);
573527a6266SJeff Kirsher 
574527a6266SJeff Kirsher 	/*
575527a6266SJeff Kirsher 	 * Remove the old list of MAC address and add dev->addr
576527a6266SJeff Kirsher 	 * and multicast address.
577527a6266SJeff Kirsher 	 */
578527a6266SJeff Kirsher 	memset(pep->htpr, 0, HASH_ADDR_TABLE_SIZE);
579527a6266SJeff Kirsher 	update_hash_table_mac_address(pep, NULL, dev->dev_addr);
580527a6266SJeff Kirsher 
581527a6266SJeff Kirsher 	netdev_for_each_mc_addr(ha, dev)
582527a6266SJeff Kirsher 		update_hash_table_mac_address(pep, NULL, ha->addr);
583527a6266SJeff Kirsher }
584527a6266SJeff Kirsher 
pxa168_eth_get_mac_address(struct net_device * dev,unsigned char * addr)58578b9b2c4SAntoine Ténart static void pxa168_eth_get_mac_address(struct net_device *dev,
58678b9b2c4SAntoine Ténart 				       unsigned char *addr)
58778b9b2c4SAntoine Ténart {
58878b9b2c4SAntoine Ténart 	struct pxa168_eth_private *pep = netdev_priv(dev);
58978b9b2c4SAntoine Ténart 	unsigned int mac_h = rdl(pep, MAC_ADDR_HIGH);
59078b9b2c4SAntoine Ténart 	unsigned int mac_l = rdl(pep, MAC_ADDR_LOW);
59178b9b2c4SAntoine Ténart 
59278b9b2c4SAntoine Ténart 	addr[0] = (mac_h >> 24) & 0xff;
59378b9b2c4SAntoine Ténart 	addr[1] = (mac_h >> 16) & 0xff;
59478b9b2c4SAntoine Ténart 	addr[2] = (mac_h >> 8) & 0xff;
59578b9b2c4SAntoine Ténart 	addr[3] = mac_h & 0xff;
59678b9b2c4SAntoine Ténart 	addr[4] = (mac_l >> 8) & 0xff;
59778b9b2c4SAntoine Ténart 	addr[5] = mac_l & 0xff;
59878b9b2c4SAntoine Ténart }
59978b9b2c4SAntoine Ténart 
pxa168_eth_set_mac_address(struct net_device * dev,void * addr)600527a6266SJeff Kirsher static int pxa168_eth_set_mac_address(struct net_device *dev, void *addr)
601527a6266SJeff Kirsher {
602527a6266SJeff Kirsher 	struct sockaddr *sa = addr;
603527a6266SJeff Kirsher 	struct pxa168_eth_private *pep = netdev_priv(dev);
604527a6266SJeff Kirsher 	unsigned char oldMac[ETH_ALEN];
60539830689SAntoine Ténart 	u32 mac_h, mac_l;
606527a6266SJeff Kirsher 
607527a6266SJeff Kirsher 	if (!is_valid_ether_addr(sa->sa_data))
608504f9b5aSDanny Kukawka 		return -EADDRNOTAVAIL;
609527a6266SJeff Kirsher 	memcpy(oldMac, dev->dev_addr, ETH_ALEN);
610a96d317fSJakub Kicinski 	eth_hw_addr_set(dev, sa->sa_data);
61139830689SAntoine Ténart 
612e885439fSAntoine Ténart 	mac_h = dev->dev_addr[0] << 24;
613e885439fSAntoine Ténart 	mac_h |= dev->dev_addr[1] << 16;
614e885439fSAntoine Ténart 	mac_h |= dev->dev_addr[2] << 8;
615e885439fSAntoine Ténart 	mac_h |= dev->dev_addr[3];
616e885439fSAntoine Ténart 	mac_l = dev->dev_addr[4] << 8;
617e885439fSAntoine Ténart 	mac_l |= dev->dev_addr[5];
61839830689SAntoine Ténart 	wrl(pep, MAC_ADDR_HIGH, mac_h);
61939830689SAntoine Ténart 	wrl(pep, MAC_ADDR_LOW, mac_l);
62039830689SAntoine Ténart 
621527a6266SJeff Kirsher 	netif_addr_lock_bh(dev);
622527a6266SJeff Kirsher 	update_hash_table_mac_address(pep, oldMac, dev->dev_addr);
623527a6266SJeff Kirsher 	netif_addr_unlock_bh(dev);
624527a6266SJeff Kirsher 	return 0;
625527a6266SJeff Kirsher }
626527a6266SJeff Kirsher 
eth_port_start(struct net_device * dev)627527a6266SJeff Kirsher static void eth_port_start(struct net_device *dev)
628527a6266SJeff Kirsher {
629527a6266SJeff Kirsher 	unsigned int val = 0;
630527a6266SJeff Kirsher 	struct pxa168_eth_private *pep = netdev_priv(dev);
631527a6266SJeff Kirsher 	int tx_curr_desc, rx_curr_desc;
632527a6266SJeff Kirsher 
6337d321845SPhilippe Reynes 	phy_start(dev->phydev);
634527a6266SJeff Kirsher 
635527a6266SJeff Kirsher 	/* Assignment of Tx CTRP of given queue */
636527a6266SJeff Kirsher 	tx_curr_desc = pep->tx_curr_desc_q;
637527a6266SJeff Kirsher 	wrl(pep, ETH_C_TX_DESC_1,
638527a6266SJeff Kirsher 	    (u32) (pep->tx_desc_dma + tx_curr_desc * sizeof(struct tx_desc)));
639527a6266SJeff Kirsher 
640527a6266SJeff Kirsher 	/* Assignment of Rx CRDP of given queue */
641527a6266SJeff Kirsher 	rx_curr_desc = pep->rx_curr_desc_q;
642527a6266SJeff Kirsher 	wrl(pep, ETH_C_RX_DESC_0,
643527a6266SJeff Kirsher 	    (u32) (pep->rx_desc_dma + rx_curr_desc * sizeof(struct rx_desc)));
644527a6266SJeff Kirsher 
645527a6266SJeff Kirsher 	wrl(pep, ETH_F_RX_DESC_0,
646527a6266SJeff Kirsher 	    (u32) (pep->rx_desc_dma + rx_curr_desc * sizeof(struct rx_desc)));
647527a6266SJeff Kirsher 
648527a6266SJeff Kirsher 	/* Clear all interrupts */
649527a6266SJeff Kirsher 	wrl(pep, INT_CAUSE, 0);
650527a6266SJeff Kirsher 
651527a6266SJeff Kirsher 	/* Enable all interrupts for receive, transmit and error. */
652527a6266SJeff Kirsher 	wrl(pep, INT_MASK, ALL_INTS);
653527a6266SJeff Kirsher 
654527a6266SJeff Kirsher 	val = rdl(pep, PORT_CONFIG);
655527a6266SJeff Kirsher 	val |= PCR_EN;
656527a6266SJeff Kirsher 	wrl(pep, PORT_CONFIG, val);
657527a6266SJeff Kirsher 
658527a6266SJeff Kirsher 	/* Start RX DMA engine */
659527a6266SJeff Kirsher 	val = rdl(pep, SDMA_CMD);
660527a6266SJeff Kirsher 	val |= SDMA_CMD_ERD;
661527a6266SJeff Kirsher 	wrl(pep, SDMA_CMD, val);
662527a6266SJeff Kirsher }
663527a6266SJeff Kirsher 
eth_port_reset(struct net_device * dev)664527a6266SJeff Kirsher static void eth_port_reset(struct net_device *dev)
665527a6266SJeff Kirsher {
666527a6266SJeff Kirsher 	struct pxa168_eth_private *pep = netdev_priv(dev);
667527a6266SJeff Kirsher 	unsigned int val = 0;
668527a6266SJeff Kirsher 
669527a6266SJeff Kirsher 	/* Stop all interrupts for receive, transmit and error. */
670527a6266SJeff Kirsher 	wrl(pep, INT_MASK, 0);
671527a6266SJeff Kirsher 
672527a6266SJeff Kirsher 	/* Clear all interrupts */
673527a6266SJeff Kirsher 	wrl(pep, INT_CAUSE, 0);
674527a6266SJeff Kirsher 
675527a6266SJeff Kirsher 	/* Stop RX DMA */
676527a6266SJeff Kirsher 	val = rdl(pep, SDMA_CMD);
677527a6266SJeff Kirsher 	val &= ~SDMA_CMD_ERD;	/* abort dma command */
678527a6266SJeff Kirsher 
679527a6266SJeff Kirsher 	/* Abort any transmit and receive operations and put DMA
680527a6266SJeff Kirsher 	 * in idle state.
681527a6266SJeff Kirsher 	 */
682527a6266SJeff Kirsher 	abort_dma(pep);
683527a6266SJeff Kirsher 
684527a6266SJeff Kirsher 	/* Disable port */
685527a6266SJeff Kirsher 	val = rdl(pep, PORT_CONFIG);
686527a6266SJeff Kirsher 	val &= ~PCR_EN;
687527a6266SJeff Kirsher 	wrl(pep, PORT_CONFIG, val);
6881a149132SSebastian Hesselbarth 
6897d321845SPhilippe Reynes 	phy_stop(dev->phydev);
690527a6266SJeff Kirsher }
691527a6266SJeff Kirsher 
692527a6266SJeff Kirsher /*
693527a6266SJeff Kirsher  * txq_reclaim - Free the tx desc data for completed descriptors
694527a6266SJeff Kirsher  * If force is non-zero, frees uncompleted descriptors as well
695527a6266SJeff Kirsher  */
txq_reclaim(struct net_device * dev,int force)696527a6266SJeff Kirsher static int txq_reclaim(struct net_device *dev, int force)
697527a6266SJeff Kirsher {
698527a6266SJeff Kirsher 	struct pxa168_eth_private *pep = netdev_priv(dev);
699527a6266SJeff Kirsher 	struct tx_desc *desc;
700527a6266SJeff Kirsher 	u32 cmd_sts;
701527a6266SJeff Kirsher 	struct sk_buff *skb;
702527a6266SJeff Kirsher 	int tx_index;
703527a6266SJeff Kirsher 	dma_addr_t addr;
704527a6266SJeff Kirsher 	int count;
705527a6266SJeff Kirsher 	int released = 0;
706527a6266SJeff Kirsher 
707527a6266SJeff Kirsher 	netif_tx_lock(dev);
708527a6266SJeff Kirsher 
709527a6266SJeff Kirsher 	pep->work_todo &= ~WORK_TX_DONE;
710527a6266SJeff Kirsher 	while (pep->tx_desc_count > 0) {
711527a6266SJeff Kirsher 		tx_index = pep->tx_used_desc_q;
712527a6266SJeff Kirsher 		desc = &pep->p_tx_desc_area[tx_index];
713527a6266SJeff Kirsher 		cmd_sts = desc->cmd_sts;
714527a6266SJeff Kirsher 		if (!force && (cmd_sts & BUF_OWNED_BY_DMA)) {
715527a6266SJeff Kirsher 			if (released > 0) {
716527a6266SJeff Kirsher 				goto txq_reclaim_end;
717527a6266SJeff Kirsher 			} else {
718527a6266SJeff Kirsher 				released = -1;
719527a6266SJeff Kirsher 				goto txq_reclaim_end;
720527a6266SJeff Kirsher 			}
721527a6266SJeff Kirsher 		}
722527a6266SJeff Kirsher 		pep->tx_used_desc_q = (tx_index + 1) % pep->tx_ring_size;
723527a6266SJeff Kirsher 		pep->tx_desc_count--;
724527a6266SJeff Kirsher 		addr = desc->buf_ptr;
725527a6266SJeff Kirsher 		count = desc->byte_cnt;
726527a6266SJeff Kirsher 		skb = pep->tx_skb[tx_index];
727527a6266SJeff Kirsher 		if (skb)
728527a6266SJeff Kirsher 			pep->tx_skb[tx_index] = NULL;
729527a6266SJeff Kirsher 
730527a6266SJeff Kirsher 		if (cmd_sts & TX_ERROR) {
731527a6266SJeff Kirsher 			if (net_ratelimit())
732307f6565SAntoine Ténart 				netdev_err(dev, "Error in TX\n");
733527a6266SJeff Kirsher 			dev->stats.tx_errors++;
734527a6266SJeff Kirsher 		}
735e86b76f6SChristoph Hellwig 		dma_unmap_single(&pep->pdev->dev, addr, count, DMA_TO_DEVICE);
736527a6266SJeff Kirsher 		if (skb)
737527a6266SJeff Kirsher 			dev_kfree_skb_irq(skb);
738527a6266SJeff Kirsher 		released++;
739527a6266SJeff Kirsher 	}
740527a6266SJeff Kirsher txq_reclaim_end:
741527a6266SJeff Kirsher 	netif_tx_unlock(dev);
742527a6266SJeff Kirsher 	return released;
743527a6266SJeff Kirsher }
744527a6266SJeff Kirsher 
pxa168_eth_tx_timeout(struct net_device * dev,unsigned int txqueue)7450290bd29SMichael S. Tsirkin static void pxa168_eth_tx_timeout(struct net_device *dev, unsigned int txqueue)
746527a6266SJeff Kirsher {
747527a6266SJeff Kirsher 	struct pxa168_eth_private *pep = netdev_priv(dev);
748527a6266SJeff Kirsher 
749307f6565SAntoine Ténart 	netdev_info(dev, "TX timeout  desc_count %d\n", pep->tx_desc_count);
750527a6266SJeff Kirsher 
751527a6266SJeff Kirsher 	schedule_work(&pep->tx_timeout_task);
752527a6266SJeff Kirsher }
753527a6266SJeff Kirsher 
pxa168_eth_tx_timeout_task(struct work_struct * work)754527a6266SJeff Kirsher static void pxa168_eth_tx_timeout_task(struct work_struct *work)
755527a6266SJeff Kirsher {
756527a6266SJeff Kirsher 	struct pxa168_eth_private *pep = container_of(work,
757527a6266SJeff Kirsher 						 struct pxa168_eth_private,
758527a6266SJeff Kirsher 						 tx_timeout_task);
759527a6266SJeff Kirsher 	struct net_device *dev = pep->dev;
760527a6266SJeff Kirsher 	pxa168_eth_stop(dev);
761527a6266SJeff Kirsher 	pxa168_eth_open(dev);
762527a6266SJeff Kirsher }
763527a6266SJeff Kirsher 
rxq_process(struct net_device * dev,int budget)764527a6266SJeff Kirsher static int rxq_process(struct net_device *dev, int budget)
765527a6266SJeff Kirsher {
766527a6266SJeff Kirsher 	struct pxa168_eth_private *pep = netdev_priv(dev);
767527a6266SJeff Kirsher 	struct net_device_stats *stats = &dev->stats;
768527a6266SJeff Kirsher 	unsigned int received_packets = 0;
769527a6266SJeff Kirsher 	struct sk_buff *skb;
770527a6266SJeff Kirsher 
771527a6266SJeff Kirsher 	while (budget-- > 0) {
772527a6266SJeff Kirsher 		int rx_next_curr_desc, rx_curr_desc, rx_used_desc;
773527a6266SJeff Kirsher 		struct rx_desc *rx_desc;
774527a6266SJeff Kirsher 		unsigned int cmd_sts;
775527a6266SJeff Kirsher 
776527a6266SJeff Kirsher 		/* Do not process Rx ring in case of Rx ring resource error */
777527a6266SJeff Kirsher 		if (pep->rx_resource_err)
778527a6266SJeff Kirsher 			break;
779527a6266SJeff Kirsher 		rx_curr_desc = pep->rx_curr_desc_q;
780527a6266SJeff Kirsher 		rx_used_desc = pep->rx_used_desc_q;
781527a6266SJeff Kirsher 		rx_desc = &pep->p_rx_desc_area[rx_curr_desc];
782527a6266SJeff Kirsher 		cmd_sts = rx_desc->cmd_sts;
783b17d1559SJisheng Zhang 		dma_rmb();
784527a6266SJeff Kirsher 		if (cmd_sts & (BUF_OWNED_BY_DMA))
785527a6266SJeff Kirsher 			break;
786527a6266SJeff Kirsher 		skb = pep->rx_skb[rx_curr_desc];
787527a6266SJeff Kirsher 		pep->rx_skb[rx_curr_desc] = NULL;
788527a6266SJeff Kirsher 
789527a6266SJeff Kirsher 		rx_next_curr_desc = (rx_curr_desc + 1) % pep->rx_ring_size;
790527a6266SJeff Kirsher 		pep->rx_curr_desc_q = rx_next_curr_desc;
791527a6266SJeff Kirsher 
792527a6266SJeff Kirsher 		/* Rx descriptors exhausted. */
793527a6266SJeff Kirsher 		/* Set the Rx ring resource error flag */
794527a6266SJeff Kirsher 		if (rx_next_curr_desc == rx_used_desc)
795527a6266SJeff Kirsher 			pep->rx_resource_err = 1;
796527a6266SJeff Kirsher 		pep->rx_desc_count--;
797e86b76f6SChristoph Hellwig 		dma_unmap_single(&pep->pdev->dev, rx_desc->buf_ptr,
798527a6266SJeff Kirsher 				 rx_desc->buf_size,
799527a6266SJeff Kirsher 				 DMA_FROM_DEVICE);
800527a6266SJeff Kirsher 		received_packets++;
801527a6266SJeff Kirsher 		/*
802527a6266SJeff Kirsher 		 * Update statistics.
803527a6266SJeff Kirsher 		 * Note byte count includes 4 byte CRC count
804527a6266SJeff Kirsher 		 */
805527a6266SJeff Kirsher 		stats->rx_packets++;
806527a6266SJeff Kirsher 		stats->rx_bytes += rx_desc->byte_cnt;
807527a6266SJeff Kirsher 		/*
808527a6266SJeff Kirsher 		 * In case received a packet without first / last bits on OR
809527a6266SJeff Kirsher 		 * the error summary bit is on, the packets needs to be droped.
810527a6266SJeff Kirsher 		 */
811527a6266SJeff Kirsher 		if (((cmd_sts & (RX_FIRST_DESC | RX_LAST_DESC)) !=
812527a6266SJeff Kirsher 		     (RX_FIRST_DESC | RX_LAST_DESC))
813527a6266SJeff Kirsher 		    || (cmd_sts & RX_ERROR)) {
814527a6266SJeff Kirsher 
815527a6266SJeff Kirsher 			stats->rx_dropped++;
816527a6266SJeff Kirsher 			if ((cmd_sts & (RX_FIRST_DESC | RX_LAST_DESC)) !=
817527a6266SJeff Kirsher 			    (RX_FIRST_DESC | RX_LAST_DESC)) {
818527a6266SJeff Kirsher 				if (net_ratelimit())
819307f6565SAntoine Ténart 					netdev_err(dev,
820307f6565SAntoine Ténart 						   "Rx pkt on multiple desc\n");
821527a6266SJeff Kirsher 			}
822527a6266SJeff Kirsher 			if (cmd_sts & RX_ERROR)
823527a6266SJeff Kirsher 				stats->rx_errors++;
824527a6266SJeff Kirsher 			dev_kfree_skb_irq(skb);
825527a6266SJeff Kirsher 		} else {
826527a6266SJeff Kirsher 			/*
827527a6266SJeff Kirsher 			 * The -4 is for the CRC in the trailer of the
828527a6266SJeff Kirsher 			 * received packet
829527a6266SJeff Kirsher 			 */
830527a6266SJeff Kirsher 			skb_put(skb, rx_desc->byte_cnt - 4);
831527a6266SJeff Kirsher 			skb->protocol = eth_type_trans(skb, dev);
832527a6266SJeff Kirsher 			netif_receive_skb(skb);
833527a6266SJeff Kirsher 		}
834527a6266SJeff Kirsher 	}
835527a6266SJeff Kirsher 	/* Fill RX ring with skb's */
836527a6266SJeff Kirsher 	rxq_refill(dev);
837527a6266SJeff Kirsher 	return received_packets;
838527a6266SJeff Kirsher }
839527a6266SJeff Kirsher 
pxa168_eth_collect_events(struct pxa168_eth_private * pep,struct net_device * dev)840527a6266SJeff Kirsher static int pxa168_eth_collect_events(struct pxa168_eth_private *pep,
841527a6266SJeff Kirsher 				     struct net_device *dev)
842527a6266SJeff Kirsher {
843527a6266SJeff Kirsher 	u32 icr;
844527a6266SJeff Kirsher 	int ret = 0;
845527a6266SJeff Kirsher 
846527a6266SJeff Kirsher 	icr = rdl(pep, INT_CAUSE);
847527a6266SJeff Kirsher 	if (icr == 0)
848527a6266SJeff Kirsher 		return IRQ_NONE;
849527a6266SJeff Kirsher 
850527a6266SJeff Kirsher 	wrl(pep, INT_CAUSE, ~icr);
851527a6266SJeff Kirsher 	if (icr & (ICR_TXBUF_H | ICR_TXBUF_L)) {
852527a6266SJeff Kirsher 		pep->work_todo |= WORK_TX_DONE;
853527a6266SJeff Kirsher 		ret = 1;
854527a6266SJeff Kirsher 	}
855527a6266SJeff Kirsher 	if (icr & ICR_RXBUF)
856527a6266SJeff Kirsher 		ret = 1;
857527a6266SJeff Kirsher 	return ret;
858527a6266SJeff Kirsher }
859527a6266SJeff Kirsher 
pxa168_eth_int_handler(int irq,void * dev_id)860527a6266SJeff Kirsher static irqreturn_t pxa168_eth_int_handler(int irq, void *dev_id)
861527a6266SJeff Kirsher {
862527a6266SJeff Kirsher 	struct net_device *dev = (struct net_device *)dev_id;
863527a6266SJeff Kirsher 	struct pxa168_eth_private *pep = netdev_priv(dev);
864527a6266SJeff Kirsher 
865527a6266SJeff Kirsher 	if (unlikely(!pxa168_eth_collect_events(pep, dev)))
866527a6266SJeff Kirsher 		return IRQ_NONE;
867527a6266SJeff Kirsher 	/* Disable interrupts */
868527a6266SJeff Kirsher 	wrl(pep, INT_MASK, 0);
869527a6266SJeff Kirsher 	napi_schedule(&pep->napi);
870527a6266SJeff Kirsher 	return IRQ_HANDLED;
871527a6266SJeff Kirsher }
872527a6266SJeff Kirsher 
pxa168_eth_recalc_skb_size(struct pxa168_eth_private * pep)873527a6266SJeff Kirsher static void pxa168_eth_recalc_skb_size(struct pxa168_eth_private *pep)
874527a6266SJeff Kirsher {
875527a6266SJeff Kirsher 	int skb_size;
876527a6266SJeff Kirsher 
877527a6266SJeff Kirsher 	/*
878527a6266SJeff Kirsher 	 * Reserve 2+14 bytes for an ethernet header (the hardware
879527a6266SJeff Kirsher 	 * automatically prepends 2 bytes of dummy data to each
880527a6266SJeff Kirsher 	 * received packet), 16 bytes for up to four VLAN tags, and
881527a6266SJeff Kirsher 	 * 4 bytes for the trailing FCS -- 36 bytes total.
882527a6266SJeff Kirsher 	 */
883527a6266SJeff Kirsher 	skb_size = pep->dev->mtu + 36;
884527a6266SJeff Kirsher 
885527a6266SJeff Kirsher 	/*
886527a6266SJeff Kirsher 	 * Make sure that the skb size is a multiple of 8 bytes, as
887527a6266SJeff Kirsher 	 * the lower three bits of the receive descriptor's buffer
888527a6266SJeff Kirsher 	 * size field are ignored by the hardware.
889527a6266SJeff Kirsher 	 */
890527a6266SJeff Kirsher 	pep->skb_size = (skb_size + 7) & ~7;
891527a6266SJeff Kirsher 
892527a6266SJeff Kirsher 	/*
893527a6266SJeff Kirsher 	 * If NET_SKB_PAD is smaller than a cache line,
894527a6266SJeff Kirsher 	 * netdev_alloc_skb() will cause skb->data to be misaligned
895527a6266SJeff Kirsher 	 * to a cache line boundary.  If this is the case, include
896527a6266SJeff Kirsher 	 * some extra space to allow re-aligning the data area.
897527a6266SJeff Kirsher 	 */
898527a6266SJeff Kirsher 	pep->skb_size += SKB_DMA_REALIGN;
899527a6266SJeff Kirsher 
900527a6266SJeff Kirsher }
901527a6266SJeff Kirsher 
set_port_config_ext(struct pxa168_eth_private * pep)902527a6266SJeff Kirsher static int set_port_config_ext(struct pxa168_eth_private *pep)
903527a6266SJeff Kirsher {
904527a6266SJeff Kirsher 	int skb_size;
905527a6266SJeff Kirsher 
906527a6266SJeff Kirsher 	pxa168_eth_recalc_skb_size(pep);
907527a6266SJeff Kirsher 	if  (pep->skb_size <= 1518)
908527a6266SJeff Kirsher 		skb_size = PCXR_MFL_1518;
909527a6266SJeff Kirsher 	else if (pep->skb_size <= 1536)
910527a6266SJeff Kirsher 		skb_size = PCXR_MFL_1536;
911527a6266SJeff Kirsher 	else if (pep->skb_size <= 2048)
912527a6266SJeff Kirsher 		skb_size = PCXR_MFL_2048;
913527a6266SJeff Kirsher 	else
914527a6266SJeff Kirsher 		skb_size = PCXR_MFL_64K;
915527a6266SJeff Kirsher 
916527a6266SJeff Kirsher 	/* Extended Port Configuration */
9171a149132SSebastian Hesselbarth 	wrl(pep, PORT_CONFIG_EXT,
9181a149132SSebastian Hesselbarth 	    PCXR_AN_SPEED_DIS |		 /* Disable HW AN */
9191a149132SSebastian Hesselbarth 	    PCXR_AN_DUPLEX_DIS |
9201a149132SSebastian Hesselbarth 	    PCXR_AN_FLOWCTL_DIS |
9211a149132SSebastian Hesselbarth 	    PCXR_2BSM |			 /* Two byte prefix aligns IP hdr */
922527a6266SJeff Kirsher 	    PCXR_DSCP_EN |		 /* Enable DSCP in IP */
923527a6266SJeff Kirsher 	    skb_size | PCXR_FLP |	 /* do not force link pass */
924527a6266SJeff Kirsher 	    PCXR_TX_HIGH_PRI);		 /* Transmit - high priority queue */
925527a6266SJeff Kirsher 
926527a6266SJeff Kirsher 	return 0;
927527a6266SJeff Kirsher }
928527a6266SJeff Kirsher 
pxa168_eth_adjust_link(struct net_device * dev)9291a149132SSebastian Hesselbarth static void pxa168_eth_adjust_link(struct net_device *dev)
9301a149132SSebastian Hesselbarth {
9311a149132SSebastian Hesselbarth 	struct pxa168_eth_private *pep = netdev_priv(dev);
9327d321845SPhilippe Reynes 	struct phy_device *phy = dev->phydev;
9331a149132SSebastian Hesselbarth 	u32 cfg, cfg_o = rdl(pep, PORT_CONFIG);
9341a149132SSebastian Hesselbarth 	u32 cfgext, cfgext_o = rdl(pep, PORT_CONFIG_EXT);
9351a149132SSebastian Hesselbarth 
9361a149132SSebastian Hesselbarth 	cfg = cfg_o & ~PCR_DUPLEX_FULL;
9371a149132SSebastian Hesselbarth 	cfgext = cfgext_o & ~(PCXR_SPEED_100 | PCXR_FLOWCTL_DIS | PCXR_RMII_EN);
9381a149132SSebastian Hesselbarth 
9391a149132SSebastian Hesselbarth 	if (phy->interface == PHY_INTERFACE_MODE_RMII)
9401a149132SSebastian Hesselbarth 		cfgext |= PCXR_RMII_EN;
9411a149132SSebastian Hesselbarth 	if (phy->speed == SPEED_100)
9421a149132SSebastian Hesselbarth 		cfgext |= PCXR_SPEED_100;
9431a149132SSebastian Hesselbarth 	if (phy->duplex)
9441a149132SSebastian Hesselbarth 		cfg |= PCR_DUPLEX_FULL;
9451a149132SSebastian Hesselbarth 	if (!phy->pause)
9461a149132SSebastian Hesselbarth 		cfgext |= PCXR_FLOWCTL_DIS;
9471a149132SSebastian Hesselbarth 
9481a149132SSebastian Hesselbarth 	/* Bail out if there has nothing changed */
9491a149132SSebastian Hesselbarth 	if (cfg == cfg_o && cfgext == cfgext_o)
9501a149132SSebastian Hesselbarth 		return;
9511a149132SSebastian Hesselbarth 
9521a149132SSebastian Hesselbarth 	wrl(pep, PORT_CONFIG, cfg);
9531a149132SSebastian Hesselbarth 	wrl(pep, PORT_CONFIG_EXT, cfgext);
9541a149132SSebastian Hesselbarth 
9551a149132SSebastian Hesselbarth 	phy_print_status(phy);
9561a149132SSebastian Hesselbarth }
9571a149132SSebastian Hesselbarth 
pxa168_init_phy(struct net_device * dev)9581a149132SSebastian Hesselbarth static int pxa168_init_phy(struct net_device *dev)
9591a149132SSebastian Hesselbarth {
9601a149132SSebastian Hesselbarth 	struct pxa168_eth_private *pep = netdev_priv(dev);
9612186f6eeSPhilippe Reynes 	struct ethtool_link_ksettings cmd;
9627d321845SPhilippe Reynes 	struct phy_device *phy = NULL;
9631a149132SSebastian Hesselbarth 	int err;
9641a149132SSebastian Hesselbarth 
9657d321845SPhilippe Reynes 	if (dev->phydev)
9661a149132SSebastian Hesselbarth 		return 0;
9671a149132SSebastian Hesselbarth 
968d41e1277SAndrew Lunn 	phy = mdiobus_scan_c22(pep->smi_bus, pep->phy_addr);
9697d321845SPhilippe Reynes 	if (IS_ERR(phy))
9707d321845SPhilippe Reynes 		return PTR_ERR(phy);
9711a149132SSebastian Hesselbarth 
9727d321845SPhilippe Reynes 	err = phy_connect_direct(dev, phy, pxa168_eth_adjust_link,
9731a149132SSebastian Hesselbarth 				 pep->phy_intf);
9741a149132SSebastian Hesselbarth 	if (err)
9751a149132SSebastian Hesselbarth 		return err;
9761a149132SSebastian Hesselbarth 
9772186f6eeSPhilippe Reynes 	cmd.base.phy_address = pep->phy_addr;
9782186f6eeSPhilippe Reynes 	cmd.base.speed = pep->phy_speed;
9792186f6eeSPhilippe Reynes 	cmd.base.duplex = pep->phy_duplex;
9804973056cSSean Anderson 	linkmode_copy(cmd.link_modes.advertising, PHY_BASIC_FEATURES);
9812186f6eeSPhilippe Reynes 	cmd.base.autoneg = AUTONEG_ENABLE;
9821a149132SSebastian Hesselbarth 
9832186f6eeSPhilippe Reynes 	if (cmd.base.speed != 0)
9842186f6eeSPhilippe Reynes 		cmd.base.autoneg = AUTONEG_DISABLE;
9851a149132SSebastian Hesselbarth 
9862186f6eeSPhilippe Reynes 	return phy_ethtool_set_link_ksettings(dev, &cmd);
9871a149132SSebastian Hesselbarth }
9881a149132SSebastian Hesselbarth 
pxa168_init_hw(struct pxa168_eth_private * pep)989527a6266SJeff Kirsher static int pxa168_init_hw(struct pxa168_eth_private *pep)
990527a6266SJeff Kirsher {
991527a6266SJeff Kirsher 	int err = 0;
992527a6266SJeff Kirsher 
993527a6266SJeff Kirsher 	/* Disable interrupts */
994527a6266SJeff Kirsher 	wrl(pep, INT_MASK, 0);
995527a6266SJeff Kirsher 	wrl(pep, INT_CAUSE, 0);
996527a6266SJeff Kirsher 	/* Write to ICR to clear interrupts. */
997527a6266SJeff Kirsher 	wrl(pep, INT_W_CLEAR, 0);
998527a6266SJeff Kirsher 	/* Abort any transmit and receive operations and put DMA
999527a6266SJeff Kirsher 	 * in idle state.
1000527a6266SJeff Kirsher 	 */
1001527a6266SJeff Kirsher 	abort_dma(pep);
1002527a6266SJeff Kirsher 	/* Initialize address hash table */
1003527a6266SJeff Kirsher 	err = init_hash_table(pep);
1004527a6266SJeff Kirsher 	if (err)
1005527a6266SJeff Kirsher 		return err;
1006527a6266SJeff Kirsher 	/* SDMA configuration */
1007527a6266SJeff Kirsher 	wrl(pep, SDMA_CONFIG, SDCR_BSZ8 |	/* Burst size = 32 bytes */
1008527a6266SJeff Kirsher 	    SDCR_RIFB |				/* Rx interrupt on frame */
1009527a6266SJeff Kirsher 	    SDCR_BLMT |				/* Little endian transmit */
1010527a6266SJeff Kirsher 	    SDCR_BLMR |				/* Little endian receive */
1011527a6266SJeff Kirsher 	    SDCR_RC_MAX_RETRANS);		/* Max retransmit count */
1012527a6266SJeff Kirsher 	/* Port Configuration */
1013527a6266SJeff Kirsher 	wrl(pep, PORT_CONFIG, PCR_HS);		/* Hash size is 1/2kb */
1014527a6266SJeff Kirsher 	set_port_config_ext(pep);
1015527a6266SJeff Kirsher 
1016527a6266SJeff Kirsher 	return err;
1017527a6266SJeff Kirsher }
1018527a6266SJeff Kirsher 
rxq_init(struct net_device * dev)1019527a6266SJeff Kirsher static int rxq_init(struct net_device *dev)
1020527a6266SJeff Kirsher {
1021527a6266SJeff Kirsher 	struct pxa168_eth_private *pep = netdev_priv(dev);
1022527a6266SJeff Kirsher 	struct rx_desc *p_rx_desc;
1023527a6266SJeff Kirsher 	int size = 0, i = 0;
1024527a6266SJeff Kirsher 	int rx_desc_num = pep->rx_ring_size;
1025527a6266SJeff Kirsher 
1026527a6266SJeff Kirsher 	/* Allocate RX skb rings */
102791acebedSMarkus Elfring 	pep->rx_skb = kcalloc(rx_desc_num, sizeof(*pep->rx_skb), GFP_KERNEL);
1028e404decbSJoe Perches 	if (!pep->rx_skb)
1029527a6266SJeff Kirsher 		return -ENOMEM;
1030e404decbSJoe Perches 
1031527a6266SJeff Kirsher 	/* Allocate RX ring */
1032527a6266SJeff Kirsher 	pep->rx_desc_count = 0;
1033527a6266SJeff Kirsher 	size = pep->rx_ring_size * sizeof(struct rx_desc);
1034527a6266SJeff Kirsher 	pep->rx_desc_area_size = size;
1035750afb08SLuis Chamberlain 	pep->p_rx_desc_area = dma_alloc_coherent(pep->dev->dev.parent, size,
10361f9061d2SJoe Perches 						 &pep->rx_desc_dma,
1037ede23fa8SJoe Perches 						 GFP_KERNEL);
1038d0320f75SJoe Perches 	if (!pep->p_rx_desc_area)
1039527a6266SJeff Kirsher 		goto out;
1040d0320f75SJoe Perches 
1041527a6266SJeff Kirsher 	/* initialize the next_desc_ptr links in the Rx descriptors ring */
104264699336SJoe Perches 	p_rx_desc = pep->p_rx_desc_area;
1043527a6266SJeff Kirsher 	for (i = 0; i < rx_desc_num; i++) {
1044527a6266SJeff Kirsher 		p_rx_desc[i].next_desc_ptr = pep->rx_desc_dma +
1045527a6266SJeff Kirsher 		    ((i + 1) % rx_desc_num) * sizeof(struct rx_desc);
1046527a6266SJeff Kirsher 	}
1047527a6266SJeff Kirsher 	/* Save Rx desc pointer to driver struct. */
1048527a6266SJeff Kirsher 	pep->rx_curr_desc_q = 0;
1049527a6266SJeff Kirsher 	pep->rx_used_desc_q = 0;
1050527a6266SJeff Kirsher 	pep->rx_desc_area_size = rx_desc_num * sizeof(struct rx_desc);
1051527a6266SJeff Kirsher 	return 0;
1052527a6266SJeff Kirsher out:
1053527a6266SJeff Kirsher 	kfree(pep->rx_skb);
1054527a6266SJeff Kirsher 	return -ENOMEM;
1055527a6266SJeff Kirsher }
1056527a6266SJeff Kirsher 
rxq_deinit(struct net_device * dev)1057527a6266SJeff Kirsher static void rxq_deinit(struct net_device *dev)
1058527a6266SJeff Kirsher {
1059527a6266SJeff Kirsher 	struct pxa168_eth_private *pep = netdev_priv(dev);
1060527a6266SJeff Kirsher 	int curr;
1061527a6266SJeff Kirsher 
1062527a6266SJeff Kirsher 	/* Free preallocated skb's on RX rings */
1063527a6266SJeff Kirsher 	for (curr = 0; pep->rx_desc_count && curr < pep->rx_ring_size; curr++) {
1064527a6266SJeff Kirsher 		if (pep->rx_skb[curr]) {
1065527a6266SJeff Kirsher 			dev_kfree_skb(pep->rx_skb[curr]);
1066527a6266SJeff Kirsher 			pep->rx_desc_count--;
1067527a6266SJeff Kirsher 		}
1068527a6266SJeff Kirsher 	}
1069527a6266SJeff Kirsher 	if (pep->rx_desc_count)
1070307f6565SAntoine Ténart 		netdev_err(dev, "Error in freeing Rx Ring. %d skb's still\n",
1071527a6266SJeff Kirsher 			   pep->rx_desc_count);
1072527a6266SJeff Kirsher 	/* Free RX ring */
1073527a6266SJeff Kirsher 	if (pep->p_rx_desc_area)
1074527a6266SJeff Kirsher 		dma_free_coherent(pep->dev->dev.parent, pep->rx_desc_area_size,
1075527a6266SJeff Kirsher 				  pep->p_rx_desc_area, pep->rx_desc_dma);
1076527a6266SJeff Kirsher 	kfree(pep->rx_skb);
1077527a6266SJeff Kirsher }
1078527a6266SJeff Kirsher 
txq_init(struct net_device * dev)1079527a6266SJeff Kirsher static int txq_init(struct net_device *dev)
1080527a6266SJeff Kirsher {
1081527a6266SJeff Kirsher 	struct pxa168_eth_private *pep = netdev_priv(dev);
1082527a6266SJeff Kirsher 	struct tx_desc *p_tx_desc;
1083527a6266SJeff Kirsher 	int size = 0, i = 0;
1084527a6266SJeff Kirsher 	int tx_desc_num = pep->tx_ring_size;
1085527a6266SJeff Kirsher 
108691acebedSMarkus Elfring 	pep->tx_skb = kcalloc(tx_desc_num, sizeof(*pep->tx_skb), GFP_KERNEL);
1087e404decbSJoe Perches 	if (!pep->tx_skb)
1088527a6266SJeff Kirsher 		return -ENOMEM;
1089e404decbSJoe Perches 
1090527a6266SJeff Kirsher 	/* Allocate TX ring */
1091527a6266SJeff Kirsher 	pep->tx_desc_count = 0;
1092527a6266SJeff Kirsher 	size = pep->tx_ring_size * sizeof(struct tx_desc);
1093527a6266SJeff Kirsher 	pep->tx_desc_area_size = size;
1094750afb08SLuis Chamberlain 	pep->p_tx_desc_area = dma_alloc_coherent(pep->dev->dev.parent, size,
10951f9061d2SJoe Perches 						 &pep->tx_desc_dma,
1096ede23fa8SJoe Perches 						 GFP_KERNEL);
1097d0320f75SJoe Perches 	if (!pep->p_tx_desc_area)
1098527a6266SJeff Kirsher 		goto out;
1099527a6266SJeff Kirsher 	/* Initialize the next_desc_ptr links in the Tx descriptors ring */
110064699336SJoe Perches 	p_tx_desc = pep->p_tx_desc_area;
1101527a6266SJeff Kirsher 	for (i = 0; i < tx_desc_num; i++) {
1102527a6266SJeff Kirsher 		p_tx_desc[i].next_desc_ptr = pep->tx_desc_dma +
1103527a6266SJeff Kirsher 		    ((i + 1) % tx_desc_num) * sizeof(struct tx_desc);
1104527a6266SJeff Kirsher 	}
1105527a6266SJeff Kirsher 	pep->tx_curr_desc_q = 0;
1106527a6266SJeff Kirsher 	pep->tx_used_desc_q = 0;
1107527a6266SJeff Kirsher 	pep->tx_desc_area_size = tx_desc_num * sizeof(struct tx_desc);
1108527a6266SJeff Kirsher 	return 0;
1109527a6266SJeff Kirsher out:
1110527a6266SJeff Kirsher 	kfree(pep->tx_skb);
1111527a6266SJeff Kirsher 	return -ENOMEM;
1112527a6266SJeff Kirsher }
1113527a6266SJeff Kirsher 
txq_deinit(struct net_device * dev)1114527a6266SJeff Kirsher static void txq_deinit(struct net_device *dev)
1115527a6266SJeff Kirsher {
1116527a6266SJeff Kirsher 	struct pxa168_eth_private *pep = netdev_priv(dev);
1117527a6266SJeff Kirsher 
1118527a6266SJeff Kirsher 	/* Free outstanding skb's on TX ring */
1119527a6266SJeff Kirsher 	txq_reclaim(dev, 1);
1120527a6266SJeff Kirsher 	BUG_ON(pep->tx_used_desc_q != pep->tx_curr_desc_q);
1121527a6266SJeff Kirsher 	/* Free TX ring */
1122527a6266SJeff Kirsher 	if (pep->p_tx_desc_area)
1123527a6266SJeff Kirsher 		dma_free_coherent(pep->dev->dev.parent, pep->tx_desc_area_size,
1124527a6266SJeff Kirsher 				  pep->p_tx_desc_area, pep->tx_desc_dma);
1125527a6266SJeff Kirsher 	kfree(pep->tx_skb);
1126527a6266SJeff Kirsher }
1127527a6266SJeff Kirsher 
pxa168_eth_open(struct net_device * dev)1128527a6266SJeff Kirsher static int pxa168_eth_open(struct net_device *dev)
1129527a6266SJeff Kirsher {
1130527a6266SJeff Kirsher 	struct pxa168_eth_private *pep = netdev_priv(dev);
1131527a6266SJeff Kirsher 	int err;
1132527a6266SJeff Kirsher 
11331a149132SSebastian Hesselbarth 	err = pxa168_init_phy(dev);
11341a149132SSebastian Hesselbarth 	if (err)
11351a149132SSebastian Hesselbarth 		return err;
11361a149132SSebastian Hesselbarth 
1137599c2e1fSMichael Opdenacker 	err = request_irq(dev->irq, pxa168_eth_int_handler, 0, dev->name, dev);
1138527a6266SJeff Kirsher 	if (err) {
1139f7b4fb22SJoe Perches 		dev_err(&dev->dev, "can't assign irq\n");
1140527a6266SJeff Kirsher 		return -EAGAIN;
1141527a6266SJeff Kirsher 	}
1142527a6266SJeff Kirsher 	pep->rx_resource_err = 0;
1143527a6266SJeff Kirsher 	err = rxq_init(dev);
1144527a6266SJeff Kirsher 	if (err != 0)
1145527a6266SJeff Kirsher 		goto out_free_irq;
1146527a6266SJeff Kirsher 	err = txq_init(dev);
1147527a6266SJeff Kirsher 	if (err != 0)
1148527a6266SJeff Kirsher 		goto out_free_rx_skb;
1149527a6266SJeff Kirsher 	pep->rx_used_desc_q = 0;
1150527a6266SJeff Kirsher 	pep->rx_curr_desc_q = 0;
1151527a6266SJeff Kirsher 
1152527a6266SJeff Kirsher 	/* Fill RX ring with skb's */
1153527a6266SJeff Kirsher 	rxq_refill(dev);
1154527a6266SJeff Kirsher 	pep->rx_used_desc_q = 0;
1155527a6266SJeff Kirsher 	pep->rx_curr_desc_q = 0;
1156527a6266SJeff Kirsher 	netif_carrier_off(dev);
1157527a6266SJeff Kirsher 	napi_enable(&pep->napi);
11588961b194SLino Sanfilippo 	eth_port_start(dev);
1159527a6266SJeff Kirsher 	return 0;
1160527a6266SJeff Kirsher out_free_rx_skb:
1161527a6266SJeff Kirsher 	rxq_deinit(dev);
1162527a6266SJeff Kirsher out_free_irq:
1163527a6266SJeff Kirsher 	free_irq(dev->irq, dev);
1164527a6266SJeff Kirsher 	return err;
1165527a6266SJeff Kirsher }
1166527a6266SJeff Kirsher 
pxa168_eth_stop(struct net_device * dev)1167527a6266SJeff Kirsher static int pxa168_eth_stop(struct net_device *dev)
1168527a6266SJeff Kirsher {
1169527a6266SJeff Kirsher 	struct pxa168_eth_private *pep = netdev_priv(dev);
1170527a6266SJeff Kirsher 	eth_port_reset(dev);
1171527a6266SJeff Kirsher 
1172527a6266SJeff Kirsher 	/* Disable interrupts */
1173527a6266SJeff Kirsher 	wrl(pep, INT_MASK, 0);
1174527a6266SJeff Kirsher 	wrl(pep, INT_CAUSE, 0);
1175527a6266SJeff Kirsher 	/* Write to ICR to clear interrupts. */
1176527a6266SJeff Kirsher 	wrl(pep, INT_W_CLEAR, 0);
1177527a6266SJeff Kirsher 	napi_disable(&pep->napi);
1178527a6266SJeff Kirsher 	del_timer_sync(&pep->timeout);
1179527a6266SJeff Kirsher 	netif_carrier_off(dev);
1180527a6266SJeff Kirsher 	free_irq(dev->irq, dev);
1181527a6266SJeff Kirsher 	rxq_deinit(dev);
1182527a6266SJeff Kirsher 	txq_deinit(dev);
1183527a6266SJeff Kirsher 
1184527a6266SJeff Kirsher 	return 0;
1185527a6266SJeff Kirsher }
1186527a6266SJeff Kirsher 
pxa168_eth_change_mtu(struct net_device * dev,int mtu)1187527a6266SJeff Kirsher static int pxa168_eth_change_mtu(struct net_device *dev, int mtu)
1188527a6266SJeff Kirsher {
1189527a6266SJeff Kirsher 	struct pxa168_eth_private *pep = netdev_priv(dev);
1190527a6266SJeff Kirsher 
1191527a6266SJeff Kirsher 	dev->mtu = mtu;
1192f7ab0f04SZhang Changzhong 	set_port_config_ext(pep);
1193527a6266SJeff Kirsher 
1194527a6266SJeff Kirsher 	if (!netif_running(dev))
1195527a6266SJeff Kirsher 		return 0;
1196527a6266SJeff Kirsher 
1197527a6266SJeff Kirsher 	/*
1198527a6266SJeff Kirsher 	 * Stop and then re-open the interface. This will allocate RX
1199527a6266SJeff Kirsher 	 * skbs of the new MTU.
1200527a6266SJeff Kirsher 	 * There is a possible danger that the open will not succeed,
1201527a6266SJeff Kirsher 	 * due to memory being full.
1202527a6266SJeff Kirsher 	 */
1203527a6266SJeff Kirsher 	pxa168_eth_stop(dev);
1204527a6266SJeff Kirsher 	if (pxa168_eth_open(dev)) {
1205f7b4fb22SJoe Perches 		dev_err(&dev->dev,
1206f7b4fb22SJoe Perches 			"fatal error on re-opening device after MTU change\n");
1207527a6266SJeff Kirsher 	}
1208527a6266SJeff Kirsher 
1209527a6266SJeff Kirsher 	return 0;
1210527a6266SJeff Kirsher }
1211527a6266SJeff Kirsher 
eth_alloc_tx_desc_index(struct pxa168_eth_private * pep)1212527a6266SJeff Kirsher static int eth_alloc_tx_desc_index(struct pxa168_eth_private *pep)
1213527a6266SJeff Kirsher {
1214527a6266SJeff Kirsher 	int tx_desc_curr;
1215527a6266SJeff Kirsher 
1216527a6266SJeff Kirsher 	tx_desc_curr = pep->tx_curr_desc_q;
1217527a6266SJeff Kirsher 	pep->tx_curr_desc_q = (tx_desc_curr + 1) % pep->tx_ring_size;
1218527a6266SJeff Kirsher 	BUG_ON(pep->tx_curr_desc_q == pep->tx_used_desc_q);
1219527a6266SJeff Kirsher 	pep->tx_desc_count++;
1220527a6266SJeff Kirsher 
1221527a6266SJeff Kirsher 	return tx_desc_curr;
1222527a6266SJeff Kirsher }
1223527a6266SJeff Kirsher 
pxa168_rx_poll(struct napi_struct * napi,int budget)1224527a6266SJeff Kirsher static int pxa168_rx_poll(struct napi_struct *napi, int budget)
1225527a6266SJeff Kirsher {
1226527a6266SJeff Kirsher 	struct pxa168_eth_private *pep =
1227527a6266SJeff Kirsher 	    container_of(napi, struct pxa168_eth_private, napi);
1228527a6266SJeff Kirsher 	struct net_device *dev = pep->dev;
1229527a6266SJeff Kirsher 	int work_done = 0;
1230527a6266SJeff Kirsher 
1231527a6266SJeff Kirsher 	/*
1232527a6266SJeff Kirsher 	 * We call txq_reclaim every time since in NAPI interupts are disabled
1233527a6266SJeff Kirsher 	 * and due to this we miss the TX_DONE interrupt,which is not updated in
1234527a6266SJeff Kirsher 	 * interrupt status register.
1235527a6266SJeff Kirsher 	 */
1236527a6266SJeff Kirsher 	txq_reclaim(dev, 0);
1237527a6266SJeff Kirsher 	if (netif_queue_stopped(dev)
1238527a6266SJeff Kirsher 	    && pep->tx_ring_size - pep->tx_desc_count > 1) {
1239527a6266SJeff Kirsher 		netif_wake_queue(dev);
1240527a6266SJeff Kirsher 	}
1241527a6266SJeff Kirsher 	work_done = rxq_process(dev, budget);
1242527a6266SJeff Kirsher 	if (work_done < budget) {
12436ad20165SEric Dumazet 		napi_complete_done(napi, work_done);
1244527a6266SJeff Kirsher 		wrl(pep, INT_MASK, ALL_INTS);
1245527a6266SJeff Kirsher 	}
1246527a6266SJeff Kirsher 
1247527a6266SJeff Kirsher 	return work_done;
1248527a6266SJeff Kirsher }
1249527a6266SJeff Kirsher 
1250f03508ceSYueHaibing static netdev_tx_t
pxa168_eth_start_xmit(struct sk_buff * skb,struct net_device * dev)1251f03508ceSYueHaibing pxa168_eth_start_xmit(struct sk_buff *skb, struct net_device *dev)
1252527a6266SJeff Kirsher {
1253527a6266SJeff Kirsher 	struct pxa168_eth_private *pep = netdev_priv(dev);
1254527a6266SJeff Kirsher 	struct net_device_stats *stats = &dev->stats;
1255527a6266SJeff Kirsher 	struct tx_desc *desc;
1256527a6266SJeff Kirsher 	int tx_index;
1257527a6266SJeff Kirsher 	int length;
1258527a6266SJeff Kirsher 
1259527a6266SJeff Kirsher 	tx_index = eth_alloc_tx_desc_index(pep);
1260527a6266SJeff Kirsher 	desc = &pep->p_tx_desc_area[tx_index];
1261527a6266SJeff Kirsher 	length = skb->len;
1262527a6266SJeff Kirsher 	pep->tx_skb[tx_index] = skb;
1263527a6266SJeff Kirsher 	desc->byte_cnt = length;
1264e86b76f6SChristoph Hellwig 	desc->buf_ptr = dma_map_single(&pep->pdev->dev, skb->data, length,
1265e86b76f6SChristoph Hellwig 					DMA_TO_DEVICE);
1266527a6266SJeff Kirsher 
1267527a6266SJeff Kirsher 	skb_tx_timestamp(skb);
1268527a6266SJeff Kirsher 
1269b17d1559SJisheng Zhang 	dma_wmb();
1270527a6266SJeff Kirsher 	desc->cmd_sts = BUF_OWNED_BY_DMA | TX_GEN_CRC | TX_FIRST_DESC |
1271527a6266SJeff Kirsher 			TX_ZERO_PADDING | TX_LAST_DESC | TX_EN_INT;
1272527a6266SJeff Kirsher 	wmb();
1273527a6266SJeff Kirsher 	wrl(pep, SDMA_CMD, SDMA_CMD_TXDH | SDMA_CMD_ERD);
1274527a6266SJeff Kirsher 
1275527a6266SJeff Kirsher 	stats->tx_bytes += length;
1276527a6266SJeff Kirsher 	stats->tx_packets++;
1277860e9538SFlorian Westphal 	netif_trans_update(dev);
1278527a6266SJeff Kirsher 	if (pep->tx_ring_size - pep->tx_desc_count <= 1) {
1279527a6266SJeff Kirsher 		/* We handled the current skb, but now we are out of space.*/
1280527a6266SJeff Kirsher 		netif_stop_queue(dev);
1281527a6266SJeff Kirsher 	}
1282527a6266SJeff Kirsher 
1283527a6266SJeff Kirsher 	return NETDEV_TX_OK;
1284527a6266SJeff Kirsher }
1285527a6266SJeff Kirsher 
smi_wait_ready(struct pxa168_eth_private * pep)1286527a6266SJeff Kirsher static int smi_wait_ready(struct pxa168_eth_private *pep)
1287527a6266SJeff Kirsher {
1288527a6266SJeff Kirsher 	int i = 0;
1289527a6266SJeff Kirsher 
1290527a6266SJeff Kirsher 	/* wait for the SMI register to become available */
1291527a6266SJeff Kirsher 	for (i = 0; rdl(pep, SMI) & SMI_BUSY; i++) {
1292527a6266SJeff Kirsher 		if (i == PHY_WAIT_ITERATIONS)
1293527a6266SJeff Kirsher 			return -ETIMEDOUT;
1294527a6266SJeff Kirsher 		msleep(10);
1295527a6266SJeff Kirsher 	}
1296527a6266SJeff Kirsher 
1297527a6266SJeff Kirsher 	return 0;
1298527a6266SJeff Kirsher }
1299527a6266SJeff Kirsher 
pxa168_smi_read(struct mii_bus * bus,int phy_addr,int regnum)1300527a6266SJeff Kirsher static int pxa168_smi_read(struct mii_bus *bus, int phy_addr, int regnum)
1301527a6266SJeff Kirsher {
1302527a6266SJeff Kirsher 	struct pxa168_eth_private *pep = bus->priv;
1303527a6266SJeff Kirsher 	int i = 0;
1304527a6266SJeff Kirsher 	int val;
1305527a6266SJeff Kirsher 
1306527a6266SJeff Kirsher 	if (smi_wait_ready(pep)) {
1307307f6565SAntoine Ténart 		netdev_warn(pep->dev, "pxa168_eth: SMI bus busy timeout\n");
1308527a6266SJeff Kirsher 		return -ETIMEDOUT;
1309527a6266SJeff Kirsher 	}
1310527a6266SJeff Kirsher 	wrl(pep, SMI, (phy_addr << 16) | (regnum << 21) | SMI_OP_R);
1311527a6266SJeff Kirsher 	/* now wait for the data to be valid */
1312527a6266SJeff Kirsher 	for (i = 0; !((val = rdl(pep, SMI)) & SMI_R_VALID); i++) {
1313527a6266SJeff Kirsher 		if (i == PHY_WAIT_ITERATIONS) {
1314307f6565SAntoine Ténart 			netdev_warn(pep->dev,
1315527a6266SJeff Kirsher 				    "pxa168_eth: SMI bus read not valid\n");
1316527a6266SJeff Kirsher 			return -ENODEV;
1317527a6266SJeff Kirsher 		}
1318527a6266SJeff Kirsher 		msleep(10);
1319527a6266SJeff Kirsher 	}
1320527a6266SJeff Kirsher 
1321527a6266SJeff Kirsher 	return val & 0xffff;
1322527a6266SJeff Kirsher }
1323527a6266SJeff Kirsher 
pxa168_smi_write(struct mii_bus * bus,int phy_addr,int regnum,u16 value)1324527a6266SJeff Kirsher static int pxa168_smi_write(struct mii_bus *bus, int phy_addr, int regnum,
1325527a6266SJeff Kirsher 			    u16 value)
1326527a6266SJeff Kirsher {
1327527a6266SJeff Kirsher 	struct pxa168_eth_private *pep = bus->priv;
1328527a6266SJeff Kirsher 
1329527a6266SJeff Kirsher 	if (smi_wait_ready(pep)) {
1330307f6565SAntoine Ténart 		netdev_warn(pep->dev, "pxa168_eth: SMI bus busy timeout\n");
1331527a6266SJeff Kirsher 		return -ETIMEDOUT;
1332527a6266SJeff Kirsher 	}
1333527a6266SJeff Kirsher 
1334527a6266SJeff Kirsher 	wrl(pep, SMI, (phy_addr << 16) | (regnum << 21) |
1335527a6266SJeff Kirsher 	    SMI_OP_W | (value & 0xffff));
1336527a6266SJeff Kirsher 
1337527a6266SJeff Kirsher 	if (smi_wait_ready(pep)) {
1338307f6565SAntoine Ténart 		netdev_err(pep->dev, "pxa168_eth: SMI bus busy timeout\n");
1339527a6266SJeff Kirsher 		return -ETIMEDOUT;
1340527a6266SJeff Kirsher 	}
1341527a6266SJeff Kirsher 
1342527a6266SJeff Kirsher 	return 0;
1343527a6266SJeff Kirsher }
1344527a6266SJeff Kirsher 
1345743ffffeSAlexander Monakov #ifdef CONFIG_NET_POLL_CONTROLLER
pxa168_eth_netpoll(struct net_device * dev)1346743ffffeSAlexander Monakov static void pxa168_eth_netpoll(struct net_device *dev)
1347743ffffeSAlexander Monakov {
1348743ffffeSAlexander Monakov 	disable_irq(dev->irq);
1349743ffffeSAlexander Monakov 	pxa168_eth_int_handler(dev->irq, dev);
1350743ffffeSAlexander Monakov 	enable_irq(dev->irq);
1351743ffffeSAlexander Monakov }
1352743ffffeSAlexander Monakov #endif
1353743ffffeSAlexander Monakov 
pxa168_get_drvinfo(struct net_device * dev,struct ethtool_drvinfo * info)1354527a6266SJeff Kirsher static void pxa168_get_drvinfo(struct net_device *dev,
1355527a6266SJeff Kirsher 			       struct ethtool_drvinfo *info)
1356527a6266SJeff Kirsher {
1357f029c781SWolfram Sang 	strscpy(info->driver, DRIVER_NAME, sizeof(info->driver));
1358f029c781SWolfram Sang 	strscpy(info->version, DRIVER_VERSION, sizeof(info->version));
1359f029c781SWolfram Sang 	strscpy(info->fw_version, "N/A", sizeof(info->fw_version));
1360f029c781SWolfram Sang 	strscpy(info->bus_info, "N/A", sizeof(info->bus_info));
1361527a6266SJeff Kirsher }
1362527a6266SJeff Kirsher 
1363527a6266SJeff Kirsher static const struct ethtool_ops pxa168_ethtool_ops = {
1364527a6266SJeff Kirsher 	.get_drvinfo	= pxa168_get_drvinfo,
136513f0ac41SFlorian Fainelli 	.nway_reset	= phy_ethtool_nway_reset,
1366527a6266SJeff Kirsher 	.get_link	= ethtool_op_get_link,
13671975a54bSRichard Cochran 	.get_ts_info	= ethtool_op_get_ts_info,
1368482ff9fdSFlorian Fainelli 	.get_link_ksettings = phy_ethtool_get_link_ksettings,
13692186f6eeSPhilippe Reynes 	.set_link_ksettings = phy_ethtool_set_link_ksettings,
1370527a6266SJeff Kirsher };
1371527a6266SJeff Kirsher 
1372527a6266SJeff Kirsher static const struct net_device_ops pxa168_eth_netdev_ops = {
1373527a6266SJeff Kirsher 	.ndo_open		= pxa168_eth_open,
1374527a6266SJeff Kirsher 	.ndo_stop		= pxa168_eth_stop,
1375527a6266SJeff Kirsher 	.ndo_start_xmit		= pxa168_eth_start_xmit,
1376527a6266SJeff Kirsher 	.ndo_set_rx_mode	= pxa168_eth_set_rx_mode,
1377527a6266SJeff Kirsher 	.ndo_set_mac_address	= pxa168_eth_set_mac_address,
1378527a6266SJeff Kirsher 	.ndo_validate_addr	= eth_validate_addr,
1379a7605370SArnd Bergmann 	.ndo_eth_ioctl		= phy_do_ioctl,
1380527a6266SJeff Kirsher 	.ndo_change_mtu		= pxa168_eth_change_mtu,
1381527a6266SJeff Kirsher 	.ndo_tx_timeout		= pxa168_eth_tx_timeout,
1382743ffffeSAlexander Monakov #ifdef CONFIG_NET_POLL_CONTROLLER
1383743ffffeSAlexander Monakov 	.ndo_poll_controller    = pxa168_eth_netpoll,
1384743ffffeSAlexander Monakov #endif
1385527a6266SJeff Kirsher };
1386527a6266SJeff Kirsher 
pxa168_eth_probe(struct platform_device * pdev)1387527a6266SJeff Kirsher static int pxa168_eth_probe(struct platform_device *pdev)
1388527a6266SJeff Kirsher {
1389527a6266SJeff Kirsher 	struct pxa168_eth_private *pep = NULL;
1390527a6266SJeff Kirsher 	struct net_device *dev = NULL;
1391527a6266SJeff Kirsher 	struct clk *clk;
139243d3ddf8SAntoine Ténart 	struct device_node *np;
1393527a6266SJeff Kirsher 	int err;
1394527a6266SJeff Kirsher 
1395527a6266SJeff Kirsher 	printk(KERN_NOTICE "PXA168 10/100 Ethernet Driver\n");
1396527a6266SJeff Kirsher 
1397*93ccc94dSVitalii Mordan 	clk = devm_clk_get_enabled(&pdev->dev, NULL);
1398527a6266SJeff Kirsher 	if (IS_ERR(clk)) {
1399*93ccc94dSVitalii Mordan 		dev_err(&pdev->dev, "Fast Ethernet failed to get and enable clock\n");
1400527a6266SJeff Kirsher 		return -ENODEV;
1401527a6266SJeff Kirsher 	}
1402527a6266SJeff Kirsher 
1403527a6266SJeff Kirsher 	dev = alloc_etherdev(sizeof(struct pxa168_eth_private));
1404*93ccc94dSVitalii Mordan 	if (!dev)
1405*93ccc94dSVitalii Mordan 		return -ENOMEM;
1406527a6266SJeff Kirsher 
1407527a6266SJeff Kirsher 	platform_set_drvdata(pdev, dev);
1408527a6266SJeff Kirsher 	pep = netdev_priv(dev);
1409527a6266SJeff Kirsher 	pep->dev = dev;
1410527a6266SJeff Kirsher 	pep->clk = clk;
14117e5ae24aSVarka Bhadram 
1412531fd23bSYueHaibing 	pep->base = devm_platform_ioremap_resource(pdev, 0);
141343d3ddf8SAntoine Ténart 	if (IS_ERR(pep->base)) {
1414ef24d6c3STiezhu Yang 		err = PTR_ERR(pep->base);
1415527a6266SJeff Kirsher 		goto err_netdev;
1416527a6266SJeff Kirsher 	}
14177e5ae24aSVarka Bhadram 
1418f83b4348SLad Prabhakar 	err = platform_get_irq(pdev, 0);
1419f83b4348SLad Prabhakar 	if (err == -EPROBE_DEFER)
1420f83b4348SLad Prabhakar 		goto err_netdev;
1421f83b4348SLad Prabhakar 	BUG_ON(dev->irq < 0);
1422f83b4348SLad Prabhakar 	dev->irq = err;
1423527a6266SJeff Kirsher 	dev->netdev_ops = &pxa168_eth_netdev_ops;
1424527a6266SJeff Kirsher 	dev->watchdog_timeo = 2 * HZ;
1425527a6266SJeff Kirsher 	dev->base_addr = 0;
14267ad24ea4SWilfried Klaebe 	dev->ethtool_ops = &pxa168_ethtool_ops;
1427527a6266SJeff Kirsher 
14285777987eSJarod Wilson 	/* MTU range: 68 - 9500 */
14295777987eSJarod Wilson 	dev->min_mtu = ETH_MIN_MTU;
14305777987eSJarod Wilson 	dev->max_mtu = 9500;
14315777987eSJarod Wilson 
1432527a6266SJeff Kirsher 	INIT_WORK(&pep->tx_timeout_task, pxa168_eth_tx_timeout_task);
1433527a6266SJeff Kirsher 
14349ca01b25SJakub Kicinski 	err = of_get_ethdev_address(pdev->dev.of_node, dev);
143583216e39SMichael Walle 	if (err) {
14364abd7cffSJakub Kicinski 		u8 addr[ETH_ALEN];
14374abd7cffSJakub Kicinski 
143878b9b2c4SAntoine Ténart 		/* try reading the mac address, if set by the bootloader */
14394abd7cffSJakub Kicinski 		pxa168_eth_get_mac_address(dev, addr);
14404abd7cffSJakub Kicinski 		if (is_valid_ether_addr(addr)) {
14414abd7cffSJakub Kicinski 			eth_hw_addr_set(dev, addr);
14424abd7cffSJakub Kicinski 		} else {
1443307f6565SAntoine Ténart 			dev_info(&pdev->dev, "Using random mac address\n");
14447ce5d222SDanny Kukawka 			eth_hw_addr_random(dev);
144578b9b2c4SAntoine Ténart 		}
144678b9b2c4SAntoine Ténart 	}
1447527a6266SJeff Kirsher 
1448527a6266SJeff Kirsher 	pep->rx_ring_size = NUM_RX_DESCS;
144943d3ddf8SAntoine Ténart 	pep->tx_ring_size = NUM_TX_DESCS;
145043d3ddf8SAntoine Ténart 
145143d3ddf8SAntoine Ténart 	pep->pd = dev_get_platdata(&pdev->dev);
145243d3ddf8SAntoine Ténart 	if (pep->pd) {
1453527a6266SJeff Kirsher 		if (pep->pd->rx_queue_size)
1454527a6266SJeff Kirsher 			pep->rx_ring_size = pep->pd->rx_queue_size;
1455527a6266SJeff Kirsher 
1456527a6266SJeff Kirsher 		if (pep->pd->tx_queue_size)
1457527a6266SJeff Kirsher 			pep->tx_ring_size = pep->pd->tx_queue_size;
1458527a6266SJeff Kirsher 
1459527a6266SJeff Kirsher 		pep->port_num = pep->pd->port_number;
146043d3ddf8SAntoine Ténart 		pep->phy_addr = pep->pd->phy_addr;
14619d8ea73dSSebastian Hesselbarth 		pep->phy_speed = pep->pd->speed;
14629d8ea73dSSebastian Hesselbarth 		pep->phy_duplex = pep->pd->duplex;
14639d8ea73dSSebastian Hesselbarth 		pep->phy_intf = pep->pd->intf;
14649d8ea73dSSebastian Hesselbarth 
14659d8ea73dSSebastian Hesselbarth 		if (pep->pd->init)
14669d8ea73dSSebastian Hesselbarth 			pep->pd->init();
146743d3ddf8SAntoine Ténart 	} else if (pdev->dev.of_node) {
146843d3ddf8SAntoine Ténart 		of_property_read_u32(pdev->dev.of_node, "port-id",
146943d3ddf8SAntoine Ténart 				     &pep->port_num);
147043d3ddf8SAntoine Ténart 
147143d3ddf8SAntoine Ténart 		np = of_parse_phandle(pdev->dev.of_node, "phy-handle", 0);
14729d8ea73dSSebastian Hesselbarth 		if (!np) {
14739d8ea73dSSebastian Hesselbarth 			dev_err(&pdev->dev, "missing phy-handle\n");
14740e03fd3eSAlexey Khoroshilov 			err = -EINVAL;
14750e03fd3eSAlexey Khoroshilov 			goto err_netdev;
14769d8ea73dSSebastian Hesselbarth 		}
147743d3ddf8SAntoine Ténart 		of_property_read_u32(np, "reg", &pep->phy_addr);
1478bd1026c6SPeter Chen 		of_node_put(np);
14790c65b2b9SAndrew Lunn 		err = of_get_phy_mode(pdev->dev.of_node, &pep->phy_intf);
14800c65b2b9SAndrew Lunn 		if (err && err != -ENODEV)
14810c65b2b9SAndrew Lunn 			goto err_netdev;
148243d3ddf8SAntoine Ténart 	}
148343d3ddf8SAntoine Ténart 
1484527a6266SJeff Kirsher 	/* Hardware supports only 3 ports */
1485527a6266SJeff Kirsher 	BUG_ON(pep->port_num > 2);
1486b707b89fSJakub Kicinski 	netif_napi_add_weight(dev, &pep->napi, pxa168_rx_poll,
1487b707b89fSJakub Kicinski 			      pep->rx_ring_size);
1488527a6266SJeff Kirsher 
1489527a6266SJeff Kirsher 	memset(&pep->timeout, 0, sizeof(struct timer_list));
1490e99e88a9SKees Cook 	timer_setup(&pep->timeout, rxq_refill_timer_wrapper, 0);
1491527a6266SJeff Kirsher 
1492527a6266SJeff Kirsher 	pep->smi_bus = mdiobus_alloc();
14938273f0a3SMarkus Elfring 	if (!pep->smi_bus) {
1494527a6266SJeff Kirsher 		err = -ENOMEM;
14950e03fd3eSAlexey Khoroshilov 		goto err_netdev;
1496527a6266SJeff Kirsher 	}
1497527a6266SJeff Kirsher 	pep->smi_bus->priv = pep;
1498527a6266SJeff Kirsher 	pep->smi_bus->name = "pxa168_eth smi";
1499527a6266SJeff Kirsher 	pep->smi_bus->read = pxa168_smi_read;
1500527a6266SJeff Kirsher 	pep->smi_bus->write = pxa168_smi_write;
1501d073a102SFlorian Fainelli 	snprintf(pep->smi_bus->id, MII_BUS_ID_SIZE, "%s-%d",
1502d073a102SFlorian Fainelli 		pdev->name, pdev->id);
1503527a6266SJeff Kirsher 	pep->smi_bus->parent = &pdev->dev;
1504527a6266SJeff Kirsher 	pep->smi_bus->phy_mask = 0xffffffff;
1505527a6266SJeff Kirsher 	err = mdiobus_register(pep->smi_bus);
1506527a6266SJeff Kirsher 	if (err)
1507527a6266SJeff Kirsher 		goto err_free_mdio;
1508527a6266SJeff Kirsher 
1509e86b76f6SChristoph Hellwig 	pep->pdev = pdev;
1510527a6266SJeff Kirsher 	SET_NETDEV_DEV(dev, &pdev->dev);
1511824ab782SJisheng Zhang 	pxa168_init_hw(pep);
1512527a6266SJeff Kirsher 	err = register_netdev(dev);
1513527a6266SJeff Kirsher 	if (err)
1514527a6266SJeff Kirsher 		goto err_mdiobus;
1515527a6266SJeff Kirsher 	return 0;
1516527a6266SJeff Kirsher 
1517527a6266SJeff Kirsher err_mdiobus:
1518527a6266SJeff Kirsher 	mdiobus_unregister(pep->smi_bus);
1519527a6266SJeff Kirsher err_free_mdio:
1520527a6266SJeff Kirsher 	mdiobus_free(pep->smi_bus);
1521527a6266SJeff Kirsher err_netdev:
1522527a6266SJeff Kirsher 	free_netdev(dev);
1523527a6266SJeff Kirsher 	return err;
1524527a6266SJeff Kirsher }
1525527a6266SJeff Kirsher 
pxa168_eth_remove(struct platform_device * pdev)1526527a6266SJeff Kirsher static int pxa168_eth_remove(struct platform_device *pdev)
1527527a6266SJeff Kirsher {
1528527a6266SJeff Kirsher 	struct net_device *dev = platform_get_drvdata(pdev);
1529527a6266SJeff Kirsher 	struct pxa168_eth_private *pep = netdev_priv(dev);
1530527a6266SJeff Kirsher 
1531bd709574SPavel Machek 	cancel_work_sync(&pep->tx_timeout_task);
1532527a6266SJeff Kirsher 	if (pep->htpr) {
1533527a6266SJeff Kirsher 		dma_free_coherent(pep->dev->dev.parent, HASH_ADDR_TABLE_SIZE,
1534527a6266SJeff Kirsher 				  pep->htpr, pep->htpr_dma);
1535527a6266SJeff Kirsher 		pep->htpr = NULL;
1536527a6266SJeff Kirsher 	}
15377d321845SPhilippe Reynes 	if (dev->phydev)
15387d321845SPhilippe Reynes 		phy_disconnect(dev->phydev);
1539527a6266SJeff Kirsher 
1540527a6266SJeff Kirsher 	mdiobus_unregister(pep->smi_bus);
1541527a6266SJeff Kirsher 	mdiobus_free(pep->smi_bus);
15420571a753SPavel Andrianov 	unregister_netdev(dev);
1543527a6266SJeff Kirsher 	free_netdev(dev);
1544527a6266SJeff Kirsher 	return 0;
1545527a6266SJeff Kirsher }
1546527a6266SJeff Kirsher 
pxa168_eth_shutdown(struct platform_device * pdev)1547527a6266SJeff Kirsher static void pxa168_eth_shutdown(struct platform_device *pdev)
1548527a6266SJeff Kirsher {
1549527a6266SJeff Kirsher 	struct net_device *dev = platform_get_drvdata(pdev);
1550527a6266SJeff Kirsher 	eth_port_reset(dev);
1551527a6266SJeff Kirsher }
1552527a6266SJeff Kirsher 
1553527a6266SJeff Kirsher #ifdef CONFIG_PM
pxa168_eth_resume(struct platform_device * pdev)1554527a6266SJeff Kirsher static int pxa168_eth_resume(struct platform_device *pdev)
1555527a6266SJeff Kirsher {
1556527a6266SJeff Kirsher 	return -ENOSYS;
1557527a6266SJeff Kirsher }
1558527a6266SJeff Kirsher 
pxa168_eth_suspend(struct platform_device * pdev,pm_message_t state)1559527a6266SJeff Kirsher static int pxa168_eth_suspend(struct platform_device *pdev, pm_message_t state)
1560527a6266SJeff Kirsher {
1561527a6266SJeff Kirsher 	return -ENOSYS;
1562527a6266SJeff Kirsher }
1563527a6266SJeff Kirsher 
1564527a6266SJeff Kirsher #else
1565527a6266SJeff Kirsher #define pxa168_eth_resume NULL
1566527a6266SJeff Kirsher #define pxa168_eth_suspend NULL
1567527a6266SJeff Kirsher #endif
1568527a6266SJeff Kirsher 
156943d3ddf8SAntoine Ténart static const struct of_device_id pxa168_eth_of_match[] = {
157043d3ddf8SAntoine Ténart 	{ .compatible = "marvell,pxa168-eth" },
157143d3ddf8SAntoine Ténart 	{ },
157243d3ddf8SAntoine Ténart };
157343d3ddf8SAntoine Ténart MODULE_DEVICE_TABLE(of, pxa168_eth_of_match);
157443d3ddf8SAntoine Ténart 
1575527a6266SJeff Kirsher static struct platform_driver pxa168_eth_driver = {
1576527a6266SJeff Kirsher 	.probe = pxa168_eth_probe,
1577527a6266SJeff Kirsher 	.remove = pxa168_eth_remove,
1578527a6266SJeff Kirsher 	.shutdown = pxa168_eth_shutdown,
1579527a6266SJeff Kirsher 	.resume = pxa168_eth_resume,
1580527a6266SJeff Kirsher 	.suspend = pxa168_eth_suspend,
1581527a6266SJeff Kirsher 	.driver = {
1582527a6266SJeff Kirsher 		.name		= DRIVER_NAME,
158369df36d5SKrzysztof Kozlowski 		.of_match_table	= pxa168_eth_of_match,
1584527a6266SJeff Kirsher 	},
1585527a6266SJeff Kirsher };
1586527a6266SJeff Kirsher 
1587db62f684SAxel Lin module_platform_driver(pxa168_eth_driver);
1588527a6266SJeff Kirsher 
1589527a6266SJeff Kirsher MODULE_LICENSE("GPL");
1590527a6266SJeff Kirsher MODULE_DESCRIPTION("Ethernet driver for Marvell PXA168");
1591527a6266SJeff Kirsher MODULE_ALIAS("platform:pxa168_eth");
1592