xref: /openbmc/linux/drivers/net/ethernet/allwinner/sun4i-emac.c (revision 4f2c0a4acffbec01079c28f839422e64ddeff004)
149220505SStefan Roese /*
249220505SStefan Roese  * Allwinner EMAC Fast Ethernet driver for Linux.
349220505SStefan Roese  *
449220505SStefan Roese  * Copyright 2012-2013 Stefan Roese <sr@denx.de>
549220505SStefan Roese  * Copyright 2013 Maxime Ripard <maxime.ripard@free-electrons.com>
649220505SStefan Roese  *
749220505SStefan Roese  * Based on the Linux driver provided by Allwinner:
849220505SStefan Roese  * Copyright (C) 1997  Sten Wang
949220505SStefan Roese  *
1049220505SStefan Roese  * This file is licensed under the terms of the GNU General Public
1149220505SStefan Roese  * License version 2. This program is licensed "as is" without any
1249220505SStefan Roese  * warranty of any kind, whether express or implied.
1349220505SStefan Roese  */
1449220505SStefan Roese 
1549220505SStefan Roese #include <linux/clk.h>
1649220505SStefan Roese #include <linux/etherdevice.h>
1749220505SStefan Roese #include <linux/ethtool.h>
1849220505SStefan Roese #include <linux/gpio.h>
1949220505SStefan Roese #include <linux/interrupt.h>
2049220505SStefan Roese #include <linux/irq.h>
2149220505SStefan Roese #include <linux/mii.h>
2249220505SStefan Roese #include <linux/module.h>
2349220505SStefan Roese #include <linux/netdevice.h>
2449220505SStefan Roese #include <linux/of_address.h>
2549220505SStefan Roese #include <linux/of_irq.h>
2649220505SStefan Roese #include <linux/of_mdio.h>
2749220505SStefan Roese #include <linux/of_net.h>
2849220505SStefan Roese #include <linux/of_platform.h>
2949220505SStefan Roese #include <linux/platform_device.h>
3049220505SStefan Roese #include <linux/phy.h>
31542a64c7SHans de Goede #include <linux/soc/sunxi/sunxi_sram.h>
3247869e82SConley Lee #include <linux/dmaengine.h>
3349220505SStefan Roese 
3449220505SStefan Roese #include "sun4i-emac.h"
3549220505SStefan Roese 
3649220505SStefan Roese #define DRV_NAME		"sun4i-emac"
3749220505SStefan Roese 
3849220505SStefan Roese #define EMAC_MAX_FRAME_LEN	0x0600
3949220505SStefan Roese 
40b8ca3387SMichael Weiser #define EMAC_DEFAULT_MSG_ENABLE 0x0000
41b8ca3387SMichael Weiser static int debug = -1;     /* defaults above */;
42b8ca3387SMichael Weiser module_param(debug, int, 0);
43b8ca3387SMichael Weiser MODULE_PARM_DESC(debug, "debug message flags");
44b8ca3387SMichael Weiser 
4549220505SStefan Roese /* Transmit timeout, default 5 seconds. */
4649220505SStefan Roese static int watchdog = 5000;
4749220505SStefan Roese module_param(watchdog, int, 0400);
4849220505SStefan Roese MODULE_PARM_DESC(watchdog, "transmit timeout in milliseconds");
4949220505SStefan Roese 
5049220505SStefan Roese /* EMAC register address locking.
5149220505SStefan Roese  *
5249220505SStefan Roese  * The EMAC uses an address register to control where data written
5349220505SStefan Roese  * to the data register goes. This means that the address register
5449220505SStefan Roese  * must be preserved over interrupts or similar calls.
5549220505SStefan Roese  *
5649220505SStefan Roese  * During interrupt and other critical calls, a spinlock is used to
5749220505SStefan Roese  * protect the system, but the calls themselves save the address
5849220505SStefan Roese  * in the address register in case they are interrupting another
5949220505SStefan Roese  * access to the device.
6049220505SStefan Roese  *
6149220505SStefan Roese  * For general accesses a lock is provided so that calls which are
6249220505SStefan Roese  * allowed to sleep are serialised so that the address register does
6349220505SStefan Roese  * not need to be saved. This lock also serves to serialise access
6449220505SStefan Roese  * to the EEPROM and PHY access registers which are shared between
6549220505SStefan Roese  * these two devices.
6649220505SStefan Roese  */
6749220505SStefan Roese 
6849220505SStefan Roese /* The driver supports the original EMACE, and now the two newer
6949220505SStefan Roese  * devices, EMACA and EMACB.
7049220505SStefan Roese  */
7149220505SStefan Roese 
7249220505SStefan Roese struct emac_board_info {
7349220505SStefan Roese 	struct clk		*clk;
7449220505SStefan Roese 	struct device		*dev;
7549220505SStefan Roese 	struct platform_device	*pdev;
7649220505SStefan Roese 	spinlock_t		lock;
7749220505SStefan Roese 	void __iomem		*membase;
7849220505SStefan Roese 	u32			msg_enable;
7949220505SStefan Roese 	struct net_device	*ndev;
8049220505SStefan Roese 	u16			tx_fifo_stat;
8149220505SStefan Roese 
8249220505SStefan Roese 	int			emacrx_completed_flag;
8349220505SStefan Roese 
8449220505SStefan Roese 	struct device_node	*phy_node;
8549220505SStefan Roese 	unsigned int		link;
8649220505SStefan Roese 	unsigned int		speed;
8749220505SStefan Roese 	unsigned int		duplex;
8849220505SStefan Roese 
8949220505SStefan Roese 	phy_interface_t		phy_interface;
9047869e82SConley Lee 	struct dma_chan	*rx_chan;
9147869e82SConley Lee 	phys_addr_t emac_rx_fifo;
9247869e82SConley Lee };
9347869e82SConley Lee 
9447869e82SConley Lee struct emac_dma_req {
9547869e82SConley Lee 	struct emac_board_info *db;
9647869e82SConley Lee 	struct dma_async_tx_descriptor *desc;
9747869e82SConley Lee 	struct sk_buff *skb;
9847869e82SConley Lee 	dma_addr_t rxbuf;
9947869e82SConley Lee 	int count;
10049220505SStefan Roese };
10149220505SStefan Roese 
emac_update_speed(struct net_device * dev)10249220505SStefan Roese static void emac_update_speed(struct net_device *dev)
10349220505SStefan Roese {
10449220505SStefan Roese 	struct emac_board_info *db = netdev_priv(dev);
10549220505SStefan Roese 	unsigned int reg_val;
10649220505SStefan Roese 
10749220505SStefan Roese 	/* set EMAC SPEED, depend on PHY  */
10849220505SStefan Roese 	reg_val = readl(db->membase + EMAC_MAC_SUPP_REG);
109274c2240SConley Lee 	reg_val &= ~EMAC_MAC_SUPP_100M;
11049220505SStefan Roese 	if (db->speed == SPEED_100)
111274c2240SConley Lee 		reg_val |= EMAC_MAC_SUPP_100M;
11249220505SStefan Roese 	writel(reg_val, db->membase + EMAC_MAC_SUPP_REG);
11349220505SStefan Roese }
11449220505SStefan Roese 
emac_update_duplex(struct net_device * dev)11549220505SStefan Roese static void emac_update_duplex(struct net_device *dev)
11649220505SStefan Roese {
11749220505SStefan Roese 	struct emac_board_info *db = netdev_priv(dev);
11849220505SStefan Roese 	unsigned int reg_val;
11949220505SStefan Roese 
12049220505SStefan Roese 	/* set duplex depend on phy */
12149220505SStefan Roese 	reg_val = readl(db->membase + EMAC_MAC_CTL1_REG);
12249220505SStefan Roese 	reg_val &= ~EMAC_MAC_CTL1_DUPLEX_EN;
12349220505SStefan Roese 	if (db->duplex)
12449220505SStefan Roese 		reg_val |= EMAC_MAC_CTL1_DUPLEX_EN;
12549220505SStefan Roese 	writel(reg_val, db->membase + EMAC_MAC_CTL1_REG);
12649220505SStefan Roese }
12749220505SStefan Roese 
emac_handle_link_change(struct net_device * dev)12849220505SStefan Roese static void emac_handle_link_change(struct net_device *dev)
12949220505SStefan Roese {
13049220505SStefan Roese 	struct emac_board_info *db = netdev_priv(dev);
1315427ccafSPhilippe Reynes 	struct phy_device *phydev = dev->phydev;
13249220505SStefan Roese 	unsigned long flags;
13349220505SStefan Roese 	int status_change = 0;
13449220505SStefan Roese 
13549220505SStefan Roese 	if (phydev->link) {
13649220505SStefan Roese 		if (db->speed != phydev->speed) {
13749220505SStefan Roese 			spin_lock_irqsave(&db->lock, flags);
13849220505SStefan Roese 			db->speed = phydev->speed;
13949220505SStefan Roese 			emac_update_speed(dev);
14049220505SStefan Roese 			spin_unlock_irqrestore(&db->lock, flags);
14149220505SStefan Roese 			status_change = 1;
14249220505SStefan Roese 		}
14349220505SStefan Roese 
14449220505SStefan Roese 		if (db->duplex != phydev->duplex) {
14549220505SStefan Roese 			spin_lock_irqsave(&db->lock, flags);
14649220505SStefan Roese 			db->duplex = phydev->duplex;
14749220505SStefan Roese 			emac_update_duplex(dev);
14849220505SStefan Roese 			spin_unlock_irqrestore(&db->lock, flags);
14949220505SStefan Roese 			status_change = 1;
15049220505SStefan Roese 		}
15149220505SStefan Roese 	}
15249220505SStefan Roese 
15349220505SStefan Roese 	if (phydev->link != db->link) {
15449220505SStefan Roese 		if (!phydev->link) {
15549220505SStefan Roese 			db->speed = 0;
15649220505SStefan Roese 			db->duplex = -1;
15749220505SStefan Roese 		}
15849220505SStefan Roese 		db->link = phydev->link;
15949220505SStefan Roese 
16049220505SStefan Roese 		status_change = 1;
16149220505SStefan Roese 	}
16249220505SStefan Roese 
16349220505SStefan Roese 	if (status_change)
16449220505SStefan Roese 		phy_print_status(phydev);
16549220505SStefan Roese }
16649220505SStefan Roese 
emac_mdio_probe(struct net_device * dev)16749220505SStefan Roese static int emac_mdio_probe(struct net_device *dev)
16849220505SStefan Roese {
16949220505SStefan Roese 	struct emac_board_info *db = netdev_priv(dev);
1705427ccafSPhilippe Reynes 	struct phy_device *phydev;
17149220505SStefan Roese 
17249220505SStefan Roese 	/* to-do: PHY interrupts are currently not supported */
17349220505SStefan Roese 
17449220505SStefan Roese 	/* attach the mac to the phy */
1755427ccafSPhilippe Reynes 	phydev = of_phy_connect(db->ndev, db->phy_node,
17649220505SStefan Roese 				&emac_handle_link_change, 0,
17749220505SStefan Roese 				db->phy_interface);
1785427ccafSPhilippe Reynes 	if (!phydev) {
17949220505SStefan Roese 		netdev_err(db->ndev, "could not find the PHY\n");
18049220505SStefan Roese 		return -ENODEV;
18149220505SStefan Roese 	}
18249220505SStefan Roese 
18349220505SStefan Roese 	/* mask with MAC supported features */
18458056c1eSAndrew Lunn 	phy_set_max_speed(phydev, SPEED_100);
18549220505SStefan Roese 
18649220505SStefan Roese 	db->link = 0;
18749220505SStefan Roese 	db->speed = 0;
18849220505SStefan Roese 	db->duplex = -1;
18949220505SStefan Roese 
19049220505SStefan Roese 	return 0;
19149220505SStefan Roese }
19249220505SStefan Roese 
emac_mdio_remove(struct net_device * dev)19349220505SStefan Roese static void emac_mdio_remove(struct net_device *dev)
19449220505SStefan Roese {
1955427ccafSPhilippe Reynes 	phy_disconnect(dev->phydev);
19649220505SStefan Roese }
19749220505SStefan Roese 
emac_reset(struct emac_board_info * db)19849220505SStefan Roese static void emac_reset(struct emac_board_info *db)
19949220505SStefan Roese {
20049220505SStefan Roese 	dev_dbg(db->dev, "resetting device\n");
20149220505SStefan Roese 
20249220505SStefan Roese 	/* RESET device */
20349220505SStefan Roese 	writel(0, db->membase + EMAC_CTL_REG);
20449220505SStefan Roese 	udelay(200);
20549220505SStefan Roese 	writel(EMAC_CTL_RESET, db->membase + EMAC_CTL_REG);
20649220505SStefan Roese 	udelay(200);
20749220505SStefan Roese }
20849220505SStefan Roese 
emac_outblk_32bit(void __iomem * reg,void * data,int count)20949220505SStefan Roese static void emac_outblk_32bit(void __iomem *reg, void *data, int count)
21049220505SStefan Roese {
21149220505SStefan Roese 	writesl(reg, data, round_up(count, 4) / 4);
21249220505SStefan Roese }
21349220505SStefan Roese 
emac_inblk_32bit(void __iomem * reg,void * data,int count)21449220505SStefan Roese static void emac_inblk_32bit(void __iomem *reg, void *data, int count)
21549220505SStefan Roese {
21649220505SStefan Roese 	readsl(reg, data, round_up(count, 4) / 4);
21749220505SStefan Roese }
21849220505SStefan Roese 
21947869e82SConley Lee static struct emac_dma_req *
emac_alloc_dma_req(struct emac_board_info * db,struct dma_async_tx_descriptor * desc,struct sk_buff * skb,dma_addr_t rxbuf,int count)22047869e82SConley Lee emac_alloc_dma_req(struct emac_board_info *db,
22147869e82SConley Lee 		   struct dma_async_tx_descriptor *desc, struct sk_buff *skb,
22247869e82SConley Lee 		   dma_addr_t rxbuf, int count)
22347869e82SConley Lee {
22447869e82SConley Lee 	struct emac_dma_req *req;
22547869e82SConley Lee 
22647869e82SConley Lee 	req = kzalloc(sizeof(struct emac_dma_req), GFP_ATOMIC);
22747869e82SConley Lee 	if (!req)
22847869e82SConley Lee 		return NULL;
22947869e82SConley Lee 
23047869e82SConley Lee 	req->db = db;
23147869e82SConley Lee 	req->desc = desc;
23247869e82SConley Lee 	req->skb = skb;
23347869e82SConley Lee 	req->rxbuf = rxbuf;
23447869e82SConley Lee 	req->count = count;
23547869e82SConley Lee 	return req;
23647869e82SConley Lee }
23747869e82SConley Lee 
emac_free_dma_req(struct emac_dma_req * req)23847869e82SConley Lee static void emac_free_dma_req(struct emac_dma_req *req)
23947869e82SConley Lee {
24047869e82SConley Lee 	kfree(req);
24147869e82SConley Lee }
24247869e82SConley Lee 
emac_dma_done_callback(void * arg)24347869e82SConley Lee static void emac_dma_done_callback(void *arg)
24447869e82SConley Lee {
24547869e82SConley Lee 	struct emac_dma_req *req = arg;
24647869e82SConley Lee 	struct emac_board_info *db = req->db;
24747869e82SConley Lee 	struct sk_buff *skb = req->skb;
24847869e82SConley Lee 	struct net_device *dev = db->ndev;
24947869e82SConley Lee 	int rxlen = req->count;
25047869e82SConley Lee 	u32 reg_val;
25147869e82SConley Lee 
25247869e82SConley Lee 	dma_unmap_single(db->dev, req->rxbuf, rxlen, DMA_FROM_DEVICE);
25347869e82SConley Lee 
25447869e82SConley Lee 	skb->protocol = eth_type_trans(skb, dev);
25547869e82SConley Lee 	netif_rx(skb);
25647869e82SConley Lee 	dev->stats.rx_bytes += rxlen;
25747869e82SConley Lee 	/* Pass to upper layer */
25847869e82SConley Lee 	dev->stats.rx_packets++;
25947869e82SConley Lee 
26047869e82SConley Lee 	/* re enable cpu receive */
26147869e82SConley Lee 	reg_val = readl(db->membase + EMAC_RX_CTL_REG);
26247869e82SConley Lee 	reg_val &= ~EMAC_RX_CTL_DMA_EN;
26347869e82SConley Lee 	writel(reg_val, db->membase + EMAC_RX_CTL_REG);
26447869e82SConley Lee 
26547869e82SConley Lee 	/* re enable interrupt */
26647869e82SConley Lee 	reg_val = readl(db->membase + EMAC_INT_CTL_REG);
267274c2240SConley Lee 	reg_val |= EMAC_INT_CTL_RX_EN;
26847869e82SConley Lee 	writel(reg_val, db->membase + EMAC_INT_CTL_REG);
26947869e82SConley Lee 
27047869e82SConley Lee 	db->emacrx_completed_flag = 1;
27147869e82SConley Lee 	emac_free_dma_req(req);
27247869e82SConley Lee }
27347869e82SConley Lee 
emac_dma_inblk_32bit(struct emac_board_info * db,struct sk_buff * skb,void * rdptr,int count)27447869e82SConley Lee static int emac_dma_inblk_32bit(struct emac_board_info *db,
27547869e82SConley Lee 		struct sk_buff *skb, void *rdptr, int count)
27647869e82SConley Lee {
27747869e82SConley Lee 	struct dma_async_tx_descriptor *desc;
27847869e82SConley Lee 	dma_cookie_t cookie;
27947869e82SConley Lee 	dma_addr_t rxbuf;
28047869e82SConley Lee 	struct emac_dma_req *req;
28147869e82SConley Lee 	int ret = 0;
28247869e82SConley Lee 
28347869e82SConley Lee 	rxbuf = dma_map_single(db->dev, rdptr, count, DMA_FROM_DEVICE);
28447869e82SConley Lee 	ret = dma_mapping_error(db->dev, rxbuf);
28547869e82SConley Lee 	if (ret) {
28647869e82SConley Lee 		dev_err(db->dev, "dma mapping error.\n");
28747869e82SConley Lee 		return ret;
28847869e82SConley Lee 	}
28947869e82SConley Lee 
29047869e82SConley Lee 	desc = dmaengine_prep_slave_single(db->rx_chan, rxbuf, count,
29147869e82SConley Lee 					   DMA_DEV_TO_MEM,
29247869e82SConley Lee 					   DMA_PREP_INTERRUPT | DMA_CTRL_ACK);
29347869e82SConley Lee 	if (!desc) {
29447869e82SConley Lee 		dev_err(db->dev, "prepare slave single failed\n");
29547869e82SConley Lee 		ret = -ENOMEM;
29647869e82SConley Lee 		goto prepare_err;
29747869e82SConley Lee 	}
29847869e82SConley Lee 
29947869e82SConley Lee 	req = emac_alloc_dma_req(db, desc, skb, rxbuf, count);
30047869e82SConley Lee 	if (!req) {
30147869e82SConley Lee 		dev_err(db->dev, "alloc emac dma req error.\n");
30247869e82SConley Lee 		ret = -ENOMEM;
30347869e82SConley Lee 		goto alloc_req_err;
30447869e82SConley Lee 	}
30547869e82SConley Lee 
30647869e82SConley Lee 	desc->callback_param = req;
30747869e82SConley Lee 	desc->callback = emac_dma_done_callback;
30847869e82SConley Lee 
30947869e82SConley Lee 	cookie = dmaengine_submit(desc);
31047869e82SConley Lee 	ret = dma_submit_error(cookie);
31147869e82SConley Lee 	if (ret) {
31247869e82SConley Lee 		dev_err(db->dev, "dma submit error.\n");
31347869e82SConley Lee 		goto submit_err;
31447869e82SConley Lee 	}
31547869e82SConley Lee 
31647869e82SConley Lee 	dma_async_issue_pending(db->rx_chan);
31747869e82SConley Lee 	return ret;
31847869e82SConley Lee 
31947869e82SConley Lee submit_err:
32047869e82SConley Lee 	emac_free_dma_req(req);
32147869e82SConley Lee 
32247869e82SConley Lee alloc_req_err:
32347869e82SConley Lee 	dmaengine_desc_free(desc);
32447869e82SConley Lee 
32547869e82SConley Lee prepare_err:
32647869e82SConley Lee 	dma_unmap_single(db->dev, rxbuf, count, DMA_FROM_DEVICE);
32747869e82SConley Lee 	return ret;
32847869e82SConley Lee }
32947869e82SConley Lee 
33049220505SStefan Roese /* ethtool ops */
emac_get_drvinfo(struct net_device * dev,struct ethtool_drvinfo * info)33149220505SStefan Roese static void emac_get_drvinfo(struct net_device *dev,
33249220505SStefan Roese 			      struct ethtool_drvinfo *info)
33349220505SStefan Roese {
334*f029c781SWolfram Sang 	strscpy(info->driver, DRV_NAME, sizeof(info->driver));
335*f029c781SWolfram Sang 	strscpy(info->bus_info, dev_name(&dev->dev), sizeof(info->bus_info));
33649220505SStefan Roese }
33749220505SStefan Roese 
emac_get_msglevel(struct net_device * dev)338b8ca3387SMichael Weiser static u32 emac_get_msglevel(struct net_device *dev)
339b8ca3387SMichael Weiser {
340b8ca3387SMichael Weiser 	struct emac_board_info *db = netdev_priv(dev);
341b8ca3387SMichael Weiser 
342b8ca3387SMichael Weiser 	return db->msg_enable;
343b8ca3387SMichael Weiser }
344b8ca3387SMichael Weiser 
emac_set_msglevel(struct net_device * dev,u32 value)345b8ca3387SMichael Weiser static void emac_set_msglevel(struct net_device *dev, u32 value)
346b8ca3387SMichael Weiser {
347b8ca3387SMichael Weiser 	struct emac_board_info *db = netdev_priv(dev);
348b8ca3387SMichael Weiser 
349b8ca3387SMichael Weiser 	db->msg_enable = value;
350b8ca3387SMichael Weiser }
351b8ca3387SMichael Weiser 
35249220505SStefan Roese static const struct ethtool_ops emac_ethtool_ops = {
35349220505SStefan Roese 	.get_drvinfo	= emac_get_drvinfo,
35449220505SStefan Roese 	.get_link	= ethtool_op_get_link,
35591cd3b44SPhilippe Reynes 	.get_link_ksettings = phy_ethtool_get_link_ksettings,
35691cd3b44SPhilippe Reynes 	.set_link_ksettings = phy_ethtool_set_link_ksettings,
357b8ca3387SMichael Weiser 	.get_msglevel	= emac_get_msglevel,
358b8ca3387SMichael Weiser 	.set_msglevel	= emac_set_msglevel,
35949220505SStefan Roese };
36049220505SStefan Roese 
emac_setup(struct net_device * ndev)36111a164a0SSachin Kamat static unsigned int emac_setup(struct net_device *ndev)
36249220505SStefan Roese {
36349220505SStefan Roese 	struct emac_board_info *db = netdev_priv(ndev);
36449220505SStefan Roese 	unsigned int reg_val;
36549220505SStefan Roese 
36649220505SStefan Roese 	/* set up TX */
36749220505SStefan Roese 	reg_val = readl(db->membase + EMAC_TX_MODE_REG);
36849220505SStefan Roese 
36949220505SStefan Roese 	writel(reg_val | EMAC_TX_MODE_ABORTED_FRAME_EN,
37049220505SStefan Roese 		db->membase + EMAC_TX_MODE_REG);
37149220505SStefan Roese 
37249220505SStefan Roese 	/* set MAC */
37349220505SStefan Roese 	/* set MAC CTL0 */
37449220505SStefan Roese 	reg_val = readl(db->membase + EMAC_MAC_CTL0_REG);
37549220505SStefan Roese 	writel(reg_val | EMAC_MAC_CTL0_RX_FLOW_CTL_EN |
37649220505SStefan Roese 		EMAC_MAC_CTL0_TX_FLOW_CTL_EN,
37749220505SStefan Roese 		db->membase + EMAC_MAC_CTL0_REG);
37849220505SStefan Roese 
37949220505SStefan Roese 	/* set MAC CTL1 */
38049220505SStefan Roese 	reg_val = readl(db->membase + EMAC_MAC_CTL1_REG);
38149220505SStefan Roese 	reg_val |= EMAC_MAC_CTL1_LEN_CHECK_EN;
38249220505SStefan Roese 	reg_val |= EMAC_MAC_CTL1_CRC_EN;
38349220505SStefan Roese 	reg_val |= EMAC_MAC_CTL1_PAD_EN;
38449220505SStefan Roese 	writel(reg_val, db->membase + EMAC_MAC_CTL1_REG);
38549220505SStefan Roese 
38649220505SStefan Roese 	/* set up IPGT */
38749220505SStefan Roese 	writel(EMAC_MAC_IPGT_FULL_DUPLEX, db->membase + EMAC_MAC_IPGT_REG);
38849220505SStefan Roese 
38949220505SStefan Roese 	/* set up IPGR */
39049220505SStefan Roese 	writel((EMAC_MAC_IPGR_IPG1 << 8) | EMAC_MAC_IPGR_IPG2,
39149220505SStefan Roese 		db->membase + EMAC_MAC_IPGR_REG);
39249220505SStefan Roese 
39349220505SStefan Roese 	/* set up Collison window */
39449220505SStefan Roese 	writel((EMAC_MAC_CLRT_COLLISION_WINDOW << 8) | EMAC_MAC_CLRT_RM,
39549220505SStefan Roese 		db->membase + EMAC_MAC_CLRT_REG);
39649220505SStefan Roese 
39749220505SStefan Roese 	/* set up Max Frame Length */
39849220505SStefan Roese 	writel(EMAC_MAX_FRAME_LEN,
39949220505SStefan Roese 		db->membase + EMAC_MAC_MAXF_REG);
40049220505SStefan Roese 
40149220505SStefan Roese 	return 0;
40249220505SStefan Roese }
40349220505SStefan Roese 
emac_set_rx_mode(struct net_device * ndev)404cec9ae50SMarc Zyngier static void emac_set_rx_mode(struct net_device *ndev)
405cec9ae50SMarc Zyngier {
406cec9ae50SMarc Zyngier 	struct emac_board_info *db = netdev_priv(ndev);
407cec9ae50SMarc Zyngier 	unsigned int reg_val;
408cec9ae50SMarc Zyngier 
409cec9ae50SMarc Zyngier 	/* set up RX */
410cec9ae50SMarc Zyngier 	reg_val = readl(db->membase + EMAC_RX_CTL_REG);
411cec9ae50SMarc Zyngier 
412cec9ae50SMarc Zyngier 	if (ndev->flags & IFF_PROMISC)
413cec9ae50SMarc Zyngier 		reg_val |= EMAC_RX_CTL_PASS_ALL_EN;
414cec9ae50SMarc Zyngier 	else
415cec9ae50SMarc Zyngier 		reg_val &= ~EMAC_RX_CTL_PASS_ALL_EN;
416cec9ae50SMarc Zyngier 
417cec9ae50SMarc Zyngier 	writel(reg_val | EMAC_RX_CTL_PASS_LEN_OOR_EN |
418cec9ae50SMarc Zyngier 		EMAC_RX_CTL_ACCEPT_UNICAST_EN | EMAC_RX_CTL_DA_FILTER_EN |
419cec9ae50SMarc Zyngier 		EMAC_RX_CTL_ACCEPT_MULTICAST_EN |
420cec9ae50SMarc Zyngier 		EMAC_RX_CTL_ACCEPT_BROADCAST_EN,
421cec9ae50SMarc Zyngier 		db->membase + EMAC_RX_CTL_REG);
422cec9ae50SMarc Zyngier }
423cec9ae50SMarc Zyngier 
emac_powerup(struct net_device * ndev)42411a164a0SSachin Kamat static unsigned int emac_powerup(struct net_device *ndev)
42549220505SStefan Roese {
42649220505SStefan Roese 	struct emac_board_info *db = netdev_priv(ndev);
42749220505SStefan Roese 	unsigned int reg_val;
42849220505SStefan Roese 
42949220505SStefan Roese 	/* initial EMAC */
43049220505SStefan Roese 	/* flush RX FIFO */
43149220505SStefan Roese 	reg_val = readl(db->membase + EMAC_RX_CTL_REG);
432274c2240SConley Lee 	reg_val |= EMAC_RX_CTL_FLUSH_FIFO;
43349220505SStefan Roese 	writel(reg_val, db->membase + EMAC_RX_CTL_REG);
43449220505SStefan Roese 	udelay(1);
43549220505SStefan Roese 
43649220505SStefan Roese 	/* initial MAC */
43749220505SStefan Roese 	/* soft reset MAC */
43849220505SStefan Roese 	reg_val = readl(db->membase + EMAC_MAC_CTL0_REG);
43949220505SStefan Roese 	reg_val &= ~EMAC_MAC_CTL0_SOFT_RESET;
44049220505SStefan Roese 	writel(reg_val, db->membase + EMAC_MAC_CTL0_REG);
44149220505SStefan Roese 
44249220505SStefan Roese 	/* set MII clock */
44349220505SStefan Roese 	reg_val = readl(db->membase + EMAC_MAC_MCFG_REG);
444274c2240SConley Lee 	reg_val &= ~EMAC_MAC_MCFG_MII_CLKD_MASK;
445274c2240SConley Lee 	reg_val |= EMAC_MAC_MCFG_MII_CLKD_72;
44649220505SStefan Roese 	writel(reg_val, db->membase + EMAC_MAC_MCFG_REG);
44749220505SStefan Roese 
44849220505SStefan Roese 	/* clear RX counter */
44949220505SStefan Roese 	writel(0x0, db->membase + EMAC_RX_FBC_REG);
45049220505SStefan Roese 
45149220505SStefan Roese 	/* disable all interrupt and clear interrupt status */
45249220505SStefan Roese 	writel(0, db->membase + EMAC_INT_CTL_REG);
45349220505SStefan Roese 	reg_val = readl(db->membase + EMAC_INT_STA_REG);
45449220505SStefan Roese 	writel(reg_val, db->membase + EMAC_INT_STA_REG);
45549220505SStefan Roese 
45649220505SStefan Roese 	udelay(1);
45749220505SStefan Roese 
45849220505SStefan Roese 	/* set up EMAC */
45949220505SStefan Roese 	emac_setup(ndev);
46049220505SStefan Roese 
46149220505SStefan Roese 	/* set mac_address to chip */
46249220505SStefan Roese 	writel(ndev->dev_addr[0] << 16 | ndev->dev_addr[1] << 8 | ndev->
46349220505SStefan Roese 	       dev_addr[2], db->membase + EMAC_MAC_A1_REG);
46449220505SStefan Roese 	writel(ndev->dev_addr[3] << 16 | ndev->dev_addr[4] << 8 | ndev->
46549220505SStefan Roese 	       dev_addr[5], db->membase + EMAC_MAC_A0_REG);
46649220505SStefan Roese 
46749220505SStefan Roese 	mdelay(1);
46849220505SStefan Roese 
46949220505SStefan Roese 	return 0;
47049220505SStefan Roese }
47149220505SStefan Roese 
emac_set_mac_address(struct net_device * dev,void * p)47249220505SStefan Roese static int emac_set_mac_address(struct net_device *dev, void *p)
47349220505SStefan Roese {
47449220505SStefan Roese 	struct sockaddr *addr = p;
47549220505SStefan Roese 	struct emac_board_info *db = netdev_priv(dev);
47649220505SStefan Roese 
47749220505SStefan Roese 	if (netif_running(dev))
47849220505SStefan Roese 		return -EBUSY;
47949220505SStefan Roese 
480a96d317fSJakub Kicinski 	eth_hw_addr_set(dev, addr->sa_data);
48149220505SStefan Roese 
48249220505SStefan Roese 	writel(dev->dev_addr[0] << 16 | dev->dev_addr[1] << 8 | dev->
48349220505SStefan Roese 	       dev_addr[2], db->membase + EMAC_MAC_A1_REG);
48449220505SStefan Roese 	writel(dev->dev_addr[3] << 16 | dev->dev_addr[4] << 8 | dev->
48549220505SStefan Roese 	       dev_addr[5], db->membase + EMAC_MAC_A0_REG);
48649220505SStefan Roese 
48749220505SStefan Roese 	return 0;
48849220505SStefan Roese }
48949220505SStefan Roese 
49049220505SStefan Roese /* Initialize emac board */
emac_init_device(struct net_device * dev)49149220505SStefan Roese static void emac_init_device(struct net_device *dev)
49249220505SStefan Roese {
49349220505SStefan Roese 	struct emac_board_info *db = netdev_priv(dev);
49449220505SStefan Roese 	unsigned long flags;
49549220505SStefan Roese 	unsigned int reg_val;
49649220505SStefan Roese 
49749220505SStefan Roese 	spin_lock_irqsave(&db->lock, flags);
49849220505SStefan Roese 
49949220505SStefan Roese 	emac_update_speed(dev);
50049220505SStefan Roese 	emac_update_duplex(dev);
50149220505SStefan Roese 
50249220505SStefan Roese 	/* enable RX/TX */
50349220505SStefan Roese 	reg_val = readl(db->membase + EMAC_CTL_REG);
50449220505SStefan Roese 	writel(reg_val | EMAC_CTL_RESET | EMAC_CTL_TX_EN | EMAC_CTL_RX_EN,
50549220505SStefan Roese 		db->membase + EMAC_CTL_REG);
50649220505SStefan Roese 
50749220505SStefan Roese 	/* enable RX/TX0/RX Hlevel interrup */
50849220505SStefan Roese 	reg_val = readl(db->membase + EMAC_INT_CTL_REG);
509274c2240SConley Lee 	reg_val |= (EMAC_INT_CTL_TX_EN | EMAC_INT_CTL_TX_ABRT_EN | EMAC_INT_CTL_RX_EN);
51049220505SStefan Roese 	writel(reg_val, db->membase + EMAC_INT_CTL_REG);
51149220505SStefan Roese 
51249220505SStefan Roese 	spin_unlock_irqrestore(&db->lock, flags);
51349220505SStefan Roese }
51449220505SStefan Roese 
51549220505SStefan Roese /* Our watchdog timed out. Called by the networking layer */
emac_timeout(struct net_device * dev,unsigned int txqueue)5160290bd29SMichael S. Tsirkin static void emac_timeout(struct net_device *dev, unsigned int txqueue)
51749220505SStefan Roese {
51849220505SStefan Roese 	struct emac_board_info *db = netdev_priv(dev);
51949220505SStefan Roese 	unsigned long flags;
52049220505SStefan Roese 
52149220505SStefan Roese 	if (netif_msg_timer(db))
52249220505SStefan Roese 		dev_err(db->dev, "tx time out.\n");
52349220505SStefan Roese 
52449220505SStefan Roese 	/* Save previous register address */
52549220505SStefan Roese 	spin_lock_irqsave(&db->lock, flags);
52649220505SStefan Roese 
52749220505SStefan Roese 	netif_stop_queue(dev);
52849220505SStefan Roese 	emac_reset(db);
52949220505SStefan Roese 	emac_init_device(dev);
53049220505SStefan Roese 	/* We can accept TX packets again */
531860e9538SFlorian Westphal 	netif_trans_update(dev);
53249220505SStefan Roese 	netif_wake_queue(dev);
53349220505SStefan Roese 
53449220505SStefan Roese 	/* Restore previous register address */
53549220505SStefan Roese 	spin_unlock_irqrestore(&db->lock, flags);
53649220505SStefan Roese }
53749220505SStefan Roese 
53849220505SStefan Roese /* Hardware start transmission.
53949220505SStefan Roese  * Send a packet to media from the upper layer.
54049220505SStefan Roese  */
emac_start_xmit(struct sk_buff * skb,struct net_device * dev)54109f6c44aSYunjian Wang static netdev_tx_t emac_start_xmit(struct sk_buff *skb, struct net_device *dev)
54249220505SStefan Roese {
54349220505SStefan Roese 	struct emac_board_info *db = netdev_priv(dev);
54449220505SStefan Roese 	unsigned long channel;
54549220505SStefan Roese 	unsigned long flags;
54649220505SStefan Roese 
54749220505SStefan Roese 	channel = db->tx_fifo_stat & 3;
54849220505SStefan Roese 	if (channel == 3)
54909f6c44aSYunjian Wang 		return NETDEV_TX_BUSY;
55049220505SStefan Roese 
55149220505SStefan Roese 	channel = (channel == 1 ? 1 : 0);
55249220505SStefan Roese 
55349220505SStefan Roese 	spin_lock_irqsave(&db->lock, flags);
55449220505SStefan Roese 
55549220505SStefan Roese 	writel(channel, db->membase + EMAC_TX_INS_REG);
55649220505SStefan Roese 
55749220505SStefan Roese 	emac_outblk_32bit(db->membase + EMAC_TX_IO_DATA_REG,
55849220505SStefan Roese 			skb->data, skb->len);
55949220505SStefan Roese 	dev->stats.tx_bytes += skb->len;
56049220505SStefan Roese 
56149220505SStefan Roese 	db->tx_fifo_stat |= 1 << channel;
56249220505SStefan Roese 	/* TX control: First packet immediately send, second packet queue */
56349220505SStefan Roese 	if (channel == 0) {
56449220505SStefan Roese 		/* set TX len */
56549220505SStefan Roese 		writel(skb->len, db->membase + EMAC_TX_PL0_REG);
56649220505SStefan Roese 		/* start translate from fifo to phy */
56749220505SStefan Roese 		writel(readl(db->membase + EMAC_TX_CTL0_REG) | 1,
56849220505SStefan Roese 		       db->membase + EMAC_TX_CTL0_REG);
56949220505SStefan Roese 
57049220505SStefan Roese 		/* save the time stamp */
571860e9538SFlorian Westphal 		netif_trans_update(dev);
57249220505SStefan Roese 	} else if (channel == 1) {
57349220505SStefan Roese 		/* set TX len */
57449220505SStefan Roese 		writel(skb->len, db->membase + EMAC_TX_PL1_REG);
57549220505SStefan Roese 		/* start translate from fifo to phy */
57649220505SStefan Roese 		writel(readl(db->membase + EMAC_TX_CTL1_REG) | 1,
57749220505SStefan Roese 		       db->membase + EMAC_TX_CTL1_REG);
57849220505SStefan Roese 
57949220505SStefan Roese 		/* save the time stamp */
580860e9538SFlorian Westphal 		netif_trans_update(dev);
58149220505SStefan Roese 	}
58249220505SStefan Roese 
58349220505SStefan Roese 	if ((db->tx_fifo_stat & 3) == 3) {
58449220505SStefan Roese 		/* Second packet */
58549220505SStefan Roese 		netif_stop_queue(dev);
58649220505SStefan Roese 	}
58749220505SStefan Roese 
58849220505SStefan Roese 	spin_unlock_irqrestore(&db->lock, flags);
58949220505SStefan Roese 
59049220505SStefan Roese 	/* free this SKB */
591c99abc8bSEric W. Biederman 	dev_consume_skb_any(skb);
59249220505SStefan Roese 
59349220505SStefan Roese 	return NETDEV_TX_OK;
59449220505SStefan Roese }
59549220505SStefan Roese 
59649220505SStefan Roese /* EMAC interrupt handler
59749220505SStefan Roese  * receive the packet to upper layer, free the transmitted packet
59849220505SStefan Roese  */
emac_tx_done(struct net_device * dev,struct emac_board_info * db,unsigned int tx_status)59949220505SStefan Roese static void emac_tx_done(struct net_device *dev, struct emac_board_info *db,
60049220505SStefan Roese 			  unsigned int tx_status)
60149220505SStefan Roese {
60249220505SStefan Roese 	/* One packet sent complete */
60349220505SStefan Roese 	db->tx_fifo_stat &= ~(tx_status & 3);
60449220505SStefan Roese 	if (3 == (tx_status & 3))
60549220505SStefan Roese 		dev->stats.tx_packets += 2;
60649220505SStefan Roese 	else
60749220505SStefan Roese 		dev->stats.tx_packets++;
60849220505SStefan Roese 
60949220505SStefan Roese 	if (netif_msg_tx_done(db))
61049220505SStefan Roese 		dev_dbg(db->dev, "tx done, NSR %02x\n", tx_status);
61149220505SStefan Roese 
61249220505SStefan Roese 	netif_wake_queue(dev);
61349220505SStefan Roese }
61449220505SStefan Roese 
61549220505SStefan Roese /* Received a packet and pass to upper layer
61649220505SStefan Roese  */
emac_rx(struct net_device * dev)61749220505SStefan Roese static void emac_rx(struct net_device *dev)
61849220505SStefan Roese {
61949220505SStefan Roese 	struct emac_board_info *db = netdev_priv(dev);
62049220505SStefan Roese 	struct sk_buff *skb;
62149220505SStefan Roese 	u8 *rdptr;
62249220505SStefan Roese 	bool good_packet;
62349220505SStefan Roese 	unsigned int reg_val;
62449220505SStefan Roese 	u32 rxhdr, rxstatus, rxcount, rxlen;
62549220505SStefan Roese 
62649220505SStefan Roese 	/* Check packet ready or not */
62749220505SStefan Roese 	while (1) {
62849220505SStefan Roese 		/* race warning: the first packet might arrive with
62949220505SStefan Roese 		 * the interrupts disabled, but the second will fix
63049220505SStefan Roese 		 * it
63149220505SStefan Roese 		 */
63249220505SStefan Roese 		rxcount = readl(db->membase + EMAC_RX_FBC_REG);
63349220505SStefan Roese 
63449220505SStefan Roese 		if (netif_msg_rx_status(db))
63549220505SStefan Roese 			dev_dbg(db->dev, "RXCount: %x\n", rxcount);
63649220505SStefan Roese 
63749220505SStefan Roese 		if (!rxcount) {
63849220505SStefan Roese 			db->emacrx_completed_flag = 1;
63949220505SStefan Roese 			reg_val = readl(db->membase + EMAC_INT_CTL_REG);
640274c2240SConley Lee 			reg_val |= (EMAC_INT_CTL_TX_EN |
641274c2240SConley Lee 					EMAC_INT_CTL_TX_ABRT_EN |
642274c2240SConley Lee 					EMAC_INT_CTL_RX_EN);
64349220505SStefan Roese 			writel(reg_val, db->membase + EMAC_INT_CTL_REG);
64449220505SStefan Roese 
64549220505SStefan Roese 			/* had one stuck? */
64649220505SStefan Roese 			rxcount = readl(db->membase + EMAC_RX_FBC_REG);
64749220505SStefan Roese 			if (!rxcount)
64849220505SStefan Roese 				return;
64949220505SStefan Roese 		}
65049220505SStefan Roese 
65149220505SStefan Roese 		reg_val = readl(db->membase + EMAC_RX_IO_DATA_REG);
65249220505SStefan Roese 		if (netif_msg_rx_status(db))
65349220505SStefan Roese 			dev_dbg(db->dev, "receive header: %x\n", reg_val);
65449220505SStefan Roese 		if (reg_val != EMAC_UNDOCUMENTED_MAGIC) {
65549220505SStefan Roese 			/* disable RX */
65649220505SStefan Roese 			reg_val = readl(db->membase + EMAC_CTL_REG);
65749220505SStefan Roese 			writel(reg_val & ~EMAC_CTL_RX_EN,
65849220505SStefan Roese 			       db->membase + EMAC_CTL_REG);
65949220505SStefan Roese 
66049220505SStefan Roese 			/* Flush RX FIFO */
66149220505SStefan Roese 			reg_val = readl(db->membase + EMAC_RX_CTL_REG);
66249220505SStefan Roese 			writel(reg_val | (1 << 3),
66349220505SStefan Roese 			       db->membase + EMAC_RX_CTL_REG);
66449220505SStefan Roese 
66549220505SStefan Roese 			do {
66649220505SStefan Roese 				reg_val = readl(db->membase + EMAC_RX_CTL_REG);
66749220505SStefan Roese 			} while (reg_val & (1 << 3));
66849220505SStefan Roese 
66949220505SStefan Roese 			/* enable RX */
67049220505SStefan Roese 			reg_val = readl(db->membase + EMAC_CTL_REG);
67149220505SStefan Roese 			writel(reg_val | EMAC_CTL_RX_EN,
67249220505SStefan Roese 			       db->membase + EMAC_CTL_REG);
67349220505SStefan Roese 			reg_val = readl(db->membase + EMAC_INT_CTL_REG);
674274c2240SConley Lee 			reg_val |= (EMAC_INT_CTL_TX_EN |
675274c2240SConley Lee 					EMAC_INT_CTL_TX_ABRT_EN |
676274c2240SConley Lee 					EMAC_INT_CTL_RX_EN);
67749220505SStefan Roese 			writel(reg_val, db->membase + EMAC_INT_CTL_REG);
67849220505SStefan Roese 
67949220505SStefan Roese 			db->emacrx_completed_flag = 1;
68049220505SStefan Roese 
68149220505SStefan Roese 			return;
68249220505SStefan Roese 		}
68349220505SStefan Roese 
68449220505SStefan Roese 		/* A packet ready now  & Get status/length */
68549220505SStefan Roese 		good_packet = true;
68649220505SStefan Roese 
687934d0048SMichael Weiser 		rxhdr = readl(db->membase + EMAC_RX_IO_DATA_REG);
68849220505SStefan Roese 
68949220505SStefan Roese 		if (netif_msg_rx_status(db))
69049220505SStefan Roese 			dev_dbg(db->dev, "rxhdr: %x\n", *((int *)(&rxhdr)));
69149220505SStefan Roese 
69249220505SStefan Roese 		rxlen = EMAC_RX_IO_DATA_LEN(rxhdr);
69349220505SStefan Roese 		rxstatus = EMAC_RX_IO_DATA_STATUS(rxhdr);
69449220505SStefan Roese 
69549220505SStefan Roese 		if (netif_msg_rx_status(db))
69649220505SStefan Roese 			dev_dbg(db->dev, "RX: status %02x, length %04x\n",
69749220505SStefan Roese 				rxstatus, rxlen);
69849220505SStefan Roese 
69949220505SStefan Roese 		/* Packet Status check */
70049220505SStefan Roese 		if (rxlen < 0x40) {
70149220505SStefan Roese 			good_packet = false;
70249220505SStefan Roese 			if (netif_msg_rx_err(db))
70349220505SStefan Roese 				dev_dbg(db->dev, "RX: Bad Packet (runt)\n");
70449220505SStefan Roese 		}
70549220505SStefan Roese 
70649220505SStefan Roese 		if (unlikely(!(rxstatus & EMAC_RX_IO_DATA_STATUS_OK))) {
70749220505SStefan Roese 			good_packet = false;
70849220505SStefan Roese 
70949220505SStefan Roese 			if (rxstatus & EMAC_RX_IO_DATA_STATUS_CRC_ERR) {
71049220505SStefan Roese 				if (netif_msg_rx_err(db))
71149220505SStefan Roese 					dev_dbg(db->dev, "crc error\n");
71249220505SStefan Roese 				dev->stats.rx_crc_errors++;
71349220505SStefan Roese 			}
71449220505SStefan Roese 
71549220505SStefan Roese 			if (rxstatus & EMAC_RX_IO_DATA_STATUS_LEN_ERR) {
71649220505SStefan Roese 				if (netif_msg_rx_err(db))
71749220505SStefan Roese 					dev_dbg(db->dev, "length error\n");
71849220505SStefan Roese 				dev->stats.rx_length_errors++;
71949220505SStefan Roese 			}
72049220505SStefan Roese 		}
72149220505SStefan Roese 
72249220505SStefan Roese 		/* Move data from EMAC */
7232670cc69SMarc Zyngier 		if (good_packet) {
7242670cc69SMarc Zyngier 			skb = netdev_alloc_skb(dev, rxlen + 4);
7252670cc69SMarc Zyngier 			if (!skb)
7262670cc69SMarc Zyngier 				continue;
72749220505SStefan Roese 			skb_reserve(skb, 2);
7284df864c1SJohannes Berg 			rdptr = skb_put(skb, rxlen - 4);
72949220505SStefan Roese 
73049220505SStefan Roese 			/* Read received packet from RX SRAM */
73149220505SStefan Roese 			if (netif_msg_rx_status(db))
73249220505SStefan Roese 				dev_dbg(db->dev, "RxLen %x\n", rxlen);
73349220505SStefan Roese 
73447869e82SConley Lee 			if (rxlen >= dev->mtu && db->rx_chan) {
73547869e82SConley Lee 				reg_val = readl(db->membase + EMAC_RX_CTL_REG);
73647869e82SConley Lee 				reg_val |= EMAC_RX_CTL_DMA_EN;
73747869e82SConley Lee 				writel(reg_val, db->membase + EMAC_RX_CTL_REG);
73847869e82SConley Lee 				if (!emac_dma_inblk_32bit(db, skb, rdptr, rxlen))
73947869e82SConley Lee 					break;
74047869e82SConley Lee 
74147869e82SConley Lee 				/* re enable cpu receive. then try to receive by emac_inblk_32bit */
74247869e82SConley Lee 				reg_val = readl(db->membase + EMAC_RX_CTL_REG);
74347869e82SConley Lee 				reg_val &= ~EMAC_RX_CTL_DMA_EN;
74447869e82SConley Lee 				writel(reg_val, db->membase + EMAC_RX_CTL_REG);
74547869e82SConley Lee 			}
74647869e82SConley Lee 
74749220505SStefan Roese 			emac_inblk_32bit(db->membase + EMAC_RX_IO_DATA_REG,
74849220505SStefan Roese 					rdptr, rxlen);
74949220505SStefan Roese 			dev->stats.rx_bytes += rxlen;
75049220505SStefan Roese 
75149220505SStefan Roese 			/* Pass to upper layer */
75249220505SStefan Roese 			skb->protocol = eth_type_trans(skb, dev);
75349220505SStefan Roese 			netif_rx(skb);
75449220505SStefan Roese 			dev->stats.rx_packets++;
75549220505SStefan Roese 		}
75649220505SStefan Roese 	}
75749220505SStefan Roese }
75849220505SStefan Roese 
emac_interrupt(int irq,void * dev_id)75949220505SStefan Roese static irqreturn_t emac_interrupt(int irq, void *dev_id)
76049220505SStefan Roese {
76149220505SStefan Roese 	struct net_device *dev = dev_id;
76249220505SStefan Roese 	struct emac_board_info *db = netdev_priv(dev);
76349220505SStefan Roese 	int int_status;
76449220505SStefan Roese 	unsigned int reg_val;
76549220505SStefan Roese 
76649220505SStefan Roese 	/* A real interrupt coming */
76749220505SStefan Roese 
76836493269SBarry Song 	spin_lock(&db->lock);
76949220505SStefan Roese 
77049220505SStefan Roese 	/* Disable all interrupts */
77149220505SStefan Roese 	writel(0, db->membase + EMAC_INT_CTL_REG);
77249220505SStefan Roese 
77349220505SStefan Roese 	/* Got EMAC interrupt status */
77449220505SStefan Roese 	/* Got ISR */
77549220505SStefan Roese 	int_status = readl(db->membase + EMAC_INT_STA_REG);
77649220505SStefan Roese 	/* Clear ISR status */
77749220505SStefan Roese 	writel(int_status, db->membase + EMAC_INT_STA_REG);
77849220505SStefan Roese 
77949220505SStefan Roese 	if (netif_msg_intr(db))
78049220505SStefan Roese 		dev_dbg(db->dev, "emac interrupt %02x\n", int_status);
78149220505SStefan Roese 
78249220505SStefan Roese 	/* Received the coming packet */
78349220505SStefan Roese 	if ((int_status & 0x100) && (db->emacrx_completed_flag == 1)) {
78449220505SStefan Roese 		/* carrier lost */
78549220505SStefan Roese 		db->emacrx_completed_flag = 0;
78649220505SStefan Roese 		emac_rx(dev);
78749220505SStefan Roese 	}
78849220505SStefan Roese 
78949220505SStefan Roese 	/* Transmit Interrupt check */
790274c2240SConley Lee 	if (int_status & EMAC_INT_STA_TX_COMPLETE)
79149220505SStefan Roese 		emac_tx_done(dev, db, int_status);
79249220505SStefan Roese 
793274c2240SConley Lee 	if (int_status & EMAC_INT_STA_TX_ABRT)
79449220505SStefan Roese 		netdev_info(dev, " ab : %x\n", int_status);
79549220505SStefan Roese 
79649220505SStefan Roese 	/* Re-enable interrupt mask */
79749220505SStefan Roese 	if (db->emacrx_completed_flag == 1) {
79849220505SStefan Roese 		reg_val = readl(db->membase + EMAC_INT_CTL_REG);
799274c2240SConley Lee 		reg_val |= (EMAC_INT_CTL_TX_EN | EMAC_INT_CTL_TX_ABRT_EN | EMAC_INT_CTL_RX_EN);
80049220505SStefan Roese 		writel(reg_val, db->membase + EMAC_INT_CTL_REG);
80147869e82SConley Lee 	} else {
80247869e82SConley Lee 		reg_val = readl(db->membase + EMAC_INT_CTL_REG);
803274c2240SConley Lee 		reg_val |= (EMAC_INT_CTL_TX_EN | EMAC_INT_CTL_TX_ABRT_EN);
80447869e82SConley Lee 		writel(reg_val, db->membase + EMAC_INT_CTL_REG);
80549220505SStefan Roese 	}
80647869e82SConley Lee 
80736493269SBarry Song 	spin_unlock(&db->lock);
80849220505SStefan Roese 
80949220505SStefan Roese 	return IRQ_HANDLED;
81049220505SStefan Roese }
81149220505SStefan Roese 
81249220505SStefan Roese #ifdef CONFIG_NET_POLL_CONTROLLER
81349220505SStefan Roese /*
81449220505SStefan Roese  * Used by netconsole
81549220505SStefan Roese  */
emac_poll_controller(struct net_device * dev)81649220505SStefan Roese static void emac_poll_controller(struct net_device *dev)
81749220505SStefan Roese {
81849220505SStefan Roese 	disable_irq(dev->irq);
81949220505SStefan Roese 	emac_interrupt(dev->irq, dev);
82049220505SStefan Roese 	enable_irq(dev->irq);
82149220505SStefan Roese }
82249220505SStefan Roese #endif
82349220505SStefan Roese 
82449220505SStefan Roese /*  Open the interface.
82549220505SStefan Roese  *  The interface is opened whenever "ifconfig" actives it.
82649220505SStefan Roese  */
emac_open(struct net_device * dev)82749220505SStefan Roese static int emac_open(struct net_device *dev)
82849220505SStefan Roese {
82949220505SStefan Roese 	struct emac_board_info *db = netdev_priv(dev);
83049220505SStefan Roese 	int ret;
83149220505SStefan Roese 
83249220505SStefan Roese 	if (netif_msg_ifup(db))
83349220505SStefan Roese 		dev_dbg(db->dev, "enabling %s\n", dev->name);
83449220505SStefan Roese 
835e9c56f8dSMaxime Ripard 	if (request_irq(dev->irq, &emac_interrupt, 0, dev->name, dev))
83649220505SStefan Roese 		return -EAGAIN;
83749220505SStefan Roese 
83849220505SStefan Roese 	/* Initialize EMAC board */
83949220505SStefan Roese 	emac_reset(db);
84049220505SStefan Roese 	emac_init_device(dev);
84149220505SStefan Roese 
84249220505SStefan Roese 	ret = emac_mdio_probe(dev);
84349220505SStefan Roese 	if (ret < 0) {
844b9111328SMaxime Ripard 		free_irq(dev->irq, dev);
84549220505SStefan Roese 		netdev_err(dev, "cannot probe MDIO bus\n");
84649220505SStefan Roese 		return ret;
84749220505SStefan Roese 	}
84849220505SStefan Roese 
8495427ccafSPhilippe Reynes 	phy_start(dev->phydev);
85049220505SStefan Roese 	netif_start_queue(dev);
85149220505SStefan Roese 
85249220505SStefan Roese 	return 0;
85349220505SStefan Roese }
85449220505SStefan Roese 
emac_shutdown(struct net_device * dev)85549220505SStefan Roese static void emac_shutdown(struct net_device *dev)
85649220505SStefan Roese {
85749220505SStefan Roese 	unsigned int reg_val;
85849220505SStefan Roese 	struct emac_board_info *db = netdev_priv(dev);
85949220505SStefan Roese 
86049220505SStefan Roese 	/* Disable all interrupt */
86149220505SStefan Roese 	writel(0, db->membase + EMAC_INT_CTL_REG);
86249220505SStefan Roese 
863dbedd44eSJoe Perches 	/* clear interrupt status */
86449220505SStefan Roese 	reg_val = readl(db->membase + EMAC_INT_STA_REG);
86549220505SStefan Roese 	writel(reg_val, db->membase + EMAC_INT_STA_REG);
86649220505SStefan Roese 
86749220505SStefan Roese 	/* Disable RX/TX */
86849220505SStefan Roese 	reg_val = readl(db->membase + EMAC_CTL_REG);
86949220505SStefan Roese 	reg_val &= ~(EMAC_CTL_TX_EN | EMAC_CTL_RX_EN | EMAC_CTL_RESET);
87049220505SStefan Roese 	writel(reg_val, db->membase + EMAC_CTL_REG);
87149220505SStefan Roese }
87249220505SStefan Roese 
87349220505SStefan Roese /* Stop the interface.
87449220505SStefan Roese  * The interface is stopped when it is brought.
87549220505SStefan Roese  */
emac_stop(struct net_device * ndev)87649220505SStefan Roese static int emac_stop(struct net_device *ndev)
87749220505SStefan Roese {
87849220505SStefan Roese 	struct emac_board_info *db = netdev_priv(ndev);
87949220505SStefan Roese 
88049220505SStefan Roese 	if (netif_msg_ifdown(db))
88149220505SStefan Roese 		dev_dbg(db->dev, "shutting down %s\n", ndev->name);
88249220505SStefan Roese 
88349220505SStefan Roese 	netif_stop_queue(ndev);
88449220505SStefan Roese 	netif_carrier_off(ndev);
88549220505SStefan Roese 
8865427ccafSPhilippe Reynes 	phy_stop(ndev->phydev);
88749220505SStefan Roese 
88849220505SStefan Roese 	emac_mdio_remove(ndev);
88949220505SStefan Roese 
89049220505SStefan Roese 	emac_shutdown(ndev);
89149220505SStefan Roese 
892e9c56f8dSMaxime Ripard 	free_irq(ndev->irq, ndev);
893e9c56f8dSMaxime Ripard 
89449220505SStefan Roese 	return 0;
89549220505SStefan Roese }
89649220505SStefan Roese 
89749220505SStefan Roese static const struct net_device_ops emac_netdev_ops = {
89849220505SStefan Roese 	.ndo_open		= emac_open,
89949220505SStefan Roese 	.ndo_stop		= emac_stop,
90049220505SStefan Roese 	.ndo_start_xmit		= emac_start_xmit,
90149220505SStefan Roese 	.ndo_tx_timeout		= emac_timeout,
902cec9ae50SMarc Zyngier 	.ndo_set_rx_mode	= emac_set_rx_mode,
903a7605370SArnd Bergmann 	.ndo_eth_ioctl		= phy_do_ioctl_running,
90449220505SStefan Roese 	.ndo_validate_addr	= eth_validate_addr,
90549220505SStefan Roese 	.ndo_set_mac_address	= emac_set_mac_address,
90649220505SStefan Roese #ifdef CONFIG_NET_POLL_CONTROLLER
90749220505SStefan Roese 	.ndo_poll_controller	= emac_poll_controller,
90849220505SStefan Roese #endif
90949220505SStefan Roese };
91049220505SStefan Roese 
emac_configure_dma(struct emac_board_info * db)91147869e82SConley Lee static int emac_configure_dma(struct emac_board_info *db)
91247869e82SConley Lee {
91347869e82SConley Lee 	struct platform_device *pdev = db->pdev;
91447869e82SConley Lee 	struct net_device *ndev = db->ndev;
91547869e82SConley Lee 	struct dma_slave_config conf = {};
91647869e82SConley Lee 	struct resource *regs;
91747869e82SConley Lee 	int err = 0;
91847869e82SConley Lee 
91947869e82SConley Lee 	regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
92047869e82SConley Lee 	if (!regs) {
92147869e82SConley Lee 		netdev_err(ndev, "get io resource from device failed.\n");
92247869e82SConley Lee 		err = -ENOMEM;
92347869e82SConley Lee 		goto out_clear_chan;
92447869e82SConley Lee 	}
92547869e82SConley Lee 
926009e4ee3SJakub Kicinski 	netdev_info(ndev, "get io resource from device: %pa, size = %u\n",
927009e4ee3SJakub Kicinski 		    &regs->start, (unsigned int)resource_size(regs));
92847869e82SConley Lee 	db->emac_rx_fifo = regs->start + EMAC_RX_IO_DATA_REG;
92947869e82SConley Lee 
93047869e82SConley Lee 	db->rx_chan = dma_request_chan(&pdev->dev, "rx");
93147869e82SConley Lee 	if (IS_ERR(db->rx_chan)) {
93247869e82SConley Lee 		netdev_err(ndev,
93347869e82SConley Lee 			   "failed to request dma channel. dma is disabled\n");
93447869e82SConley Lee 		err = PTR_ERR(db->rx_chan);
93547869e82SConley Lee 		goto out_clear_chan;
93647869e82SConley Lee 	}
93747869e82SConley Lee 
93847869e82SConley Lee 	conf.direction = DMA_DEV_TO_MEM;
93947869e82SConley Lee 	conf.dst_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
94047869e82SConley Lee 	conf.src_addr_width = DMA_SLAVE_BUSWIDTH_4_BYTES;
94147869e82SConley Lee 	conf.src_addr = db->emac_rx_fifo;
94247869e82SConley Lee 	conf.dst_maxburst = 4;
94347869e82SConley Lee 	conf.src_maxburst = 4;
94447869e82SConley Lee 	conf.device_fc = false;
94547869e82SConley Lee 
94647869e82SConley Lee 	err = dmaengine_slave_config(db->rx_chan, &conf);
94747869e82SConley Lee 	if (err) {
94847869e82SConley Lee 		netdev_err(ndev, "config dma slave failed\n");
94947869e82SConley Lee 		err = -EINVAL;
95047869e82SConley Lee 		goto out_slave_configure_err;
95147869e82SConley Lee 	}
95247869e82SConley Lee 
95347869e82SConley Lee 	return err;
95447869e82SConley Lee 
95547869e82SConley Lee out_slave_configure_err:
95647869e82SConley Lee 	dma_release_channel(db->rx_chan);
95747869e82SConley Lee 
95847869e82SConley Lee out_clear_chan:
95947869e82SConley Lee 	db->rx_chan = NULL;
96047869e82SConley Lee 	return err;
96147869e82SConley Lee }
96247869e82SConley Lee 
96349220505SStefan Roese /* Search EMAC board, allocate space and register it
96449220505SStefan Roese  */
emac_probe(struct platform_device * pdev)96549220505SStefan Roese static int emac_probe(struct platform_device *pdev)
96649220505SStefan Roese {
96749220505SStefan Roese 	struct device_node *np = pdev->dev.of_node;
96849220505SStefan Roese 	struct emac_board_info *db;
96949220505SStefan Roese 	struct net_device *ndev;
97049220505SStefan Roese 	int ret = 0;
97149220505SStefan Roese 
97249220505SStefan Roese 	ndev = alloc_etherdev(sizeof(struct emac_board_info));
97349220505SStefan Roese 	if (!ndev) {
97449220505SStefan Roese 		dev_err(&pdev->dev, "could not allocate device.\n");
97549220505SStefan Roese 		return -ENOMEM;
97649220505SStefan Roese 	}
97749220505SStefan Roese 
97849220505SStefan Roese 	SET_NETDEV_DEV(ndev, &pdev->dev);
97949220505SStefan Roese 
98049220505SStefan Roese 	db = netdev_priv(ndev);
98149220505SStefan Roese 
98249220505SStefan Roese 	db->dev = &pdev->dev;
98349220505SStefan Roese 	db->ndev = ndev;
98449220505SStefan Roese 	db->pdev = pdev;
985b8ca3387SMichael Weiser 	db->msg_enable = netif_msg_init(debug, EMAC_DEFAULT_MSG_ENABLE);
98649220505SStefan Roese 
98749220505SStefan Roese 	spin_lock_init(&db->lock);
98849220505SStefan Roese 
98949220505SStefan Roese 	db->membase = of_iomap(np, 0);
99049220505SStefan Roese 	if (!db->membase) {
99149220505SStefan Roese 		dev_err(&pdev->dev, "failed to remap registers\n");
99293baf4c6SWei Yongjun 		ret = -ENOMEM;
99349220505SStefan Roese 		goto out;
99449220505SStefan Roese 	}
99549220505SStefan Roese 
99649220505SStefan Roese 	/* fill in parameters for net-dev structure */
99749220505SStefan Roese 	ndev->base_addr = (unsigned long)db->membase;
99849220505SStefan Roese 	ndev->irq = irq_of_parse_and_map(np, 0);
99949220505SStefan Roese 	if (ndev->irq == -ENXIO) {
100049220505SStefan Roese 		netdev_err(ndev, "No irq resource\n");
100149220505SStefan Roese 		ret = ndev->irq;
1002104eb270SHans de Goede 		goto out_iounmap;
100349220505SStefan Roese 	}
100449220505SStefan Roese 
100547869e82SConley Lee 	if (emac_configure_dma(db))
100647869e82SConley Lee 		netdev_info(ndev, "configure dma failed. disable dma.\n");
100747869e82SConley Lee 
100849220505SStefan Roese 	db->clk = devm_clk_get(&pdev->dev, NULL);
10093d2232f5SJulia Lawall 	if (IS_ERR(db->clk)) {
10103d2232f5SJulia Lawall 		ret = PTR_ERR(db->clk);
1011322e53d1SChristophe JAILLET 		goto out_dispose_mapping;
10123d2232f5SJulia Lawall 	}
101349220505SStefan Roese 
1014104eb270SHans de Goede 	ret = clk_prepare_enable(db->clk);
1015104eb270SHans de Goede 	if (ret) {
1016104eb270SHans de Goede 		dev_err(&pdev->dev, "Error couldn't enable clock (%d)\n", ret);
1017322e53d1SChristophe JAILLET 		goto out_dispose_mapping;
1018104eb270SHans de Goede 	}
101949220505SStefan Roese 
1020542a64c7SHans de Goede 	ret = sunxi_sram_claim(&pdev->dev);
1021542a64c7SHans de Goede 	if (ret) {
1022542a64c7SHans de Goede 		dev_err(&pdev->dev, "Error couldn't map SRAM to device\n");
1023104eb270SHans de Goede 		goto out_clk_disable_unprepare;
1024542a64c7SHans de Goede 	}
1025542a64c7SHans de Goede 
10265c4e2e1aSChen-Yu Tsai 	db->phy_node = of_parse_phandle(np, "phy-handle", 0);
10275c4e2e1aSChen-Yu Tsai 	if (!db->phy_node)
102849220505SStefan Roese 		db->phy_node = of_parse_phandle(np, "phy", 0);
102949220505SStefan Roese 	if (!db->phy_node) {
103049220505SStefan Roese 		dev_err(&pdev->dev, "no associated PHY\n");
103149220505SStefan Roese 		ret = -ENODEV;
1032542a64c7SHans de Goede 		goto out_release_sram;
103349220505SStefan Roese 	}
103449220505SStefan Roese 
103549220505SStefan Roese 	/* Read MAC-address from DT */
10369ca01b25SJakub Kicinski 	ret = of_get_ethdev_address(np, ndev);
103783216e39SMichael Walle 	if (ret) {
103883216e39SMichael Walle 		/* if the MAC address is invalid get a random one */
103949220505SStefan Roese 		eth_hw_addr_random(ndev);
104049220505SStefan Roese 		dev_warn(&pdev->dev, "using random MAC address %pM\n",
104149220505SStefan Roese 			 ndev->dev_addr);
104249220505SStefan Roese 	}
104349220505SStefan Roese 
104449220505SStefan Roese 	db->emacrx_completed_flag = 1;
104549220505SStefan Roese 	emac_powerup(ndev);
104649220505SStefan Roese 	emac_reset(db);
104749220505SStefan Roese 
104849220505SStefan Roese 	ndev->netdev_ops = &emac_netdev_ops;
104949220505SStefan Roese 	ndev->watchdog_timeo = msecs_to_jiffies(watchdog);
105049220505SStefan Roese 	ndev->ethtool_ops = &emac_ethtool_ops;
105149220505SStefan Roese 
105249220505SStefan Roese 	platform_set_drvdata(pdev, ndev);
105349220505SStefan Roese 
105449220505SStefan Roese 	/* Carrier starts down, phylib will bring it up */
105549220505SStefan Roese 	netif_carrier_off(ndev);
105649220505SStefan Roese 
105749220505SStefan Roese 	ret = register_netdev(ndev);
105849220505SStefan Roese 	if (ret) {
105949220505SStefan Roese 		dev_err(&pdev->dev, "Registering netdev failed!\n");
106049220505SStefan Roese 		ret = -ENODEV;
1061542a64c7SHans de Goede 		goto out_release_sram;
106249220505SStefan Roese 	}
106349220505SStefan Roese 
106449220505SStefan Roese 	dev_info(&pdev->dev, "%s: at %p, IRQ %d MAC: %pM\n",
106549220505SStefan Roese 		 ndev->name, db->membase, ndev->irq, ndev->dev_addr);
106649220505SStefan Roese 
106749220505SStefan Roese 	return 0;
106849220505SStefan Roese 
1069542a64c7SHans de Goede out_release_sram:
1070542a64c7SHans de Goede 	sunxi_sram_release(&pdev->dev);
1071104eb270SHans de Goede out_clk_disable_unprepare:
1072104eb270SHans de Goede 	clk_disable_unprepare(db->clk);
1073322e53d1SChristophe JAILLET out_dispose_mapping:
1074322e53d1SChristophe JAILLET 	irq_dispose_mapping(ndev->irq);
10759a9acdccSChristophe JAILLET 	dma_release_channel(db->rx_chan);
1076104eb270SHans de Goede out_iounmap:
1077104eb270SHans de Goede 	iounmap(db->membase);
107849220505SStefan Roese out:
107949220505SStefan Roese 	dev_err(db->dev, "not found (%d).\n", ret);
108049220505SStefan Roese 
108149220505SStefan Roese 	free_netdev(ndev);
108249220505SStefan Roese 
108349220505SStefan Roese 	return ret;
108449220505SStefan Roese }
108549220505SStefan Roese 
emac_remove(struct platform_device * pdev)108649220505SStefan Roese static int emac_remove(struct platform_device *pdev)
108749220505SStefan Roese {
108849220505SStefan Roese 	struct net_device *ndev = platform_get_drvdata(pdev);
1089104eb270SHans de Goede 	struct emac_board_info *db = netdev_priv(ndev);
109049220505SStefan Roese 
109147869e82SConley Lee 	if (db->rx_chan) {
109247869e82SConley Lee 		dmaengine_terminate_all(db->rx_chan);
109347869e82SConley Lee 		dma_release_channel(db->rx_chan);
109447869e82SConley Lee 	}
109547869e82SConley Lee 
109649220505SStefan Roese 	unregister_netdev(ndev);
1097104eb270SHans de Goede 	sunxi_sram_release(&pdev->dev);
1098104eb270SHans de Goede 	clk_disable_unprepare(db->clk);
1099322e53d1SChristophe JAILLET 	irq_dispose_mapping(ndev->irq);
1100104eb270SHans de Goede 	iounmap(db->membase);
110149220505SStefan Roese 	free_netdev(ndev);
110249220505SStefan Roese 
110349220505SStefan Roese 	dev_dbg(&pdev->dev, "released and freed device\n");
110449220505SStefan Roese 	return 0;
110549220505SStefan Roese }
110649220505SStefan Roese 
emac_suspend(struct platform_device * dev,pm_message_t state)110749220505SStefan Roese static int emac_suspend(struct platform_device *dev, pm_message_t state)
110849220505SStefan Roese {
110949220505SStefan Roese 	struct net_device *ndev = platform_get_drvdata(dev);
111049220505SStefan Roese 
111149220505SStefan Roese 	netif_carrier_off(ndev);
111249220505SStefan Roese 	netif_device_detach(ndev);
111349220505SStefan Roese 	emac_shutdown(ndev);
111449220505SStefan Roese 
111549220505SStefan Roese 	return 0;
111649220505SStefan Roese }
111749220505SStefan Roese 
emac_resume(struct platform_device * dev)111849220505SStefan Roese static int emac_resume(struct platform_device *dev)
111949220505SStefan Roese {
112049220505SStefan Roese 	struct net_device *ndev = platform_get_drvdata(dev);
112149220505SStefan Roese 	struct emac_board_info *db = netdev_priv(ndev);
112249220505SStefan Roese 
112349220505SStefan Roese 	emac_reset(db);
112449220505SStefan Roese 	emac_init_device(ndev);
112549220505SStefan Roese 	netif_device_attach(ndev);
112649220505SStefan Roese 
112749220505SStefan Roese 	return 0;
112849220505SStefan Roese }
112949220505SStefan Roese 
113049220505SStefan Roese static const struct of_device_id emac_of_match[] = {
11314dae1686SMaxime Ripard 	{.compatible = "allwinner,sun4i-a10-emac",},
11324dae1686SMaxime Ripard 
11334dae1686SMaxime Ripard 	/* Deprecated */
113449220505SStefan Roese 	{.compatible = "allwinner,sun4i-emac",},
113549220505SStefan Roese 	{},
113649220505SStefan Roese };
113749220505SStefan Roese 
113849220505SStefan Roese MODULE_DEVICE_TABLE(of, emac_of_match);
113949220505SStefan Roese 
114049220505SStefan Roese static struct platform_driver emac_driver = {
114149220505SStefan Roese 	.driver = {
114249220505SStefan Roese 		.name = "sun4i-emac",
114349220505SStefan Roese 		.of_match_table = emac_of_match,
114449220505SStefan Roese 	},
114549220505SStefan Roese 	.probe = emac_probe,
114649220505SStefan Roese 	.remove = emac_remove,
114749220505SStefan Roese 	.suspend = emac_suspend,
114849220505SStefan Roese 	.resume = emac_resume,
114949220505SStefan Roese };
115049220505SStefan Roese 
115149220505SStefan Roese module_platform_driver(emac_driver);
115249220505SStefan Roese 
115349220505SStefan Roese MODULE_AUTHOR("Stefan Roese <sr@denx.de>");
115449220505SStefan Roese MODULE_AUTHOR("Maxime Ripard <maxime.ripard@free-electrons.com>");
115549220505SStefan Roese MODULE_DESCRIPTION("Allwinner A10 emac network driver");
115649220505SStefan Roese MODULE_LICENSE("GPL");
1157