ll_temac_main.c revision 8513fbd880093f00a47e85a552f14ca2de8d84d6
192744989533cbe85e8057935d230e128810168ceGrant Likely/*
292744989533cbe85e8057935d230e128810168ceGrant Likely * Driver for Xilinx TEMAC Ethernet device
392744989533cbe85e8057935d230e128810168ceGrant Likely *
492744989533cbe85e8057935d230e128810168ceGrant Likely * Copyright (c) 2008 Nissin Systems Co., Ltd.,  Yoshio Kashiwagi
592744989533cbe85e8057935d230e128810168ceGrant Likely * Copyright (c) 2005-2008 DLA Systems,  David H. Lynch Jr. <dhlii@dlasys.net>
692744989533cbe85e8057935d230e128810168ceGrant Likely * Copyright (c) 2008-2009 Secret Lab Technologies Ltd.
792744989533cbe85e8057935d230e128810168ceGrant Likely *
892744989533cbe85e8057935d230e128810168ceGrant Likely * This is a driver for the Xilinx ll_temac ipcore which is often used
992744989533cbe85e8057935d230e128810168ceGrant Likely * in the Virtex and Spartan series of chips.
1092744989533cbe85e8057935d230e128810168ceGrant Likely *
1192744989533cbe85e8057935d230e128810168ceGrant Likely * Notes:
1292744989533cbe85e8057935d230e128810168ceGrant Likely * - The ll_temac hardware uses indirect access for many of the TEMAC
1392744989533cbe85e8057935d230e128810168ceGrant Likely *   registers, include the MDIO bus.  However, indirect access to MDIO
1492744989533cbe85e8057935d230e128810168ceGrant Likely *   registers take considerably more clock cycles than to TEMAC registers.
1592744989533cbe85e8057935d230e128810168ceGrant Likely *   MDIO accesses are long, so threads doing them should probably sleep
1692744989533cbe85e8057935d230e128810168ceGrant Likely *   rather than busywait.  However, since only one indirect access can be
1792744989533cbe85e8057935d230e128810168ceGrant Likely *   in progress at any given time, that means that *all* indirect accesses
1892744989533cbe85e8057935d230e128810168ceGrant Likely *   could end up sleeping (to wait for an MDIO access to complete).
1992744989533cbe85e8057935d230e128810168ceGrant Likely *   Fortunately none of the indirect accesses are on the 'hot' path for tx
2092744989533cbe85e8057935d230e128810168ceGrant Likely *   or rx, so this should be okay.
2192744989533cbe85e8057935d230e128810168ceGrant Likely *
2292744989533cbe85e8057935d230e128810168ceGrant Likely * TODO:
2392744989533cbe85e8057935d230e128810168ceGrant Likely * - Factor out locallink DMA code into separate driver
2492744989533cbe85e8057935d230e128810168ceGrant Likely * - Fix multicast assignment.
2592744989533cbe85e8057935d230e128810168ceGrant Likely * - Fix support for hardware checksumming.
2692744989533cbe85e8057935d230e128810168ceGrant Likely * - Testing.  Lots and lots of testing.
2792744989533cbe85e8057935d230e128810168ceGrant Likely *
2892744989533cbe85e8057935d230e128810168ceGrant Likely */
2992744989533cbe85e8057935d230e128810168ceGrant Likely
3092744989533cbe85e8057935d230e128810168ceGrant Likely#include <linux/delay.h>
3192744989533cbe85e8057935d230e128810168ceGrant Likely#include <linux/etherdevice.h>
3292744989533cbe85e8057935d230e128810168ceGrant Likely#include <linux/init.h>
3392744989533cbe85e8057935d230e128810168ceGrant Likely#include <linux/mii.h>
3492744989533cbe85e8057935d230e128810168ceGrant Likely#include <linux/module.h>
3592744989533cbe85e8057935d230e128810168ceGrant Likely#include <linux/mutex.h>
3692744989533cbe85e8057935d230e128810168ceGrant Likely#include <linux/netdevice.h>
3792744989533cbe85e8057935d230e128810168ceGrant Likely#include <linux/of.h>
3892744989533cbe85e8057935d230e128810168ceGrant Likely#include <linux/of_device.h>
3992744989533cbe85e8057935d230e128810168ceGrant Likely#include <linux/of_mdio.h>
4092744989533cbe85e8057935d230e128810168ceGrant Likely#include <linux/of_platform.h>
419f1a1fca35066117353994bff80a5115cddad7a2Michal Simek#include <linux/of_address.h>
4292744989533cbe85e8057935d230e128810168ceGrant Likely#include <linux/skbuff.h>
4392744989533cbe85e8057935d230e128810168ceGrant Likely#include <linux/spinlock.h>
4492744989533cbe85e8057935d230e128810168ceGrant Likely#include <linux/tcp.h>      /* needed for sizeof(tcphdr) */
4592744989533cbe85e8057935d230e128810168ceGrant Likely#include <linux/udp.h>      /* needed for sizeof(udphdr) */
4692744989533cbe85e8057935d230e128810168ceGrant Likely#include <linux/phy.h>
4792744989533cbe85e8057935d230e128810168ceGrant Likely#include <linux/in.h>
4892744989533cbe85e8057935d230e128810168ceGrant Likely#include <linux/io.h>
4992744989533cbe85e8057935d230e128810168ceGrant Likely#include <linux/ip.h>
505a0e3ad6af8660be21ca98a971cd00f331318c05Tejun Heo#include <linux/slab.h>
51ffbc03bc75b39c7bd412e7cc6d2185c11b0ffeddStephen Rothwell#include <linux/interrupt.h>
5284cac3989a0fa009fff63c315759006560c91c13Stephen Rothwell#include <linux/dma-mapping.h>
5392744989533cbe85e8057935d230e128810168ceGrant Likely
5492744989533cbe85e8057935d230e128810168ceGrant Likely#include "ll_temac.h"
5592744989533cbe85e8057935d230e128810168ceGrant Likely
5692744989533cbe85e8057935d230e128810168ceGrant Likely#define TX_BD_NUM   64
5792744989533cbe85e8057935d230e128810168ceGrant Likely#define RX_BD_NUM   128
5892744989533cbe85e8057935d230e128810168ceGrant Likely
5992744989533cbe85e8057935d230e128810168ceGrant Likely/* ---------------------------------------------------------------------
6092744989533cbe85e8057935d230e128810168ceGrant Likely * Low level register access functions
6192744989533cbe85e8057935d230e128810168ceGrant Likely */
6292744989533cbe85e8057935d230e128810168ceGrant Likely
6392744989533cbe85e8057935d230e128810168ceGrant Likelyu32 temac_ior(struct temac_local *lp, int offset)
6492744989533cbe85e8057935d230e128810168ceGrant Likely{
6592744989533cbe85e8057935d230e128810168ceGrant Likely	return in_be32((u32 *)(lp->regs + offset));
6692744989533cbe85e8057935d230e128810168ceGrant Likely}
6792744989533cbe85e8057935d230e128810168ceGrant Likely
6892744989533cbe85e8057935d230e128810168ceGrant Likelyvoid temac_iow(struct temac_local *lp, int offset, u32 value)
6992744989533cbe85e8057935d230e128810168ceGrant Likely{
7092744989533cbe85e8057935d230e128810168ceGrant Likely	out_be32((u32 *) (lp->regs + offset), value);
7192744989533cbe85e8057935d230e128810168ceGrant Likely}
7292744989533cbe85e8057935d230e128810168ceGrant Likely
7392744989533cbe85e8057935d230e128810168ceGrant Likelyint temac_indirect_busywait(struct temac_local *lp)
7492744989533cbe85e8057935d230e128810168ceGrant Likely{
7592744989533cbe85e8057935d230e128810168ceGrant Likely	long end = jiffies + 2;
7692744989533cbe85e8057935d230e128810168ceGrant Likely
7792744989533cbe85e8057935d230e128810168ceGrant Likely	while (!(temac_ior(lp, XTE_RDY0_OFFSET) & XTE_RDY0_HARD_ACS_RDY_MASK)) {
7892744989533cbe85e8057935d230e128810168ceGrant Likely		if (end - jiffies <= 0) {
7992744989533cbe85e8057935d230e128810168ceGrant Likely			WARN_ON(1);
8092744989533cbe85e8057935d230e128810168ceGrant Likely			return -ETIMEDOUT;
8192744989533cbe85e8057935d230e128810168ceGrant Likely		}
8292744989533cbe85e8057935d230e128810168ceGrant Likely		msleep(1);
8392744989533cbe85e8057935d230e128810168ceGrant Likely	}
8492744989533cbe85e8057935d230e128810168ceGrant Likely	return 0;
8592744989533cbe85e8057935d230e128810168ceGrant Likely}
8692744989533cbe85e8057935d230e128810168ceGrant Likely
8792744989533cbe85e8057935d230e128810168ceGrant Likely/**
8892744989533cbe85e8057935d230e128810168ceGrant Likely * temac_indirect_in32
8992744989533cbe85e8057935d230e128810168ceGrant Likely *
9092744989533cbe85e8057935d230e128810168ceGrant Likely * lp->indirect_mutex must be held when calling this function
9192744989533cbe85e8057935d230e128810168ceGrant Likely */
9292744989533cbe85e8057935d230e128810168ceGrant Likelyu32 temac_indirect_in32(struct temac_local *lp, int reg)
9392744989533cbe85e8057935d230e128810168ceGrant Likely{
9492744989533cbe85e8057935d230e128810168ceGrant Likely	u32 val;
9592744989533cbe85e8057935d230e128810168ceGrant Likely
9692744989533cbe85e8057935d230e128810168ceGrant Likely	if (temac_indirect_busywait(lp))
9792744989533cbe85e8057935d230e128810168ceGrant Likely		return -ETIMEDOUT;
9892744989533cbe85e8057935d230e128810168ceGrant Likely	temac_iow(lp, XTE_CTL0_OFFSET, reg);
9992744989533cbe85e8057935d230e128810168ceGrant Likely	if (temac_indirect_busywait(lp))
10092744989533cbe85e8057935d230e128810168ceGrant Likely		return -ETIMEDOUT;
10192744989533cbe85e8057935d230e128810168ceGrant Likely	val = temac_ior(lp, XTE_LSW0_OFFSET);
10292744989533cbe85e8057935d230e128810168ceGrant Likely
10392744989533cbe85e8057935d230e128810168ceGrant Likely	return val;
10492744989533cbe85e8057935d230e128810168ceGrant Likely}
10592744989533cbe85e8057935d230e128810168ceGrant Likely
10692744989533cbe85e8057935d230e128810168ceGrant Likely/**
10792744989533cbe85e8057935d230e128810168ceGrant Likely * temac_indirect_out32
10892744989533cbe85e8057935d230e128810168ceGrant Likely *
10992744989533cbe85e8057935d230e128810168ceGrant Likely * lp->indirect_mutex must be held when calling this function
11092744989533cbe85e8057935d230e128810168ceGrant Likely */
11192744989533cbe85e8057935d230e128810168ceGrant Likelyvoid temac_indirect_out32(struct temac_local *lp, int reg, u32 value)
11292744989533cbe85e8057935d230e128810168ceGrant Likely{
11392744989533cbe85e8057935d230e128810168ceGrant Likely	if (temac_indirect_busywait(lp))
11492744989533cbe85e8057935d230e128810168ceGrant Likely		return;
11592744989533cbe85e8057935d230e128810168ceGrant Likely	temac_iow(lp, XTE_LSW0_OFFSET, value);
11692744989533cbe85e8057935d230e128810168ceGrant Likely	temac_iow(lp, XTE_CTL0_OFFSET, CNTLREG_WRITE_ENABLE_MASK | reg);
117f79d7e6f6ae397caf219cef1392ca39b3ff10833Ricardo Ribalda	temac_indirect_busywait(lp);
11892744989533cbe85e8057935d230e128810168ceGrant Likely}
11992744989533cbe85e8057935d230e128810168ceGrant Likely
120e44171f115de3dedf34064646206deb91549865fJohn Linn/**
121e44171f115de3dedf34064646206deb91549865fJohn Linn * temac_dma_in32 - Memory mapped DMA read, this function expects a
122e44171f115de3dedf34064646206deb91549865fJohn Linn * register input that is based on DCR word addresses which
123e44171f115de3dedf34064646206deb91549865fJohn Linn * are then converted to memory mapped byte addresses
124e44171f115de3dedf34064646206deb91549865fJohn Linn */
12592744989533cbe85e8057935d230e128810168ceGrant Likelystatic u32 temac_dma_in32(struct temac_local *lp, int reg)
12692744989533cbe85e8057935d230e128810168ceGrant Likely{
127e44171f115de3dedf34064646206deb91549865fJohn Linn	return in_be32((u32 *)(lp->sdma_regs + (reg << 2)));
12892744989533cbe85e8057935d230e128810168ceGrant Likely}
12992744989533cbe85e8057935d230e128810168ceGrant Likely
130e44171f115de3dedf34064646206deb91549865fJohn Linn/**
131e44171f115de3dedf34064646206deb91549865fJohn Linn * temac_dma_out32 - Memory mapped DMA read, this function expects a
132e44171f115de3dedf34064646206deb91549865fJohn Linn * register input that is based on DCR word addresses which
133e44171f115de3dedf34064646206deb91549865fJohn Linn * are then converted to memory mapped byte addresses
134e44171f115de3dedf34064646206deb91549865fJohn Linn */
13592744989533cbe85e8057935d230e128810168ceGrant Likelystatic void temac_dma_out32(struct temac_local *lp, int reg, u32 value)
13692744989533cbe85e8057935d230e128810168ceGrant Likely{
137e44171f115de3dedf34064646206deb91549865fJohn Linn	out_be32((u32 *)(lp->sdma_regs + (reg << 2)), value);
138e44171f115de3dedf34064646206deb91549865fJohn Linn}
139e44171f115de3dedf34064646206deb91549865fJohn Linn
140e44171f115de3dedf34064646206deb91549865fJohn Linn/* DMA register access functions can be DCR based or memory mapped.
141e44171f115de3dedf34064646206deb91549865fJohn Linn * The PowerPC 440 is DCR based, the PowerPC 405 and MicroBlaze are both
142e44171f115de3dedf34064646206deb91549865fJohn Linn * memory mapped.
143e44171f115de3dedf34064646206deb91549865fJohn Linn */
144e44171f115de3dedf34064646206deb91549865fJohn Linn#ifdef CONFIG_PPC_DCR
145e44171f115de3dedf34064646206deb91549865fJohn Linn
146e44171f115de3dedf34064646206deb91549865fJohn Linn/**
147e44171f115de3dedf34064646206deb91549865fJohn Linn * temac_dma_dcr_in32 - DCR based DMA read
148e44171f115de3dedf34064646206deb91549865fJohn Linn */
149e44171f115de3dedf34064646206deb91549865fJohn Linnstatic u32 temac_dma_dcr_in(struct temac_local *lp, int reg)
150e44171f115de3dedf34064646206deb91549865fJohn Linn{
151e44171f115de3dedf34064646206deb91549865fJohn Linn	return dcr_read(lp->sdma_dcrs, reg);
152e44171f115de3dedf34064646206deb91549865fJohn Linn}
153e44171f115de3dedf34064646206deb91549865fJohn Linn
154e44171f115de3dedf34064646206deb91549865fJohn Linn/**
155e44171f115de3dedf34064646206deb91549865fJohn Linn * temac_dma_dcr_out32 - DCR based DMA write
156e44171f115de3dedf34064646206deb91549865fJohn Linn */
157e44171f115de3dedf34064646206deb91549865fJohn Linnstatic void temac_dma_dcr_out(struct temac_local *lp, int reg, u32 value)
158e44171f115de3dedf34064646206deb91549865fJohn Linn{
15992744989533cbe85e8057935d230e128810168ceGrant Likely	dcr_write(lp->sdma_dcrs, reg, value);
16092744989533cbe85e8057935d230e128810168ceGrant Likely}
16192744989533cbe85e8057935d230e128810168ceGrant Likely
16292744989533cbe85e8057935d230e128810168ceGrant Likely/**
163e44171f115de3dedf34064646206deb91549865fJohn Linn * temac_dcr_setup - If the DMA is DCR based, then setup the address and
164e44171f115de3dedf34064646206deb91549865fJohn Linn * I/O  functions
165e44171f115de3dedf34064646206deb91549865fJohn Linn */
1662dc11581376829303b98eadb2de253bee065a56aGrant Likelystatic int temac_dcr_setup(struct temac_local *lp, struct platform_device *op,
167e44171f115de3dedf34064646206deb91549865fJohn Linn				struct device_node *np)
168e44171f115de3dedf34064646206deb91549865fJohn Linn{
169e44171f115de3dedf34064646206deb91549865fJohn Linn	unsigned int dcrs;
170e44171f115de3dedf34064646206deb91549865fJohn Linn
171e44171f115de3dedf34064646206deb91549865fJohn Linn	/* setup the dcr address mapping if it's in the device tree */
172e44171f115de3dedf34064646206deb91549865fJohn Linn
173e44171f115de3dedf34064646206deb91549865fJohn Linn	dcrs = dcr_resource_start(np, 0);
174e44171f115de3dedf34064646206deb91549865fJohn Linn	if (dcrs != 0) {
175e44171f115de3dedf34064646206deb91549865fJohn Linn		lp->sdma_dcrs = dcr_map(np, dcrs, dcr_resource_len(np, 0));
176e44171f115de3dedf34064646206deb91549865fJohn Linn		lp->dma_in = temac_dma_dcr_in;
177e44171f115de3dedf34064646206deb91549865fJohn Linn		lp->dma_out = temac_dma_dcr_out;
178e44171f115de3dedf34064646206deb91549865fJohn Linn		dev_dbg(&op->dev, "DCR base: %x\n", dcrs);
179e44171f115de3dedf34064646206deb91549865fJohn Linn		return 0;
180e44171f115de3dedf34064646206deb91549865fJohn Linn	}
181e44171f115de3dedf34064646206deb91549865fJohn Linn	/* no DCR in the device tree, indicate a failure */
182e44171f115de3dedf34064646206deb91549865fJohn Linn	return -1;
183e44171f115de3dedf34064646206deb91549865fJohn Linn}
184e44171f115de3dedf34064646206deb91549865fJohn Linn
185e44171f115de3dedf34064646206deb91549865fJohn Linn#else
186e44171f115de3dedf34064646206deb91549865fJohn Linn
187e44171f115de3dedf34064646206deb91549865fJohn Linn/*
188e44171f115de3dedf34064646206deb91549865fJohn Linn * temac_dcr_setup - This is a stub for when DCR is not supported,
189e44171f115de3dedf34064646206deb91549865fJohn Linn * such as with MicroBlaze
190e44171f115de3dedf34064646206deb91549865fJohn Linn */
1912dc11581376829303b98eadb2de253bee065a56aGrant Likelystatic int temac_dcr_setup(struct temac_local *lp, struct platform_device *op,
192e44171f115de3dedf34064646206deb91549865fJohn Linn				struct device_node *np)
193e44171f115de3dedf34064646206deb91549865fJohn Linn{
194e44171f115de3dedf34064646206deb91549865fJohn Linn	return -1;
195e44171f115de3dedf34064646206deb91549865fJohn Linn}
196e44171f115de3dedf34064646206deb91549865fJohn Linn
197e44171f115de3dedf34064646206deb91549865fJohn Linn#endif
198e44171f115de3dedf34064646206deb91549865fJohn Linn
199e44171f115de3dedf34064646206deb91549865fJohn Linn/**
20049ce9c2cda18f62b13055dc715e7b514157c2da8Ben Hutchings * temac_dma_bd_release - Release buffer descriptor rings
201301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov */
202301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanovstatic void temac_dma_bd_release(struct net_device *ndev)
203301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov{
204301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov	struct temac_local *lp = netdev_priv(ndev);
205301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov	int i;
206301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov
20750ec1538fac0e39078d45ca5f8a5186621830058Ricardo Ribalda	/* Reset Local Link (DMA) */
20850ec1538fac0e39078d45ca5f8a5186621830058Ricardo Ribalda	lp->dma_out(lp, DMA_CONTROL_REG, DMA_CONTROL_RST);
20950ec1538fac0e39078d45ca5f8a5186621830058Ricardo Ribalda
210301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov	for (i = 0; i < RX_BD_NUM; i++) {
211301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov		if (!lp->rx_skb[i])
212301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov			break;
213301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov		else {
214301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov			dma_unmap_single(ndev->dev.parent, lp->rx_bd_v[i].phys,
215301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov					XTE_MAX_JUMBO_FRAME_SIZE, DMA_FROM_DEVICE);
216301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov			dev_kfree_skb(lp->rx_skb[i]);
217301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov		}
218301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov	}
219301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov	if (lp->rx_bd_v)
220301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov		dma_free_coherent(ndev->dev.parent,
221301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov				sizeof(*lp->rx_bd_v) * RX_BD_NUM,
222301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov				lp->rx_bd_v, lp->rx_bd_p);
223301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov	if (lp->tx_bd_v)
224301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov		dma_free_coherent(ndev->dev.parent,
225301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov				sizeof(*lp->tx_bd_v) * TX_BD_NUM,
226301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov				lp->tx_bd_v, lp->tx_bd_p);
227301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov	if (lp->rx_skb)
228301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov		kfree(lp->rx_skb);
229301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov}
230301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov
231301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov/**
23292744989533cbe85e8057935d230e128810168ceGrant Likely * temac_dma_bd_init - Setup buffer descriptor rings
23392744989533cbe85e8057935d230e128810168ceGrant Likely */
23492744989533cbe85e8057935d230e128810168ceGrant Likelystatic int temac_dma_bd_init(struct net_device *ndev)
23592744989533cbe85e8057935d230e128810168ceGrant Likely{
23692744989533cbe85e8057935d230e128810168ceGrant Likely	struct temac_local *lp = netdev_priv(ndev);
23792744989533cbe85e8057935d230e128810168ceGrant Likely	struct sk_buff *skb;
23892744989533cbe85e8057935d230e128810168ceGrant Likely	int i;
23992744989533cbe85e8057935d230e128810168ceGrant Likely
240ddf98e6d30a966dbd6e675c90e2caa5b9486e519Thomas Meyer	lp->rx_skb = kcalloc(RX_BD_NUM, sizeof(*lp->rx_skb), GFP_KERNEL);
241b2adaca92c63b9bb8beb021d554f656e387a7648Joe Perches	if (!lp->rx_skb)
242fe62c298e5bcff8b3414205b7b54975918b3b5c4Denis Kirjanov		goto out;
243b2adaca92c63b9bb8beb021d554f656e387a7648Joe Perches
24492744989533cbe85e8057935d230e128810168ceGrant Likely	/* allocate the tx and rx ring buffer descriptors. */
245b595076a180a56d1bb170e6eceda6eb9d76f4cd3Uwe Kleine-König	/* returns a virtual address and a physical address. */
24692744989533cbe85e8057935d230e128810168ceGrant Likely	lp->tx_bd_v = dma_alloc_coherent(ndev->dev.parent,
24792744989533cbe85e8057935d230e128810168ceGrant Likely					 sizeof(*lp->tx_bd_v) * TX_BD_NUM,
2481f9061d27d3d2028805549c4a306324a48209057Joe Perches					 &lp->tx_bd_p, GFP_KERNEL | __GFP_ZERO);
249d0320f750093d012d3ed69fc1e8b385f654523d5Joe Perches	if (!lp->tx_bd_v)
250fe62c298e5bcff8b3414205b7b54975918b3b5c4Denis Kirjanov		goto out;
251d0320f750093d012d3ed69fc1e8b385f654523d5Joe Perches
25292744989533cbe85e8057935d230e128810168ceGrant Likely	lp->rx_bd_v = dma_alloc_coherent(ndev->dev.parent,
25392744989533cbe85e8057935d230e128810168ceGrant Likely					 sizeof(*lp->rx_bd_v) * RX_BD_NUM,
2541f9061d27d3d2028805549c4a306324a48209057Joe Perches					 &lp->rx_bd_p, GFP_KERNEL | __GFP_ZERO);
255d0320f750093d012d3ed69fc1e8b385f654523d5Joe Perches	if (!lp->rx_bd_v)
256fe62c298e5bcff8b3414205b7b54975918b3b5c4Denis Kirjanov		goto out;
25792744989533cbe85e8057935d230e128810168ceGrant Likely
25892744989533cbe85e8057935d230e128810168ceGrant Likely	for (i = 0; i < TX_BD_NUM; i++) {
25992744989533cbe85e8057935d230e128810168ceGrant Likely		lp->tx_bd_v[i].next = lp->tx_bd_p +
26092744989533cbe85e8057935d230e128810168ceGrant Likely				sizeof(*lp->tx_bd_v) * ((i + 1) % TX_BD_NUM);
26192744989533cbe85e8057935d230e128810168ceGrant Likely	}
26292744989533cbe85e8057935d230e128810168ceGrant Likely
26392744989533cbe85e8057935d230e128810168ceGrant Likely	for (i = 0; i < RX_BD_NUM; i++) {
26492744989533cbe85e8057935d230e128810168ceGrant Likely		lp->rx_bd_v[i].next = lp->rx_bd_p +
26592744989533cbe85e8057935d230e128810168ceGrant Likely				sizeof(*lp->rx_bd_v) * ((i + 1) % RX_BD_NUM);
26692744989533cbe85e8057935d230e128810168ceGrant Likely
267e44171f115de3dedf34064646206deb91549865fJohn Linn		skb = netdev_alloc_skb_ip_align(ndev,
268e44171f115de3dedf34064646206deb91549865fJohn Linn						XTE_MAX_JUMBO_FRAME_SIZE);
269720a43efd30f04a0a492c85fb997361c44fbae05Joe Perches		if (!skb)
270fe62c298e5bcff8b3414205b7b54975918b3b5c4Denis Kirjanov			goto out;
271720a43efd30f04a0a492c85fb997361c44fbae05Joe Perches
27292744989533cbe85e8057935d230e128810168ceGrant Likely		lp->rx_skb[i] = skb;
27392744989533cbe85e8057935d230e128810168ceGrant Likely		/* returns physical address of skb->data */
27492744989533cbe85e8057935d230e128810168ceGrant Likely		lp->rx_bd_v[i].phys = dma_map_single(ndev->dev.parent,
27592744989533cbe85e8057935d230e128810168ceGrant Likely						     skb->data,
27692744989533cbe85e8057935d230e128810168ceGrant Likely						     XTE_MAX_JUMBO_FRAME_SIZE,
27792744989533cbe85e8057935d230e128810168ceGrant Likely						     DMA_FROM_DEVICE);
27892744989533cbe85e8057935d230e128810168ceGrant Likely		lp->rx_bd_v[i].len = XTE_MAX_JUMBO_FRAME_SIZE;
27992744989533cbe85e8057935d230e128810168ceGrant Likely		lp->rx_bd_v[i].app0 = STS_CTRL_APP0_IRQONEND;
28092744989533cbe85e8057935d230e128810168ceGrant Likely	}
28192744989533cbe85e8057935d230e128810168ceGrant Likely
282e44171f115de3dedf34064646206deb91549865fJohn Linn	lp->dma_out(lp, TX_CHNL_CTRL, 0x10220400 |
28392744989533cbe85e8057935d230e128810168ceGrant Likely					  CHNL_CTRL_IRQ_EN |
28492744989533cbe85e8057935d230e128810168ceGrant Likely					  CHNL_CTRL_IRQ_DLY_EN |
28592744989533cbe85e8057935d230e128810168ceGrant Likely					  CHNL_CTRL_IRQ_COAL_EN);
28692744989533cbe85e8057935d230e128810168ceGrant Likely	/* 0x10220483 */
28792744989533cbe85e8057935d230e128810168ceGrant Likely	/* 0x00100483 */
28823ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill	lp->dma_out(lp, RX_CHNL_CTRL, 0xff070000 |
28992744989533cbe85e8057935d230e128810168ceGrant Likely					  CHNL_CTRL_IRQ_EN |
29092744989533cbe85e8057935d230e128810168ceGrant Likely					  CHNL_CTRL_IRQ_DLY_EN |
29192744989533cbe85e8057935d230e128810168ceGrant Likely					  CHNL_CTRL_IRQ_COAL_EN |
29292744989533cbe85e8057935d230e128810168ceGrant Likely					  CHNL_CTRL_IRQ_IOE);
29392744989533cbe85e8057935d230e128810168ceGrant Likely	/* 0xff010283 */
29492744989533cbe85e8057935d230e128810168ceGrant Likely
295e44171f115de3dedf34064646206deb91549865fJohn Linn	lp->dma_out(lp, RX_CURDESC_PTR,  lp->rx_bd_p);
296e44171f115de3dedf34064646206deb91549865fJohn Linn	lp->dma_out(lp, RX_TAILDESC_PTR,
29792744989533cbe85e8057935d230e128810168ceGrant Likely		       lp->rx_bd_p + (sizeof(*lp->rx_bd_v) * (RX_BD_NUM - 1)));
298e44171f115de3dedf34064646206deb91549865fJohn Linn	lp->dma_out(lp, TX_CURDESC_PTR, lp->tx_bd_p);
29992744989533cbe85e8057935d230e128810168ceGrant Likely
30092744989533cbe85e8057935d230e128810168ceGrant Likely	return 0;
301fe62c298e5bcff8b3414205b7b54975918b3b5c4Denis Kirjanov
302fe62c298e5bcff8b3414205b7b54975918b3b5c4Denis Kirjanovout:
303301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov	temac_dma_bd_release(ndev);
304fe62c298e5bcff8b3414205b7b54975918b3b5c4Denis Kirjanov	return -ENOMEM;
30592744989533cbe85e8057935d230e128810168ceGrant Likely}
30692744989533cbe85e8057935d230e128810168ceGrant Likely
30792744989533cbe85e8057935d230e128810168ceGrant Likely/* ---------------------------------------------------------------------
30892744989533cbe85e8057935d230e128810168ceGrant Likely * net_device_ops
30992744989533cbe85e8057935d230e128810168ceGrant Likely */
31092744989533cbe85e8057935d230e128810168ceGrant Likely
31104e406dcc54cfd84d333ea673fa986fb5a1840e7Jiri Pirkostatic void temac_do_set_mac_address(struct net_device *ndev)
31292744989533cbe85e8057935d230e128810168ceGrant Likely{
31392744989533cbe85e8057935d230e128810168ceGrant Likely	struct temac_local *lp = netdev_priv(ndev);
31492744989533cbe85e8057935d230e128810168ceGrant Likely
31592744989533cbe85e8057935d230e128810168ceGrant Likely	/* set up unicast MAC address filter set its mac address */
31692744989533cbe85e8057935d230e128810168ceGrant Likely	mutex_lock(&lp->indirect_mutex);
31792744989533cbe85e8057935d230e128810168ceGrant Likely	temac_indirect_out32(lp, XTE_UAW0_OFFSET,
31892744989533cbe85e8057935d230e128810168ceGrant Likely			     (ndev->dev_addr[0]) |
31992744989533cbe85e8057935d230e128810168ceGrant Likely			     (ndev->dev_addr[1] << 8) |
32092744989533cbe85e8057935d230e128810168ceGrant Likely			     (ndev->dev_addr[2] << 16) |
32192744989533cbe85e8057935d230e128810168ceGrant Likely			     (ndev->dev_addr[3] << 24));
32292744989533cbe85e8057935d230e128810168ceGrant Likely	/* There are reserved bits in EUAW1
32392744989533cbe85e8057935d230e128810168ceGrant Likely	 * so don't affect them Set MAC bits [47:32] in EUAW1 */
32492744989533cbe85e8057935d230e128810168ceGrant Likely	temac_indirect_out32(lp, XTE_UAW1_OFFSET,
32592744989533cbe85e8057935d230e128810168ceGrant Likely			     (ndev->dev_addr[4] & 0x000000ff) |
32692744989533cbe85e8057935d230e128810168ceGrant Likely			     (ndev->dev_addr[5] << 8));
32792744989533cbe85e8057935d230e128810168ceGrant Likely	mutex_unlock(&lp->indirect_mutex);
32804e406dcc54cfd84d333ea673fa986fb5a1840e7Jiri Pirko}
32992744989533cbe85e8057935d230e128810168ceGrant Likely
33004e406dcc54cfd84d333ea673fa986fb5a1840e7Jiri Pirkostatic int temac_init_mac_address(struct net_device *ndev, void *address)
33104e406dcc54cfd84d333ea673fa986fb5a1840e7Jiri Pirko{
33204e406dcc54cfd84d333ea673fa986fb5a1840e7Jiri Pirko	memcpy(ndev->dev_addr, address, ETH_ALEN);
33304e406dcc54cfd84d333ea673fa986fb5a1840e7Jiri Pirko	if (!is_valid_ether_addr(ndev->dev_addr))
33404e406dcc54cfd84d333ea673fa986fb5a1840e7Jiri Pirko		eth_hw_addr_random(ndev);
33504e406dcc54cfd84d333ea673fa986fb5a1840e7Jiri Pirko	temac_do_set_mac_address(ndev);
33692744989533cbe85e8057935d230e128810168ceGrant Likely	return 0;
33792744989533cbe85e8057935d230e128810168ceGrant Likely}
33892744989533cbe85e8057935d230e128810168ceGrant Likely
33904e406dcc54cfd84d333ea673fa986fb5a1840e7Jiri Pirkostatic int temac_set_mac_address(struct net_device *ndev, void *p)
3408ea7a37c5a312bfee51ff7f12f78efe4fbc901ccSteven J. Magnani{
3418ea7a37c5a312bfee51ff7f12f78efe4fbc901ccSteven J. Magnani	struct sockaddr *addr = p;
3428ea7a37c5a312bfee51ff7f12f78efe4fbc901ccSteven J. Magnani
34304e406dcc54cfd84d333ea673fa986fb5a1840e7Jiri Pirko	if (!is_valid_ether_addr(addr->sa_data))
34404e406dcc54cfd84d333ea673fa986fb5a1840e7Jiri Pirko		return -EADDRNOTAVAIL;
34504e406dcc54cfd84d333ea673fa986fb5a1840e7Jiri Pirko	memcpy(ndev->dev_addr, addr->sa_data, ETH_ALEN);
34604e406dcc54cfd84d333ea673fa986fb5a1840e7Jiri Pirko	temac_do_set_mac_address(ndev);
34704e406dcc54cfd84d333ea673fa986fb5a1840e7Jiri Pirko	return 0;
3488ea7a37c5a312bfee51ff7f12f78efe4fbc901ccSteven J. Magnani}
3498ea7a37c5a312bfee51ff7f12f78efe4fbc901ccSteven J. Magnani
35092744989533cbe85e8057935d230e128810168ceGrant Likelystatic void temac_set_multicast_list(struct net_device *ndev)
35192744989533cbe85e8057935d230e128810168ceGrant Likely{
35292744989533cbe85e8057935d230e128810168ceGrant Likely	struct temac_local *lp = netdev_priv(ndev);
35392744989533cbe85e8057935d230e128810168ceGrant Likely	u32 multi_addr_msw, multi_addr_lsw, val;
35492744989533cbe85e8057935d230e128810168ceGrant Likely	int i;
35592744989533cbe85e8057935d230e128810168ceGrant Likely
35692744989533cbe85e8057935d230e128810168ceGrant Likely	mutex_lock(&lp->indirect_mutex);
3578e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches	if (ndev->flags & (IFF_ALLMULTI | IFF_PROMISC) ||
3584cd24eaf0c6ee7f0242e34ee77ec899f255e66b5Jiri Pirko	    netdev_mc_count(ndev) > MULTICAST_CAM_TABLE_NUM) {
35992744989533cbe85e8057935d230e128810168ceGrant Likely		/*
36092744989533cbe85e8057935d230e128810168ceGrant Likely		 *	We must make the kernel realise we had to move
36192744989533cbe85e8057935d230e128810168ceGrant Likely		 *	into promisc mode or we start all out war on
36292744989533cbe85e8057935d230e128810168ceGrant Likely		 *	the cable. If it was a promisc request the
36392744989533cbe85e8057935d230e128810168ceGrant Likely		 *	flag is already set. If not we assert it.
36492744989533cbe85e8057935d230e128810168ceGrant Likely		 */
36592744989533cbe85e8057935d230e128810168ceGrant Likely		ndev->flags |= IFF_PROMISC;
36692744989533cbe85e8057935d230e128810168ceGrant Likely		temac_indirect_out32(lp, XTE_AFM_OFFSET, XTE_AFM_EPPRM_MASK);
36792744989533cbe85e8057935d230e128810168ceGrant Likely		dev_info(&ndev->dev, "Promiscuous mode enabled.\n");
3684cd24eaf0c6ee7f0242e34ee77ec899f255e66b5Jiri Pirko	} else if (!netdev_mc_empty(ndev)) {
36922bedad3ce112d5ca1eaf043d4990fa2ed698c87Jiri Pirko		struct netdev_hw_addr *ha;
37092744989533cbe85e8057935d230e128810168ceGrant Likely
371f9dcbcc9e338d08c0f7de7eba4eaafbbb7f81249Jiri Pirko		i = 0;
37222bedad3ce112d5ca1eaf043d4990fa2ed698c87Jiri Pirko		netdev_for_each_mc_addr(ha, ndev) {
37392744989533cbe85e8057935d230e128810168ceGrant Likely			if (i >= MULTICAST_CAM_TABLE_NUM)
37492744989533cbe85e8057935d230e128810168ceGrant Likely				break;
37522bedad3ce112d5ca1eaf043d4990fa2ed698c87Jiri Pirko			multi_addr_msw = ((ha->addr[3] << 24) |
37622bedad3ce112d5ca1eaf043d4990fa2ed698c87Jiri Pirko					  (ha->addr[2] << 16) |
37722bedad3ce112d5ca1eaf043d4990fa2ed698c87Jiri Pirko					  (ha->addr[1] << 8) |
37822bedad3ce112d5ca1eaf043d4990fa2ed698c87Jiri Pirko					  (ha->addr[0]));
37992744989533cbe85e8057935d230e128810168ceGrant Likely			temac_indirect_out32(lp, XTE_MAW0_OFFSET,
38092744989533cbe85e8057935d230e128810168ceGrant Likely					     multi_addr_msw);
38122bedad3ce112d5ca1eaf043d4990fa2ed698c87Jiri Pirko			multi_addr_lsw = ((ha->addr[5] << 8) |
38222bedad3ce112d5ca1eaf043d4990fa2ed698c87Jiri Pirko					  (ha->addr[4]) | (i << 16));
38392744989533cbe85e8057935d230e128810168ceGrant Likely			temac_indirect_out32(lp, XTE_MAW1_OFFSET,
38492744989533cbe85e8057935d230e128810168ceGrant Likely					     multi_addr_lsw);
385f9dcbcc9e338d08c0f7de7eba4eaafbbb7f81249Jiri Pirko			i++;
38692744989533cbe85e8057935d230e128810168ceGrant Likely		}
38792744989533cbe85e8057935d230e128810168ceGrant Likely	} else {
38892744989533cbe85e8057935d230e128810168ceGrant Likely		val = temac_indirect_in32(lp, XTE_AFM_OFFSET);
38992744989533cbe85e8057935d230e128810168ceGrant Likely		temac_indirect_out32(lp, XTE_AFM_OFFSET,
39092744989533cbe85e8057935d230e128810168ceGrant Likely				     val & ~XTE_AFM_EPPRM_MASK);
39192744989533cbe85e8057935d230e128810168ceGrant Likely		temac_indirect_out32(lp, XTE_MAW0_OFFSET, 0);
39292744989533cbe85e8057935d230e128810168ceGrant Likely		temac_indirect_out32(lp, XTE_MAW1_OFFSET, 0);
39392744989533cbe85e8057935d230e128810168ceGrant Likely		dev_info(&ndev->dev, "Promiscuous mode disabled.\n");
39492744989533cbe85e8057935d230e128810168ceGrant Likely	}
39592744989533cbe85e8057935d230e128810168ceGrant Likely	mutex_unlock(&lp->indirect_mutex);
39692744989533cbe85e8057935d230e128810168ceGrant Likely}
39792744989533cbe85e8057935d230e128810168ceGrant Likely
39892744989533cbe85e8057935d230e128810168ceGrant Likelystruct temac_option {
39992744989533cbe85e8057935d230e128810168ceGrant Likely	int flg;
40092744989533cbe85e8057935d230e128810168ceGrant Likely	u32 opt;
40192744989533cbe85e8057935d230e128810168ceGrant Likely	u32 reg;
40292744989533cbe85e8057935d230e128810168ceGrant Likely	u32 m_or;
40392744989533cbe85e8057935d230e128810168ceGrant Likely	u32 m_and;
40492744989533cbe85e8057935d230e128810168ceGrant Likely} temac_options[] = {
40592744989533cbe85e8057935d230e128810168ceGrant Likely	/* Turn on jumbo packet support for both Rx and Tx */
40692744989533cbe85e8057935d230e128810168ceGrant Likely	{
40792744989533cbe85e8057935d230e128810168ceGrant Likely		.opt = XTE_OPTION_JUMBO,
40892744989533cbe85e8057935d230e128810168ceGrant Likely		.reg = XTE_TXC_OFFSET,
40992744989533cbe85e8057935d230e128810168ceGrant Likely		.m_or = XTE_TXC_TXJMBO_MASK,
41092744989533cbe85e8057935d230e128810168ceGrant Likely	},
41192744989533cbe85e8057935d230e128810168ceGrant Likely	{
41292744989533cbe85e8057935d230e128810168ceGrant Likely		.opt = XTE_OPTION_JUMBO,
41392744989533cbe85e8057935d230e128810168ceGrant Likely		.reg = XTE_RXC1_OFFSET,
41492744989533cbe85e8057935d230e128810168ceGrant Likely		.m_or =XTE_RXC1_RXJMBO_MASK,
41592744989533cbe85e8057935d230e128810168ceGrant Likely	},
41692744989533cbe85e8057935d230e128810168ceGrant Likely	/* Turn on VLAN packet support for both Rx and Tx */
41792744989533cbe85e8057935d230e128810168ceGrant Likely	{
41892744989533cbe85e8057935d230e128810168ceGrant Likely		.opt = XTE_OPTION_VLAN,
41992744989533cbe85e8057935d230e128810168ceGrant Likely		.reg = XTE_TXC_OFFSET,
42092744989533cbe85e8057935d230e128810168ceGrant Likely		.m_or =XTE_TXC_TXVLAN_MASK,
42192744989533cbe85e8057935d230e128810168ceGrant Likely	},
42292744989533cbe85e8057935d230e128810168ceGrant Likely	{
42392744989533cbe85e8057935d230e128810168ceGrant Likely		.opt = XTE_OPTION_VLAN,
42492744989533cbe85e8057935d230e128810168ceGrant Likely		.reg = XTE_RXC1_OFFSET,
42592744989533cbe85e8057935d230e128810168ceGrant Likely		.m_or =XTE_RXC1_RXVLAN_MASK,
42692744989533cbe85e8057935d230e128810168ceGrant Likely	},
42792744989533cbe85e8057935d230e128810168ceGrant Likely	/* Turn on FCS stripping on receive packets */
42892744989533cbe85e8057935d230e128810168ceGrant Likely	{
42992744989533cbe85e8057935d230e128810168ceGrant Likely		.opt = XTE_OPTION_FCS_STRIP,
43092744989533cbe85e8057935d230e128810168ceGrant Likely		.reg = XTE_RXC1_OFFSET,
43192744989533cbe85e8057935d230e128810168ceGrant Likely		.m_or =XTE_RXC1_RXFCS_MASK,
43292744989533cbe85e8057935d230e128810168ceGrant Likely	},
43392744989533cbe85e8057935d230e128810168ceGrant Likely	/* Turn on FCS insertion on transmit packets */
43492744989533cbe85e8057935d230e128810168ceGrant Likely	{
43592744989533cbe85e8057935d230e128810168ceGrant Likely		.opt = XTE_OPTION_FCS_INSERT,
43692744989533cbe85e8057935d230e128810168ceGrant Likely		.reg = XTE_TXC_OFFSET,
43792744989533cbe85e8057935d230e128810168ceGrant Likely		.m_or =XTE_TXC_TXFCS_MASK,
43892744989533cbe85e8057935d230e128810168ceGrant Likely	},
43992744989533cbe85e8057935d230e128810168ceGrant Likely	/* Turn on length/type field checking on receive packets */
44092744989533cbe85e8057935d230e128810168ceGrant Likely	{
44192744989533cbe85e8057935d230e128810168ceGrant Likely		.opt = XTE_OPTION_LENTYPE_ERR,
44292744989533cbe85e8057935d230e128810168ceGrant Likely		.reg = XTE_RXC1_OFFSET,
44392744989533cbe85e8057935d230e128810168ceGrant Likely		.m_or =XTE_RXC1_RXLT_MASK,
44492744989533cbe85e8057935d230e128810168ceGrant Likely	},
44592744989533cbe85e8057935d230e128810168ceGrant Likely	/* Turn on flow control */
44692744989533cbe85e8057935d230e128810168ceGrant Likely	{
44792744989533cbe85e8057935d230e128810168ceGrant Likely		.opt = XTE_OPTION_FLOW_CONTROL,
44892744989533cbe85e8057935d230e128810168ceGrant Likely		.reg = XTE_FCC_OFFSET,
44992744989533cbe85e8057935d230e128810168ceGrant Likely		.m_or =XTE_FCC_RXFLO_MASK,
45092744989533cbe85e8057935d230e128810168ceGrant Likely	},
45192744989533cbe85e8057935d230e128810168ceGrant Likely	/* Turn on flow control */
45292744989533cbe85e8057935d230e128810168ceGrant Likely	{
45392744989533cbe85e8057935d230e128810168ceGrant Likely		.opt = XTE_OPTION_FLOW_CONTROL,
45492744989533cbe85e8057935d230e128810168ceGrant Likely		.reg = XTE_FCC_OFFSET,
45592744989533cbe85e8057935d230e128810168ceGrant Likely		.m_or =XTE_FCC_TXFLO_MASK,
45692744989533cbe85e8057935d230e128810168ceGrant Likely	},
45792744989533cbe85e8057935d230e128810168ceGrant Likely	/* Turn on promiscuous frame filtering (all frames are received ) */
45892744989533cbe85e8057935d230e128810168ceGrant Likely	{
45992744989533cbe85e8057935d230e128810168ceGrant Likely		.opt = XTE_OPTION_PROMISC,
46092744989533cbe85e8057935d230e128810168ceGrant Likely		.reg = XTE_AFM_OFFSET,
46192744989533cbe85e8057935d230e128810168ceGrant Likely		.m_or =XTE_AFM_EPPRM_MASK,
46292744989533cbe85e8057935d230e128810168ceGrant Likely	},
46392744989533cbe85e8057935d230e128810168ceGrant Likely	/* Enable transmitter if not already enabled */
46492744989533cbe85e8057935d230e128810168ceGrant Likely	{
46592744989533cbe85e8057935d230e128810168ceGrant Likely		.opt = XTE_OPTION_TXEN,
46692744989533cbe85e8057935d230e128810168ceGrant Likely		.reg = XTE_TXC_OFFSET,
46792744989533cbe85e8057935d230e128810168ceGrant Likely		.m_or =XTE_TXC_TXEN_MASK,
46892744989533cbe85e8057935d230e128810168ceGrant Likely	},
46992744989533cbe85e8057935d230e128810168ceGrant Likely	/* Enable receiver? */
47092744989533cbe85e8057935d230e128810168ceGrant Likely	{
47192744989533cbe85e8057935d230e128810168ceGrant Likely		.opt = XTE_OPTION_RXEN,
47292744989533cbe85e8057935d230e128810168ceGrant Likely		.reg = XTE_RXC1_OFFSET,
47392744989533cbe85e8057935d230e128810168ceGrant Likely		.m_or =XTE_RXC1_RXEN_MASK,
47492744989533cbe85e8057935d230e128810168ceGrant Likely	},
47592744989533cbe85e8057935d230e128810168ceGrant Likely	{}
47692744989533cbe85e8057935d230e128810168ceGrant Likely};
47792744989533cbe85e8057935d230e128810168ceGrant Likely
47892744989533cbe85e8057935d230e128810168ceGrant Likely/**
47992744989533cbe85e8057935d230e128810168ceGrant Likely * temac_setoptions
48092744989533cbe85e8057935d230e128810168ceGrant Likely */
48192744989533cbe85e8057935d230e128810168ceGrant Likelystatic u32 temac_setoptions(struct net_device *ndev, u32 options)
48292744989533cbe85e8057935d230e128810168ceGrant Likely{
48392744989533cbe85e8057935d230e128810168ceGrant Likely	struct temac_local *lp = netdev_priv(ndev);
48492744989533cbe85e8057935d230e128810168ceGrant Likely	struct temac_option *tp = &temac_options[0];
48592744989533cbe85e8057935d230e128810168ceGrant Likely	int reg;
48692744989533cbe85e8057935d230e128810168ceGrant Likely
48792744989533cbe85e8057935d230e128810168ceGrant Likely	mutex_lock(&lp->indirect_mutex);
48892744989533cbe85e8057935d230e128810168ceGrant Likely	while (tp->opt) {
48992744989533cbe85e8057935d230e128810168ceGrant Likely		reg = temac_indirect_in32(lp, tp->reg) & ~tp->m_or;
49092744989533cbe85e8057935d230e128810168ceGrant Likely		if (options & tp->opt)
49192744989533cbe85e8057935d230e128810168ceGrant Likely			reg |= tp->m_or;
49292744989533cbe85e8057935d230e128810168ceGrant Likely		temac_indirect_out32(lp, tp->reg, reg);
49392744989533cbe85e8057935d230e128810168ceGrant Likely		tp++;
49492744989533cbe85e8057935d230e128810168ceGrant Likely	}
49592744989533cbe85e8057935d230e128810168ceGrant Likely	lp->options |= options;
49692744989533cbe85e8057935d230e128810168ceGrant Likely	mutex_unlock(&lp->indirect_mutex);
49792744989533cbe85e8057935d230e128810168ceGrant Likely
498807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet	return 0;
49992744989533cbe85e8057935d230e128810168ceGrant Likely}
50092744989533cbe85e8057935d230e128810168ceGrant Likely
501421f91d21ad6f799dc7b489bb33cc560ccc56f98Uwe Kleine-König/* Initialize temac */
50292744989533cbe85e8057935d230e128810168ceGrant Likelystatic void temac_device_reset(struct net_device *ndev)
50392744989533cbe85e8057935d230e128810168ceGrant Likely{
50492744989533cbe85e8057935d230e128810168ceGrant Likely	struct temac_local *lp = netdev_priv(ndev);
50592744989533cbe85e8057935d230e128810168ceGrant Likely	u32 timeout;
50692744989533cbe85e8057935d230e128810168ceGrant Likely	u32 val;
50792744989533cbe85e8057935d230e128810168ceGrant Likely
50892744989533cbe85e8057935d230e128810168ceGrant Likely	/* Perform a software reset */
50992744989533cbe85e8057935d230e128810168ceGrant Likely
51092744989533cbe85e8057935d230e128810168ceGrant Likely	/* 0x300 host enable bit ? */
51192744989533cbe85e8057935d230e128810168ceGrant Likely	/* reset PHY through control register ?:1 */
51292744989533cbe85e8057935d230e128810168ceGrant Likely
51392744989533cbe85e8057935d230e128810168ceGrant Likely	dev_dbg(&ndev->dev, "%s()\n", __func__);
51492744989533cbe85e8057935d230e128810168ceGrant Likely
51592744989533cbe85e8057935d230e128810168ceGrant Likely	mutex_lock(&lp->indirect_mutex);
51692744989533cbe85e8057935d230e128810168ceGrant Likely	/* Reset the receiver and wait for it to finish reset */
51792744989533cbe85e8057935d230e128810168ceGrant Likely	temac_indirect_out32(lp, XTE_RXC1_OFFSET, XTE_RXC1_RXRST_MASK);
51892744989533cbe85e8057935d230e128810168ceGrant Likely	timeout = 1000;
51992744989533cbe85e8057935d230e128810168ceGrant Likely	while (temac_indirect_in32(lp, XTE_RXC1_OFFSET) & XTE_RXC1_RXRST_MASK) {
52092744989533cbe85e8057935d230e128810168ceGrant Likely		udelay(1);
52192744989533cbe85e8057935d230e128810168ceGrant Likely		if (--timeout == 0) {
52292744989533cbe85e8057935d230e128810168ceGrant Likely			dev_err(&ndev->dev,
52392744989533cbe85e8057935d230e128810168ceGrant Likely				"temac_device_reset RX reset timeout!!\n");
52492744989533cbe85e8057935d230e128810168ceGrant Likely			break;
52592744989533cbe85e8057935d230e128810168ceGrant Likely		}
52692744989533cbe85e8057935d230e128810168ceGrant Likely	}
52792744989533cbe85e8057935d230e128810168ceGrant Likely
52892744989533cbe85e8057935d230e128810168ceGrant Likely	/* Reset the transmitter and wait for it to finish reset */
52992744989533cbe85e8057935d230e128810168ceGrant Likely	temac_indirect_out32(lp, XTE_TXC_OFFSET, XTE_TXC_TXRST_MASK);
53092744989533cbe85e8057935d230e128810168ceGrant Likely	timeout = 1000;
53192744989533cbe85e8057935d230e128810168ceGrant Likely	while (temac_indirect_in32(lp, XTE_TXC_OFFSET) & XTE_TXC_TXRST_MASK) {
53292744989533cbe85e8057935d230e128810168ceGrant Likely		udelay(1);
53392744989533cbe85e8057935d230e128810168ceGrant Likely		if (--timeout == 0) {
53492744989533cbe85e8057935d230e128810168ceGrant Likely			dev_err(&ndev->dev,
53592744989533cbe85e8057935d230e128810168ceGrant Likely				"temac_device_reset TX reset timeout!!\n");
53692744989533cbe85e8057935d230e128810168ceGrant Likely			break;
53792744989533cbe85e8057935d230e128810168ceGrant Likely		}
53892744989533cbe85e8057935d230e128810168ceGrant Likely	}
53992744989533cbe85e8057935d230e128810168ceGrant Likely
54092744989533cbe85e8057935d230e128810168ceGrant Likely	/* Disable the receiver */
54192744989533cbe85e8057935d230e128810168ceGrant Likely	val = temac_indirect_in32(lp, XTE_RXC1_OFFSET);
54292744989533cbe85e8057935d230e128810168ceGrant Likely	temac_indirect_out32(lp, XTE_RXC1_OFFSET, val & ~XTE_RXC1_RXEN_MASK);
54392744989533cbe85e8057935d230e128810168ceGrant Likely
54492744989533cbe85e8057935d230e128810168ceGrant Likely	/* Reset Local Link (DMA) */
545e44171f115de3dedf34064646206deb91549865fJohn Linn	lp->dma_out(lp, DMA_CONTROL_REG, DMA_CONTROL_RST);
54692744989533cbe85e8057935d230e128810168ceGrant Likely	timeout = 1000;
547e44171f115de3dedf34064646206deb91549865fJohn Linn	while (lp->dma_in(lp, DMA_CONTROL_REG) & DMA_CONTROL_RST) {
54892744989533cbe85e8057935d230e128810168ceGrant Likely		udelay(1);
54992744989533cbe85e8057935d230e128810168ceGrant Likely		if (--timeout == 0) {
55092744989533cbe85e8057935d230e128810168ceGrant Likely			dev_err(&ndev->dev,
55192744989533cbe85e8057935d230e128810168ceGrant Likely				"temac_device_reset DMA reset timeout!!\n");
55292744989533cbe85e8057935d230e128810168ceGrant Likely			break;
55392744989533cbe85e8057935d230e128810168ceGrant Likely		}
55492744989533cbe85e8057935d230e128810168ceGrant Likely	}
555e44171f115de3dedf34064646206deb91549865fJohn Linn	lp->dma_out(lp, DMA_CONTROL_REG, DMA_TAIL_ENABLE);
55692744989533cbe85e8057935d230e128810168ceGrant Likely
557fe62c298e5bcff8b3414205b7b54975918b3b5c4Denis Kirjanov	if (temac_dma_bd_init(ndev)) {
558fe62c298e5bcff8b3414205b7b54975918b3b5c4Denis Kirjanov		dev_err(&ndev->dev,
559fe62c298e5bcff8b3414205b7b54975918b3b5c4Denis Kirjanov				"temac_device_reset descriptor allocation failed\n");
560fe62c298e5bcff8b3414205b7b54975918b3b5c4Denis Kirjanov	}
56192744989533cbe85e8057935d230e128810168ceGrant Likely
56292744989533cbe85e8057935d230e128810168ceGrant Likely	temac_indirect_out32(lp, XTE_RXC0_OFFSET, 0);
56392744989533cbe85e8057935d230e128810168ceGrant Likely	temac_indirect_out32(lp, XTE_RXC1_OFFSET, 0);
56492744989533cbe85e8057935d230e128810168ceGrant Likely	temac_indirect_out32(lp, XTE_TXC_OFFSET, 0);
56592744989533cbe85e8057935d230e128810168ceGrant Likely	temac_indirect_out32(lp, XTE_FCC_OFFSET, XTE_FCC_RXFLO_MASK);
56692744989533cbe85e8057935d230e128810168ceGrant Likely
56792744989533cbe85e8057935d230e128810168ceGrant Likely	mutex_unlock(&lp->indirect_mutex);
56892744989533cbe85e8057935d230e128810168ceGrant Likely
56992744989533cbe85e8057935d230e128810168ceGrant Likely	/* Sync default options with HW
57092744989533cbe85e8057935d230e128810168ceGrant Likely	 * but leave receiver and transmitter disabled.  */
57192744989533cbe85e8057935d230e128810168ceGrant Likely	temac_setoptions(ndev,
57292744989533cbe85e8057935d230e128810168ceGrant Likely			 lp->options & ~(XTE_OPTION_TXEN | XTE_OPTION_RXEN));
57392744989533cbe85e8057935d230e128810168ceGrant Likely
57404e406dcc54cfd84d333ea673fa986fb5a1840e7Jiri Pirko	temac_do_set_mac_address(ndev);
57592744989533cbe85e8057935d230e128810168ceGrant Likely
57692744989533cbe85e8057935d230e128810168ceGrant Likely	/* Set address filter table */
57792744989533cbe85e8057935d230e128810168ceGrant Likely	temac_set_multicast_list(ndev);
57892744989533cbe85e8057935d230e128810168ceGrant Likely	if (temac_setoptions(ndev, lp->options))
57992744989533cbe85e8057935d230e128810168ceGrant Likely		dev_err(&ndev->dev, "Error setting TEMAC options\n");
58092744989533cbe85e8057935d230e128810168ceGrant Likely
58192744989533cbe85e8057935d230e128810168ceGrant Likely	/* Init Driver variable */
5821ae5dc342ac78d7a42965fd1f323815f6f5ef2c1Eric Dumazet	ndev->trans_start = jiffies; /* prevent tx timeout */
58392744989533cbe85e8057935d230e128810168ceGrant Likely}
58492744989533cbe85e8057935d230e128810168ceGrant Likely
58592744989533cbe85e8057935d230e128810168ceGrant Likelyvoid temac_adjust_link(struct net_device *ndev)
58692744989533cbe85e8057935d230e128810168ceGrant Likely{
58792744989533cbe85e8057935d230e128810168ceGrant Likely	struct temac_local *lp = netdev_priv(ndev);
58892744989533cbe85e8057935d230e128810168ceGrant Likely	struct phy_device *phy = lp->phy_dev;
58992744989533cbe85e8057935d230e128810168ceGrant Likely	u32 mii_speed;
59092744989533cbe85e8057935d230e128810168ceGrant Likely	int link_state;
59192744989533cbe85e8057935d230e128810168ceGrant Likely
59292744989533cbe85e8057935d230e128810168ceGrant Likely	/* hash together the state values to decide if something has changed */
59392744989533cbe85e8057935d230e128810168ceGrant Likely	link_state = phy->speed | (phy->duplex << 1) | phy->link;
59492744989533cbe85e8057935d230e128810168ceGrant Likely
59592744989533cbe85e8057935d230e128810168ceGrant Likely	mutex_lock(&lp->indirect_mutex);
59692744989533cbe85e8057935d230e128810168ceGrant Likely	if (lp->last_link != link_state) {
59792744989533cbe85e8057935d230e128810168ceGrant Likely		mii_speed = temac_indirect_in32(lp, XTE_EMCFG_OFFSET);
59892744989533cbe85e8057935d230e128810168ceGrant Likely		mii_speed &= ~XTE_EMCFG_LINKSPD_MASK;
59992744989533cbe85e8057935d230e128810168ceGrant Likely
60092744989533cbe85e8057935d230e128810168ceGrant Likely		switch (phy->speed) {
60192744989533cbe85e8057935d230e128810168ceGrant Likely		case SPEED_1000: mii_speed |= XTE_EMCFG_LINKSPD_1000; break;
60292744989533cbe85e8057935d230e128810168ceGrant Likely		case SPEED_100: mii_speed |= XTE_EMCFG_LINKSPD_100; break;
60392744989533cbe85e8057935d230e128810168ceGrant Likely		case SPEED_10: mii_speed |= XTE_EMCFG_LINKSPD_10; break;
60492744989533cbe85e8057935d230e128810168ceGrant Likely		}
60592744989533cbe85e8057935d230e128810168ceGrant Likely
60692744989533cbe85e8057935d230e128810168ceGrant Likely		/* Write new speed setting out to TEMAC */
60792744989533cbe85e8057935d230e128810168ceGrant Likely		temac_indirect_out32(lp, XTE_EMCFG_OFFSET, mii_speed);
60892744989533cbe85e8057935d230e128810168ceGrant Likely		lp->last_link = link_state;
60992744989533cbe85e8057935d230e128810168ceGrant Likely		phy_print_status(phy);
61092744989533cbe85e8057935d230e128810168ceGrant Likely	}
61192744989533cbe85e8057935d230e128810168ceGrant Likely	mutex_unlock(&lp->indirect_mutex);
61292744989533cbe85e8057935d230e128810168ceGrant Likely}
61392744989533cbe85e8057935d230e128810168ceGrant Likely
61492744989533cbe85e8057935d230e128810168ceGrant Likelystatic void temac_start_xmit_done(struct net_device *ndev)
61592744989533cbe85e8057935d230e128810168ceGrant Likely{
61692744989533cbe85e8057935d230e128810168ceGrant Likely	struct temac_local *lp = netdev_priv(ndev);
61792744989533cbe85e8057935d230e128810168ceGrant Likely	struct cdmac_bd *cur_p;
61892744989533cbe85e8057935d230e128810168ceGrant Likely	unsigned int stat = 0;
61992744989533cbe85e8057935d230e128810168ceGrant Likely
62092744989533cbe85e8057935d230e128810168ceGrant Likely	cur_p = &lp->tx_bd_v[lp->tx_bd_ci];
62192744989533cbe85e8057935d230e128810168ceGrant Likely	stat = cur_p->app0;
62292744989533cbe85e8057935d230e128810168ceGrant Likely
62392744989533cbe85e8057935d230e128810168ceGrant Likely	while (stat & STS_CTRL_APP0_CMPLT) {
62492744989533cbe85e8057935d230e128810168ceGrant Likely		dma_unmap_single(ndev->dev.parent, cur_p->phys, cur_p->len,
62592744989533cbe85e8057935d230e128810168ceGrant Likely				 DMA_TO_DEVICE);
62692744989533cbe85e8057935d230e128810168ceGrant Likely		if (cur_p->app4)
62792744989533cbe85e8057935d230e128810168ceGrant Likely			dev_kfree_skb_irq((struct sk_buff *)cur_p->app4);
62892744989533cbe85e8057935d230e128810168ceGrant Likely		cur_p->app0 = 0;
62923ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill		cur_p->app1 = 0;
63023ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill		cur_p->app2 = 0;
63123ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill		cur_p->app3 = 0;
63223ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill		cur_p->app4 = 0;
63392744989533cbe85e8057935d230e128810168ceGrant Likely
63492744989533cbe85e8057935d230e128810168ceGrant Likely		ndev->stats.tx_packets++;
63592744989533cbe85e8057935d230e128810168ceGrant Likely		ndev->stats.tx_bytes += cur_p->len;
63692744989533cbe85e8057935d230e128810168ceGrant Likely
63792744989533cbe85e8057935d230e128810168ceGrant Likely		lp->tx_bd_ci++;
63892744989533cbe85e8057935d230e128810168ceGrant Likely		if (lp->tx_bd_ci >= TX_BD_NUM)
63992744989533cbe85e8057935d230e128810168ceGrant Likely			lp->tx_bd_ci = 0;
64092744989533cbe85e8057935d230e128810168ceGrant Likely
64192744989533cbe85e8057935d230e128810168ceGrant Likely		cur_p = &lp->tx_bd_v[lp->tx_bd_ci];
64292744989533cbe85e8057935d230e128810168ceGrant Likely		stat = cur_p->app0;
64392744989533cbe85e8057935d230e128810168ceGrant Likely	}
64492744989533cbe85e8057935d230e128810168ceGrant Likely
64592744989533cbe85e8057935d230e128810168ceGrant Likely	netif_wake_queue(ndev);
64692744989533cbe85e8057935d230e128810168ceGrant Likely}
64792744989533cbe85e8057935d230e128810168ceGrant Likely
64823ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hillstatic inline int temac_check_tx_bd_space(struct temac_local *lp, int num_frag)
64923ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill{
65023ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill	struct cdmac_bd *cur_p;
65123ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill	int tail;
65223ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill
65323ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill	tail = lp->tx_bd_tail;
65423ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill	cur_p = &lp->tx_bd_v[tail];
65523ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill
65623ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill	do {
65723ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill		if (cur_p->app0)
65823ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill			return NETDEV_TX_BUSY;
65923ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill
66023ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill		tail++;
66123ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill		if (tail >= TX_BD_NUM)
66223ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill			tail = 0;
66323ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill
66423ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill		cur_p = &lp->tx_bd_v[tail];
66523ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill		num_frag--;
66623ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill	} while (num_frag >= 0);
66723ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill
66823ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill	return 0;
66923ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill}
67023ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill
67192744989533cbe85e8057935d230e128810168ceGrant Likelystatic int temac_start_xmit(struct sk_buff *skb, struct net_device *ndev)
67292744989533cbe85e8057935d230e128810168ceGrant Likely{
67392744989533cbe85e8057935d230e128810168ceGrant Likely	struct temac_local *lp = netdev_priv(ndev);
67492744989533cbe85e8057935d230e128810168ceGrant Likely	struct cdmac_bd *cur_p;
67592744989533cbe85e8057935d230e128810168ceGrant Likely	dma_addr_t start_p, tail_p;
67692744989533cbe85e8057935d230e128810168ceGrant Likely	int ii;
67792744989533cbe85e8057935d230e128810168ceGrant Likely	unsigned long num_frag;
67892744989533cbe85e8057935d230e128810168ceGrant Likely	skb_frag_t *frag;
67992744989533cbe85e8057935d230e128810168ceGrant Likely
68092744989533cbe85e8057935d230e128810168ceGrant Likely	num_frag = skb_shinfo(skb)->nr_frags;
68192744989533cbe85e8057935d230e128810168ceGrant Likely	frag = &skb_shinfo(skb)->frags[0];
68292744989533cbe85e8057935d230e128810168ceGrant Likely	start_p = lp->tx_bd_p + sizeof(*lp->tx_bd_v) * lp->tx_bd_tail;
68392744989533cbe85e8057935d230e128810168ceGrant Likely	cur_p = &lp->tx_bd_v[lp->tx_bd_tail];
68492744989533cbe85e8057935d230e128810168ceGrant Likely
68523ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill	if (temac_check_tx_bd_space(lp, num_frag)) {
68692744989533cbe85e8057935d230e128810168ceGrant Likely		if (!netif_queue_stopped(ndev)) {
68792744989533cbe85e8057935d230e128810168ceGrant Likely			netif_stop_queue(ndev);
68892744989533cbe85e8057935d230e128810168ceGrant Likely			return NETDEV_TX_BUSY;
68992744989533cbe85e8057935d230e128810168ceGrant Likely		}
69092744989533cbe85e8057935d230e128810168ceGrant Likely		return NETDEV_TX_BUSY;
69192744989533cbe85e8057935d230e128810168ceGrant Likely	}
69292744989533cbe85e8057935d230e128810168ceGrant Likely
69392744989533cbe85e8057935d230e128810168ceGrant Likely	cur_p->app0 = 0;
69492744989533cbe85e8057935d230e128810168ceGrant Likely	if (skb->ip_summed == CHECKSUM_PARTIAL) {
6950d0b16727f24f8258eeb33818347ca0f4557f982Michał Mirosław		unsigned int csum_start_off = skb_checksum_start_offset(skb);
69623ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill		unsigned int csum_index_off = csum_start_off + skb->csum_offset;
69723ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill
69823ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill		cur_p->app0 |= 1; /* TX Checksum Enabled */
69923ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill		cur_p->app1 = (csum_start_off << 16) | csum_index_off;
70023ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill		cur_p->app2 = 0;  /* initial checksum seed */
70192744989533cbe85e8057935d230e128810168ceGrant Likely	}
70223ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill
70392744989533cbe85e8057935d230e128810168ceGrant Likely	cur_p->app0 |= STS_CTRL_APP0_SOP;
70492744989533cbe85e8057935d230e128810168ceGrant Likely	cur_p->len = skb_headlen(skb);
70592744989533cbe85e8057935d230e128810168ceGrant Likely	cur_p->phys = dma_map_single(ndev->dev.parent, skb->data, skb->len,
70692744989533cbe85e8057935d230e128810168ceGrant Likely				     DMA_TO_DEVICE);
70792744989533cbe85e8057935d230e128810168ceGrant Likely	cur_p->app4 = (unsigned long)skb;
70892744989533cbe85e8057935d230e128810168ceGrant Likely
70992744989533cbe85e8057935d230e128810168ceGrant Likely	for (ii = 0; ii < num_frag; ii++) {
71092744989533cbe85e8057935d230e128810168ceGrant Likely		lp->tx_bd_tail++;
71192744989533cbe85e8057935d230e128810168ceGrant Likely		if (lp->tx_bd_tail >= TX_BD_NUM)
71292744989533cbe85e8057935d230e128810168ceGrant Likely			lp->tx_bd_tail = 0;
71392744989533cbe85e8057935d230e128810168ceGrant Likely
71492744989533cbe85e8057935d230e128810168ceGrant Likely		cur_p = &lp->tx_bd_v[lp->tx_bd_tail];
71592744989533cbe85e8057935d230e128810168ceGrant Likely		cur_p->phys = dma_map_single(ndev->dev.parent,
7163ed6f6958c0ac21958285d8648f14d34da4bbcb3Ian Campbell					     skb_frag_address(frag),
7172edcd4ca43df3c1d1d392753531cc73a53e709baStephen Rothwell					     skb_frag_size(frag), DMA_TO_DEVICE);
7182edcd4ca43df3c1d1d392753531cc73a53e709baStephen Rothwell		cur_p->len = skb_frag_size(frag);
71992744989533cbe85e8057935d230e128810168ceGrant Likely		cur_p->app0 = 0;
72092744989533cbe85e8057935d230e128810168ceGrant Likely		frag++;
72192744989533cbe85e8057935d230e128810168ceGrant Likely	}
72292744989533cbe85e8057935d230e128810168ceGrant Likely	cur_p->app0 |= STS_CTRL_APP0_EOP;
72392744989533cbe85e8057935d230e128810168ceGrant Likely
72492744989533cbe85e8057935d230e128810168ceGrant Likely	tail_p = lp->tx_bd_p + sizeof(*lp->tx_bd_v) * lp->tx_bd_tail;
72592744989533cbe85e8057935d230e128810168ceGrant Likely	lp->tx_bd_tail++;
72692744989533cbe85e8057935d230e128810168ceGrant Likely	if (lp->tx_bd_tail >= TX_BD_NUM)
72792744989533cbe85e8057935d230e128810168ceGrant Likely		lp->tx_bd_tail = 0;
72892744989533cbe85e8057935d230e128810168ceGrant Likely
72993e0ed158c15b3d3d76125de6364f8f95528c25aRichard Cochran	skb_tx_timestamp(skb);
73093e0ed158c15b3d3d76125de6364f8f95528c25aRichard Cochran
73192744989533cbe85e8057935d230e128810168ceGrant Likely	/* Kick off the transfer */
732e44171f115de3dedf34064646206deb91549865fJohn Linn	lp->dma_out(lp, TX_TAILDESC_PTR, tail_p); /* DMA start */
73392744989533cbe85e8057935d230e128810168ceGrant Likely
7346ed106549d17474ca17a16057f4c0ed4eba5a7caPatrick McHardy	return NETDEV_TX_OK;
73592744989533cbe85e8057935d230e128810168ceGrant Likely}
73692744989533cbe85e8057935d230e128810168ceGrant Likely
73792744989533cbe85e8057935d230e128810168ceGrant Likely
73892744989533cbe85e8057935d230e128810168ceGrant Likelystatic void ll_temac_recv(struct net_device *ndev)
73992744989533cbe85e8057935d230e128810168ceGrant Likely{
74092744989533cbe85e8057935d230e128810168ceGrant Likely	struct temac_local *lp = netdev_priv(ndev);
74192744989533cbe85e8057935d230e128810168ceGrant Likely	struct sk_buff *skb, *new_skb;
74292744989533cbe85e8057935d230e128810168ceGrant Likely	unsigned int bdstat;
74392744989533cbe85e8057935d230e128810168ceGrant Likely	struct cdmac_bd *cur_p;
74492744989533cbe85e8057935d230e128810168ceGrant Likely	dma_addr_t tail_p;
74592744989533cbe85e8057935d230e128810168ceGrant Likely	int length;
74692744989533cbe85e8057935d230e128810168ceGrant Likely	unsigned long flags;
74792744989533cbe85e8057935d230e128810168ceGrant Likely
74892744989533cbe85e8057935d230e128810168ceGrant Likely	spin_lock_irqsave(&lp->rx_lock, flags);
74992744989533cbe85e8057935d230e128810168ceGrant Likely
75092744989533cbe85e8057935d230e128810168ceGrant Likely	tail_p = lp->rx_bd_p + sizeof(*lp->rx_bd_v) * lp->rx_bd_ci;
75192744989533cbe85e8057935d230e128810168ceGrant Likely	cur_p = &lp->rx_bd_v[lp->rx_bd_ci];
75292744989533cbe85e8057935d230e128810168ceGrant Likely
75392744989533cbe85e8057935d230e128810168ceGrant Likely	bdstat = cur_p->app0;
75492744989533cbe85e8057935d230e128810168ceGrant Likely	while ((bdstat & STS_CTRL_APP0_CMPLT)) {
75592744989533cbe85e8057935d230e128810168ceGrant Likely
75692744989533cbe85e8057935d230e128810168ceGrant Likely		skb = lp->rx_skb[lp->rx_bd_ci];
757c3b7c12cd78d5c8264c87c29dcd9a8f1819f8313Steven J. Magnani		length = cur_p->app4 & 0x3FFF;
75892744989533cbe85e8057935d230e128810168ceGrant Likely
75933646d7ff5f47225cbbf3a06597ded649bf34e8dJohn Linn		dma_unmap_single(ndev->dev.parent, cur_p->phys, length,
76092744989533cbe85e8057935d230e128810168ceGrant Likely				 DMA_FROM_DEVICE);
76192744989533cbe85e8057935d230e128810168ceGrant Likely
76292744989533cbe85e8057935d230e128810168ceGrant Likely		skb_put(skb, length);
76392744989533cbe85e8057935d230e128810168ceGrant Likely		skb->protocol = eth_type_trans(skb, ndev);
764bc8acf2c8c3e43fcc192762a9f964b3e9a17748bEric Dumazet		skb_checksum_none_assert(skb);
76592744989533cbe85e8057935d230e128810168ceGrant Likely
76623ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill		/* if we're doing rx csum offload, set it up */
76723ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill		if (((lp->temac_features & TEMAC_FEATURE_RX_CSUM) != 0) &&
76823ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill			(skb->protocol == __constant_htons(ETH_P_IP)) &&
76923ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill			(skb->len > 64)) {
77023ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill
77123ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill			skb->csum = cur_p->app3 & 0xFFFF;
77223ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill			skb->ip_summed = CHECKSUM_COMPLETE;
77323ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill		}
77423ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill
77593e0ed158c15b3d3d76125de6364f8f95528c25aRichard Cochran		if (!skb_defer_rx_timestamp(skb))
77693e0ed158c15b3d3d76125de6364f8f95528c25aRichard Cochran			netif_rx(skb);
77792744989533cbe85e8057935d230e128810168ceGrant Likely
77892744989533cbe85e8057935d230e128810168ceGrant Likely		ndev->stats.rx_packets++;
77992744989533cbe85e8057935d230e128810168ceGrant Likely		ndev->stats.rx_bytes += length;
78092744989533cbe85e8057935d230e128810168ceGrant Likely
781e44171f115de3dedf34064646206deb91549865fJohn Linn		new_skb = netdev_alloc_skb_ip_align(ndev,
782e44171f115de3dedf34064646206deb91549865fJohn Linn						XTE_MAX_JUMBO_FRAME_SIZE);
783720a43efd30f04a0a492c85fb997361c44fbae05Joe Perches		if (!new_skb) {
78492744989533cbe85e8057935d230e128810168ceGrant Likely			spin_unlock_irqrestore(&lp->rx_lock, flags);
78592744989533cbe85e8057935d230e128810168ceGrant Likely			return;
78692744989533cbe85e8057935d230e128810168ceGrant Likely		}
78792744989533cbe85e8057935d230e128810168ceGrant Likely
78892744989533cbe85e8057935d230e128810168ceGrant Likely		cur_p->app0 = STS_CTRL_APP0_IRQONEND;
78992744989533cbe85e8057935d230e128810168ceGrant Likely		cur_p->phys = dma_map_single(ndev->dev.parent, new_skb->data,
79092744989533cbe85e8057935d230e128810168ceGrant Likely					     XTE_MAX_JUMBO_FRAME_SIZE,
79192744989533cbe85e8057935d230e128810168ceGrant Likely					     DMA_FROM_DEVICE);
79292744989533cbe85e8057935d230e128810168ceGrant Likely		cur_p->len = XTE_MAX_JUMBO_FRAME_SIZE;
79392744989533cbe85e8057935d230e128810168ceGrant Likely		lp->rx_skb[lp->rx_bd_ci] = new_skb;
79492744989533cbe85e8057935d230e128810168ceGrant Likely
79592744989533cbe85e8057935d230e128810168ceGrant Likely		lp->rx_bd_ci++;
79692744989533cbe85e8057935d230e128810168ceGrant Likely		if (lp->rx_bd_ci >= RX_BD_NUM)
79792744989533cbe85e8057935d230e128810168ceGrant Likely			lp->rx_bd_ci = 0;
79892744989533cbe85e8057935d230e128810168ceGrant Likely
79992744989533cbe85e8057935d230e128810168ceGrant Likely		cur_p = &lp->rx_bd_v[lp->rx_bd_ci];
80092744989533cbe85e8057935d230e128810168ceGrant Likely		bdstat = cur_p->app0;
80192744989533cbe85e8057935d230e128810168ceGrant Likely	}
802e44171f115de3dedf34064646206deb91549865fJohn Linn	lp->dma_out(lp, RX_TAILDESC_PTR, tail_p);
80392744989533cbe85e8057935d230e128810168ceGrant Likely
80492744989533cbe85e8057935d230e128810168ceGrant Likely	spin_unlock_irqrestore(&lp->rx_lock, flags);
80592744989533cbe85e8057935d230e128810168ceGrant Likely}
80692744989533cbe85e8057935d230e128810168ceGrant Likely
80792744989533cbe85e8057935d230e128810168ceGrant Likelystatic irqreturn_t ll_temac_tx_irq(int irq, void *_ndev)
80892744989533cbe85e8057935d230e128810168ceGrant Likely{
80992744989533cbe85e8057935d230e128810168ceGrant Likely	struct net_device *ndev = _ndev;
81092744989533cbe85e8057935d230e128810168ceGrant Likely	struct temac_local *lp = netdev_priv(ndev);
81192744989533cbe85e8057935d230e128810168ceGrant Likely	unsigned int status;
81292744989533cbe85e8057935d230e128810168ceGrant Likely
813e44171f115de3dedf34064646206deb91549865fJohn Linn	status = lp->dma_in(lp, TX_IRQ_REG);
814e44171f115de3dedf34064646206deb91549865fJohn Linn	lp->dma_out(lp, TX_IRQ_REG, status);
81592744989533cbe85e8057935d230e128810168ceGrant Likely
81692744989533cbe85e8057935d230e128810168ceGrant Likely	if (status & (IRQ_COAL | IRQ_DLY))
81792744989533cbe85e8057935d230e128810168ceGrant Likely		temac_start_xmit_done(lp->ndev);
81892744989533cbe85e8057935d230e128810168ceGrant Likely	if (status & 0x080)
81992744989533cbe85e8057935d230e128810168ceGrant Likely		dev_err(&ndev->dev, "DMA error 0x%x\n", status);
82092744989533cbe85e8057935d230e128810168ceGrant Likely
82192744989533cbe85e8057935d230e128810168ceGrant Likely	return IRQ_HANDLED;
82292744989533cbe85e8057935d230e128810168ceGrant Likely}
82392744989533cbe85e8057935d230e128810168ceGrant Likely
82492744989533cbe85e8057935d230e128810168ceGrant Likelystatic irqreturn_t ll_temac_rx_irq(int irq, void *_ndev)
82592744989533cbe85e8057935d230e128810168ceGrant Likely{
82692744989533cbe85e8057935d230e128810168ceGrant Likely	struct net_device *ndev = _ndev;
82792744989533cbe85e8057935d230e128810168ceGrant Likely	struct temac_local *lp = netdev_priv(ndev);
82892744989533cbe85e8057935d230e128810168ceGrant Likely	unsigned int status;
82992744989533cbe85e8057935d230e128810168ceGrant Likely
83092744989533cbe85e8057935d230e128810168ceGrant Likely	/* Read and clear the status registers */
831e44171f115de3dedf34064646206deb91549865fJohn Linn	status = lp->dma_in(lp, RX_IRQ_REG);
832e44171f115de3dedf34064646206deb91549865fJohn Linn	lp->dma_out(lp, RX_IRQ_REG, status);
83392744989533cbe85e8057935d230e128810168ceGrant Likely
83492744989533cbe85e8057935d230e128810168ceGrant Likely	if (status & (IRQ_COAL | IRQ_DLY))
83592744989533cbe85e8057935d230e128810168ceGrant Likely		ll_temac_recv(lp->ndev);
83692744989533cbe85e8057935d230e128810168ceGrant Likely
83792744989533cbe85e8057935d230e128810168ceGrant Likely	return IRQ_HANDLED;
83892744989533cbe85e8057935d230e128810168ceGrant Likely}
83992744989533cbe85e8057935d230e128810168ceGrant Likely
84092744989533cbe85e8057935d230e128810168ceGrant Likelystatic int temac_open(struct net_device *ndev)
84192744989533cbe85e8057935d230e128810168ceGrant Likely{
84292744989533cbe85e8057935d230e128810168ceGrant Likely	struct temac_local *lp = netdev_priv(ndev);
84392744989533cbe85e8057935d230e128810168ceGrant Likely	int rc;
84492744989533cbe85e8057935d230e128810168ceGrant Likely
84592744989533cbe85e8057935d230e128810168ceGrant Likely	dev_dbg(&ndev->dev, "temac_open()\n");
84692744989533cbe85e8057935d230e128810168ceGrant Likely
84792744989533cbe85e8057935d230e128810168ceGrant Likely	if (lp->phy_node) {
84892744989533cbe85e8057935d230e128810168ceGrant Likely		lp->phy_dev = of_phy_connect(lp->ndev, lp->phy_node,
84992744989533cbe85e8057935d230e128810168ceGrant Likely					     temac_adjust_link, 0, 0);
85092744989533cbe85e8057935d230e128810168ceGrant Likely		if (!lp->phy_dev) {
85192744989533cbe85e8057935d230e128810168ceGrant Likely			dev_err(lp->dev, "of_phy_connect() failed\n");
85292744989533cbe85e8057935d230e128810168ceGrant Likely			return -ENODEV;
85392744989533cbe85e8057935d230e128810168ceGrant Likely		}
85492744989533cbe85e8057935d230e128810168ceGrant Likely
85592744989533cbe85e8057935d230e128810168ceGrant Likely		phy_start(lp->phy_dev);
85692744989533cbe85e8057935d230e128810168ceGrant Likely	}
85792744989533cbe85e8057935d230e128810168ceGrant Likely
85850ec1538fac0e39078d45ca5f8a5186621830058Ricardo Ribalda	temac_device_reset(ndev);
85950ec1538fac0e39078d45ca5f8a5186621830058Ricardo Ribalda
86092744989533cbe85e8057935d230e128810168ceGrant Likely	rc = request_irq(lp->tx_irq, ll_temac_tx_irq, 0, ndev->name, ndev);
86192744989533cbe85e8057935d230e128810168ceGrant Likely	if (rc)
86292744989533cbe85e8057935d230e128810168ceGrant Likely		goto err_tx_irq;
86392744989533cbe85e8057935d230e128810168ceGrant Likely	rc = request_irq(lp->rx_irq, ll_temac_rx_irq, 0, ndev->name, ndev);
86492744989533cbe85e8057935d230e128810168ceGrant Likely	if (rc)
86592744989533cbe85e8057935d230e128810168ceGrant Likely		goto err_rx_irq;
86692744989533cbe85e8057935d230e128810168ceGrant Likely
86792744989533cbe85e8057935d230e128810168ceGrant Likely	return 0;
86892744989533cbe85e8057935d230e128810168ceGrant Likely
86992744989533cbe85e8057935d230e128810168ceGrant Likely err_rx_irq:
87092744989533cbe85e8057935d230e128810168ceGrant Likely	free_irq(lp->tx_irq, ndev);
87192744989533cbe85e8057935d230e128810168ceGrant Likely err_tx_irq:
87292744989533cbe85e8057935d230e128810168ceGrant Likely	if (lp->phy_dev)
87392744989533cbe85e8057935d230e128810168ceGrant Likely		phy_disconnect(lp->phy_dev);
87492744989533cbe85e8057935d230e128810168ceGrant Likely	lp->phy_dev = NULL;
87592744989533cbe85e8057935d230e128810168ceGrant Likely	dev_err(lp->dev, "request_irq() failed\n");
87692744989533cbe85e8057935d230e128810168ceGrant Likely	return rc;
87792744989533cbe85e8057935d230e128810168ceGrant Likely}
87892744989533cbe85e8057935d230e128810168ceGrant Likely
87992744989533cbe85e8057935d230e128810168ceGrant Likelystatic int temac_stop(struct net_device *ndev)
88092744989533cbe85e8057935d230e128810168ceGrant Likely{
88192744989533cbe85e8057935d230e128810168ceGrant Likely	struct temac_local *lp = netdev_priv(ndev);
88292744989533cbe85e8057935d230e128810168ceGrant Likely
88392744989533cbe85e8057935d230e128810168ceGrant Likely	dev_dbg(&ndev->dev, "temac_close()\n");
88492744989533cbe85e8057935d230e128810168ceGrant Likely
88592744989533cbe85e8057935d230e128810168ceGrant Likely	free_irq(lp->tx_irq, ndev);
88692744989533cbe85e8057935d230e128810168ceGrant Likely	free_irq(lp->rx_irq, ndev);
88792744989533cbe85e8057935d230e128810168ceGrant Likely
88892744989533cbe85e8057935d230e128810168ceGrant Likely	if (lp->phy_dev)
88992744989533cbe85e8057935d230e128810168ceGrant Likely		phy_disconnect(lp->phy_dev);
89092744989533cbe85e8057935d230e128810168ceGrant Likely	lp->phy_dev = NULL;
89192744989533cbe85e8057935d230e128810168ceGrant Likely
892301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov	temac_dma_bd_release(ndev);
893301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov
89492744989533cbe85e8057935d230e128810168ceGrant Likely	return 0;
89592744989533cbe85e8057935d230e128810168ceGrant Likely}
89692744989533cbe85e8057935d230e128810168ceGrant Likely
89792744989533cbe85e8057935d230e128810168ceGrant Likely#ifdef CONFIG_NET_POLL_CONTROLLER
89892744989533cbe85e8057935d230e128810168ceGrant Likelystatic void
89992744989533cbe85e8057935d230e128810168ceGrant Likelytemac_poll_controller(struct net_device *ndev)
90092744989533cbe85e8057935d230e128810168ceGrant Likely{
90192744989533cbe85e8057935d230e128810168ceGrant Likely	struct temac_local *lp = netdev_priv(ndev);
90292744989533cbe85e8057935d230e128810168ceGrant Likely
90392744989533cbe85e8057935d230e128810168ceGrant Likely	disable_irq(lp->tx_irq);
90492744989533cbe85e8057935d230e128810168ceGrant Likely	disable_irq(lp->rx_irq);
90592744989533cbe85e8057935d230e128810168ceGrant Likely
9068539992f6091eb8206c781421312157d0c282e6eMichal Simek	ll_temac_rx_irq(lp->tx_irq, ndev);
9078539992f6091eb8206c781421312157d0c282e6eMichal Simek	ll_temac_tx_irq(lp->rx_irq, ndev);
90892744989533cbe85e8057935d230e128810168ceGrant Likely
90992744989533cbe85e8057935d230e128810168ceGrant Likely	enable_irq(lp->tx_irq);
91092744989533cbe85e8057935d230e128810168ceGrant Likely	enable_irq(lp->rx_irq);
91192744989533cbe85e8057935d230e128810168ceGrant Likely}
91292744989533cbe85e8057935d230e128810168ceGrant Likely#endif
91392744989533cbe85e8057935d230e128810168ceGrant Likely
9148d8bdfe8034399357df58b5f3e4da638a9e9a257Ricardo Ribaldastatic int temac_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
9158d8bdfe8034399357df58b5f3e4da638a9e9a257Ricardo Ribalda{
9168d8bdfe8034399357df58b5f3e4da638a9e9a257Ricardo Ribalda	struct temac_local *lp = netdev_priv(ndev);
9178d8bdfe8034399357df58b5f3e4da638a9e9a257Ricardo Ribalda
9188d8bdfe8034399357df58b5f3e4da638a9e9a257Ricardo Ribalda	if (!netif_running(ndev))
9198d8bdfe8034399357df58b5f3e4da638a9e9a257Ricardo Ribalda		return -EINVAL;
9208d8bdfe8034399357df58b5f3e4da638a9e9a257Ricardo Ribalda
9218d8bdfe8034399357df58b5f3e4da638a9e9a257Ricardo Ribalda	if (!lp->phy_dev)
9228d8bdfe8034399357df58b5f3e4da638a9e9a257Ricardo Ribalda		return -EINVAL;
9238d8bdfe8034399357df58b5f3e4da638a9e9a257Ricardo Ribalda
9248d8bdfe8034399357df58b5f3e4da638a9e9a257Ricardo Ribalda	return phy_mii_ioctl(lp->phy_dev, rq, cmd);
9258d8bdfe8034399357df58b5f3e4da638a9e9a257Ricardo Ribalda}
9268d8bdfe8034399357df58b5f3e4da638a9e9a257Ricardo Ribalda
92792744989533cbe85e8057935d230e128810168ceGrant Likelystatic const struct net_device_ops temac_netdev_ops = {
92892744989533cbe85e8057935d230e128810168ceGrant Likely	.ndo_open = temac_open,
92992744989533cbe85e8057935d230e128810168ceGrant Likely	.ndo_stop = temac_stop,
93092744989533cbe85e8057935d230e128810168ceGrant Likely	.ndo_start_xmit = temac_start_xmit,
93104e406dcc54cfd84d333ea673fa986fb5a1840e7Jiri Pirko	.ndo_set_mac_address = temac_set_mac_address,
93260eb5fd11d1c6050c45a5aab141f42dd396e2a7fDenis Kirjanov	.ndo_validate_addr = eth_validate_addr,
9338d8bdfe8034399357df58b5f3e4da638a9e9a257Ricardo Ribalda	.ndo_do_ioctl = temac_ioctl,
93492744989533cbe85e8057935d230e128810168ceGrant Likely#ifdef CONFIG_NET_POLL_CONTROLLER
93592744989533cbe85e8057935d230e128810168ceGrant Likely	.ndo_poll_controller = temac_poll_controller,
93692744989533cbe85e8057935d230e128810168ceGrant Likely#endif
93792744989533cbe85e8057935d230e128810168ceGrant Likely};
93892744989533cbe85e8057935d230e128810168ceGrant Likely
93992744989533cbe85e8057935d230e128810168ceGrant Likely/* ---------------------------------------------------------------------
94092744989533cbe85e8057935d230e128810168ceGrant Likely * SYSFS device attributes
94192744989533cbe85e8057935d230e128810168ceGrant Likely */
94292744989533cbe85e8057935d230e128810168ceGrant Likelystatic ssize_t temac_show_llink_regs(struct device *dev,
94392744989533cbe85e8057935d230e128810168ceGrant Likely				     struct device_attribute *attr, char *buf)
94492744989533cbe85e8057935d230e128810168ceGrant Likely{
94592744989533cbe85e8057935d230e128810168ceGrant Likely	struct net_device *ndev = dev_get_drvdata(dev);
94692744989533cbe85e8057935d230e128810168ceGrant Likely	struct temac_local *lp = netdev_priv(ndev);
94792744989533cbe85e8057935d230e128810168ceGrant Likely	int i, len = 0;
94892744989533cbe85e8057935d230e128810168ceGrant Likely
94992744989533cbe85e8057935d230e128810168ceGrant Likely	for (i = 0; i < 0x11; i++)
950e44171f115de3dedf34064646206deb91549865fJohn Linn		len += sprintf(buf + len, "%.8x%s", lp->dma_in(lp, i),
95192744989533cbe85e8057935d230e128810168ceGrant Likely			       (i % 8) == 7 ? "\n" : " ");
95292744989533cbe85e8057935d230e128810168ceGrant Likely	len += sprintf(buf + len, "\n");
95392744989533cbe85e8057935d230e128810168ceGrant Likely
95492744989533cbe85e8057935d230e128810168ceGrant Likely	return len;
95592744989533cbe85e8057935d230e128810168ceGrant Likely}
95692744989533cbe85e8057935d230e128810168ceGrant Likely
95792744989533cbe85e8057935d230e128810168ceGrant Likelystatic DEVICE_ATTR(llink_regs, 0440, temac_show_llink_regs, NULL);
95892744989533cbe85e8057935d230e128810168ceGrant Likely
95992744989533cbe85e8057935d230e128810168ceGrant Likelystatic struct attribute *temac_device_attrs[] = {
96092744989533cbe85e8057935d230e128810168ceGrant Likely	&dev_attr_llink_regs.attr,
96192744989533cbe85e8057935d230e128810168ceGrant Likely	NULL,
96292744989533cbe85e8057935d230e128810168ceGrant Likely};
96392744989533cbe85e8057935d230e128810168ceGrant Likely
96492744989533cbe85e8057935d230e128810168ceGrant Likelystatic const struct attribute_group temac_attr_group = {
96592744989533cbe85e8057935d230e128810168ceGrant Likely	.attrs = temac_device_attrs,
96692744989533cbe85e8057935d230e128810168ceGrant Likely};
96792744989533cbe85e8057935d230e128810168ceGrant Likely
9689eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo/* ethtool support */
9699eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardostatic int temac_get_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
9709eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo{
9719eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo	struct temac_local *lp = netdev_priv(ndev);
9729eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo	return phy_ethtool_gset(lp->phy_dev, cmd);
9739eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo}
9749eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo
9759eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardostatic int temac_set_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
9769eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo{
9779eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo	struct temac_local *lp = netdev_priv(ndev);
9789eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo	return phy_ethtool_sset(lp->phy_dev, cmd);
9799eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo}
9809eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo
9819eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardostatic int temac_nway_reset(struct net_device *ndev)
9829eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo{
9839eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo	struct temac_local *lp = netdev_priv(ndev);
9849eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo	return phy_start_aneg(lp->phy_dev);
9859eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo}
9869eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo
9879eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardostatic const struct ethtool_ops temac_ethtool_ops = {
9889eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo	.get_settings = temac_get_settings,
9899eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo	.set_settings = temac_set_settings,
9909eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo	.nway_reset = temac_nway_reset,
9919eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo	.get_link = ethtool_op_get_link,
992f85e5ea28f5c1d31b22ae5777a1a08ebd76ff7e1Richard Cochran	.get_ts_info = ethtool_op_get_ts_info,
9939eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo};
9949eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo
99506b0e68327d499c3588c954d2a2d86458d451c4bBill Pembertonstatic int temac_of_probe(struct platform_device *op)
99692744989533cbe85e8057935d230e128810168ceGrant Likely{
99792744989533cbe85e8057935d230e128810168ceGrant Likely	struct device_node *np;
99892744989533cbe85e8057935d230e128810168ceGrant Likely	struct temac_local *lp;
99992744989533cbe85e8057935d230e128810168ceGrant Likely	struct net_device *ndev;
100092744989533cbe85e8057935d230e128810168ceGrant Likely	const void *addr;
100123ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill	__be32 *p;
100292744989533cbe85e8057935d230e128810168ceGrant Likely	int size, rc = 0;
100392744989533cbe85e8057935d230e128810168ceGrant Likely
100492744989533cbe85e8057935d230e128810168ceGrant Likely	/* Init network device structure */
100592744989533cbe85e8057935d230e128810168ceGrant Likely	ndev = alloc_etherdev(sizeof(*lp));
100641de8d4cff21a2e81e3d9ff66f5f7c903f9c3ab1Joe Perches	if (!ndev)
100792744989533cbe85e8057935d230e128810168ceGrant Likely		return -ENOMEM;
100841de8d4cff21a2e81e3d9ff66f5f7c903f9c3ab1Joe Perches
100992744989533cbe85e8057935d230e128810168ceGrant Likely	ether_setup(ndev);
10108513fbd880093f00a47e85a552f14ca2de8d84d6Jingoo Han	platform_set_drvdata(op, ndev);
101192744989533cbe85e8057935d230e128810168ceGrant Likely	SET_NETDEV_DEV(ndev, &op->dev);
101292744989533cbe85e8057935d230e128810168ceGrant Likely	ndev->flags &= ~IFF_MULTICAST;  /* clear multicast */
101392744989533cbe85e8057935d230e128810168ceGrant Likely	ndev->features = NETIF_F_SG | NETIF_F_FRAGLIST;
101492744989533cbe85e8057935d230e128810168ceGrant Likely	ndev->netdev_ops = &temac_netdev_ops;
10159eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo	ndev->ethtool_ops = &temac_ethtool_ops;
101692744989533cbe85e8057935d230e128810168ceGrant Likely#if 0
101792744989533cbe85e8057935d230e128810168ceGrant Likely	ndev->features |= NETIF_F_IP_CSUM; /* Can checksum TCP/UDP over IPv4. */
101892744989533cbe85e8057935d230e128810168ceGrant Likely	ndev->features |= NETIF_F_HW_CSUM; /* Can checksum all the packets. */
101992744989533cbe85e8057935d230e128810168ceGrant Likely	ndev->features |= NETIF_F_IPV6_CSUM; /* Can checksum IPV6 TCP/UDP */
102092744989533cbe85e8057935d230e128810168ceGrant Likely	ndev->features |= NETIF_F_HIGHDMA; /* Can DMA to high memory. */
1021f646968f8f7c624587de729115d802372b9063ddPatrick McHardy	ndev->features |= NETIF_F_HW_VLAN_CTAG_TX; /* Transmit VLAN hw accel */
1022f646968f8f7c624587de729115d802372b9063ddPatrick McHardy	ndev->features |= NETIF_F_HW_VLAN_CTAG_RX; /* Receive VLAN hw acceleration */
1023f646968f8f7c624587de729115d802372b9063ddPatrick McHardy	ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER; /* Receive VLAN filtering */
102492744989533cbe85e8057935d230e128810168ceGrant Likely	ndev->features |= NETIF_F_VLAN_CHALLENGED; /* cannot handle VLAN pkts */
102592744989533cbe85e8057935d230e128810168ceGrant Likely	ndev->features |= NETIF_F_GSO; /* Enable software GSO. */
102692744989533cbe85e8057935d230e128810168ceGrant Likely	ndev->features |= NETIF_F_MULTI_QUEUE; /* Has multiple TX/RX queues */
102792744989533cbe85e8057935d230e128810168ceGrant Likely	ndev->features |= NETIF_F_LRO; /* large receive offload */
102892744989533cbe85e8057935d230e128810168ceGrant Likely#endif
102992744989533cbe85e8057935d230e128810168ceGrant Likely
103092744989533cbe85e8057935d230e128810168ceGrant Likely	/* setup temac private info structure */
103192744989533cbe85e8057935d230e128810168ceGrant Likely	lp = netdev_priv(ndev);
103292744989533cbe85e8057935d230e128810168ceGrant Likely	lp->ndev = ndev;
103392744989533cbe85e8057935d230e128810168ceGrant Likely	lp->dev = &op->dev;
103492744989533cbe85e8057935d230e128810168ceGrant Likely	lp->options = XTE_OPTION_DEFAULTS;
103592744989533cbe85e8057935d230e128810168ceGrant Likely	spin_lock_init(&lp->rx_lock);
103692744989533cbe85e8057935d230e128810168ceGrant Likely	mutex_init(&lp->indirect_mutex);
103792744989533cbe85e8057935d230e128810168ceGrant Likely
103892744989533cbe85e8057935d230e128810168ceGrant Likely	/* map device registers */
103961c7a080a5a061c976988fd4b844dfb468dda255Grant Likely	lp->regs = of_iomap(op->dev.of_node, 0);
104092744989533cbe85e8057935d230e128810168ceGrant Likely	if (!lp->regs) {
104192744989533cbe85e8057935d230e128810168ceGrant Likely		dev_err(&op->dev, "could not map temac regs.\n");
104292744989533cbe85e8057935d230e128810168ceGrant Likely		goto nodev;
104392744989533cbe85e8057935d230e128810168ceGrant Likely	}
104492744989533cbe85e8057935d230e128810168ceGrant Likely
104523ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill	/* Setup checksum offload, but default to off if not specified */
104623ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill	lp->temac_features = 0;
104723ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill	p = (__be32 *)of_get_property(op->dev.of_node, "xlnx,txcsum", NULL);
104823ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill	if (p && be32_to_cpu(*p)) {
104923ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill		lp->temac_features |= TEMAC_FEATURE_TX_CSUM;
105023ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill		/* Can checksum TCP/UDP over IPv4. */
105123ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill		ndev->features |= NETIF_F_IP_CSUM;
105223ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill	}
105323ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill	p = (__be32 *)of_get_property(op->dev.of_node, "xlnx,rxcsum", NULL);
105423ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill	if (p && be32_to_cpu(*p))
105523ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill		lp->temac_features |= TEMAC_FEATURE_RX_CSUM;
105623ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill
105792744989533cbe85e8057935d230e128810168ceGrant Likely	/* Find the DMA node, map the DMA registers, and decode the DMA IRQs */
105861c7a080a5a061c976988fd4b844dfb468dda255Grant Likely	np = of_parse_phandle(op->dev.of_node, "llink-connected", 0);
105992744989533cbe85e8057935d230e128810168ceGrant Likely	if (!np) {
106092744989533cbe85e8057935d230e128810168ceGrant Likely		dev_err(&op->dev, "could not find DMA node\n");
1061dfe1e8eddcd73fc58124933c14c2efe93fab0b8fDenis Kirjanov		goto err_iounmap;
106292744989533cbe85e8057935d230e128810168ceGrant Likely	}
106392744989533cbe85e8057935d230e128810168ceGrant Likely
1064e44171f115de3dedf34064646206deb91549865fJohn Linn	/* Setup the DMA register accesses, could be DCR or memory mapped */
1065e44171f115de3dedf34064646206deb91549865fJohn Linn	if (temac_dcr_setup(lp, op, np)) {
1066e44171f115de3dedf34064646206deb91549865fJohn Linn
1067e44171f115de3dedf34064646206deb91549865fJohn Linn		/* no DCR in the device tree, try non-DCR */
1068e44171f115de3dedf34064646206deb91549865fJohn Linn		lp->sdma_regs = of_iomap(np, 0);
1069e44171f115de3dedf34064646206deb91549865fJohn Linn		if (lp->sdma_regs) {
1070e44171f115de3dedf34064646206deb91549865fJohn Linn			lp->dma_in = temac_dma_in32;
1071e44171f115de3dedf34064646206deb91549865fJohn Linn			lp->dma_out = temac_dma_out32;
1072e44171f115de3dedf34064646206deb91549865fJohn Linn			dev_dbg(&op->dev, "MEM base: %p\n", lp->sdma_regs);
1073e44171f115de3dedf34064646206deb91549865fJohn Linn		} else {
1074e44171f115de3dedf34064646206deb91549865fJohn Linn			dev_err(&op->dev, "unable to map DMA registers\n");
10757cc36f6f7116918c8a8990a0f23f62d2288a81bfKulikov Vasiliy			of_node_put(np);
1076dfe1e8eddcd73fc58124933c14c2efe93fab0b8fDenis Kirjanov			goto err_iounmap;
1077e44171f115de3dedf34064646206deb91549865fJohn Linn		}
107892744989533cbe85e8057935d230e128810168ceGrant Likely	}
107992744989533cbe85e8057935d230e128810168ceGrant Likely
108092744989533cbe85e8057935d230e128810168ceGrant Likely	lp->rx_irq = irq_of_parse_and_map(np, 0);
108192744989533cbe85e8057935d230e128810168ceGrant Likely	lp->tx_irq = irq_of_parse_and_map(np, 1);
10827cc36f6f7116918c8a8990a0f23f62d2288a81bfKulikov Vasiliy
10837cc36f6f7116918c8a8990a0f23f62d2288a81bfKulikov Vasiliy	of_node_put(np); /* Finished with the DMA node; drop the reference */
10847cc36f6f7116918c8a8990a0f23f62d2288a81bfKulikov Vasiliy
10854e68ea26e76273cc62a981a414a8319a7f4c1077Michal Simek	if (!lp->rx_irq || !lp->tx_irq) {
108692744989533cbe85e8057935d230e128810168ceGrant Likely		dev_err(&op->dev, "could not determine irqs\n");
108792744989533cbe85e8057935d230e128810168ceGrant Likely		rc = -ENOMEM;
1088dfe1e8eddcd73fc58124933c14c2efe93fab0b8fDenis Kirjanov		goto err_iounmap_2;
108992744989533cbe85e8057935d230e128810168ceGrant Likely	}
109092744989533cbe85e8057935d230e128810168ceGrant Likely
109192744989533cbe85e8057935d230e128810168ceGrant Likely
109292744989533cbe85e8057935d230e128810168ceGrant Likely	/* Retrieve the MAC address */
109361c7a080a5a061c976988fd4b844dfb468dda255Grant Likely	addr = of_get_property(op->dev.of_node, "local-mac-address", &size);
109492744989533cbe85e8057935d230e128810168ceGrant Likely	if ((!addr) || (size != 6)) {
109592744989533cbe85e8057935d230e128810168ceGrant Likely		dev_err(&op->dev, "could not find MAC address\n");
109692744989533cbe85e8057935d230e128810168ceGrant Likely		rc = -ENODEV;
1097dfe1e8eddcd73fc58124933c14c2efe93fab0b8fDenis Kirjanov		goto err_iounmap_2;
109892744989533cbe85e8057935d230e128810168ceGrant Likely	}
109904e406dcc54cfd84d333ea673fa986fb5a1840e7Jiri Pirko	temac_init_mac_address(ndev, (void *)addr);
110092744989533cbe85e8057935d230e128810168ceGrant Likely
110161c7a080a5a061c976988fd4b844dfb468dda255Grant Likely	rc = temac_mdio_setup(lp, op->dev.of_node);
110292744989533cbe85e8057935d230e128810168ceGrant Likely	if (rc)
110392744989533cbe85e8057935d230e128810168ceGrant Likely		dev_warn(&op->dev, "error registering MDIO bus\n");
110492744989533cbe85e8057935d230e128810168ceGrant Likely
110561c7a080a5a061c976988fd4b844dfb468dda255Grant Likely	lp->phy_node = of_parse_phandle(op->dev.of_node, "phy-handle", 0);
110692744989533cbe85e8057935d230e128810168ceGrant Likely	if (lp->phy_node)
110792744989533cbe85e8057935d230e128810168ceGrant Likely		dev_dbg(lp->dev, "using PHY node %s (%p)\n", np->full_name, np);
110892744989533cbe85e8057935d230e128810168ceGrant Likely
110992744989533cbe85e8057935d230e128810168ceGrant Likely	/* Add the device attributes */
111092744989533cbe85e8057935d230e128810168ceGrant Likely	rc = sysfs_create_group(&lp->dev->kobj, &temac_attr_group);
111192744989533cbe85e8057935d230e128810168ceGrant Likely	if (rc) {
111292744989533cbe85e8057935d230e128810168ceGrant Likely		dev_err(lp->dev, "Error creating sysfs files\n");
1113dfe1e8eddcd73fc58124933c14c2efe93fab0b8fDenis Kirjanov		goto err_iounmap_2;
111492744989533cbe85e8057935d230e128810168ceGrant Likely	}
111592744989533cbe85e8057935d230e128810168ceGrant Likely
111692744989533cbe85e8057935d230e128810168ceGrant Likely	rc = register_netdev(lp->ndev);
111792744989533cbe85e8057935d230e128810168ceGrant Likely	if (rc) {
111892744989533cbe85e8057935d230e128810168ceGrant Likely		dev_err(lp->dev, "register_netdev() error (%i)\n", rc);
111992744989533cbe85e8057935d230e128810168ceGrant Likely		goto err_register_ndev;
112092744989533cbe85e8057935d230e128810168ceGrant Likely	}
112192744989533cbe85e8057935d230e128810168ceGrant Likely
112292744989533cbe85e8057935d230e128810168ceGrant Likely	return 0;
112392744989533cbe85e8057935d230e128810168ceGrant Likely
112492744989533cbe85e8057935d230e128810168ceGrant Likely err_register_ndev:
112592744989533cbe85e8057935d230e128810168ceGrant Likely	sysfs_remove_group(&lp->dev->kobj, &temac_attr_group);
1126dfe1e8eddcd73fc58124933c14c2efe93fab0b8fDenis Kirjanov err_iounmap_2:
1127dfe1e8eddcd73fc58124933c14c2efe93fab0b8fDenis Kirjanov	if (lp->sdma_regs)
1128dfe1e8eddcd73fc58124933c14c2efe93fab0b8fDenis Kirjanov		iounmap(lp->sdma_regs);
1129dfe1e8eddcd73fc58124933c14c2efe93fab0b8fDenis Kirjanov err_iounmap:
1130dfe1e8eddcd73fc58124933c14c2efe93fab0b8fDenis Kirjanov	iounmap(lp->regs);
113192744989533cbe85e8057935d230e128810168ceGrant Likely nodev:
113292744989533cbe85e8057935d230e128810168ceGrant Likely	free_netdev(ndev);
113392744989533cbe85e8057935d230e128810168ceGrant Likely	ndev = NULL;
113492744989533cbe85e8057935d230e128810168ceGrant Likely	return rc;
113592744989533cbe85e8057935d230e128810168ceGrant Likely}
113692744989533cbe85e8057935d230e128810168ceGrant Likely
113706b0e68327d499c3588c954d2a2d86458d451c4bBill Pembertonstatic int temac_of_remove(struct platform_device *op)
113892744989533cbe85e8057935d230e128810168ceGrant Likely{
11398513fbd880093f00a47e85a552f14ca2de8d84d6Jingoo Han	struct net_device *ndev = platform_get_drvdata(op);
114092744989533cbe85e8057935d230e128810168ceGrant Likely	struct temac_local *lp = netdev_priv(ndev);
114192744989533cbe85e8057935d230e128810168ceGrant Likely
114292744989533cbe85e8057935d230e128810168ceGrant Likely	temac_mdio_teardown(lp);
114392744989533cbe85e8057935d230e128810168ceGrant Likely	unregister_netdev(ndev);
114492744989533cbe85e8057935d230e128810168ceGrant Likely	sysfs_remove_group(&lp->dev->kobj, &temac_attr_group);
114592744989533cbe85e8057935d230e128810168ceGrant Likely	if (lp->phy_node)
114692744989533cbe85e8057935d230e128810168ceGrant Likely		of_node_put(lp->phy_node);
114792744989533cbe85e8057935d230e128810168ceGrant Likely	lp->phy_node = NULL;
1148dfe1e8eddcd73fc58124933c14c2efe93fab0b8fDenis Kirjanov	iounmap(lp->regs);
1149dfe1e8eddcd73fc58124933c14c2efe93fab0b8fDenis Kirjanov	if (lp->sdma_regs)
1150dfe1e8eddcd73fc58124933c14c2efe93fab0b8fDenis Kirjanov		iounmap(lp->sdma_regs);
115192744989533cbe85e8057935d230e128810168ceGrant Likely	free_netdev(ndev);
115292744989533cbe85e8057935d230e128810168ceGrant Likely	return 0;
115392744989533cbe85e8057935d230e128810168ceGrant Likely}
115492744989533cbe85e8057935d230e128810168ceGrant Likely
115506b0e68327d499c3588c954d2a2d86458d451c4bBill Pembertonstatic struct of_device_id temac_of_match[] = {
115692744989533cbe85e8057935d230e128810168ceGrant Likely	{ .compatible = "xlnx,xps-ll-temac-1.01.b", },
1157c3b7c12cd78d5c8264c87c29dcd9a8f1819f8313Steven J. Magnani	{ .compatible = "xlnx,xps-ll-temac-2.00.a", },
1158c3b7c12cd78d5c8264c87c29dcd9a8f1819f8313Steven J. Magnani	{ .compatible = "xlnx,xps-ll-temac-2.02.a", },
1159c3b7c12cd78d5c8264c87c29dcd9a8f1819f8313Steven J. Magnani	{ .compatible = "xlnx,xps-ll-temac-2.03.a", },
116092744989533cbe85e8057935d230e128810168ceGrant Likely	{},
116192744989533cbe85e8057935d230e128810168ceGrant Likely};
116292744989533cbe85e8057935d230e128810168ceGrant LikelyMODULE_DEVICE_TABLE(of, temac_of_match);
116392744989533cbe85e8057935d230e128810168ceGrant Likely
116474888760d40b3ac9054f9c5fa07b566c0676ba2dGrant Likelystatic struct platform_driver temac_of_driver = {
116592744989533cbe85e8057935d230e128810168ceGrant Likely	.probe = temac_of_probe,
116606b0e68327d499c3588c954d2a2d86458d451c4bBill Pemberton	.remove = temac_of_remove,
116792744989533cbe85e8057935d230e128810168ceGrant Likely	.driver = {
116892744989533cbe85e8057935d230e128810168ceGrant Likely		.owner = THIS_MODULE,
116992744989533cbe85e8057935d230e128810168ceGrant Likely		.name = "xilinx_temac",
11704018294b53d1dae026880e45f174c1cc63b5d435Grant Likely		.of_match_table = temac_of_match,
117192744989533cbe85e8057935d230e128810168ceGrant Likely	},
117292744989533cbe85e8057935d230e128810168ceGrant Likely};
117392744989533cbe85e8057935d230e128810168ceGrant Likely
1174db62f684deeb291ab2533b99843d5df9a36b1f19Axel Linmodule_platform_driver(temac_of_driver);
117592744989533cbe85e8057935d230e128810168ceGrant Likely
117692744989533cbe85e8057935d230e128810168ceGrant LikelyMODULE_DESCRIPTION("Xilinx LL_TEMAC Ethernet driver");
117792744989533cbe85e8057935d230e128810168ceGrant LikelyMODULE_AUTHOR("Yoshio Kashiwagi");
117892744989533cbe85e8057935d230e128810168ceGrant LikelyMODULE_LICENSE("GPL");
1179