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/mii.h>
3392744989533cbe85e8057935d230e128810168ceGrant Likely#include <linux/module.h>
3492744989533cbe85e8057935d230e128810168ceGrant Likely#include <linux/mutex.h>
3592744989533cbe85e8057935d230e128810168ceGrant Likely#include <linux/netdevice.h>
3692744989533cbe85e8057935d230e128810168ceGrant Likely#include <linux/of.h>
3792744989533cbe85e8057935d230e128810168ceGrant Likely#include <linux/of_device.h>
385c9f303e996516dd0dcc2ce8c2b95504d3137b19Rob Herring#include <linux/of_irq.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{
759f8b93cb32e088d3377c86fabb666b884bac0f12Manuel Schölling	unsigned long end = jiffies + 2;
7692744989533cbe85e8057935d230e128810168ceGrant Likely
7792744989533cbe85e8057935d230e128810168ceGrant Likely	while (!(temac_ior(lp, XTE_RDY0_OFFSET) & XTE_RDY0_HARD_ACS_RDY_MASK)) {
783aeea53f0a372a8adbfc150b37319bff3d24fd04Manuel Schölling		if (time_before_eq(end, jiffies)) {
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. */
246ede23fa8161c1a04aa1b3bf5447812ca14b3fef1Joe Perches	lp->tx_bd_v = dma_zalloc_coherent(ndev->dev.parent,
247ede23fa8161c1a04aa1b3bf5447812ca14b3fef1Joe Perches					  sizeof(*lp->tx_bd_v) * TX_BD_NUM,
248ede23fa8161c1a04aa1b3bf5447812ca14b3fef1Joe Perches					  &lp->tx_bd_p, GFP_KERNEL);
249d0320f750093d012d3ed69fc1e8b385f654523d5Joe Perches	if (!lp->tx_bd_v)
250fe62c298e5bcff8b3414205b7b54975918b3b5c4Denis Kirjanov		goto out;
251d0320f750093d012d3ed69fc1e8b385f654523d5Joe Perches
252ede23fa8161c1a04aa1b3bf5447812ca14b3fef1Joe Perches	lp->rx_bd_v = dma_zalloc_coherent(ndev->dev.parent,
253ede23fa8161c1a04aa1b3bf5447812ca14b3fef1Joe Perches					  sizeof(*lp->rx_bd_v) * RX_BD_NUM,
254ede23fa8161c1a04aa1b3bf5447812ca14b3fef1Joe Perches					  &lp->rx_bd_p, GFP_KERNEL);
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
3007167cf0e8cd10287b7912b9ffcccd9616f382922Ricardo Ribalda	/* Init descriptor indexes */
3017167cf0e8cd10287b7912b9ffcccd9616f382922Ricardo Ribalda	lp->tx_bd_ci = 0;
3027167cf0e8cd10287b7912b9ffcccd9616f382922Ricardo Ribalda	lp->tx_bd_next = 0;
3037167cf0e8cd10287b7912b9ffcccd9616f382922Ricardo Ribalda	lp->tx_bd_tail = 0;
3047167cf0e8cd10287b7912b9ffcccd9616f382922Ricardo Ribalda	lp->rx_bd_ci = 0;
3057167cf0e8cd10287b7912b9ffcccd9616f382922Ricardo Ribalda
30692744989533cbe85e8057935d230e128810168ceGrant Likely	return 0;
307fe62c298e5bcff8b3414205b7b54975918b3b5c4Denis Kirjanov
308fe62c298e5bcff8b3414205b7b54975918b3b5c4Denis Kirjanovout:
309301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov	temac_dma_bd_release(ndev);
310fe62c298e5bcff8b3414205b7b54975918b3b5c4Denis Kirjanov	return -ENOMEM;
31192744989533cbe85e8057935d230e128810168ceGrant Likely}
31292744989533cbe85e8057935d230e128810168ceGrant Likely
31392744989533cbe85e8057935d230e128810168ceGrant Likely/* ---------------------------------------------------------------------
31492744989533cbe85e8057935d230e128810168ceGrant Likely * net_device_ops
31592744989533cbe85e8057935d230e128810168ceGrant Likely */
31692744989533cbe85e8057935d230e128810168ceGrant Likely
31704e406dcc54cfd84d333ea673fa986fb5a1840e7Jiri Pirkostatic void temac_do_set_mac_address(struct net_device *ndev)
31892744989533cbe85e8057935d230e128810168ceGrant Likely{
31992744989533cbe85e8057935d230e128810168ceGrant Likely	struct temac_local *lp = netdev_priv(ndev);
32092744989533cbe85e8057935d230e128810168ceGrant Likely
32192744989533cbe85e8057935d230e128810168ceGrant Likely	/* set up unicast MAC address filter set its mac address */
32292744989533cbe85e8057935d230e128810168ceGrant Likely	mutex_lock(&lp->indirect_mutex);
32392744989533cbe85e8057935d230e128810168ceGrant Likely	temac_indirect_out32(lp, XTE_UAW0_OFFSET,
32492744989533cbe85e8057935d230e128810168ceGrant Likely			     (ndev->dev_addr[0]) |
32592744989533cbe85e8057935d230e128810168ceGrant Likely			     (ndev->dev_addr[1] << 8) |
32692744989533cbe85e8057935d230e128810168ceGrant Likely			     (ndev->dev_addr[2] << 16) |
32792744989533cbe85e8057935d230e128810168ceGrant Likely			     (ndev->dev_addr[3] << 24));
32892744989533cbe85e8057935d230e128810168ceGrant Likely	/* There are reserved bits in EUAW1
32992744989533cbe85e8057935d230e128810168ceGrant Likely	 * so don't affect them Set MAC bits [47:32] in EUAW1 */
33092744989533cbe85e8057935d230e128810168ceGrant Likely	temac_indirect_out32(lp, XTE_UAW1_OFFSET,
33192744989533cbe85e8057935d230e128810168ceGrant Likely			     (ndev->dev_addr[4] & 0x000000ff) |
33292744989533cbe85e8057935d230e128810168ceGrant Likely			     (ndev->dev_addr[5] << 8));
33392744989533cbe85e8057935d230e128810168ceGrant Likely	mutex_unlock(&lp->indirect_mutex);
33404e406dcc54cfd84d333ea673fa986fb5a1840e7Jiri Pirko}
33592744989533cbe85e8057935d230e128810168ceGrant Likely
33604e406dcc54cfd84d333ea673fa986fb5a1840e7Jiri Pirkostatic int temac_init_mac_address(struct net_device *ndev, void *address)
33704e406dcc54cfd84d333ea673fa986fb5a1840e7Jiri Pirko{
33804e406dcc54cfd84d333ea673fa986fb5a1840e7Jiri Pirko	memcpy(ndev->dev_addr, address, ETH_ALEN);
33904e406dcc54cfd84d333ea673fa986fb5a1840e7Jiri Pirko	if (!is_valid_ether_addr(ndev->dev_addr))
34004e406dcc54cfd84d333ea673fa986fb5a1840e7Jiri Pirko		eth_hw_addr_random(ndev);
34104e406dcc54cfd84d333ea673fa986fb5a1840e7Jiri Pirko	temac_do_set_mac_address(ndev);
34292744989533cbe85e8057935d230e128810168ceGrant Likely	return 0;
34392744989533cbe85e8057935d230e128810168ceGrant Likely}
34492744989533cbe85e8057935d230e128810168ceGrant Likely
34504e406dcc54cfd84d333ea673fa986fb5a1840e7Jiri Pirkostatic int temac_set_mac_address(struct net_device *ndev, void *p)
3468ea7a37c5a312bfee51ff7f12f78efe4fbc901ccSteven J. Magnani{
3478ea7a37c5a312bfee51ff7f12f78efe4fbc901ccSteven J. Magnani	struct sockaddr *addr = p;
3488ea7a37c5a312bfee51ff7f12f78efe4fbc901ccSteven J. Magnani
34904e406dcc54cfd84d333ea673fa986fb5a1840e7Jiri Pirko	if (!is_valid_ether_addr(addr->sa_data))
35004e406dcc54cfd84d333ea673fa986fb5a1840e7Jiri Pirko		return -EADDRNOTAVAIL;
35104e406dcc54cfd84d333ea673fa986fb5a1840e7Jiri Pirko	memcpy(ndev->dev_addr, addr->sa_data, ETH_ALEN);
35204e406dcc54cfd84d333ea673fa986fb5a1840e7Jiri Pirko	temac_do_set_mac_address(ndev);
35304e406dcc54cfd84d333ea673fa986fb5a1840e7Jiri Pirko	return 0;
3548ea7a37c5a312bfee51ff7f12f78efe4fbc901ccSteven J. Magnani}
3558ea7a37c5a312bfee51ff7f12f78efe4fbc901ccSteven J. Magnani
35692744989533cbe85e8057935d230e128810168ceGrant Likelystatic void temac_set_multicast_list(struct net_device *ndev)
35792744989533cbe85e8057935d230e128810168ceGrant Likely{
35892744989533cbe85e8057935d230e128810168ceGrant Likely	struct temac_local *lp = netdev_priv(ndev);
35992744989533cbe85e8057935d230e128810168ceGrant Likely	u32 multi_addr_msw, multi_addr_lsw, val;
36092744989533cbe85e8057935d230e128810168ceGrant Likely	int i;
36192744989533cbe85e8057935d230e128810168ceGrant Likely
36292744989533cbe85e8057935d230e128810168ceGrant Likely	mutex_lock(&lp->indirect_mutex);
3638e95a2026f3b43f7c3d676adaccd2de9532e8dccJoe Perches	if (ndev->flags & (IFF_ALLMULTI | IFF_PROMISC) ||
3644cd24eaf0c6ee7f0242e34ee77ec899f255e66b5Jiri Pirko	    netdev_mc_count(ndev) > MULTICAST_CAM_TABLE_NUM) {
36592744989533cbe85e8057935d230e128810168ceGrant Likely		/*
36692744989533cbe85e8057935d230e128810168ceGrant Likely		 *	We must make the kernel realise we had to move
36792744989533cbe85e8057935d230e128810168ceGrant Likely		 *	into promisc mode or we start all out war on
36892744989533cbe85e8057935d230e128810168ceGrant Likely		 *	the cable. If it was a promisc request the
36992744989533cbe85e8057935d230e128810168ceGrant Likely		 *	flag is already set. If not we assert it.
37092744989533cbe85e8057935d230e128810168ceGrant Likely		 */
37192744989533cbe85e8057935d230e128810168ceGrant Likely		ndev->flags |= IFF_PROMISC;
37292744989533cbe85e8057935d230e128810168ceGrant Likely		temac_indirect_out32(lp, XTE_AFM_OFFSET, XTE_AFM_EPPRM_MASK);
37392744989533cbe85e8057935d230e128810168ceGrant Likely		dev_info(&ndev->dev, "Promiscuous mode enabled.\n");
3744cd24eaf0c6ee7f0242e34ee77ec899f255e66b5Jiri Pirko	} else if (!netdev_mc_empty(ndev)) {
37522bedad3ce112d5ca1eaf043d4990fa2ed698c87Jiri Pirko		struct netdev_hw_addr *ha;
37692744989533cbe85e8057935d230e128810168ceGrant Likely
377f9dcbcc9e338d08c0f7de7eba4eaafbbb7f81249Jiri Pirko		i = 0;
37822bedad3ce112d5ca1eaf043d4990fa2ed698c87Jiri Pirko		netdev_for_each_mc_addr(ha, ndev) {
37992744989533cbe85e8057935d230e128810168ceGrant Likely			if (i >= MULTICAST_CAM_TABLE_NUM)
38092744989533cbe85e8057935d230e128810168ceGrant Likely				break;
38122bedad3ce112d5ca1eaf043d4990fa2ed698c87Jiri Pirko			multi_addr_msw = ((ha->addr[3] << 24) |
38222bedad3ce112d5ca1eaf043d4990fa2ed698c87Jiri Pirko					  (ha->addr[2] << 16) |
38322bedad3ce112d5ca1eaf043d4990fa2ed698c87Jiri Pirko					  (ha->addr[1] << 8) |
38422bedad3ce112d5ca1eaf043d4990fa2ed698c87Jiri Pirko					  (ha->addr[0]));
38592744989533cbe85e8057935d230e128810168ceGrant Likely			temac_indirect_out32(lp, XTE_MAW0_OFFSET,
38692744989533cbe85e8057935d230e128810168ceGrant Likely					     multi_addr_msw);
38722bedad3ce112d5ca1eaf043d4990fa2ed698c87Jiri Pirko			multi_addr_lsw = ((ha->addr[5] << 8) |
38822bedad3ce112d5ca1eaf043d4990fa2ed698c87Jiri Pirko					  (ha->addr[4]) | (i << 16));
38992744989533cbe85e8057935d230e128810168ceGrant Likely			temac_indirect_out32(lp, XTE_MAW1_OFFSET,
39092744989533cbe85e8057935d230e128810168ceGrant Likely					     multi_addr_lsw);
391f9dcbcc9e338d08c0f7de7eba4eaafbbb7f81249Jiri Pirko			i++;
39292744989533cbe85e8057935d230e128810168ceGrant Likely		}
39392744989533cbe85e8057935d230e128810168ceGrant Likely	} else {
39492744989533cbe85e8057935d230e128810168ceGrant Likely		val = temac_indirect_in32(lp, XTE_AFM_OFFSET);
39592744989533cbe85e8057935d230e128810168ceGrant Likely		temac_indirect_out32(lp, XTE_AFM_OFFSET,
39692744989533cbe85e8057935d230e128810168ceGrant Likely				     val & ~XTE_AFM_EPPRM_MASK);
39792744989533cbe85e8057935d230e128810168ceGrant Likely		temac_indirect_out32(lp, XTE_MAW0_OFFSET, 0);
39892744989533cbe85e8057935d230e128810168ceGrant Likely		temac_indirect_out32(lp, XTE_MAW1_OFFSET, 0);
39992744989533cbe85e8057935d230e128810168ceGrant Likely		dev_info(&ndev->dev, "Promiscuous mode disabled.\n");
40092744989533cbe85e8057935d230e128810168ceGrant Likely	}
40192744989533cbe85e8057935d230e128810168ceGrant Likely	mutex_unlock(&lp->indirect_mutex);
40292744989533cbe85e8057935d230e128810168ceGrant Likely}
40392744989533cbe85e8057935d230e128810168ceGrant Likely
40492744989533cbe85e8057935d230e128810168ceGrant Likelystruct temac_option {
40592744989533cbe85e8057935d230e128810168ceGrant Likely	int flg;
40692744989533cbe85e8057935d230e128810168ceGrant Likely	u32 opt;
40792744989533cbe85e8057935d230e128810168ceGrant Likely	u32 reg;
40892744989533cbe85e8057935d230e128810168ceGrant Likely	u32 m_or;
40992744989533cbe85e8057935d230e128810168ceGrant Likely	u32 m_and;
41092744989533cbe85e8057935d230e128810168ceGrant Likely} temac_options[] = {
41192744989533cbe85e8057935d230e128810168ceGrant Likely	/* Turn on jumbo packet support for both Rx and Tx */
41292744989533cbe85e8057935d230e128810168ceGrant Likely	{
41392744989533cbe85e8057935d230e128810168ceGrant Likely		.opt = XTE_OPTION_JUMBO,
41492744989533cbe85e8057935d230e128810168ceGrant Likely		.reg = XTE_TXC_OFFSET,
41592744989533cbe85e8057935d230e128810168ceGrant Likely		.m_or = XTE_TXC_TXJMBO_MASK,
41692744989533cbe85e8057935d230e128810168ceGrant Likely	},
41792744989533cbe85e8057935d230e128810168ceGrant Likely	{
41892744989533cbe85e8057935d230e128810168ceGrant Likely		.opt = XTE_OPTION_JUMBO,
41992744989533cbe85e8057935d230e128810168ceGrant Likely		.reg = XTE_RXC1_OFFSET,
42092744989533cbe85e8057935d230e128810168ceGrant Likely		.m_or =XTE_RXC1_RXJMBO_MASK,
42192744989533cbe85e8057935d230e128810168ceGrant Likely	},
42292744989533cbe85e8057935d230e128810168ceGrant Likely	/* Turn on VLAN packet support for both Rx and Tx */
42392744989533cbe85e8057935d230e128810168ceGrant Likely	{
42492744989533cbe85e8057935d230e128810168ceGrant Likely		.opt = XTE_OPTION_VLAN,
42592744989533cbe85e8057935d230e128810168ceGrant Likely		.reg = XTE_TXC_OFFSET,
42692744989533cbe85e8057935d230e128810168ceGrant Likely		.m_or =XTE_TXC_TXVLAN_MASK,
42792744989533cbe85e8057935d230e128810168ceGrant Likely	},
42892744989533cbe85e8057935d230e128810168ceGrant Likely	{
42992744989533cbe85e8057935d230e128810168ceGrant Likely		.opt = XTE_OPTION_VLAN,
43092744989533cbe85e8057935d230e128810168ceGrant Likely		.reg = XTE_RXC1_OFFSET,
43192744989533cbe85e8057935d230e128810168ceGrant Likely		.m_or =XTE_RXC1_RXVLAN_MASK,
43292744989533cbe85e8057935d230e128810168ceGrant Likely	},
43392744989533cbe85e8057935d230e128810168ceGrant Likely	/* Turn on FCS stripping on receive packets */
43492744989533cbe85e8057935d230e128810168ceGrant Likely	{
43592744989533cbe85e8057935d230e128810168ceGrant Likely		.opt = XTE_OPTION_FCS_STRIP,
43692744989533cbe85e8057935d230e128810168ceGrant Likely		.reg = XTE_RXC1_OFFSET,
43792744989533cbe85e8057935d230e128810168ceGrant Likely		.m_or =XTE_RXC1_RXFCS_MASK,
43892744989533cbe85e8057935d230e128810168ceGrant Likely	},
43992744989533cbe85e8057935d230e128810168ceGrant Likely	/* Turn on FCS insertion on transmit packets */
44092744989533cbe85e8057935d230e128810168ceGrant Likely	{
44192744989533cbe85e8057935d230e128810168ceGrant Likely		.opt = XTE_OPTION_FCS_INSERT,
44292744989533cbe85e8057935d230e128810168ceGrant Likely		.reg = XTE_TXC_OFFSET,
44392744989533cbe85e8057935d230e128810168ceGrant Likely		.m_or =XTE_TXC_TXFCS_MASK,
44492744989533cbe85e8057935d230e128810168ceGrant Likely	},
44592744989533cbe85e8057935d230e128810168ceGrant Likely	/* Turn on length/type field checking on receive packets */
44692744989533cbe85e8057935d230e128810168ceGrant Likely	{
44792744989533cbe85e8057935d230e128810168ceGrant Likely		.opt = XTE_OPTION_LENTYPE_ERR,
44892744989533cbe85e8057935d230e128810168ceGrant Likely		.reg = XTE_RXC1_OFFSET,
44992744989533cbe85e8057935d230e128810168ceGrant Likely		.m_or =XTE_RXC1_RXLT_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_RXFLO_MASK,
45692744989533cbe85e8057935d230e128810168ceGrant Likely	},
45792744989533cbe85e8057935d230e128810168ceGrant Likely	/* Turn on flow control */
45892744989533cbe85e8057935d230e128810168ceGrant Likely	{
45992744989533cbe85e8057935d230e128810168ceGrant Likely		.opt = XTE_OPTION_FLOW_CONTROL,
46092744989533cbe85e8057935d230e128810168ceGrant Likely		.reg = XTE_FCC_OFFSET,
46192744989533cbe85e8057935d230e128810168ceGrant Likely		.m_or =XTE_FCC_TXFLO_MASK,
46292744989533cbe85e8057935d230e128810168ceGrant Likely	},
46392744989533cbe85e8057935d230e128810168ceGrant Likely	/* Turn on promiscuous frame filtering (all frames are received ) */
46492744989533cbe85e8057935d230e128810168ceGrant Likely	{
46592744989533cbe85e8057935d230e128810168ceGrant Likely		.opt = XTE_OPTION_PROMISC,
46692744989533cbe85e8057935d230e128810168ceGrant Likely		.reg = XTE_AFM_OFFSET,
46792744989533cbe85e8057935d230e128810168ceGrant Likely		.m_or =XTE_AFM_EPPRM_MASK,
46892744989533cbe85e8057935d230e128810168ceGrant Likely	},
46992744989533cbe85e8057935d230e128810168ceGrant Likely	/* Enable transmitter if not already enabled */
47092744989533cbe85e8057935d230e128810168ceGrant Likely	{
47192744989533cbe85e8057935d230e128810168ceGrant Likely		.opt = XTE_OPTION_TXEN,
47292744989533cbe85e8057935d230e128810168ceGrant Likely		.reg = XTE_TXC_OFFSET,
47392744989533cbe85e8057935d230e128810168ceGrant Likely		.m_or =XTE_TXC_TXEN_MASK,
47492744989533cbe85e8057935d230e128810168ceGrant Likely	},
47592744989533cbe85e8057935d230e128810168ceGrant Likely	/* Enable receiver? */
47692744989533cbe85e8057935d230e128810168ceGrant Likely	{
47792744989533cbe85e8057935d230e128810168ceGrant Likely		.opt = XTE_OPTION_RXEN,
47892744989533cbe85e8057935d230e128810168ceGrant Likely		.reg = XTE_RXC1_OFFSET,
47992744989533cbe85e8057935d230e128810168ceGrant Likely		.m_or =XTE_RXC1_RXEN_MASK,
48092744989533cbe85e8057935d230e128810168ceGrant Likely	},
48192744989533cbe85e8057935d230e128810168ceGrant Likely	{}
48292744989533cbe85e8057935d230e128810168ceGrant Likely};
48392744989533cbe85e8057935d230e128810168ceGrant Likely
48492744989533cbe85e8057935d230e128810168ceGrant Likely/**
48592744989533cbe85e8057935d230e128810168ceGrant Likely * temac_setoptions
48692744989533cbe85e8057935d230e128810168ceGrant Likely */
48792744989533cbe85e8057935d230e128810168ceGrant Likelystatic u32 temac_setoptions(struct net_device *ndev, u32 options)
48892744989533cbe85e8057935d230e128810168ceGrant Likely{
48992744989533cbe85e8057935d230e128810168ceGrant Likely	struct temac_local *lp = netdev_priv(ndev);
49092744989533cbe85e8057935d230e128810168ceGrant Likely	struct temac_option *tp = &temac_options[0];
49192744989533cbe85e8057935d230e128810168ceGrant Likely	int reg;
49292744989533cbe85e8057935d230e128810168ceGrant Likely
49392744989533cbe85e8057935d230e128810168ceGrant Likely	mutex_lock(&lp->indirect_mutex);
49492744989533cbe85e8057935d230e128810168ceGrant Likely	while (tp->opt) {
49592744989533cbe85e8057935d230e128810168ceGrant Likely		reg = temac_indirect_in32(lp, tp->reg) & ~tp->m_or;
49692744989533cbe85e8057935d230e128810168ceGrant Likely		if (options & tp->opt)
49792744989533cbe85e8057935d230e128810168ceGrant Likely			reg |= tp->m_or;
49892744989533cbe85e8057935d230e128810168ceGrant Likely		temac_indirect_out32(lp, tp->reg, reg);
49992744989533cbe85e8057935d230e128810168ceGrant Likely		tp++;
50092744989533cbe85e8057935d230e128810168ceGrant Likely	}
50192744989533cbe85e8057935d230e128810168ceGrant Likely	lp->options |= options;
50292744989533cbe85e8057935d230e128810168ceGrant Likely	mutex_unlock(&lp->indirect_mutex);
50392744989533cbe85e8057935d230e128810168ceGrant Likely
504807540baae406c84dcb9c1c8ef07a56d2d2ae84aEric Dumazet	return 0;
50592744989533cbe85e8057935d230e128810168ceGrant Likely}
50692744989533cbe85e8057935d230e128810168ceGrant Likely
507421f91d21ad6f799dc7b489bb33cc560ccc56f98Uwe Kleine-König/* Initialize temac */
50892744989533cbe85e8057935d230e128810168ceGrant Likelystatic void temac_device_reset(struct net_device *ndev)
50992744989533cbe85e8057935d230e128810168ceGrant Likely{
51092744989533cbe85e8057935d230e128810168ceGrant Likely	struct temac_local *lp = netdev_priv(ndev);
51192744989533cbe85e8057935d230e128810168ceGrant Likely	u32 timeout;
51292744989533cbe85e8057935d230e128810168ceGrant Likely	u32 val;
51392744989533cbe85e8057935d230e128810168ceGrant Likely
51492744989533cbe85e8057935d230e128810168ceGrant Likely	/* Perform a software reset */
51592744989533cbe85e8057935d230e128810168ceGrant Likely
51692744989533cbe85e8057935d230e128810168ceGrant Likely	/* 0x300 host enable bit ? */
51792744989533cbe85e8057935d230e128810168ceGrant Likely	/* reset PHY through control register ?:1 */
51892744989533cbe85e8057935d230e128810168ceGrant Likely
51992744989533cbe85e8057935d230e128810168ceGrant Likely	dev_dbg(&ndev->dev, "%s()\n", __func__);
52092744989533cbe85e8057935d230e128810168ceGrant Likely
52192744989533cbe85e8057935d230e128810168ceGrant Likely	mutex_lock(&lp->indirect_mutex);
52292744989533cbe85e8057935d230e128810168ceGrant Likely	/* Reset the receiver and wait for it to finish reset */
52392744989533cbe85e8057935d230e128810168ceGrant Likely	temac_indirect_out32(lp, XTE_RXC1_OFFSET, XTE_RXC1_RXRST_MASK);
52492744989533cbe85e8057935d230e128810168ceGrant Likely	timeout = 1000;
52592744989533cbe85e8057935d230e128810168ceGrant Likely	while (temac_indirect_in32(lp, XTE_RXC1_OFFSET) & XTE_RXC1_RXRST_MASK) {
52692744989533cbe85e8057935d230e128810168ceGrant Likely		udelay(1);
52792744989533cbe85e8057935d230e128810168ceGrant Likely		if (--timeout == 0) {
52892744989533cbe85e8057935d230e128810168ceGrant Likely			dev_err(&ndev->dev,
52992744989533cbe85e8057935d230e128810168ceGrant Likely				"temac_device_reset RX reset timeout!!\n");
53092744989533cbe85e8057935d230e128810168ceGrant Likely			break;
53192744989533cbe85e8057935d230e128810168ceGrant Likely		}
53292744989533cbe85e8057935d230e128810168ceGrant Likely	}
53392744989533cbe85e8057935d230e128810168ceGrant Likely
53492744989533cbe85e8057935d230e128810168ceGrant Likely	/* Reset the transmitter and wait for it to finish reset */
53592744989533cbe85e8057935d230e128810168ceGrant Likely	temac_indirect_out32(lp, XTE_TXC_OFFSET, XTE_TXC_TXRST_MASK);
53692744989533cbe85e8057935d230e128810168ceGrant Likely	timeout = 1000;
53792744989533cbe85e8057935d230e128810168ceGrant Likely	while (temac_indirect_in32(lp, XTE_TXC_OFFSET) & XTE_TXC_TXRST_MASK) {
53892744989533cbe85e8057935d230e128810168ceGrant Likely		udelay(1);
53992744989533cbe85e8057935d230e128810168ceGrant Likely		if (--timeout == 0) {
54092744989533cbe85e8057935d230e128810168ceGrant Likely			dev_err(&ndev->dev,
54192744989533cbe85e8057935d230e128810168ceGrant Likely				"temac_device_reset TX reset timeout!!\n");
54292744989533cbe85e8057935d230e128810168ceGrant Likely			break;
54392744989533cbe85e8057935d230e128810168ceGrant Likely		}
54492744989533cbe85e8057935d230e128810168ceGrant Likely	}
54592744989533cbe85e8057935d230e128810168ceGrant Likely
54692744989533cbe85e8057935d230e128810168ceGrant Likely	/* Disable the receiver */
54792744989533cbe85e8057935d230e128810168ceGrant Likely	val = temac_indirect_in32(lp, XTE_RXC1_OFFSET);
54892744989533cbe85e8057935d230e128810168ceGrant Likely	temac_indirect_out32(lp, XTE_RXC1_OFFSET, val & ~XTE_RXC1_RXEN_MASK);
54992744989533cbe85e8057935d230e128810168ceGrant Likely
55092744989533cbe85e8057935d230e128810168ceGrant Likely	/* Reset Local Link (DMA) */
551e44171f115de3dedf34064646206deb91549865fJohn Linn	lp->dma_out(lp, DMA_CONTROL_REG, DMA_CONTROL_RST);
55292744989533cbe85e8057935d230e128810168ceGrant Likely	timeout = 1000;
553e44171f115de3dedf34064646206deb91549865fJohn Linn	while (lp->dma_in(lp, DMA_CONTROL_REG) & DMA_CONTROL_RST) {
55492744989533cbe85e8057935d230e128810168ceGrant Likely		udelay(1);
55592744989533cbe85e8057935d230e128810168ceGrant Likely		if (--timeout == 0) {
55692744989533cbe85e8057935d230e128810168ceGrant Likely			dev_err(&ndev->dev,
55792744989533cbe85e8057935d230e128810168ceGrant Likely				"temac_device_reset DMA reset timeout!!\n");
55892744989533cbe85e8057935d230e128810168ceGrant Likely			break;
55992744989533cbe85e8057935d230e128810168ceGrant Likely		}
56092744989533cbe85e8057935d230e128810168ceGrant Likely	}
561e44171f115de3dedf34064646206deb91549865fJohn Linn	lp->dma_out(lp, DMA_CONTROL_REG, DMA_TAIL_ENABLE);
56292744989533cbe85e8057935d230e128810168ceGrant Likely
563fe62c298e5bcff8b3414205b7b54975918b3b5c4Denis Kirjanov	if (temac_dma_bd_init(ndev)) {
564fe62c298e5bcff8b3414205b7b54975918b3b5c4Denis Kirjanov		dev_err(&ndev->dev,
565fe62c298e5bcff8b3414205b7b54975918b3b5c4Denis Kirjanov				"temac_device_reset descriptor allocation failed\n");
566fe62c298e5bcff8b3414205b7b54975918b3b5c4Denis Kirjanov	}
56792744989533cbe85e8057935d230e128810168ceGrant Likely
56892744989533cbe85e8057935d230e128810168ceGrant Likely	temac_indirect_out32(lp, XTE_RXC0_OFFSET, 0);
56992744989533cbe85e8057935d230e128810168ceGrant Likely	temac_indirect_out32(lp, XTE_RXC1_OFFSET, 0);
57092744989533cbe85e8057935d230e128810168ceGrant Likely	temac_indirect_out32(lp, XTE_TXC_OFFSET, 0);
57192744989533cbe85e8057935d230e128810168ceGrant Likely	temac_indirect_out32(lp, XTE_FCC_OFFSET, XTE_FCC_RXFLO_MASK);
57292744989533cbe85e8057935d230e128810168ceGrant Likely
57392744989533cbe85e8057935d230e128810168ceGrant Likely	mutex_unlock(&lp->indirect_mutex);
57492744989533cbe85e8057935d230e128810168ceGrant Likely
57592744989533cbe85e8057935d230e128810168ceGrant Likely	/* Sync default options with HW
57692744989533cbe85e8057935d230e128810168ceGrant Likely	 * but leave receiver and transmitter disabled.  */
57792744989533cbe85e8057935d230e128810168ceGrant Likely	temac_setoptions(ndev,
57892744989533cbe85e8057935d230e128810168ceGrant Likely			 lp->options & ~(XTE_OPTION_TXEN | XTE_OPTION_RXEN));
57992744989533cbe85e8057935d230e128810168ceGrant Likely
58004e406dcc54cfd84d333ea673fa986fb5a1840e7Jiri Pirko	temac_do_set_mac_address(ndev);
58192744989533cbe85e8057935d230e128810168ceGrant Likely
58292744989533cbe85e8057935d230e128810168ceGrant Likely	/* Set address filter table */
58392744989533cbe85e8057935d230e128810168ceGrant Likely	temac_set_multicast_list(ndev);
58492744989533cbe85e8057935d230e128810168ceGrant Likely	if (temac_setoptions(ndev, lp->options))
58592744989533cbe85e8057935d230e128810168ceGrant Likely		dev_err(&ndev->dev, "Error setting TEMAC options\n");
58692744989533cbe85e8057935d230e128810168ceGrant Likely
58792744989533cbe85e8057935d230e128810168ceGrant Likely	/* Init Driver variable */
5881ae5dc342ac78d7a42965fd1f323815f6f5ef2c1Eric Dumazet	ndev->trans_start = jiffies; /* prevent tx timeout */
58992744989533cbe85e8057935d230e128810168ceGrant Likely}
59092744989533cbe85e8057935d230e128810168ceGrant Likely
59192744989533cbe85e8057935d230e128810168ceGrant Likelyvoid temac_adjust_link(struct net_device *ndev)
59292744989533cbe85e8057935d230e128810168ceGrant Likely{
59392744989533cbe85e8057935d230e128810168ceGrant Likely	struct temac_local *lp = netdev_priv(ndev);
59492744989533cbe85e8057935d230e128810168ceGrant Likely	struct phy_device *phy = lp->phy_dev;
59592744989533cbe85e8057935d230e128810168ceGrant Likely	u32 mii_speed;
59692744989533cbe85e8057935d230e128810168ceGrant Likely	int link_state;
59792744989533cbe85e8057935d230e128810168ceGrant Likely
59892744989533cbe85e8057935d230e128810168ceGrant Likely	/* hash together the state values to decide if something has changed */
59992744989533cbe85e8057935d230e128810168ceGrant Likely	link_state = phy->speed | (phy->duplex << 1) | phy->link;
60092744989533cbe85e8057935d230e128810168ceGrant Likely
60192744989533cbe85e8057935d230e128810168ceGrant Likely	mutex_lock(&lp->indirect_mutex);
60292744989533cbe85e8057935d230e128810168ceGrant Likely	if (lp->last_link != link_state) {
60392744989533cbe85e8057935d230e128810168ceGrant Likely		mii_speed = temac_indirect_in32(lp, XTE_EMCFG_OFFSET);
60492744989533cbe85e8057935d230e128810168ceGrant Likely		mii_speed &= ~XTE_EMCFG_LINKSPD_MASK;
60592744989533cbe85e8057935d230e128810168ceGrant Likely
60692744989533cbe85e8057935d230e128810168ceGrant Likely		switch (phy->speed) {
60792744989533cbe85e8057935d230e128810168ceGrant Likely		case SPEED_1000: mii_speed |= XTE_EMCFG_LINKSPD_1000; break;
60892744989533cbe85e8057935d230e128810168ceGrant Likely		case SPEED_100: mii_speed |= XTE_EMCFG_LINKSPD_100; break;
60992744989533cbe85e8057935d230e128810168ceGrant Likely		case SPEED_10: mii_speed |= XTE_EMCFG_LINKSPD_10; break;
61092744989533cbe85e8057935d230e128810168ceGrant Likely		}
61192744989533cbe85e8057935d230e128810168ceGrant Likely
61292744989533cbe85e8057935d230e128810168ceGrant Likely		/* Write new speed setting out to TEMAC */
61392744989533cbe85e8057935d230e128810168ceGrant Likely		temac_indirect_out32(lp, XTE_EMCFG_OFFSET, mii_speed);
61492744989533cbe85e8057935d230e128810168ceGrant Likely		lp->last_link = link_state;
61592744989533cbe85e8057935d230e128810168ceGrant Likely		phy_print_status(phy);
61692744989533cbe85e8057935d230e128810168ceGrant Likely	}
61792744989533cbe85e8057935d230e128810168ceGrant Likely	mutex_unlock(&lp->indirect_mutex);
61892744989533cbe85e8057935d230e128810168ceGrant Likely}
61992744989533cbe85e8057935d230e128810168ceGrant Likely
62092744989533cbe85e8057935d230e128810168ceGrant Likelystatic void temac_start_xmit_done(struct net_device *ndev)
62192744989533cbe85e8057935d230e128810168ceGrant Likely{
62292744989533cbe85e8057935d230e128810168ceGrant Likely	struct temac_local *lp = netdev_priv(ndev);
62392744989533cbe85e8057935d230e128810168ceGrant Likely	struct cdmac_bd *cur_p;
62492744989533cbe85e8057935d230e128810168ceGrant Likely	unsigned int stat = 0;
62592744989533cbe85e8057935d230e128810168ceGrant Likely
62692744989533cbe85e8057935d230e128810168ceGrant Likely	cur_p = &lp->tx_bd_v[lp->tx_bd_ci];
62792744989533cbe85e8057935d230e128810168ceGrant Likely	stat = cur_p->app0;
62892744989533cbe85e8057935d230e128810168ceGrant Likely
62992744989533cbe85e8057935d230e128810168ceGrant Likely	while (stat & STS_CTRL_APP0_CMPLT) {
63092744989533cbe85e8057935d230e128810168ceGrant Likely		dma_unmap_single(ndev->dev.parent, cur_p->phys, cur_p->len,
63192744989533cbe85e8057935d230e128810168ceGrant Likely				 DMA_TO_DEVICE);
63292744989533cbe85e8057935d230e128810168ceGrant Likely		if (cur_p->app4)
63392744989533cbe85e8057935d230e128810168ceGrant Likely			dev_kfree_skb_irq((struct sk_buff *)cur_p->app4);
63492744989533cbe85e8057935d230e128810168ceGrant Likely		cur_p->app0 = 0;
63523ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill		cur_p->app1 = 0;
63623ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill		cur_p->app2 = 0;
63723ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill		cur_p->app3 = 0;
63823ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill		cur_p->app4 = 0;
63992744989533cbe85e8057935d230e128810168ceGrant Likely
64092744989533cbe85e8057935d230e128810168ceGrant Likely		ndev->stats.tx_packets++;
64192744989533cbe85e8057935d230e128810168ceGrant Likely		ndev->stats.tx_bytes += cur_p->len;
64292744989533cbe85e8057935d230e128810168ceGrant Likely
64392744989533cbe85e8057935d230e128810168ceGrant Likely		lp->tx_bd_ci++;
64492744989533cbe85e8057935d230e128810168ceGrant Likely		if (lp->tx_bd_ci >= TX_BD_NUM)
64592744989533cbe85e8057935d230e128810168ceGrant Likely			lp->tx_bd_ci = 0;
64692744989533cbe85e8057935d230e128810168ceGrant Likely
64792744989533cbe85e8057935d230e128810168ceGrant Likely		cur_p = &lp->tx_bd_v[lp->tx_bd_ci];
64892744989533cbe85e8057935d230e128810168ceGrant Likely		stat = cur_p->app0;
64992744989533cbe85e8057935d230e128810168ceGrant Likely	}
65092744989533cbe85e8057935d230e128810168ceGrant Likely
65192744989533cbe85e8057935d230e128810168ceGrant Likely	netif_wake_queue(ndev);
65292744989533cbe85e8057935d230e128810168ceGrant Likely}
65392744989533cbe85e8057935d230e128810168ceGrant Likely
65423ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hillstatic inline int temac_check_tx_bd_space(struct temac_local *lp, int num_frag)
65523ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill{
65623ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill	struct cdmac_bd *cur_p;
65723ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill	int tail;
65823ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill
65923ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill	tail = lp->tx_bd_tail;
66023ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill	cur_p = &lp->tx_bd_v[tail];
66123ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill
66223ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill	do {
66323ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill		if (cur_p->app0)
66423ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill			return NETDEV_TX_BUSY;
66523ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill
66623ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill		tail++;
66723ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill		if (tail >= TX_BD_NUM)
66823ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill			tail = 0;
66923ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill
67023ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill		cur_p = &lp->tx_bd_v[tail];
67123ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill		num_frag--;
67223ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill	} while (num_frag >= 0);
67323ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill
67423ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill	return 0;
67523ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill}
67623ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill
67792744989533cbe85e8057935d230e128810168ceGrant Likelystatic int temac_start_xmit(struct sk_buff *skb, struct net_device *ndev)
67892744989533cbe85e8057935d230e128810168ceGrant Likely{
67992744989533cbe85e8057935d230e128810168ceGrant Likely	struct temac_local *lp = netdev_priv(ndev);
68092744989533cbe85e8057935d230e128810168ceGrant Likely	struct cdmac_bd *cur_p;
68192744989533cbe85e8057935d230e128810168ceGrant Likely	dma_addr_t start_p, tail_p;
68292744989533cbe85e8057935d230e128810168ceGrant Likely	int ii;
68392744989533cbe85e8057935d230e128810168ceGrant Likely	unsigned long num_frag;
68492744989533cbe85e8057935d230e128810168ceGrant Likely	skb_frag_t *frag;
68592744989533cbe85e8057935d230e128810168ceGrant Likely
68692744989533cbe85e8057935d230e128810168ceGrant Likely	num_frag = skb_shinfo(skb)->nr_frags;
68792744989533cbe85e8057935d230e128810168ceGrant Likely	frag = &skb_shinfo(skb)->frags[0];
68892744989533cbe85e8057935d230e128810168ceGrant Likely	start_p = lp->tx_bd_p + sizeof(*lp->tx_bd_v) * lp->tx_bd_tail;
68992744989533cbe85e8057935d230e128810168ceGrant Likely	cur_p = &lp->tx_bd_v[lp->tx_bd_tail];
69092744989533cbe85e8057935d230e128810168ceGrant Likely
69123ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill	if (temac_check_tx_bd_space(lp, num_frag)) {
69292744989533cbe85e8057935d230e128810168ceGrant Likely		if (!netif_queue_stopped(ndev)) {
69392744989533cbe85e8057935d230e128810168ceGrant Likely			netif_stop_queue(ndev);
69492744989533cbe85e8057935d230e128810168ceGrant Likely			return NETDEV_TX_BUSY;
69592744989533cbe85e8057935d230e128810168ceGrant Likely		}
69692744989533cbe85e8057935d230e128810168ceGrant Likely		return NETDEV_TX_BUSY;
69792744989533cbe85e8057935d230e128810168ceGrant Likely	}
69892744989533cbe85e8057935d230e128810168ceGrant Likely
69992744989533cbe85e8057935d230e128810168ceGrant Likely	cur_p->app0 = 0;
70092744989533cbe85e8057935d230e128810168ceGrant Likely	if (skb->ip_summed == CHECKSUM_PARTIAL) {
7010d0b16727f24f8258eeb33818347ca0f4557f982Michał Mirosław		unsigned int csum_start_off = skb_checksum_start_offset(skb);
70223ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill		unsigned int csum_index_off = csum_start_off + skb->csum_offset;
70323ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill
70423ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill		cur_p->app0 |= 1; /* TX Checksum Enabled */
70523ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill		cur_p->app1 = (csum_start_off << 16) | csum_index_off;
70623ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill		cur_p->app2 = 0;  /* initial checksum seed */
70792744989533cbe85e8057935d230e128810168ceGrant Likely	}
70823ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill
70992744989533cbe85e8057935d230e128810168ceGrant Likely	cur_p->app0 |= STS_CTRL_APP0_SOP;
71092744989533cbe85e8057935d230e128810168ceGrant Likely	cur_p->len = skb_headlen(skb);
71192744989533cbe85e8057935d230e128810168ceGrant Likely	cur_p->phys = dma_map_single(ndev->dev.parent, skb->data, skb->len,
71292744989533cbe85e8057935d230e128810168ceGrant Likely				     DMA_TO_DEVICE);
71392744989533cbe85e8057935d230e128810168ceGrant Likely	cur_p->app4 = (unsigned long)skb;
71492744989533cbe85e8057935d230e128810168ceGrant Likely
71592744989533cbe85e8057935d230e128810168ceGrant Likely	for (ii = 0; ii < num_frag; ii++) {
71692744989533cbe85e8057935d230e128810168ceGrant Likely		lp->tx_bd_tail++;
71792744989533cbe85e8057935d230e128810168ceGrant Likely		if (lp->tx_bd_tail >= TX_BD_NUM)
71892744989533cbe85e8057935d230e128810168ceGrant Likely			lp->tx_bd_tail = 0;
71992744989533cbe85e8057935d230e128810168ceGrant Likely
72092744989533cbe85e8057935d230e128810168ceGrant Likely		cur_p = &lp->tx_bd_v[lp->tx_bd_tail];
72192744989533cbe85e8057935d230e128810168ceGrant Likely		cur_p->phys = dma_map_single(ndev->dev.parent,
7223ed6f6958c0ac21958285d8648f14d34da4bbcb3Ian Campbell					     skb_frag_address(frag),
7232edcd4ca43df3c1d1d392753531cc73a53e709baStephen Rothwell					     skb_frag_size(frag), DMA_TO_DEVICE);
7242edcd4ca43df3c1d1d392753531cc73a53e709baStephen Rothwell		cur_p->len = skb_frag_size(frag);
72592744989533cbe85e8057935d230e128810168ceGrant Likely		cur_p->app0 = 0;
72692744989533cbe85e8057935d230e128810168ceGrant Likely		frag++;
72792744989533cbe85e8057935d230e128810168ceGrant Likely	}
72892744989533cbe85e8057935d230e128810168ceGrant Likely	cur_p->app0 |= STS_CTRL_APP0_EOP;
72992744989533cbe85e8057935d230e128810168ceGrant Likely
73092744989533cbe85e8057935d230e128810168ceGrant Likely	tail_p = lp->tx_bd_p + sizeof(*lp->tx_bd_v) * lp->tx_bd_tail;
73192744989533cbe85e8057935d230e128810168ceGrant Likely	lp->tx_bd_tail++;
73292744989533cbe85e8057935d230e128810168ceGrant Likely	if (lp->tx_bd_tail >= TX_BD_NUM)
73392744989533cbe85e8057935d230e128810168ceGrant Likely		lp->tx_bd_tail = 0;
73492744989533cbe85e8057935d230e128810168ceGrant Likely
73593e0ed158c15b3d3d76125de6364f8f95528c25aRichard Cochran	skb_tx_timestamp(skb);
73693e0ed158c15b3d3d76125de6364f8f95528c25aRichard Cochran
73792744989533cbe85e8057935d230e128810168ceGrant Likely	/* Kick off the transfer */
738e44171f115de3dedf34064646206deb91549865fJohn Linn	lp->dma_out(lp, TX_TAILDESC_PTR, tail_p); /* DMA start */
73992744989533cbe85e8057935d230e128810168ceGrant Likely
7406ed106549d17474ca17a16057f4c0ed4eba5a7caPatrick McHardy	return NETDEV_TX_OK;
74192744989533cbe85e8057935d230e128810168ceGrant Likely}
74292744989533cbe85e8057935d230e128810168ceGrant Likely
74392744989533cbe85e8057935d230e128810168ceGrant Likely
74492744989533cbe85e8057935d230e128810168ceGrant Likelystatic void ll_temac_recv(struct net_device *ndev)
74592744989533cbe85e8057935d230e128810168ceGrant Likely{
74692744989533cbe85e8057935d230e128810168ceGrant Likely	struct temac_local *lp = netdev_priv(ndev);
74792744989533cbe85e8057935d230e128810168ceGrant Likely	struct sk_buff *skb, *new_skb;
74892744989533cbe85e8057935d230e128810168ceGrant Likely	unsigned int bdstat;
74992744989533cbe85e8057935d230e128810168ceGrant Likely	struct cdmac_bd *cur_p;
75092744989533cbe85e8057935d230e128810168ceGrant Likely	dma_addr_t tail_p;
75192744989533cbe85e8057935d230e128810168ceGrant Likely	int length;
75292744989533cbe85e8057935d230e128810168ceGrant Likely	unsigned long flags;
75392744989533cbe85e8057935d230e128810168ceGrant Likely
75492744989533cbe85e8057935d230e128810168ceGrant Likely	spin_lock_irqsave(&lp->rx_lock, flags);
75592744989533cbe85e8057935d230e128810168ceGrant Likely
75692744989533cbe85e8057935d230e128810168ceGrant Likely	tail_p = lp->rx_bd_p + sizeof(*lp->rx_bd_v) * lp->rx_bd_ci;
75792744989533cbe85e8057935d230e128810168ceGrant Likely	cur_p = &lp->rx_bd_v[lp->rx_bd_ci];
75892744989533cbe85e8057935d230e128810168ceGrant Likely
75992744989533cbe85e8057935d230e128810168ceGrant Likely	bdstat = cur_p->app0;
76092744989533cbe85e8057935d230e128810168ceGrant Likely	while ((bdstat & STS_CTRL_APP0_CMPLT)) {
76192744989533cbe85e8057935d230e128810168ceGrant Likely
76292744989533cbe85e8057935d230e128810168ceGrant Likely		skb = lp->rx_skb[lp->rx_bd_ci];
763c3b7c12cd78d5c8264c87c29dcd9a8f1819f8313Steven J. Magnani		length = cur_p->app4 & 0x3FFF;
76492744989533cbe85e8057935d230e128810168ceGrant Likely
76533646d7ff5f47225cbbf3a06597ded649bf34e8dJohn Linn		dma_unmap_single(ndev->dev.parent, cur_p->phys, length,
76692744989533cbe85e8057935d230e128810168ceGrant Likely				 DMA_FROM_DEVICE);
76792744989533cbe85e8057935d230e128810168ceGrant Likely
76892744989533cbe85e8057935d230e128810168ceGrant Likely		skb_put(skb, length);
76992744989533cbe85e8057935d230e128810168ceGrant Likely		skb->protocol = eth_type_trans(skb, ndev);
770bc8acf2c8c3e43fcc192762a9f964b3e9a17748bEric Dumazet		skb_checksum_none_assert(skb);
77192744989533cbe85e8057935d230e128810168ceGrant Likely
77223ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill		/* if we're doing rx csum offload, set it up */
77323ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill		if (((lp->temac_features & TEMAC_FEATURE_RX_CSUM) != 0) &&
774ceffc4acfc8c4cf4badaa93921f00e2b34e24a97Joe Perches		    (skb->protocol == htons(ETH_P_IP)) &&
775ceffc4acfc8c4cf4badaa93921f00e2b34e24a97Joe Perches		    (skb->len > 64)) {
77623ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill
77723ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill			skb->csum = cur_p->app3 & 0xFFFF;
77823ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill			skb->ip_summed = CHECKSUM_COMPLETE;
77923ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill		}
78023ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill
78193e0ed158c15b3d3d76125de6364f8f95528c25aRichard Cochran		if (!skb_defer_rx_timestamp(skb))
78293e0ed158c15b3d3d76125de6364f8f95528c25aRichard Cochran			netif_rx(skb);
78392744989533cbe85e8057935d230e128810168ceGrant Likely
78492744989533cbe85e8057935d230e128810168ceGrant Likely		ndev->stats.rx_packets++;
78592744989533cbe85e8057935d230e128810168ceGrant Likely		ndev->stats.rx_bytes += length;
78692744989533cbe85e8057935d230e128810168ceGrant Likely
787e44171f115de3dedf34064646206deb91549865fJohn Linn		new_skb = netdev_alloc_skb_ip_align(ndev,
788e44171f115de3dedf34064646206deb91549865fJohn Linn						XTE_MAX_JUMBO_FRAME_SIZE);
789720a43efd30f04a0a492c85fb997361c44fbae05Joe Perches		if (!new_skb) {
79092744989533cbe85e8057935d230e128810168ceGrant Likely			spin_unlock_irqrestore(&lp->rx_lock, flags);
79192744989533cbe85e8057935d230e128810168ceGrant Likely			return;
79292744989533cbe85e8057935d230e128810168ceGrant Likely		}
79392744989533cbe85e8057935d230e128810168ceGrant Likely
79492744989533cbe85e8057935d230e128810168ceGrant Likely		cur_p->app0 = STS_CTRL_APP0_IRQONEND;
79592744989533cbe85e8057935d230e128810168ceGrant Likely		cur_p->phys = dma_map_single(ndev->dev.parent, new_skb->data,
79692744989533cbe85e8057935d230e128810168ceGrant Likely					     XTE_MAX_JUMBO_FRAME_SIZE,
79792744989533cbe85e8057935d230e128810168ceGrant Likely					     DMA_FROM_DEVICE);
79892744989533cbe85e8057935d230e128810168ceGrant Likely		cur_p->len = XTE_MAX_JUMBO_FRAME_SIZE;
79992744989533cbe85e8057935d230e128810168ceGrant Likely		lp->rx_skb[lp->rx_bd_ci] = new_skb;
80092744989533cbe85e8057935d230e128810168ceGrant Likely
80192744989533cbe85e8057935d230e128810168ceGrant Likely		lp->rx_bd_ci++;
80292744989533cbe85e8057935d230e128810168ceGrant Likely		if (lp->rx_bd_ci >= RX_BD_NUM)
80392744989533cbe85e8057935d230e128810168ceGrant Likely			lp->rx_bd_ci = 0;
80492744989533cbe85e8057935d230e128810168ceGrant Likely
80592744989533cbe85e8057935d230e128810168ceGrant Likely		cur_p = &lp->rx_bd_v[lp->rx_bd_ci];
80692744989533cbe85e8057935d230e128810168ceGrant Likely		bdstat = cur_p->app0;
80792744989533cbe85e8057935d230e128810168ceGrant Likely	}
808e44171f115de3dedf34064646206deb91549865fJohn Linn	lp->dma_out(lp, RX_TAILDESC_PTR, tail_p);
80992744989533cbe85e8057935d230e128810168ceGrant Likely
81092744989533cbe85e8057935d230e128810168ceGrant Likely	spin_unlock_irqrestore(&lp->rx_lock, flags);
81192744989533cbe85e8057935d230e128810168ceGrant Likely}
81292744989533cbe85e8057935d230e128810168ceGrant Likely
81392744989533cbe85e8057935d230e128810168ceGrant Likelystatic irqreturn_t ll_temac_tx_irq(int irq, void *_ndev)
81492744989533cbe85e8057935d230e128810168ceGrant Likely{
81592744989533cbe85e8057935d230e128810168ceGrant Likely	struct net_device *ndev = _ndev;
81692744989533cbe85e8057935d230e128810168ceGrant Likely	struct temac_local *lp = netdev_priv(ndev);
81792744989533cbe85e8057935d230e128810168ceGrant Likely	unsigned int status;
81892744989533cbe85e8057935d230e128810168ceGrant Likely
819e44171f115de3dedf34064646206deb91549865fJohn Linn	status = lp->dma_in(lp, TX_IRQ_REG);
820e44171f115de3dedf34064646206deb91549865fJohn Linn	lp->dma_out(lp, TX_IRQ_REG, status);
82192744989533cbe85e8057935d230e128810168ceGrant Likely
82292744989533cbe85e8057935d230e128810168ceGrant Likely	if (status & (IRQ_COAL | IRQ_DLY))
82392744989533cbe85e8057935d230e128810168ceGrant Likely		temac_start_xmit_done(lp->ndev);
82492744989533cbe85e8057935d230e128810168ceGrant Likely	if (status & 0x080)
82592744989533cbe85e8057935d230e128810168ceGrant Likely		dev_err(&ndev->dev, "DMA error 0x%x\n", status);
82692744989533cbe85e8057935d230e128810168ceGrant Likely
82792744989533cbe85e8057935d230e128810168ceGrant Likely	return IRQ_HANDLED;
82892744989533cbe85e8057935d230e128810168ceGrant Likely}
82992744989533cbe85e8057935d230e128810168ceGrant Likely
83092744989533cbe85e8057935d230e128810168ceGrant Likelystatic irqreturn_t ll_temac_rx_irq(int irq, void *_ndev)
83192744989533cbe85e8057935d230e128810168ceGrant Likely{
83292744989533cbe85e8057935d230e128810168ceGrant Likely	struct net_device *ndev = _ndev;
83392744989533cbe85e8057935d230e128810168ceGrant Likely	struct temac_local *lp = netdev_priv(ndev);
83492744989533cbe85e8057935d230e128810168ceGrant Likely	unsigned int status;
83592744989533cbe85e8057935d230e128810168ceGrant Likely
83692744989533cbe85e8057935d230e128810168ceGrant Likely	/* Read and clear the status registers */
837e44171f115de3dedf34064646206deb91549865fJohn Linn	status = lp->dma_in(lp, RX_IRQ_REG);
838e44171f115de3dedf34064646206deb91549865fJohn Linn	lp->dma_out(lp, RX_IRQ_REG, status);
83992744989533cbe85e8057935d230e128810168ceGrant Likely
84092744989533cbe85e8057935d230e128810168ceGrant Likely	if (status & (IRQ_COAL | IRQ_DLY))
84192744989533cbe85e8057935d230e128810168ceGrant Likely		ll_temac_recv(lp->ndev);
84292744989533cbe85e8057935d230e128810168ceGrant Likely
84392744989533cbe85e8057935d230e128810168ceGrant Likely	return IRQ_HANDLED;
84492744989533cbe85e8057935d230e128810168ceGrant Likely}
84592744989533cbe85e8057935d230e128810168ceGrant Likely
84692744989533cbe85e8057935d230e128810168ceGrant Likelystatic int temac_open(struct net_device *ndev)
84792744989533cbe85e8057935d230e128810168ceGrant Likely{
84892744989533cbe85e8057935d230e128810168ceGrant Likely	struct temac_local *lp = netdev_priv(ndev);
84992744989533cbe85e8057935d230e128810168ceGrant Likely	int rc;
85092744989533cbe85e8057935d230e128810168ceGrant Likely
85192744989533cbe85e8057935d230e128810168ceGrant Likely	dev_dbg(&ndev->dev, "temac_open()\n");
85292744989533cbe85e8057935d230e128810168ceGrant Likely
85392744989533cbe85e8057935d230e128810168ceGrant Likely	if (lp->phy_node) {
85492744989533cbe85e8057935d230e128810168ceGrant Likely		lp->phy_dev = of_phy_connect(lp->ndev, lp->phy_node,
85592744989533cbe85e8057935d230e128810168ceGrant Likely					     temac_adjust_link, 0, 0);
85692744989533cbe85e8057935d230e128810168ceGrant Likely		if (!lp->phy_dev) {
85792744989533cbe85e8057935d230e128810168ceGrant Likely			dev_err(lp->dev, "of_phy_connect() failed\n");
85892744989533cbe85e8057935d230e128810168ceGrant Likely			return -ENODEV;
85992744989533cbe85e8057935d230e128810168ceGrant Likely		}
86092744989533cbe85e8057935d230e128810168ceGrant Likely
86192744989533cbe85e8057935d230e128810168ceGrant Likely		phy_start(lp->phy_dev);
86292744989533cbe85e8057935d230e128810168ceGrant Likely	}
86392744989533cbe85e8057935d230e128810168ceGrant Likely
86450ec1538fac0e39078d45ca5f8a5186621830058Ricardo Ribalda	temac_device_reset(ndev);
86550ec1538fac0e39078d45ca5f8a5186621830058Ricardo Ribalda
86692744989533cbe85e8057935d230e128810168ceGrant Likely	rc = request_irq(lp->tx_irq, ll_temac_tx_irq, 0, ndev->name, ndev);
86792744989533cbe85e8057935d230e128810168ceGrant Likely	if (rc)
86892744989533cbe85e8057935d230e128810168ceGrant Likely		goto err_tx_irq;
86992744989533cbe85e8057935d230e128810168ceGrant Likely	rc = request_irq(lp->rx_irq, ll_temac_rx_irq, 0, ndev->name, ndev);
87092744989533cbe85e8057935d230e128810168ceGrant Likely	if (rc)
87192744989533cbe85e8057935d230e128810168ceGrant Likely		goto err_rx_irq;
87292744989533cbe85e8057935d230e128810168ceGrant Likely
87392744989533cbe85e8057935d230e128810168ceGrant Likely	return 0;
87492744989533cbe85e8057935d230e128810168ceGrant Likely
87592744989533cbe85e8057935d230e128810168ceGrant Likely err_rx_irq:
87692744989533cbe85e8057935d230e128810168ceGrant Likely	free_irq(lp->tx_irq, ndev);
87792744989533cbe85e8057935d230e128810168ceGrant Likely err_tx_irq:
87892744989533cbe85e8057935d230e128810168ceGrant Likely	if (lp->phy_dev)
87992744989533cbe85e8057935d230e128810168ceGrant Likely		phy_disconnect(lp->phy_dev);
88092744989533cbe85e8057935d230e128810168ceGrant Likely	lp->phy_dev = NULL;
88192744989533cbe85e8057935d230e128810168ceGrant Likely	dev_err(lp->dev, "request_irq() failed\n");
88292744989533cbe85e8057935d230e128810168ceGrant Likely	return rc;
88392744989533cbe85e8057935d230e128810168ceGrant Likely}
88492744989533cbe85e8057935d230e128810168ceGrant Likely
88592744989533cbe85e8057935d230e128810168ceGrant Likelystatic int temac_stop(struct net_device *ndev)
88692744989533cbe85e8057935d230e128810168ceGrant Likely{
88792744989533cbe85e8057935d230e128810168ceGrant Likely	struct temac_local *lp = netdev_priv(ndev);
88892744989533cbe85e8057935d230e128810168ceGrant Likely
88992744989533cbe85e8057935d230e128810168ceGrant Likely	dev_dbg(&ndev->dev, "temac_close()\n");
89092744989533cbe85e8057935d230e128810168ceGrant Likely
89192744989533cbe85e8057935d230e128810168ceGrant Likely	free_irq(lp->tx_irq, ndev);
89292744989533cbe85e8057935d230e128810168ceGrant Likely	free_irq(lp->rx_irq, ndev);
89392744989533cbe85e8057935d230e128810168ceGrant Likely
89492744989533cbe85e8057935d230e128810168ceGrant Likely	if (lp->phy_dev)
89592744989533cbe85e8057935d230e128810168ceGrant Likely		phy_disconnect(lp->phy_dev);
89692744989533cbe85e8057935d230e128810168ceGrant Likely	lp->phy_dev = NULL;
89792744989533cbe85e8057935d230e128810168ceGrant Likely
898301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov	temac_dma_bd_release(ndev);
899301e9d96bf65292f916a3936d63c504ac7792ee6Denis Kirjanov
90092744989533cbe85e8057935d230e128810168ceGrant Likely	return 0;
90192744989533cbe85e8057935d230e128810168ceGrant Likely}
90292744989533cbe85e8057935d230e128810168ceGrant Likely
90392744989533cbe85e8057935d230e128810168ceGrant Likely#ifdef CONFIG_NET_POLL_CONTROLLER
90492744989533cbe85e8057935d230e128810168ceGrant Likelystatic void
90592744989533cbe85e8057935d230e128810168ceGrant Likelytemac_poll_controller(struct net_device *ndev)
90692744989533cbe85e8057935d230e128810168ceGrant Likely{
90792744989533cbe85e8057935d230e128810168ceGrant Likely	struct temac_local *lp = netdev_priv(ndev);
90892744989533cbe85e8057935d230e128810168ceGrant Likely
90992744989533cbe85e8057935d230e128810168ceGrant Likely	disable_irq(lp->tx_irq);
91092744989533cbe85e8057935d230e128810168ceGrant Likely	disable_irq(lp->rx_irq);
91192744989533cbe85e8057935d230e128810168ceGrant Likely
9128539992f6091eb8206c781421312157d0c282e6eMichal Simek	ll_temac_rx_irq(lp->tx_irq, ndev);
9138539992f6091eb8206c781421312157d0c282e6eMichal Simek	ll_temac_tx_irq(lp->rx_irq, ndev);
91492744989533cbe85e8057935d230e128810168ceGrant Likely
91592744989533cbe85e8057935d230e128810168ceGrant Likely	enable_irq(lp->tx_irq);
91692744989533cbe85e8057935d230e128810168ceGrant Likely	enable_irq(lp->rx_irq);
91792744989533cbe85e8057935d230e128810168ceGrant Likely}
91892744989533cbe85e8057935d230e128810168ceGrant Likely#endif
91992744989533cbe85e8057935d230e128810168ceGrant Likely
9208d8bdfe8034399357df58b5f3e4da638a9e9a257Ricardo Ribaldastatic int temac_ioctl(struct net_device *ndev, struct ifreq *rq, int cmd)
9218d8bdfe8034399357df58b5f3e4da638a9e9a257Ricardo Ribalda{
9228d8bdfe8034399357df58b5f3e4da638a9e9a257Ricardo Ribalda	struct temac_local *lp = netdev_priv(ndev);
9238d8bdfe8034399357df58b5f3e4da638a9e9a257Ricardo Ribalda
9248d8bdfe8034399357df58b5f3e4da638a9e9a257Ricardo Ribalda	if (!netif_running(ndev))
9258d8bdfe8034399357df58b5f3e4da638a9e9a257Ricardo Ribalda		return -EINVAL;
9268d8bdfe8034399357df58b5f3e4da638a9e9a257Ricardo Ribalda
9278d8bdfe8034399357df58b5f3e4da638a9e9a257Ricardo Ribalda	if (!lp->phy_dev)
9288d8bdfe8034399357df58b5f3e4da638a9e9a257Ricardo Ribalda		return -EINVAL;
9298d8bdfe8034399357df58b5f3e4da638a9e9a257Ricardo Ribalda
9308d8bdfe8034399357df58b5f3e4da638a9e9a257Ricardo Ribalda	return phy_mii_ioctl(lp->phy_dev, rq, cmd);
9318d8bdfe8034399357df58b5f3e4da638a9e9a257Ricardo Ribalda}
9328d8bdfe8034399357df58b5f3e4da638a9e9a257Ricardo Ribalda
93392744989533cbe85e8057935d230e128810168ceGrant Likelystatic const struct net_device_ops temac_netdev_ops = {
93492744989533cbe85e8057935d230e128810168ceGrant Likely	.ndo_open = temac_open,
93592744989533cbe85e8057935d230e128810168ceGrant Likely	.ndo_stop = temac_stop,
93692744989533cbe85e8057935d230e128810168ceGrant Likely	.ndo_start_xmit = temac_start_xmit,
93704e406dcc54cfd84d333ea673fa986fb5a1840e7Jiri Pirko	.ndo_set_mac_address = temac_set_mac_address,
93860eb5fd11d1c6050c45a5aab141f42dd396e2a7fDenis Kirjanov	.ndo_validate_addr = eth_validate_addr,
9398d8bdfe8034399357df58b5f3e4da638a9e9a257Ricardo Ribalda	.ndo_do_ioctl = temac_ioctl,
94092744989533cbe85e8057935d230e128810168ceGrant Likely#ifdef CONFIG_NET_POLL_CONTROLLER
94192744989533cbe85e8057935d230e128810168ceGrant Likely	.ndo_poll_controller = temac_poll_controller,
94292744989533cbe85e8057935d230e128810168ceGrant Likely#endif
94392744989533cbe85e8057935d230e128810168ceGrant Likely};
94492744989533cbe85e8057935d230e128810168ceGrant Likely
94592744989533cbe85e8057935d230e128810168ceGrant Likely/* ---------------------------------------------------------------------
94692744989533cbe85e8057935d230e128810168ceGrant Likely * SYSFS device attributes
94792744989533cbe85e8057935d230e128810168ceGrant Likely */
94892744989533cbe85e8057935d230e128810168ceGrant Likelystatic ssize_t temac_show_llink_regs(struct device *dev,
94992744989533cbe85e8057935d230e128810168ceGrant Likely				     struct device_attribute *attr, char *buf)
95092744989533cbe85e8057935d230e128810168ceGrant Likely{
95192744989533cbe85e8057935d230e128810168ceGrant Likely	struct net_device *ndev = dev_get_drvdata(dev);
95292744989533cbe85e8057935d230e128810168ceGrant Likely	struct temac_local *lp = netdev_priv(ndev);
95392744989533cbe85e8057935d230e128810168ceGrant Likely	int i, len = 0;
95492744989533cbe85e8057935d230e128810168ceGrant Likely
95592744989533cbe85e8057935d230e128810168ceGrant Likely	for (i = 0; i < 0x11; i++)
956e44171f115de3dedf34064646206deb91549865fJohn Linn		len += sprintf(buf + len, "%.8x%s", lp->dma_in(lp, i),
95792744989533cbe85e8057935d230e128810168ceGrant Likely			       (i % 8) == 7 ? "\n" : " ");
95892744989533cbe85e8057935d230e128810168ceGrant Likely	len += sprintf(buf + len, "\n");
95992744989533cbe85e8057935d230e128810168ceGrant Likely
96092744989533cbe85e8057935d230e128810168ceGrant Likely	return len;
96192744989533cbe85e8057935d230e128810168ceGrant Likely}
96292744989533cbe85e8057935d230e128810168ceGrant Likely
96392744989533cbe85e8057935d230e128810168ceGrant Likelystatic DEVICE_ATTR(llink_regs, 0440, temac_show_llink_regs, NULL);
96492744989533cbe85e8057935d230e128810168ceGrant Likely
96592744989533cbe85e8057935d230e128810168ceGrant Likelystatic struct attribute *temac_device_attrs[] = {
96692744989533cbe85e8057935d230e128810168ceGrant Likely	&dev_attr_llink_regs.attr,
96792744989533cbe85e8057935d230e128810168ceGrant Likely	NULL,
96892744989533cbe85e8057935d230e128810168ceGrant Likely};
96992744989533cbe85e8057935d230e128810168ceGrant Likely
97092744989533cbe85e8057935d230e128810168ceGrant Likelystatic const struct attribute_group temac_attr_group = {
97192744989533cbe85e8057935d230e128810168ceGrant Likely	.attrs = temac_device_attrs,
97292744989533cbe85e8057935d230e128810168ceGrant Likely};
97392744989533cbe85e8057935d230e128810168ceGrant Likely
9749eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo/* ethtool support */
9759eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardostatic int temac_get_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
9769eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo{
9779eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo	struct temac_local *lp = netdev_priv(ndev);
9789eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo	return phy_ethtool_gset(lp->phy_dev, cmd);
9799eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo}
9809eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo
9819eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardostatic int temac_set_settings(struct net_device *ndev, struct ethtool_cmd *cmd)
9829eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo{
9839eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo	struct temac_local *lp = netdev_priv(ndev);
9849eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo	return phy_ethtool_sset(lp->phy_dev, cmd);
9859eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo}
9869eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo
9879eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardostatic int temac_nway_reset(struct net_device *ndev)
9889eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo{
9899eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo	struct temac_local *lp = netdev_priv(ndev);
9909eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo	return phy_start_aneg(lp->phy_dev);
9919eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo}
9929eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo
9939eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardostatic const struct ethtool_ops temac_ethtool_ops = {
9949eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo	.get_settings = temac_get_settings,
9959eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo	.set_settings = temac_set_settings,
9969eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo	.nway_reset = temac_nway_reset,
9979eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo	.get_link = ethtool_op_get_link,
998f85e5ea28f5c1d31b22ae5777a1a08ebd76ff7e1Richard Cochran	.get_ts_info = ethtool_op_get_ts_info,
9999eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo};
10009eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo
100106b0e68327d499c3588c954d2a2d86458d451c4bBill Pembertonstatic int temac_of_probe(struct platform_device *op)
100292744989533cbe85e8057935d230e128810168ceGrant Likely{
100392744989533cbe85e8057935d230e128810168ceGrant Likely	struct device_node *np;
100492744989533cbe85e8057935d230e128810168ceGrant Likely	struct temac_local *lp;
100592744989533cbe85e8057935d230e128810168ceGrant Likely	struct net_device *ndev;
100692744989533cbe85e8057935d230e128810168ceGrant Likely	const void *addr;
100723ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill	__be32 *p;
100892744989533cbe85e8057935d230e128810168ceGrant Likely	int size, rc = 0;
100992744989533cbe85e8057935d230e128810168ceGrant Likely
101092744989533cbe85e8057935d230e128810168ceGrant Likely	/* Init network device structure */
101192744989533cbe85e8057935d230e128810168ceGrant Likely	ndev = alloc_etherdev(sizeof(*lp));
101241de8d4cff21a2e81e3d9ff66f5f7c903f9c3ab1Joe Perches	if (!ndev)
101392744989533cbe85e8057935d230e128810168ceGrant Likely		return -ENOMEM;
101441de8d4cff21a2e81e3d9ff66f5f7c903f9c3ab1Joe Perches
10158513fbd880093f00a47e85a552f14ca2de8d84d6Jingoo Han	platform_set_drvdata(op, ndev);
101692744989533cbe85e8057935d230e128810168ceGrant Likely	SET_NETDEV_DEV(ndev, &op->dev);
101792744989533cbe85e8057935d230e128810168ceGrant Likely	ndev->flags &= ~IFF_MULTICAST;  /* clear multicast */
101828e24c62ab3062e965ef1b3bcc244d50aee7fa85Eric Dumazet	ndev->features = NETIF_F_SG;
101992744989533cbe85e8057935d230e128810168ceGrant Likely	ndev->netdev_ops = &temac_netdev_ops;
10209eac2d4d5312d2ea05c0dbba8051b868fe9961a4Ricardo	ndev->ethtool_ops = &temac_ethtool_ops;
102192744989533cbe85e8057935d230e128810168ceGrant Likely#if 0
102292744989533cbe85e8057935d230e128810168ceGrant Likely	ndev->features |= NETIF_F_IP_CSUM; /* Can checksum TCP/UDP over IPv4. */
102392744989533cbe85e8057935d230e128810168ceGrant Likely	ndev->features |= NETIF_F_HW_CSUM; /* Can checksum all the packets. */
102492744989533cbe85e8057935d230e128810168ceGrant Likely	ndev->features |= NETIF_F_IPV6_CSUM; /* Can checksum IPV6 TCP/UDP */
102592744989533cbe85e8057935d230e128810168ceGrant Likely	ndev->features |= NETIF_F_HIGHDMA; /* Can DMA to high memory. */
1026f646968f8f7c624587de729115d802372b9063ddPatrick McHardy	ndev->features |= NETIF_F_HW_VLAN_CTAG_TX; /* Transmit VLAN hw accel */
1027f646968f8f7c624587de729115d802372b9063ddPatrick McHardy	ndev->features |= NETIF_F_HW_VLAN_CTAG_RX; /* Receive VLAN hw acceleration */
1028f646968f8f7c624587de729115d802372b9063ddPatrick McHardy	ndev->features |= NETIF_F_HW_VLAN_CTAG_FILTER; /* Receive VLAN filtering */
102992744989533cbe85e8057935d230e128810168ceGrant Likely	ndev->features |= NETIF_F_VLAN_CHALLENGED; /* cannot handle VLAN pkts */
103092744989533cbe85e8057935d230e128810168ceGrant Likely	ndev->features |= NETIF_F_GSO; /* Enable software GSO. */
103192744989533cbe85e8057935d230e128810168ceGrant Likely	ndev->features |= NETIF_F_MULTI_QUEUE; /* Has multiple TX/RX queues */
103292744989533cbe85e8057935d230e128810168ceGrant Likely	ndev->features |= NETIF_F_LRO; /* large receive offload */
103392744989533cbe85e8057935d230e128810168ceGrant Likely#endif
103492744989533cbe85e8057935d230e128810168ceGrant Likely
103592744989533cbe85e8057935d230e128810168ceGrant Likely	/* setup temac private info structure */
103692744989533cbe85e8057935d230e128810168ceGrant Likely	lp = netdev_priv(ndev);
103792744989533cbe85e8057935d230e128810168ceGrant Likely	lp->ndev = ndev;
103892744989533cbe85e8057935d230e128810168ceGrant Likely	lp->dev = &op->dev;
103992744989533cbe85e8057935d230e128810168ceGrant Likely	lp->options = XTE_OPTION_DEFAULTS;
104092744989533cbe85e8057935d230e128810168ceGrant Likely	spin_lock_init(&lp->rx_lock);
104192744989533cbe85e8057935d230e128810168ceGrant Likely	mutex_init(&lp->indirect_mutex);
104292744989533cbe85e8057935d230e128810168ceGrant Likely
104392744989533cbe85e8057935d230e128810168ceGrant Likely	/* map device registers */
104461c7a080a5a061c976988fd4b844dfb468dda255Grant Likely	lp->regs = of_iomap(op->dev.of_node, 0);
104592744989533cbe85e8057935d230e128810168ceGrant Likely	if (!lp->regs) {
104692744989533cbe85e8057935d230e128810168ceGrant Likely		dev_err(&op->dev, "could not map temac regs.\n");
104792744989533cbe85e8057935d230e128810168ceGrant Likely		goto nodev;
104892744989533cbe85e8057935d230e128810168ceGrant Likely	}
104992744989533cbe85e8057935d230e128810168ceGrant Likely
105023ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill	/* Setup checksum offload, but default to off if not specified */
105123ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill	lp->temac_features = 0;
105223ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill	p = (__be32 *)of_get_property(op->dev.of_node, "xlnx,txcsum", NULL);
105323ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill	if (p && be32_to_cpu(*p)) {
105423ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill		lp->temac_features |= TEMAC_FEATURE_TX_CSUM;
105523ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill		/* Can checksum TCP/UDP over IPv4. */
105623ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill		ndev->features |= NETIF_F_IP_CSUM;
105723ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill	}
105823ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill	p = (__be32 *)of_get_property(op->dev.of_node, "xlnx,rxcsum", NULL);
105923ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill	if (p && be32_to_cpu(*p))
106023ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill		lp->temac_features |= TEMAC_FEATURE_RX_CSUM;
106123ecc4bde21f0ccb38f4b53cadde7fc5d67d68e3Brian Hill
106292744989533cbe85e8057935d230e128810168ceGrant Likely	/* Find the DMA node, map the DMA registers, and decode the DMA IRQs */
106361c7a080a5a061c976988fd4b844dfb468dda255Grant Likely	np = of_parse_phandle(op->dev.of_node, "llink-connected", 0);
106492744989533cbe85e8057935d230e128810168ceGrant Likely	if (!np) {
106592744989533cbe85e8057935d230e128810168ceGrant Likely		dev_err(&op->dev, "could not find DMA node\n");
1066dfe1e8eddcd73fc58124933c14c2efe93fab0b8fDenis Kirjanov		goto err_iounmap;
106792744989533cbe85e8057935d230e128810168ceGrant Likely	}
106892744989533cbe85e8057935d230e128810168ceGrant Likely
1069e44171f115de3dedf34064646206deb91549865fJohn Linn	/* Setup the DMA register accesses, could be DCR or memory mapped */
1070e44171f115de3dedf34064646206deb91549865fJohn Linn	if (temac_dcr_setup(lp, op, np)) {
1071e44171f115de3dedf34064646206deb91549865fJohn Linn
1072e44171f115de3dedf34064646206deb91549865fJohn Linn		/* no DCR in the device tree, try non-DCR */
1073e44171f115de3dedf34064646206deb91549865fJohn Linn		lp->sdma_regs = of_iomap(np, 0);
1074e44171f115de3dedf34064646206deb91549865fJohn Linn		if (lp->sdma_regs) {
1075e44171f115de3dedf34064646206deb91549865fJohn Linn			lp->dma_in = temac_dma_in32;
1076e44171f115de3dedf34064646206deb91549865fJohn Linn			lp->dma_out = temac_dma_out32;
1077e44171f115de3dedf34064646206deb91549865fJohn Linn			dev_dbg(&op->dev, "MEM base: %p\n", lp->sdma_regs);
1078e44171f115de3dedf34064646206deb91549865fJohn Linn		} else {
1079e44171f115de3dedf34064646206deb91549865fJohn Linn			dev_err(&op->dev, "unable to map DMA registers\n");
10807cc36f6f7116918c8a8990a0f23f62d2288a81bfKulikov Vasiliy			of_node_put(np);
1081dfe1e8eddcd73fc58124933c14c2efe93fab0b8fDenis Kirjanov			goto err_iounmap;
1082e44171f115de3dedf34064646206deb91549865fJohn Linn		}
108392744989533cbe85e8057935d230e128810168ceGrant Likely	}
108492744989533cbe85e8057935d230e128810168ceGrant Likely
108592744989533cbe85e8057935d230e128810168ceGrant Likely	lp->rx_irq = irq_of_parse_and_map(np, 0);
108692744989533cbe85e8057935d230e128810168ceGrant Likely	lp->tx_irq = irq_of_parse_and_map(np, 1);
10877cc36f6f7116918c8a8990a0f23f62d2288a81bfKulikov Vasiliy
10887cc36f6f7116918c8a8990a0f23f62d2288a81bfKulikov Vasiliy	of_node_put(np); /* Finished with the DMA node; drop the reference */
10897cc36f6f7116918c8a8990a0f23f62d2288a81bfKulikov Vasiliy
10904e68ea26e76273cc62a981a414a8319a7f4c1077Michal Simek	if (!lp->rx_irq || !lp->tx_irq) {
109192744989533cbe85e8057935d230e128810168ceGrant Likely		dev_err(&op->dev, "could not determine irqs\n");
109292744989533cbe85e8057935d230e128810168ceGrant Likely		rc = -ENOMEM;
1093dfe1e8eddcd73fc58124933c14c2efe93fab0b8fDenis Kirjanov		goto err_iounmap_2;
109492744989533cbe85e8057935d230e128810168ceGrant Likely	}
109592744989533cbe85e8057935d230e128810168ceGrant Likely
109692744989533cbe85e8057935d230e128810168ceGrant Likely
109792744989533cbe85e8057935d230e128810168ceGrant Likely	/* Retrieve the MAC address */
109861c7a080a5a061c976988fd4b844dfb468dda255Grant Likely	addr = of_get_property(op->dev.of_node, "local-mac-address", &size);
109992744989533cbe85e8057935d230e128810168ceGrant Likely	if ((!addr) || (size != 6)) {
110092744989533cbe85e8057935d230e128810168ceGrant Likely		dev_err(&op->dev, "could not find MAC address\n");
110192744989533cbe85e8057935d230e128810168ceGrant Likely		rc = -ENODEV;
1102dfe1e8eddcd73fc58124933c14c2efe93fab0b8fDenis Kirjanov		goto err_iounmap_2;
110392744989533cbe85e8057935d230e128810168ceGrant Likely	}
110404e406dcc54cfd84d333ea673fa986fb5a1840e7Jiri Pirko	temac_init_mac_address(ndev, (void *)addr);
110592744989533cbe85e8057935d230e128810168ceGrant Likely
110661c7a080a5a061c976988fd4b844dfb468dda255Grant Likely	rc = temac_mdio_setup(lp, op->dev.of_node);
110792744989533cbe85e8057935d230e128810168ceGrant Likely	if (rc)
110892744989533cbe85e8057935d230e128810168ceGrant Likely		dev_warn(&op->dev, "error registering MDIO bus\n");
110992744989533cbe85e8057935d230e128810168ceGrant Likely
111061c7a080a5a061c976988fd4b844dfb468dda255Grant Likely	lp->phy_node = of_parse_phandle(op->dev.of_node, "phy-handle", 0);
111192744989533cbe85e8057935d230e128810168ceGrant Likely	if (lp->phy_node)
111292744989533cbe85e8057935d230e128810168ceGrant Likely		dev_dbg(lp->dev, "using PHY node %s (%p)\n", np->full_name, np);
111392744989533cbe85e8057935d230e128810168ceGrant Likely
111492744989533cbe85e8057935d230e128810168ceGrant Likely	/* Add the device attributes */
111592744989533cbe85e8057935d230e128810168ceGrant Likely	rc = sysfs_create_group(&lp->dev->kobj, &temac_attr_group);
111692744989533cbe85e8057935d230e128810168ceGrant Likely	if (rc) {
111792744989533cbe85e8057935d230e128810168ceGrant Likely		dev_err(lp->dev, "Error creating sysfs files\n");
1118dfe1e8eddcd73fc58124933c14c2efe93fab0b8fDenis Kirjanov		goto err_iounmap_2;
111992744989533cbe85e8057935d230e128810168ceGrant Likely	}
112092744989533cbe85e8057935d230e128810168ceGrant Likely
112192744989533cbe85e8057935d230e128810168ceGrant Likely	rc = register_netdev(lp->ndev);
112292744989533cbe85e8057935d230e128810168ceGrant Likely	if (rc) {
112392744989533cbe85e8057935d230e128810168ceGrant Likely		dev_err(lp->dev, "register_netdev() error (%i)\n", rc);
112492744989533cbe85e8057935d230e128810168ceGrant Likely		goto err_register_ndev;
112592744989533cbe85e8057935d230e128810168ceGrant Likely	}
112692744989533cbe85e8057935d230e128810168ceGrant Likely
112792744989533cbe85e8057935d230e128810168ceGrant Likely	return 0;
112892744989533cbe85e8057935d230e128810168ceGrant Likely
112992744989533cbe85e8057935d230e128810168ceGrant Likely err_register_ndev:
113092744989533cbe85e8057935d230e128810168ceGrant Likely	sysfs_remove_group(&lp->dev->kobj, &temac_attr_group);
1131dfe1e8eddcd73fc58124933c14c2efe93fab0b8fDenis Kirjanov err_iounmap_2:
1132dfe1e8eddcd73fc58124933c14c2efe93fab0b8fDenis Kirjanov	if (lp->sdma_regs)
1133dfe1e8eddcd73fc58124933c14c2efe93fab0b8fDenis Kirjanov		iounmap(lp->sdma_regs);
1134dfe1e8eddcd73fc58124933c14c2efe93fab0b8fDenis Kirjanov err_iounmap:
1135dfe1e8eddcd73fc58124933c14c2efe93fab0b8fDenis Kirjanov	iounmap(lp->regs);
113692744989533cbe85e8057935d230e128810168ceGrant Likely nodev:
113792744989533cbe85e8057935d230e128810168ceGrant Likely	free_netdev(ndev);
113892744989533cbe85e8057935d230e128810168ceGrant Likely	ndev = NULL;
113992744989533cbe85e8057935d230e128810168ceGrant Likely	return rc;
114092744989533cbe85e8057935d230e128810168ceGrant Likely}
114192744989533cbe85e8057935d230e128810168ceGrant Likely
114206b0e68327d499c3588c954d2a2d86458d451c4bBill Pembertonstatic int temac_of_remove(struct platform_device *op)
114392744989533cbe85e8057935d230e128810168ceGrant Likely{
11448513fbd880093f00a47e85a552f14ca2de8d84d6Jingoo Han	struct net_device *ndev = platform_get_drvdata(op);
114592744989533cbe85e8057935d230e128810168ceGrant Likely	struct temac_local *lp = netdev_priv(ndev);
114692744989533cbe85e8057935d230e128810168ceGrant Likely
114792744989533cbe85e8057935d230e128810168ceGrant Likely	temac_mdio_teardown(lp);
114892744989533cbe85e8057935d230e128810168ceGrant Likely	unregister_netdev(ndev);
114992744989533cbe85e8057935d230e128810168ceGrant Likely	sysfs_remove_group(&lp->dev->kobj, &temac_attr_group);
11506a3e6aa10bf516c5c507292489e4d1fddeb2901bJulia Lawall	of_node_put(lp->phy_node);
115192744989533cbe85e8057935d230e128810168ceGrant Likely	lp->phy_node = NULL;
1152dfe1e8eddcd73fc58124933c14c2efe93fab0b8fDenis Kirjanov	iounmap(lp->regs);
1153dfe1e8eddcd73fc58124933c14c2efe93fab0b8fDenis Kirjanov	if (lp->sdma_regs)
1154dfe1e8eddcd73fc58124933c14c2efe93fab0b8fDenis Kirjanov		iounmap(lp->sdma_regs);
115592744989533cbe85e8057935d230e128810168ceGrant Likely	free_netdev(ndev);
115692744989533cbe85e8057935d230e128810168ceGrant Likely	return 0;
115792744989533cbe85e8057935d230e128810168ceGrant Likely}
115892744989533cbe85e8057935d230e128810168ceGrant Likely
115906b0e68327d499c3588c954d2a2d86458d451c4bBill Pembertonstatic struct of_device_id temac_of_match[] = {
116092744989533cbe85e8057935d230e128810168ceGrant Likely	{ .compatible = "xlnx,xps-ll-temac-1.01.b", },
1161c3b7c12cd78d5c8264c87c29dcd9a8f1819f8313Steven J. Magnani	{ .compatible = "xlnx,xps-ll-temac-2.00.a", },
1162c3b7c12cd78d5c8264c87c29dcd9a8f1819f8313Steven J. Magnani	{ .compatible = "xlnx,xps-ll-temac-2.02.a", },
1163c3b7c12cd78d5c8264c87c29dcd9a8f1819f8313Steven J. Magnani	{ .compatible = "xlnx,xps-ll-temac-2.03.a", },
116492744989533cbe85e8057935d230e128810168ceGrant Likely	{},
116592744989533cbe85e8057935d230e128810168ceGrant Likely};
116692744989533cbe85e8057935d230e128810168ceGrant LikelyMODULE_DEVICE_TABLE(of, temac_of_match);
116792744989533cbe85e8057935d230e128810168ceGrant Likely
116874888760d40b3ac9054f9c5fa07b566c0676ba2dGrant Likelystatic struct platform_driver temac_of_driver = {
116992744989533cbe85e8057935d230e128810168ceGrant Likely	.probe = temac_of_probe,
117006b0e68327d499c3588c954d2a2d86458d451c4bBill Pemberton	.remove = temac_of_remove,
117192744989533cbe85e8057935d230e128810168ceGrant Likely	.driver = {
117292744989533cbe85e8057935d230e128810168ceGrant Likely		.name = "xilinx_temac",
11734018294b53d1dae026880e45f174c1cc63b5d435Grant Likely		.of_match_table = temac_of_match,
117492744989533cbe85e8057935d230e128810168ceGrant Likely	},
117592744989533cbe85e8057935d230e128810168ceGrant Likely};
117692744989533cbe85e8057935d230e128810168ceGrant Likely
1177db62f684deeb291ab2533b99843d5df9a36b1f19Axel Linmodule_platform_driver(temac_of_driver);
117892744989533cbe85e8057935d230e128810168ceGrant Likely
117992744989533cbe85e8057935d230e128810168ceGrant LikelyMODULE_DESCRIPTION("Xilinx LL_TEMAC Ethernet driver");
118092744989533cbe85e8057935d230e128810168ceGrant LikelyMODULE_AUTHOR("Yoshio Kashiwagi");
118192744989533cbe85e8057935d230e128810168ceGrant LikelyMODULE_LICENSE("GPL");
1182