Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 1 | /* |
| 2 | * Ethernet driver for the Atmel AT91RM9200 (Thunder) |
| 3 | * |
| 4 | * Copyright (C) 2003 SAN People (Pty) Ltd |
| 5 | * |
| 6 | * Based on an earlier Atmel EMAC macrocell driver by Atmel and Lineo Inc. |
| 7 | * Initial version by Rick Bronson 01/11/2003 |
| 8 | * |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 9 | * This program is free software; you can redistribute it and/or |
| 10 | * modify it under the terms of the GNU General Public License |
| 11 | * as published by the Free Software Foundation; either version |
| 12 | * 2 of the License, or (at your option) any later version. |
| 13 | */ |
| 14 | |
| 15 | #include <linux/module.h> |
| 16 | #include <linux/init.h> |
Alexey Dobriyan | a6b7a40 | 2011-06-06 10:43:46 +0000 | [diff] [blame] | 17 | #include <linux/interrupt.h> |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 18 | #include <linux/netdevice.h> |
| 19 | #include <linux/etherdevice.h> |
| 20 | #include <linux/skbuff.h> |
| 21 | #include <linux/dma-mapping.h> |
| 22 | #include <linux/ethtool.h> |
Jamie Iles | 84e0cdb | 2011-03-08 20:17:06 +0000 | [diff] [blame] | 23 | #include <linux/platform_data/macb.h> |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 24 | #include <linux/platform_device.h> |
| 25 | #include <linux/clk.h> |
Tejun Heo | 5a0e3ad | 2010-03-24 17:04:11 +0900 | [diff] [blame] | 26 | #include <linux/gfp.h> |
Andrew Victor | c5f0f83 | 2012-04-26 00:30:42 +0000 | [diff] [blame] | 27 | #include <linux/phy.h> |
Joachim Eastwood | 6397346 | 2012-10-18 11:01:18 +0000 | [diff] [blame] | 28 | #include <linux/io.h> |
Jean-Christophe PLAGNIOL-VILLARD | 96f6360 | 2012-11-04 21:34:51 +0000 | [diff] [blame] | 29 | #include <linux/of.h> |
| 30 | #include <linux/of_device.h> |
| 31 | #include <linux/of_net.h> |
Jean-Christophe PLAGNIOL-VILLARD | dea0924 | 2012-11-04 21:34:52 +0000 | [diff] [blame] | 32 | #include <linux/pinctrl/consumer.h> |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 33 | |
Joachim Eastwood | bc3bbef | 2012-10-18 11:01:07 +0000 | [diff] [blame] | 34 | #include "macb.h" |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 35 | |
Joachim Eastwood | 04879e5 | 2012-10-18 11:01:17 +0000 | [diff] [blame] | 36 | /* 1518 rounded up */ |
| 37 | #define MAX_RBUFF_SZ 0x600 |
| 38 | /* max number of receive buffers */ |
| 39 | #define MAX_RX_DESCR 9 |
| 40 | |
Joachim Eastwood | 50b5ca1 | 2012-11-07 08:14:57 +0000 | [diff] [blame] | 41 | /* Initialize and start the Receiver and Transmit subsystems */ |
Joachim Eastwood | 04879e5 | 2012-10-18 11:01:17 +0000 | [diff] [blame] | 42 | static int at91ether_start(struct net_device *dev) |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 43 | { |
Joachim Eastwood | b85008b | 2012-10-18 11:01:10 +0000 | [diff] [blame] | 44 | struct macb *lp = netdev_priv(dev); |
Joachim Eastwood | 04879e5 | 2012-10-18 11:01:17 +0000 | [diff] [blame] | 45 | dma_addr_t addr; |
Joachim Eastwood | 50b5ca1 | 2012-11-07 08:14:57 +0000 | [diff] [blame] | 46 | u32 ctl; |
Joachim Eastwood | 04879e5 | 2012-10-18 11:01:17 +0000 | [diff] [blame] | 47 | int i; |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 48 | |
Joachim Eastwood | 04879e5 | 2012-10-18 11:01:17 +0000 | [diff] [blame] | 49 | lp->rx_ring = dma_alloc_coherent(&lp->pdev->dev, |
Havard Skinnemoen | 55054a1 | 2012-10-31 06:04:55 +0000 | [diff] [blame] | 50 | MAX_RX_DESCR * sizeof(struct macb_dma_desc), |
Joachim Eastwood | 04879e5 | 2012-10-18 11:01:17 +0000 | [diff] [blame] | 51 | &lp->rx_ring_dma, GFP_KERNEL); |
| 52 | if (!lp->rx_ring) { |
Joachim Eastwood | ed2b97d | 2012-11-07 08:14:56 +0000 | [diff] [blame] | 53 | netdev_err(dev, "unable to alloc rx ring DMA buffer\n"); |
Joachim Eastwood | 04879e5 | 2012-10-18 11:01:17 +0000 | [diff] [blame] | 54 | return -ENOMEM; |
| 55 | } |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 56 | |
Joachim Eastwood | 04879e5 | 2012-10-18 11:01:17 +0000 | [diff] [blame] | 57 | lp->rx_buffers = dma_alloc_coherent(&lp->pdev->dev, |
| 58 | MAX_RX_DESCR * MAX_RBUFF_SZ, |
| 59 | &lp->rx_buffers_dma, GFP_KERNEL); |
| 60 | if (!lp->rx_buffers) { |
Joachim Eastwood | ed2b97d | 2012-11-07 08:14:56 +0000 | [diff] [blame] | 61 | netdev_err(dev, "unable to alloc rx data DMA buffer\n"); |
Joachim Eastwood | 04879e5 | 2012-10-18 11:01:17 +0000 | [diff] [blame] | 62 | |
| 63 | dma_free_coherent(&lp->pdev->dev, |
Havard Skinnemoen | 55054a1 | 2012-10-31 06:04:55 +0000 | [diff] [blame] | 64 | MAX_RX_DESCR * sizeof(struct macb_dma_desc), |
Joachim Eastwood | 04879e5 | 2012-10-18 11:01:17 +0000 | [diff] [blame] | 65 | lp->rx_ring, lp->rx_ring_dma); |
| 66 | lp->rx_ring = NULL; |
| 67 | return -ENOMEM; |
| 68 | } |
| 69 | |
| 70 | addr = lp->rx_buffers_dma; |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 71 | for (i = 0; i < MAX_RX_DESCR; i++) { |
Joachim Eastwood | 04879e5 | 2012-10-18 11:01:17 +0000 | [diff] [blame] | 72 | lp->rx_ring[i].addr = addr; |
| 73 | lp->rx_ring[i].ctrl = 0; |
| 74 | addr += MAX_RBUFF_SZ; |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 75 | } |
| 76 | |
| 77 | /* Set the Wrap bit on the last descriptor */ |
Joachim Eastwood | 04879e5 | 2012-10-18 11:01:17 +0000 | [diff] [blame] | 78 | lp->rx_ring[MAX_RX_DESCR - 1].addr |= MACB_BIT(RX_WRAP); |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 79 | |
| 80 | /* Reset buffer index */ |
Joachim Eastwood | 04879e5 | 2012-10-18 11:01:17 +0000 | [diff] [blame] | 81 | lp->rx_tail = 0; |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 82 | |
| 83 | /* Program address of descriptor list in Rx Buffer Queue register */ |
Joachim Eastwood | 04879e5 | 2012-10-18 11:01:17 +0000 | [diff] [blame] | 84 | macb_writel(lp, RBQP, lp->rx_ring_dma); |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 85 | |
| 86 | /* Enable Receive and Transmit */ |
Joachim Eastwood | f8bded3 | 2012-10-18 11:01:08 +0000 | [diff] [blame] | 87 | ctl = macb_readl(lp, NCR); |
| 88 | macb_writel(lp, NCR, ctl | MACB_BIT(RE) | MACB_BIT(TE)); |
Joachim Eastwood | 04879e5 | 2012-10-18 11:01:17 +0000 | [diff] [blame] | 89 | |
| 90 | return 0; |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 91 | } |
| 92 | |
Joachim Eastwood | 50b5ca1 | 2012-11-07 08:14:57 +0000 | [diff] [blame] | 93 | /* Open the ethernet interface */ |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 94 | static int at91ether_open(struct net_device *dev) |
| 95 | { |
Joachim Eastwood | b85008b | 2012-10-18 11:01:10 +0000 | [diff] [blame] | 96 | struct macb *lp = netdev_priv(dev); |
Joachim Eastwood | 50b5ca1 | 2012-11-07 08:14:57 +0000 | [diff] [blame] | 97 | u32 ctl; |
Joachim Eastwood | 04879e5 | 2012-10-18 11:01:17 +0000 | [diff] [blame] | 98 | int ret; |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 99 | |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 100 | /* Clear internal statistics */ |
Joachim Eastwood | f8bded3 | 2012-10-18 11:01:08 +0000 | [diff] [blame] | 101 | ctl = macb_readl(lp, NCR); |
| 102 | macb_writel(lp, NCR, ctl | MACB_BIT(CLRSTAT)); |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 103 | |
Joachim Eastwood | 3423247 | 2012-11-07 08:14:53 +0000 | [diff] [blame] | 104 | macb_set_hwaddr(lp); |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 105 | |
Joachim Eastwood | 04879e5 | 2012-10-18 11:01:17 +0000 | [diff] [blame] | 106 | ret = at91ether_start(dev); |
| 107 | if (ret) |
| 108 | return ret; |
| 109 | |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 110 | /* Enable MAC interrupts */ |
Joachim Eastwood | 50b5ca1 | 2012-11-07 08:14:57 +0000 | [diff] [blame] | 111 | macb_writel(lp, IER, MACB_BIT(RCOMP) | |
| 112 | MACB_BIT(RXUBR) | |
| 113 | MACB_BIT(ISR_TUND) | |
| 114 | MACB_BIT(ISR_RLE) | |
| 115 | MACB_BIT(TCOMP) | |
| 116 | MACB_BIT(ISR_ROVR) | |
| 117 | MACB_BIT(HRESP)); |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 118 | |
Joachim Eastwood | 5e32353d | 2012-10-18 11:01:14 +0000 | [diff] [blame] | 119 | /* schedule a link state check */ |
| 120 | phy_start(lp->phy_dev); |
| 121 | |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 122 | netif_start_queue(dev); |
Joachim Eastwood | 5e32353d | 2012-10-18 11:01:14 +0000 | [diff] [blame] | 123 | |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 124 | return 0; |
| 125 | } |
| 126 | |
Joachim Eastwood | 50b5ca1 | 2012-11-07 08:14:57 +0000 | [diff] [blame] | 127 | /* Close the interface */ |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 128 | static int at91ether_close(struct net_device *dev) |
| 129 | { |
Joachim Eastwood | b85008b | 2012-10-18 11:01:10 +0000 | [diff] [blame] | 130 | struct macb *lp = netdev_priv(dev); |
Joachim Eastwood | 50b5ca1 | 2012-11-07 08:14:57 +0000 | [diff] [blame] | 131 | u32 ctl; |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 132 | |
| 133 | /* Disable Receiver and Transmitter */ |
Joachim Eastwood | f8bded3 | 2012-10-18 11:01:08 +0000 | [diff] [blame] | 134 | ctl = macb_readl(lp, NCR); |
| 135 | macb_writel(lp, NCR, ctl & ~(MACB_BIT(TE) | MACB_BIT(RE))); |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 136 | |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 137 | /* Disable MAC interrupts */ |
Joachim Eastwood | 50b5ca1 | 2012-11-07 08:14:57 +0000 | [diff] [blame] | 138 | macb_writel(lp, IDR, MACB_BIT(RCOMP) | |
| 139 | MACB_BIT(RXUBR) | |
| 140 | MACB_BIT(ISR_TUND) | |
| 141 | MACB_BIT(ISR_RLE) | |
| 142 | MACB_BIT(TCOMP) | |
| 143 | MACB_BIT(ISR_ROVR) | |
| 144 | MACB_BIT(HRESP)); |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 145 | |
| 146 | netif_stop_queue(dev); |
| 147 | |
Joachim Eastwood | 04879e5 | 2012-10-18 11:01:17 +0000 | [diff] [blame] | 148 | dma_free_coherent(&lp->pdev->dev, |
Havard Skinnemoen | 55054a1 | 2012-10-31 06:04:55 +0000 | [diff] [blame] | 149 | MAX_RX_DESCR * sizeof(struct macb_dma_desc), |
Joachim Eastwood | 04879e5 | 2012-10-18 11:01:17 +0000 | [diff] [blame] | 150 | lp->rx_ring, lp->rx_ring_dma); |
| 151 | lp->rx_ring = NULL; |
| 152 | |
| 153 | dma_free_coherent(&lp->pdev->dev, |
| 154 | MAX_RX_DESCR * MAX_RBUFF_SZ, |
| 155 | lp->rx_buffers, lp->rx_buffers_dma); |
| 156 | lp->rx_buffers = NULL; |
| 157 | |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 158 | return 0; |
| 159 | } |
| 160 | |
Joachim Eastwood | 50b5ca1 | 2012-11-07 08:14:57 +0000 | [diff] [blame] | 161 | /* Transmit packet */ |
Alexander Beregalov | 531c680 | 2009-04-09 17:27:00 +0000 | [diff] [blame] | 162 | static int at91ether_start_xmit(struct sk_buff *skb, struct net_device *dev) |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 163 | { |
Joachim Eastwood | b85008b | 2012-10-18 11:01:10 +0000 | [diff] [blame] | 164 | struct macb *lp = netdev_priv(dev); |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 165 | |
Joachim Eastwood | f8bded3 | 2012-10-18 11:01:08 +0000 | [diff] [blame] | 166 | if (macb_readl(lp, TSR) & MACB_BIT(RM9200_BNQ)) { |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 167 | netif_stop_queue(dev); |
| 168 | |
| 169 | /* Store packet information (to free when Tx completed) */ |
| 170 | lp->skb = skb; |
| 171 | lp->skb_length = skb->len; |
Joachim Eastwood | 50b5ca1 | 2012-11-07 08:14:57 +0000 | [diff] [blame] | 172 | lp->skb_physaddr = dma_map_single(NULL, skb->data, skb->len, |
| 173 | DMA_TO_DEVICE); |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 174 | |
| 175 | /* Set address of the data in the Transmit Address register */ |
Joachim Eastwood | f8bded3 | 2012-10-18 11:01:08 +0000 | [diff] [blame] | 176 | macb_writel(lp, TAR, lp->skb_physaddr); |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 177 | /* Set length of the packet in the Transmit Control register */ |
Joachim Eastwood | f8bded3 | 2012-10-18 11:01:08 +0000 | [diff] [blame] | 178 | macb_writel(lp, TCR, skb->len); |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 179 | |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 180 | } else { |
Joachim Eastwood | ed2b97d | 2012-11-07 08:14:56 +0000 | [diff] [blame] | 181 | netdev_err(dev, "%s called, but device is busy!\n", __func__); |
Joachim Eastwood | 50b5ca1 | 2012-11-07 08:14:57 +0000 | [diff] [blame] | 182 | return NETDEV_TX_BUSY; |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 183 | } |
| 184 | |
Patrick McHardy | 6ed1065 | 2009-06-23 06:03:08 +0000 | [diff] [blame] | 185 | return NETDEV_TX_OK; |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 186 | } |
| 187 | |
Joachim Eastwood | 50b5ca1 | 2012-11-07 08:14:57 +0000 | [diff] [blame] | 188 | /* Extract received frame from buffer descriptors and sent to upper layers. |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 189 | * (Called from interrupt context) |
| 190 | */ |
| 191 | static void at91ether_rx(struct net_device *dev) |
| 192 | { |
Joachim Eastwood | b85008b | 2012-10-18 11:01:10 +0000 | [diff] [blame] | 193 | struct macb *lp = netdev_priv(dev); |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 194 | unsigned char *p_recv; |
| 195 | struct sk_buff *skb; |
| 196 | unsigned int pktlen; |
| 197 | |
Joachim Eastwood | 04879e5 | 2012-10-18 11:01:17 +0000 | [diff] [blame] | 198 | while (lp->rx_ring[lp->rx_tail].addr & MACB_BIT(RX_USED)) { |
| 199 | p_recv = lp->rx_buffers + lp->rx_tail * MAX_RBUFF_SZ; |
| 200 | pktlen = MACB_BF(RX_FRMLEN, lp->rx_ring[lp->rx_tail].ctrl); |
Pradeep A Dalvi | 1d26643 | 2012-02-05 02:49:09 +0000 | [diff] [blame] | 201 | skb = netdev_alloc_skb(dev, pktlen + 2); |
Joachim Eastwood | 04879e5 | 2012-10-18 11:01:17 +0000 | [diff] [blame] | 202 | if (skb) { |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 203 | skb_reserve(skb, 2); |
| 204 | memcpy(skb_put(skb, pktlen), p_recv, pktlen); |
| 205 | |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 206 | skb->protocol = eth_type_trans(skb, dev); |
Joachim Eastwood | 2ea32ee | 2012-11-07 08:14:54 +0000 | [diff] [blame] | 207 | lp->stats.rx_packets++; |
| 208 | lp->stats.rx_bytes += pktlen; |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 209 | netif_rx(skb); |
Joachim Eastwood | 04879e5 | 2012-10-18 11:01:17 +0000 | [diff] [blame] | 210 | } else { |
Joachim Eastwood | 2ea32ee | 2012-11-07 08:14:54 +0000 | [diff] [blame] | 211 | lp->stats.rx_dropped++; |
Joachim Eastwood | 04879e5 | 2012-10-18 11:01:17 +0000 | [diff] [blame] | 212 | netdev_notice(dev, "Memory squeeze, dropping packet.\n"); |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 213 | } |
| 214 | |
Joachim Eastwood | 04879e5 | 2012-10-18 11:01:17 +0000 | [diff] [blame] | 215 | if (lp->rx_ring[lp->rx_tail].ctrl & MACB_BIT(RX_MHASH_MATCH)) |
Joachim Eastwood | 2ea32ee | 2012-11-07 08:14:54 +0000 | [diff] [blame] | 216 | lp->stats.multicast++; |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 217 | |
Joachim Eastwood | 04879e5 | 2012-10-18 11:01:17 +0000 | [diff] [blame] | 218 | /* reset ownership bit */ |
| 219 | lp->rx_ring[lp->rx_tail].addr &= ~MACB_BIT(RX_USED); |
| 220 | |
| 221 | /* wrap after last buffer */ |
| 222 | if (lp->rx_tail == MAX_RX_DESCR - 1) |
| 223 | lp->rx_tail = 0; |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 224 | else |
Joachim Eastwood | 04879e5 | 2012-10-18 11:01:17 +0000 | [diff] [blame] | 225 | lp->rx_tail++; |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 226 | } |
| 227 | } |
| 228 | |
Joachim Eastwood | 50b5ca1 | 2012-11-07 08:14:57 +0000 | [diff] [blame] | 229 | /* MAC interrupt handler */ |
David Howells | 7d12e78 | 2006-10-05 14:55:46 +0100 | [diff] [blame] | 230 | static irqreturn_t at91ether_interrupt(int irq, void *dev_id) |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 231 | { |
Joachim Eastwood | 50b5ca1 | 2012-11-07 08:14:57 +0000 | [diff] [blame] | 232 | struct net_device *dev = dev_id; |
Joachim Eastwood | b85008b | 2012-10-18 11:01:10 +0000 | [diff] [blame] | 233 | struct macb *lp = netdev_priv(dev); |
Joachim Eastwood | 50b5ca1 | 2012-11-07 08:14:57 +0000 | [diff] [blame] | 234 | u32 intstatus, ctl; |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 235 | |
| 236 | /* MAC Interrupt Status register indicates what interrupts are pending. |
Joachim Eastwood | 50b5ca1 | 2012-11-07 08:14:57 +0000 | [diff] [blame] | 237 | * It is automatically cleared once read. |
| 238 | */ |
Joachim Eastwood | f8bded3 | 2012-10-18 11:01:08 +0000 | [diff] [blame] | 239 | intstatus = macb_readl(lp, ISR); |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 240 | |
Joachim Eastwood | 50b5ca1 | 2012-11-07 08:14:57 +0000 | [diff] [blame] | 241 | /* Receive complete */ |
| 242 | if (intstatus & MACB_BIT(RCOMP)) |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 243 | at91ether_rx(dev); |
| 244 | |
Joachim Eastwood | 50b5ca1 | 2012-11-07 08:14:57 +0000 | [diff] [blame] | 245 | /* Transmit complete */ |
| 246 | if (intstatus & MACB_BIT(TCOMP)) { |
| 247 | /* The TCOM bit is set even if the transmission failed */ |
Joachim Eastwood | bc3bbef | 2012-10-18 11:01:07 +0000 | [diff] [blame] | 248 | if (intstatus & (MACB_BIT(ISR_TUND) | MACB_BIT(ISR_RLE))) |
Joachim Eastwood | 2ea32ee | 2012-11-07 08:14:54 +0000 | [diff] [blame] | 249 | lp->stats.tx_errors++; |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 250 | |
| 251 | if (lp->skb) { |
| 252 | dev_kfree_skb_irq(lp->skb); |
| 253 | lp->skb = NULL; |
| 254 | dma_unmap_single(NULL, lp->skb_physaddr, lp->skb_length, DMA_TO_DEVICE); |
Joachim Eastwood | 2ea32ee | 2012-11-07 08:14:54 +0000 | [diff] [blame] | 255 | lp->stats.tx_packets++; |
| 256 | lp->stats.tx_bytes += lp->skb_length; |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 257 | } |
| 258 | netif_wake_queue(dev); |
| 259 | } |
| 260 | |
Joachim Eastwood | 50b5ca1 | 2012-11-07 08:14:57 +0000 | [diff] [blame] | 261 | /* Work-around for EMAC Errata section 41.3.1 */ |
Joachim Eastwood | bc3bbef | 2012-10-18 11:01:07 +0000 | [diff] [blame] | 262 | if (intstatus & MACB_BIT(RXUBR)) { |
Joachim Eastwood | f8bded3 | 2012-10-18 11:01:08 +0000 | [diff] [blame] | 263 | ctl = macb_readl(lp, NCR); |
| 264 | macb_writel(lp, NCR, ctl & ~MACB_BIT(RE)); |
| 265 | macb_writel(lp, NCR, ctl | MACB_BIT(RE)); |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 266 | } |
| 267 | |
Joachim Eastwood | bc3bbef | 2012-10-18 11:01:07 +0000 | [diff] [blame] | 268 | if (intstatus & MACB_BIT(ISR_ROVR)) |
Joachim Eastwood | ed2b97d | 2012-11-07 08:14:56 +0000 | [diff] [blame] | 269 | netdev_err(dev, "ROVR error\n"); |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 270 | |
| 271 | return IRQ_HANDLED; |
| 272 | } |
| 273 | |
Andrew Victor | 51cc210 | 2006-12-05 15:33:05 +0200 | [diff] [blame] | 274 | #ifdef CONFIG_NET_POLL_CONTROLLER |
| 275 | static void at91ether_poll_controller(struct net_device *dev) |
| 276 | { |
| 277 | unsigned long flags; |
| 278 | |
| 279 | local_irq_save(flags); |
| 280 | at91ether_interrupt(dev->irq, dev); |
| 281 | local_irq_restore(flags); |
| 282 | } |
| 283 | #endif |
| 284 | |
Alexander Beregalov | 531c680 | 2009-04-09 17:27:00 +0000 | [diff] [blame] | 285 | static const struct net_device_ops at91ether_netdev_ops = { |
| 286 | .ndo_open = at91ether_open, |
| 287 | .ndo_stop = at91ether_close, |
| 288 | .ndo_start_xmit = at91ether_start_xmit, |
Joachim Eastwood | 2ea32ee | 2012-11-07 08:14:54 +0000 | [diff] [blame] | 289 | .ndo_get_stats = macb_get_stats, |
Joachim Eastwood | e0da1f1 | 2012-10-18 11:01:15 +0000 | [diff] [blame] | 290 | .ndo_set_rx_mode = macb_set_rx_mode, |
Joachim Eastwood | 3423247 | 2012-11-07 08:14:53 +0000 | [diff] [blame] | 291 | .ndo_set_mac_address = eth_mac_addr, |
Joachim Eastwood | 5e32353d | 2012-10-18 11:01:14 +0000 | [diff] [blame] | 292 | .ndo_do_ioctl = macb_ioctl, |
Alexander Beregalov | 531c680 | 2009-04-09 17:27:00 +0000 | [diff] [blame] | 293 | .ndo_validate_addr = eth_validate_addr, |
| 294 | .ndo_change_mtu = eth_change_mtu, |
| 295 | #ifdef CONFIG_NET_POLL_CONTROLLER |
| 296 | .ndo_poll_controller = at91ether_poll_controller, |
| 297 | #endif |
| 298 | }; |
| 299 | |
Jean-Christophe PLAGNIOL-VILLARD | 96f6360 | 2012-11-04 21:34:51 +0000 | [diff] [blame] | 300 | #if defined(CONFIG_OF) |
| 301 | static const struct of_device_id at91ether_dt_ids[] = { |
| 302 | { .compatible = "cdns,at91rm9200-emac" }, |
| 303 | { .compatible = "cdns,emac" }, |
| 304 | { /* sentinel */ } |
| 305 | }; |
| 306 | |
| 307 | MODULE_DEVICE_TABLE(of, at91ether_dt_ids); |
| 308 | |
| 309 | static int at91ether_get_phy_mode_dt(struct platform_device *pdev) |
| 310 | { |
| 311 | struct device_node *np = pdev->dev.of_node; |
| 312 | |
| 313 | if (np) |
| 314 | return of_get_phy_mode(np); |
| 315 | |
| 316 | return -ENODEV; |
| 317 | } |
| 318 | |
| 319 | static int at91ether_get_hwaddr_dt(struct macb *bp) |
| 320 | { |
| 321 | struct device_node *np = bp->pdev->dev.of_node; |
| 322 | |
| 323 | if (np) { |
| 324 | const char *mac = of_get_mac_address(np); |
| 325 | if (mac) { |
| 326 | memcpy(bp->dev->dev_addr, mac, ETH_ALEN); |
| 327 | return 0; |
| 328 | } |
| 329 | } |
| 330 | |
| 331 | return -ENODEV; |
| 332 | } |
| 333 | #else |
| 334 | static int at91ether_get_phy_mode_dt(struct platform_device *pdev) |
| 335 | { |
| 336 | return -ENODEV; |
| 337 | } |
| 338 | static int at91ether_get_hwaddr_dt(struct macb *bp) |
| 339 | { |
| 340 | return -ENODEV; |
| 341 | } |
| 342 | #endif |
| 343 | |
Joachim Eastwood | 50b5ca1 | 2012-11-07 08:14:57 +0000 | [diff] [blame] | 344 | /* Detect MAC & PHY and perform ethernet interface initialization */ |
Andrew Victor | c5f0f83 | 2012-04-26 00:30:42 +0000 | [diff] [blame] | 345 | static int __init at91ether_probe(struct platform_device *pdev) |
| 346 | { |
| 347 | struct macb_platform_data *board_data = pdev->dev.platform_data; |
| 348 | struct resource *regs; |
| 349 | struct net_device *dev; |
Joachim Eastwood | 5e32353d | 2012-10-18 11:01:14 +0000 | [diff] [blame] | 350 | struct phy_device *phydev; |
Joachim Eastwood | 50b5ca1 | 2012-11-07 08:14:57 +0000 | [diff] [blame] | 351 | struct pinctrl *pinctrl; |
Joachim Eastwood | b85008b | 2012-10-18 11:01:10 +0000 | [diff] [blame] | 352 | struct macb *lp; |
Andrew Victor | c5f0f83 | 2012-04-26 00:30:42 +0000 | [diff] [blame] | 353 | int res; |
Joachim Eastwood | 50b5ca1 | 2012-11-07 08:14:57 +0000 | [diff] [blame] | 354 | u32 reg; |
Andrew Victor | c5f0f83 | 2012-04-26 00:30:42 +0000 | [diff] [blame] | 355 | |
| 356 | regs = platform_get_resource(pdev, IORESOURCE_MEM, 0); |
| 357 | if (!regs) |
| 358 | return -ENOENT; |
| 359 | |
Jean-Christophe PLAGNIOL-VILLARD | dea0924 | 2012-11-04 21:34:52 +0000 | [diff] [blame] | 360 | pinctrl = devm_pinctrl_get_select_default(&pdev->dev); |
| 361 | if (IS_ERR(pinctrl)) { |
| 362 | res = PTR_ERR(pinctrl); |
| 363 | if (res == -EPROBE_DEFER) |
| 364 | return res; |
| 365 | |
| 366 | dev_warn(&pdev->dev, "No pinctrl provided\n"); |
| 367 | } |
| 368 | |
Joachim Eastwood | b85008b | 2012-10-18 11:01:10 +0000 | [diff] [blame] | 369 | dev = alloc_etherdev(sizeof(struct macb)); |
Andrew Victor | c5f0f83 | 2012-04-26 00:30:42 +0000 | [diff] [blame] | 370 | if (!dev) |
| 371 | return -ENOMEM; |
| 372 | |
| 373 | lp = netdev_priv(dev); |
Joachim Eastwood | 5e32353d | 2012-10-18 11:01:14 +0000 | [diff] [blame] | 374 | lp->pdev = pdev; |
| 375 | lp->dev = dev; |
Andrew Victor | c5f0f83 | 2012-04-26 00:30:42 +0000 | [diff] [blame] | 376 | spin_lock_init(&lp->lock); |
| 377 | |
Joachim Eastwood | 50b5ca1 | 2012-11-07 08:14:57 +0000 | [diff] [blame] | 378 | /* physical base address */ |
| 379 | dev->base_addr = regs->start; |
Joachim Eastwood | 6397346 | 2012-10-18 11:01:18 +0000 | [diff] [blame] | 380 | lp->regs = devm_ioremap(&pdev->dev, regs->start, resource_size(regs)); |
Joachim Eastwood | f8bded3 | 2012-10-18 11:01:08 +0000 | [diff] [blame] | 381 | if (!lp->regs) { |
Andrew Victor | c5f0f83 | 2012-04-26 00:30:42 +0000 | [diff] [blame] | 382 | res = -ENOMEM; |
| 383 | goto err_free_dev; |
| 384 | } |
| 385 | |
| 386 | /* Clock */ |
Joachim Eastwood | 6397346 | 2012-10-18 11:01:18 +0000 | [diff] [blame] | 387 | lp->pclk = devm_clk_get(&pdev->dev, "ether_clk"); |
Joachim Eastwood | 54f14e4 | 2012-10-18 11:01:11 +0000 | [diff] [blame] | 388 | if (IS_ERR(lp->pclk)) { |
| 389 | res = PTR_ERR(lp->pclk); |
Joachim Eastwood | 6397346 | 2012-10-18 11:01:18 +0000 | [diff] [blame] | 390 | goto err_free_dev; |
Andrew Victor | c5f0f83 | 2012-04-26 00:30:42 +0000 | [diff] [blame] | 391 | } |
Joachim Eastwood | 54f14e4 | 2012-10-18 11:01:11 +0000 | [diff] [blame] | 392 | clk_enable(lp->pclk); |
Andrew Victor | c5f0f83 | 2012-04-26 00:30:42 +0000 | [diff] [blame] | 393 | |
| 394 | /* Install the interrupt handler */ |
| 395 | dev->irq = platform_get_irq(pdev, 0); |
Joachim Eastwood | 6397346 | 2012-10-18 11:01:18 +0000 | [diff] [blame] | 396 | res = devm_request_irq(&pdev->dev, dev->irq, at91ether_interrupt, 0, dev->name, dev); |
| 397 | if (res) |
Andrew Victor | c5f0f83 | 2012-04-26 00:30:42 +0000 | [diff] [blame] | 398 | goto err_disable_clock; |
Andrew Victor | c5f0f83 | 2012-04-26 00:30:42 +0000 | [diff] [blame] | 399 | |
Andrew Victor | c5f0f83 | 2012-04-26 00:30:42 +0000 | [diff] [blame] | 400 | ether_setup(dev); |
| 401 | dev->netdev_ops = &at91ether_netdev_ops; |
Joachim Eastwood | 5e32353d | 2012-10-18 11:01:14 +0000 | [diff] [blame] | 402 | dev->ethtool_ops = &macb_ethtool_ops; |
Andrew Victor | c5f0f83 | 2012-04-26 00:30:42 +0000 | [diff] [blame] | 403 | platform_set_drvdata(pdev, dev); |
| 404 | SET_NETDEV_DEV(dev, &pdev->dev); |
| 405 | |
Jean-Christophe PLAGNIOL-VILLARD | 96f6360 | 2012-11-04 21:34:51 +0000 | [diff] [blame] | 406 | res = at91ether_get_hwaddr_dt(lp); |
| 407 | if (res < 0) |
Joachim Eastwood | 3423247 | 2012-11-07 08:14:53 +0000 | [diff] [blame] | 408 | macb_get_hwaddr(lp); |
Andrew Victor | c5f0f83 | 2012-04-26 00:30:42 +0000 | [diff] [blame] | 409 | |
Jean-Christophe PLAGNIOL-VILLARD | 96f6360 | 2012-11-04 21:34:51 +0000 | [diff] [blame] | 410 | res = at91ether_get_phy_mode_dt(pdev); |
| 411 | if (res < 0) { |
| 412 | if (board_data && board_data->is_rmii) |
| 413 | lp->phy_interface = PHY_INTERFACE_MODE_RMII; |
| 414 | else |
| 415 | lp->phy_interface = PHY_INTERFACE_MODE_MII; |
| 416 | } else { |
| 417 | lp->phy_interface = res; |
| 418 | } |
| 419 | |
Joachim Eastwood | f8bded3 | 2012-10-18 11:01:08 +0000 | [diff] [blame] | 420 | macb_writel(lp, NCR, 0); |
Andrew Victor | c5f0f83 | 2012-04-26 00:30:42 +0000 | [diff] [blame] | 421 | |
Joachim Eastwood | 50b5ca1 | 2012-11-07 08:14:57 +0000 | [diff] [blame] | 422 | reg = MACB_BF(CLK, MACB_CLK_DIV32) | MACB_BIT(BIG); |
Jean-Christophe PLAGNIOL-VILLARD | 96f6360 | 2012-11-04 21:34:51 +0000 | [diff] [blame] | 423 | if (lp->phy_interface == PHY_INTERFACE_MODE_RMII) |
Joachim Eastwood | 50b5ca1 | 2012-11-07 08:14:57 +0000 | [diff] [blame] | 424 | reg |= MACB_BIT(RM9200_RMII); |
| 425 | |
| 426 | macb_writel(lp, NCFGR, reg); |
Andrew Victor | c5f0f83 | 2012-04-26 00:30:42 +0000 | [diff] [blame] | 427 | |
Andrew Victor | c5f0f83 | 2012-04-26 00:30:42 +0000 | [diff] [blame] | 428 | /* Register the network interface */ |
| 429 | res = register_netdev(dev); |
| 430 | if (res) |
Joachim Eastwood | 6397346 | 2012-10-18 11:01:18 +0000 | [diff] [blame] | 431 | goto err_disable_clock; |
Andrew Victor | c5f0f83 | 2012-04-26 00:30:42 +0000 | [diff] [blame] | 432 | |
Joachim Eastwood | 5e32353d | 2012-10-18 11:01:14 +0000 | [diff] [blame] | 433 | if (macb_mii_init(lp) != 0) |
| 434 | goto err_out_unregister_netdev; |
| 435 | |
Joachim Eastwood | 50b5ca1 | 2012-11-07 08:14:57 +0000 | [diff] [blame] | 436 | /* will be enabled in open() */ |
| 437 | netif_carrier_off(dev); |
Andrew Victor | c5f0f83 | 2012-04-26 00:30:42 +0000 | [diff] [blame] | 438 | |
Joachim Eastwood | 5e32353d | 2012-10-18 11:01:14 +0000 | [diff] [blame] | 439 | phydev = lp->phy_dev; |
| 440 | netdev_info(dev, "attached PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n", |
Joachim Eastwood | 50b5ca1 | 2012-11-07 08:14:57 +0000 | [diff] [blame] | 441 | phydev->drv->name, dev_name(&phydev->dev), |
| 442 | phydev->irq); |
Andrew Victor | c5f0f83 | 2012-04-26 00:30:42 +0000 | [diff] [blame] | 443 | |
| 444 | /* Display ethernet banner */ |
Joachim Eastwood | ed2b97d | 2012-11-07 08:14:56 +0000 | [diff] [blame] | 445 | netdev_info(dev, "AT91 ethernet at 0x%08lx int=%d (%pM)\n", |
| 446 | dev->base_addr, dev->irq, dev->dev_addr); |
Andrew Victor | c5f0f83 | 2012-04-26 00:30:42 +0000 | [diff] [blame] | 447 | |
| 448 | return 0; |
| 449 | |
Joachim Eastwood | 5e32353d | 2012-10-18 11:01:14 +0000 | [diff] [blame] | 450 | err_out_unregister_netdev: |
| 451 | unregister_netdev(dev); |
Andrew Victor | c5f0f83 | 2012-04-26 00:30:42 +0000 | [diff] [blame] | 452 | err_disable_clock: |
Joachim Eastwood | 54f14e4 | 2012-10-18 11:01:11 +0000 | [diff] [blame] | 453 | clk_disable(lp->pclk); |
Andrew Victor | c5f0f83 | 2012-04-26 00:30:42 +0000 | [diff] [blame] | 454 | err_free_dev: |
| 455 | free_netdev(dev); |
| 456 | return res; |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 457 | } |
| 458 | |
Bill Pemberton | 37a5b3d | 2012-12-03 09:23:57 -0500 | [diff] [blame] | 459 | static int at91ether_remove(struct platform_device *pdev) |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 460 | { |
Andrew Victor | c57ee09 | 2006-12-05 15:09:16 +0200 | [diff] [blame] | 461 | struct net_device *dev = platform_get_drvdata(pdev); |
Joachim Eastwood | b85008b | 2012-10-18 11:01:10 +0000 | [diff] [blame] | 462 | struct macb *lp = netdev_priv(dev); |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 463 | |
Joachim Eastwood | 5e32353d | 2012-10-18 11:01:14 +0000 | [diff] [blame] | 464 | if (lp->phy_dev) |
| 465 | phy_disconnect(lp->phy_dev); |
David Brownell | 71527ef | 2008-10-27 14:11:34 -0700 | [diff] [blame] | 466 | |
Joachim Eastwood | 5e32353d | 2012-10-18 11:01:14 +0000 | [diff] [blame] | 467 | mdiobus_unregister(lp->mii_bus); |
| 468 | kfree(lp->mii_bus->irq); |
| 469 | mdiobus_free(lp->mii_bus); |
Andrew Victor | c57ee09 | 2006-12-05 15:09:16 +0200 | [diff] [blame] | 470 | unregister_netdev(dev); |
Joachim Eastwood | 5e32353d | 2012-10-18 11:01:14 +0000 | [diff] [blame] | 471 | clk_disable(lp->pclk); |
Andrew Victor | c57ee09 | 2006-12-05 15:09:16 +0200 | [diff] [blame] | 472 | free_netdev(dev); |
Joachim Eastwood | 5e32353d | 2012-10-18 11:01:14 +0000 | [diff] [blame] | 473 | platform_set_drvdata(pdev, NULL); |
| 474 | |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 475 | return 0; |
| 476 | } |
| 477 | |
Andrew Victor | 00e5edc | 2006-06-20 12:19:13 +0200 | [diff] [blame] | 478 | #ifdef CONFIG_PM |
Andrew Victor | 00e5edc | 2006-06-20 12:19:13 +0200 | [diff] [blame] | 479 | static int at91ether_suspend(struct platform_device *pdev, pm_message_t mesg) |
| 480 | { |
Andrew Victor | 00e5edc | 2006-06-20 12:19:13 +0200 | [diff] [blame] | 481 | struct net_device *net_dev = platform_get_drvdata(pdev); |
Joachim Eastwood | b85008b | 2012-10-18 11:01:10 +0000 | [diff] [blame] | 482 | struct macb *lp = netdev_priv(net_dev); |
Andrew Victor | 00e5edc | 2006-06-20 12:19:13 +0200 | [diff] [blame] | 483 | |
| 484 | if (netif_running(net_dev)) { |
Andrew Victor | 00e5edc | 2006-06-20 12:19:13 +0200 | [diff] [blame] | 485 | netif_stop_queue(net_dev); |
| 486 | netif_device_detach(net_dev); |
| 487 | |
Joachim Eastwood | 54f14e4 | 2012-10-18 11:01:11 +0000 | [diff] [blame] | 488 | clk_disable(lp->pclk); |
Andrew Victor | 00e5edc | 2006-06-20 12:19:13 +0200 | [diff] [blame] | 489 | } |
| 490 | return 0; |
| 491 | } |
| 492 | |
| 493 | static int at91ether_resume(struct platform_device *pdev) |
| 494 | { |
Andrew Victor | 00e5edc | 2006-06-20 12:19:13 +0200 | [diff] [blame] | 495 | struct net_device *net_dev = platform_get_drvdata(pdev); |
Joachim Eastwood | b85008b | 2012-10-18 11:01:10 +0000 | [diff] [blame] | 496 | struct macb *lp = netdev_priv(net_dev); |
Andrew Victor | 00e5edc | 2006-06-20 12:19:13 +0200 | [diff] [blame] | 497 | |
| 498 | if (netif_running(net_dev)) { |
Joachim Eastwood | 54f14e4 | 2012-10-18 11:01:11 +0000 | [diff] [blame] | 499 | clk_enable(lp->pclk); |
Andrew Victor | 00e5edc | 2006-06-20 12:19:13 +0200 | [diff] [blame] | 500 | |
| 501 | netif_device_attach(net_dev); |
| 502 | netif_start_queue(net_dev); |
Andrew Victor | 00e5edc | 2006-06-20 12:19:13 +0200 | [diff] [blame] | 503 | } |
| 504 | return 0; |
| 505 | } |
Andrew Victor | 00e5edc | 2006-06-20 12:19:13 +0200 | [diff] [blame] | 506 | #else |
| 507 | #define at91ether_suspend NULL |
| 508 | #define at91ether_resume NULL |
| 509 | #endif |
| 510 | |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 511 | static struct platform_driver at91ether_driver = { |
Bill Pemberton | 37a5b3d | 2012-12-03 09:23:57 -0500 | [diff] [blame] | 512 | .remove = at91ether_remove, |
Andrew Victor | 00e5edc | 2006-06-20 12:19:13 +0200 | [diff] [blame] | 513 | .suspend = at91ether_suspend, |
| 514 | .resume = at91ether_resume, |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 515 | .driver = { |
Joachim Eastwood | 50b5ca1 | 2012-11-07 08:14:57 +0000 | [diff] [blame] | 516 | .name = "at91_ether", |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 517 | .owner = THIS_MODULE, |
Jean-Christophe PLAGNIOL-VILLARD | 96f6360 | 2012-11-04 21:34:51 +0000 | [diff] [blame] | 518 | .of_match_table = of_match_ptr(at91ether_dt_ids), |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 519 | }, |
| 520 | }; |
| 521 | |
| 522 | static int __init at91ether_init(void) |
| 523 | { |
Uwe Kleine-König | 78a9c9c | 2009-07-21 10:11:39 +0000 | [diff] [blame] | 524 | return platform_driver_probe(&at91ether_driver, at91ether_probe); |
Andrew Victor | d4b7780 | 2006-03-24 11:50:17 +0200 | [diff] [blame] | 525 | } |
| 526 | |
| 527 | static void __exit at91ether_exit(void) |
| 528 | { |
| 529 | platform_driver_unregister(&at91ether_driver); |
| 530 | } |
| 531 | |
| 532 | module_init(at91ether_init) |
| 533 | module_exit(at91ether_exit) |
| 534 | |
| 535 | MODULE_LICENSE("GPL"); |
| 536 | MODULE_DESCRIPTION("AT91RM9200 EMAC Ethernet driver"); |
| 537 | MODULE_AUTHOR("Andrew Victor"); |
Joachim Eastwood | 50b5ca1 | 2012-11-07 08:14:57 +0000 | [diff] [blame] | 538 | MODULE_ALIAS("platform:at91_ether"); |