code style scripts/checkpatch.pl (linux-3.9-rc1) formatting
[linux-2.6.34.14-moxart.git] / drivers / net / arm / moxart_ether.c
blob48839029049cdd030364c1f677e2917ccde263b7
1 /* MOXART Ethernet (RTL8201CP) Device Driver (based on MOXA sources)
2 * Copyright (C) 2013 Jonas Jensen <jonas.jensen@gmail.com>
3 * This program is free software; you can redistribute it and/or modify it
4 * under the terms of the GNU General Public License as published by the
5 * Free Software Foundation; either version 2 of the License,
6 * or (at your option) any later version.
7 */
9 #include <linux/module.h>
10 #include <linux/init.h>
11 #include <linux/netdevice.h>
12 #include <linux/etherdevice.h>
13 #include <linux/skbuff.h>
14 #include <linux/dma-mapping.h>
15 #include <linux/ethtool.h>
16 #include <linux/platform_device.h>
18 #include <mach/hardware.h>
19 #include <mach/board.h>
21 #include "moxart_ether.h"
23 #define DRV_NAME "moxart_ether"
24 #define DRV_VERSION "1.0"
26 static inline unsigned long moxart_emac_read(struct net_device *dev,
27 unsigned int reg)
29 void __iomem *emac_base = (void __iomem *)dev->base_addr;
30 return __raw_readl(emac_base + reg);
33 static inline void moxart_emac_write(struct net_device *dev,
34 unsigned int reg, unsigned long value)
36 void __iomem *emac_base = (void __iomem *)dev->base_addr;
37 __raw_writel(value, emac_base + reg);
40 /* Program the hardware MAC address from dev->dev_addr */
41 static void moxart_update_mac_address(struct net_device *dev)
43 moxart_emac_write(dev, MAC_MADR_REG_OFFSET,
44 ((dev->dev_addr[0] << 8) | (dev->dev_addr[1])));
45 moxart_emac_write(dev, MAC_MADR_REG_OFFSET + 4,
46 ((dev->dev_addr[2] << 24) | (dev->dev_addr[3] << 16) |
47 (dev->dev_addr[4] << 8) | (dev->dev_addr[5])));
48 dbg_printk(
49 "MOXART Ethernet: moxart_update_mac_address baddr=%x MAC=%x%x\n"
50 , (unsigned int) dev->base_addr,
51 __raw_readl(dev->base_addr + MAC_MADR_REG_OFFSET),
52 __raw_readl(dev->base_addr + MAC_MADR_REG_OFFSET + 4));
55 static int moxart_set_mac_address(struct net_device *dev, void *addr)
57 struct sockaddr *address = addr;
59 if (!is_valid_ether_addr(address->sa_data))
60 return -EADDRNOTAVAIL;
63 memcpy(dev->dev_addr, address->sa_data, dev->addr_len);
64 moxart_update_mac_address(dev);
66 dbg_printk(
67 "MOXART Ethernet: moxart_set_mac_address dev->base_addr=%x\n"
68 , (unsigned int) dev->base_addr);
69 return 0;
72 static void moxart_mac_free_memory(struct net_device *dev)
74 struct moxart_mac_priv_t *priv = netdev_priv(dev);
75 if (priv->virt_tx_desc_baseaddr)
76 dma_free_coherent(NULL, sizeof(struct tx_desc_t)*TX_DESC_NUM,
77 priv->virt_tx_desc_baseaddr,
78 priv->phy_tx_desc_baseaddr);
79 if (priv->virt_rx_desc_baseaddr)
80 dma_free_coherent(NULL, sizeof(struct rx_desc_t)*RX_DESC_NUM,
81 priv->virt_rx_desc_baseaddr,
82 priv->phy_rx_desc_baseaddr);
83 if (priv->virt_tx_buf_baseaddr)
84 dma_free_coherent(NULL, TX_BUF_SIZE*TX_DESC_NUM,
85 priv->virt_tx_buf_baseaddr,
86 priv->phy_tx_buf_baseaddr);
87 if (priv->virt_rx_buf_baseaddr)
88 dma_free_coherent(NULL, RX_BUF_SIZE*RX_DESC_NUM,
89 priv->virt_rx_buf_baseaddr,
90 priv->phy_rx_buf_baseaddr);
93 static void moxart_mac_reset(struct net_device *dev)
95 struct moxart_mac_priv_t *priv = netdev_priv(dev);
96 outl(SW_RST, dev->base_addr + MACCR_REG_OFFSET);
97 while (inl(dev->base_addr + MACCR_REG_OFFSET) & SW_RST)
98 mdelay(10);
100 /* maybe we need to disable the all interrupt */
101 outl(0, dev->base_addr + IMR_REG_OFFSET);
103 /* removed ENRX_IN_HALFTX. RX_FTL added for 802.1Q support */
104 priv->maccr = RX_BROADPKT | FULLDUP | CRC_APD | RX_FTL;
106 dbg_printk(
107 "MOXART Ethernet: moxart_mac_reset dev->base_addr=%x\n"
108 , (unsigned int) dev->base_addr);
111 static void moxart_mac_enable(struct net_device *dev)
113 struct moxart_mac_priv_t *priv = netdev_priv(dev);
114 outl(0x00001010, dev->base_addr + ITC_REG_OFFSET);
115 outl(0x00000001, dev->base_addr + APTC_REG_OFFSET);
116 outl(0x00000390, dev->base_addr + DBLAC_REG_OFFSET);
118 /* use NORXBUF_M to test interrupt */
119 /* outl(RPKT_FINISH_M | NORXBUF_M | AHB_ERR_M,
120 dev->base_addr + IMR_REG_OFFSET);
123 outl(RPKT_FINISH_M, dev->base_addr + IMR_REG_OFFSET);
124 priv->maccr |= (RCV_EN | XMT_EN | RDMA_EN | XDMA_EN);
125 outl(priv->maccr, dev->base_addr + MACCR_REG_OFFSET);
127 dbg_printk(
128 "MOXART Ethernet: moxart_mac_enable dev->base=%x\n"
129 , (unsigned int) dev->base_addr);
132 static void moxart_mac_setup_desc_ring(struct net_device *dev)
134 struct moxart_mac_priv_t *priv = netdev_priv(dev);
135 struct tx_desc_t *txdesc;
136 struct rx_desc_t *rxdesc;
137 unsigned char *virtbuf;
138 unsigned int phybuf;
139 int i;
141 virtbuf = priv->virt_tx_buf_baseaddr;
142 phybuf = priv->phy_tx_buf_baseaddr;
143 for (i = 0; i < TX_DESC_NUM; i++,
144 virtbuf += TX_BUF_SIZE, phybuf += TX_BUF_SIZE) {
145 txdesc = &priv->virt_tx_desc_baseaddr[i];
146 memset(txdesc, 0, sizeof(struct tx_desc_t));
147 txdesc->txdes2.phy_tx_buf_baseaddr = phybuf;
148 txdesc->txdes2.virt_tx_buf_baseaddr = virtbuf;
150 priv->virt_tx_desc_baseaddr[TX_DESC_NUM - 1].txdes1.ubit.edotr = 1;
152 virtbuf = priv->virt_rx_buf_baseaddr;
153 phybuf = priv->phy_rx_buf_baseaddr;
154 for (i = 0; i < RX_DESC_NUM; i++,
155 virtbuf += RX_BUF_SIZE, phybuf += RX_BUF_SIZE) {
156 rxdesc = &priv->virt_rx_desc_baseaddr[i];
157 memset(rxdesc, 0, sizeof(struct rx_desc_t));
158 rxdesc->rxdes0.ubit.rx_dma_own = 1;
159 rxdesc->rxdes1.ubit.rx_buf_size = RX_BUF_SIZE;
160 rxdesc->rxdes2.phy_rx_buf_baseaddr = phybuf;
161 rxdesc->rxdes2.virt_rx_buf_baseaddr = virtbuf;
163 priv->virt_rx_desc_baseaddr[RX_DESC_NUM - 1].rxdes1.ubit.edorr = 1;
164 /* dbg_printk("First Rx desc des0=0x%x, des1=%x\n",
165 priv->virt_rx_desc_baseaddr[0].rxdes0.ui,
166 priv->virt_rx_desc_baseaddr[0].rxdes1.ui);
169 priv->tx_desc_now = priv->rx_desc_now = 0;
171 /* reset the MAC controler Tx/Rx desciptor base address */
172 outl(priv->phy_tx_desc_baseaddr, dev->base_addr + TXR_BADR_REG_OFFSET);
173 outl(priv->phy_rx_desc_baseaddr, dev->base_addr + RXR_BADR_REG_OFFSET);
175 dbg_printk(
176 "MOXART Ethernet: moxart_mac_setup_desc_ring base_addr=%x\n"
177 "Tx/Rx desc phy=0x%x,0x%x, virt=0x%x,0x%x\n"
178 "set Tx desc base address=0x%x, Rx=0x%x\n",
179 (unsigned int) dev->base_addr, priv->phy_tx_desc_baseaddr,
180 priv->phy_rx_desc_baseaddr,
181 (unsigned int)priv->virt_tx_desc_baseaddr,
182 (unsigned int)priv->virt_rx_desc_baseaddr,
183 inl(dev->base_addr+TXR_BADR_REG_OFFSET),
184 inl(dev->base_addr+RXR_BADR_REG_OFFSET));
187 static int moxart_mac_open(struct net_device *dev)
189 struct moxart_mac_priv_t *priv = netdev_priv(dev);
190 if (!is_valid_ether_addr(dev->dev_addr))
191 return -EADDRNOTAVAIL;
192 spin_lock_irq(&priv->txlock);
193 moxart_mac_reset(dev);
194 moxart_update_mac_address(dev);
195 moxart_mac_setup_desc_ring(dev);
196 moxart_mac_enable(dev);
197 spin_unlock_irq(&priv->txlock);
198 netif_start_queue(dev);
200 dbg_printk("MOXART Ethernet: moxart_mac_open IMR=0x%x, MACCR=0x%x\n"
201 , inl(dev->base_addr+IMR_REG_OFFSET),
202 inl(dev->base_addr+MACCR_REG_OFFSET));
203 return 0;
206 static int moxart_mac_stop(struct net_device *dev)
208 struct moxart_mac_priv_t *priv = netdev_priv(dev);
209 netif_stop_queue(dev);
210 spin_lock_irq(&priv->txlock);
212 /* disable all interrupt */
213 outl(0, dev->base_addr + IMR_REG_OFFSET);
215 /* disable all function */
216 outl(0, dev->base_addr + MACCR_REG_OFFSET);
218 spin_unlock_irq(&priv->txlock);
220 dbg_printk("MOXART Ethernet: finished moxart_mac_stop\n");
221 return 0;
224 static void moxart_mac_recv(struct work_struct *ptr)
226 struct net_device *dev = (struct net_device *) ptr;
227 struct moxart_mac_priv_t *priv = netdev_priv((struct net_device *)ptr);
228 struct rx_desc_t *rxdesc;
229 struct sk_buff *skb;
230 unsigned int ui, len;
231 int rxnow = priv->rx_desc_now;
232 int loops = RX_DESC_NUM;
234 /* dbg_printk("MOXART Ethernet: moxart_mac_recv\n"); */
236 /*dbg_printk("rx_desc_now=%d, desc phy=0x%x, virt=0x%x, buf phy=0x%x,
237 virt=0x%x\n", priv->rx_desc_now,
238 priv->phy_rx_desc_baseaddr+
239 (priv->rx_desc_now*sizeof(rx_desc_t)),
240 (unsigned int)&priv->virt_rx_desc_baseaddr[priv->rx_desc_now],
241 priv->virt_rx_desc_baseaddr[priv->rx_desc_now]
242 .rxdes2.phy_rx_buf_baseaddr,
243 (unsigned int)priv->virt_rx_desc_baseaddr[priv->rx_desc_now]
244 .rxdes2.virt_rx_buf_baseaddr);
245 dbg_printk("Now Rx desc des0=0x%x, des1=0x%x\n",
246 priv->virt_rx_desc_baseaddr[priv->rx_desc_now].rxdes0.ui,
247 priv->virt_rx_desc_baseaddr[priv->rx_desc_now].rxdes1.ui);
250 repeat_recv:
251 rxdesc = &priv->virt_rx_desc_baseaddr[rxnow];
252 ui = rxdesc->rxdes0.ui;
254 /* if ( rxdesc->rxdes0.ubit.RxDMAOwn ) { */
255 if (ui & RXDMA_OWN)
256 return;
258 if (ui & (RX_ERR | CRC_ERR | FTL | RUNT | RX_ODD_NB)) {
259 dbg_printk("MOXART Ethernet: packet error !\n");
260 priv->stats.rx_dropped++;
261 priv->stats.rx_errors++;
262 goto recv_finish;
265 len = ui & RFL_MASK;
267 if (len > RX_BUF_SIZE)
268 len = RX_BUF_SIZE;
270 skb = dev_alloc_skb(len + 2);
271 if (skb == NULL) {
272 dbg_printk("Allocate memory fail !\n");
273 priv->stats.rx_dropped++;
274 goto recv_finish;
276 skb_reserve(skb, 2);
277 skb->dev = dev;
279 memcpy(skb_put(skb, len), rxdesc->rxdes2.virt_rx_buf_baseaddr, len);
280 netif_rx(skb);
282 /* dbg_printk("MOXART Ethernet: receive data pointer = 0x%x\n",
283 (unsigned long)data);
286 skb->protocol = eth_type_trans(skb, dev);
287 dev->last_rx = jiffies;
288 priv->stats.rx_packets++;
289 priv->stats.rx_bytes += len;
290 if (ui & MULTICAST_RXDES0)
291 priv->stats.multicast++;
293 recv_finish:
294 rxdesc->rxdes0.ui = RXDMA_OWN;
295 rxnow++;
296 rxnow &= RX_DESC_NUM_MASK;
297 priv->rx_desc_now = rxnow;
298 if (loops-- > 0)
299 goto repeat_recv;
302 static irqreturn_t moxart_mac_interrupt(int irq, void *dev_id)
304 struct net_device *dev = (struct net_device *) dev_id;
305 unsigned int ists = inl(dev->base_addr + ISR_REG_OFFSET);
307 /* dbg_printk("MOXART Ethernet: moxart_mac_interrupt\n"); */
309 if (ists & RPKT_FINISH) {
310 moxart_mac_recv((void *) dev);
311 } else {
312 #ifdef MOXART_MAC_DEBUG
313 if (ists & NORXBUF) {
314 dbg_printk("MOXART Ethernet: NORXBUF interrupt\n");
315 outl(inl(dev->base_addr + IMR_REG_OFFSET) & ~NORXBUF_M,
316 dev->base_addr + IMR_REG_OFFSET);
318 if (ists & AHB_ERR)
319 dbg_printk("MOXART Ethernet: AHB_ERR interrupt.\n");
320 #endif
322 return IRQ_HANDLED;
325 static int moxart_mac_start_xmit(struct sk_buff *skb, struct net_device *dev)
327 struct moxart_mac_priv_t *priv = netdev_priv(dev);
328 struct tx_desc_t *txdesc;
329 int len;
330 int txnow = priv->tx_desc_now;
332 /* dbg_printk("MOXART Ethernet: moxart_mac_hard_start_xmit\n"); */
334 spin_lock_irq(&priv->txlock);
335 txdesc = &priv->virt_tx_desc_baseaddr[txnow];
336 if (txdesc->txdes0.ubit.tx_dma_own) {
337 dbg_printk(
338 "MOXART Ethernet: no Tx space for packet!\n");
339 priv->stats.tx_dropped++;
340 goto xmit_final;
344 /*len = skb->len < ETH_ZLEN ? ETH_ZLEN : skb->len;
345 len = len > TX_BUF_SIZE ? TX_BUF_SIZE : len;
348 len = skb->len > TX_BUF_SIZE ? TX_BUF_SIZE : skb->len;
349 memcpy(txdesc->txdes2.virt_tx_buf_baseaddr, skb->data, len);
351 if (skb->len < ETH_ZLEN) {
352 memset(&txdesc->txdes2.virt_tx_buf_baseaddr[skb->len],
353 0, ETH_ZLEN - skb->len);
354 len = ETH_ZLEN;
357 txdesc->txdes1.ubit.lts = 1;
358 txdesc->txdes1.ubit.fts = 1;
359 txdesc->txdes1.ubit.tx2_fic = 0;
360 txdesc->txdes1.ubit.tx_ic = 0;
361 txdesc->txdes1.ubit.tx_buf_size = len;
362 txdesc->txdes0.ui = TXDMA_OWN;
364 dbg_printk("MOXART Ethernet: transmit data pointer = 0x%x\n",
365 (unsigned int)skb->data);
367 /* start to send packet */
368 outl(0xffffffff, dev->base_addr + TXPD_REG_OFFSET);
370 /*dbg_printk("tx_desc_now=%d, address=0x%x, des0=0x%x,
371 des1=0x%x\n", priv->tx_desc_now,
372 (unsigned int)&priv->virt_tx_desc_baseaddr[priv->tx_desc_now],
373 txdesc->txdes0.ui, txdesc->txdes1.ui);
374 dbg_printk("Buffer phy address=0x%x, virt=0x%x\n",
375 txdesc->txdes2.phy_tx_buf_baseaddr,
376 (unsigned int)txdesc->txdes2.virt_tx_buf_baseaddr);
377 dbg_printk("tx_desc_now-1=%d, address=0x%x, des0=0x%x\n",
378 (priv->tx_desc_now-1)&TX_DESC_NUM_MASK,
379 (unsigned int)&priv->virt_tx_desc_baseaddr[(priv->tx_desc_now-1)
380 &TX_DESC_NUM_MASK],
381 priv->virt_tx_desc_baseaddr[(priv->tx_desc_now-1)
382 &TX_DESC_NUM_MASK].txdes0.ui);
385 txnow++;
386 txnow &= TX_DESC_NUM_MASK;
387 priv->tx_desc_now = txnow;
388 dev->trans_start = jiffies;
389 priv->stats.tx_packets++;
390 priv->stats.tx_bytes += len;
392 xmit_final:
393 spin_unlock_irq(&priv->txlock);
394 dev_kfree_skb_any(skb);
396 return NETDEV_TX_OK;
399 static struct net_device_stats *moxart_mac_get_stats(struct net_device *dev)
401 struct moxart_mac_priv_t *priv = netdev_priv(dev);
402 int desc = priv->rx_desc_now;
403 #ifdef MOXART_DEBUG
404 unsigned int base = dev->base_addr;
405 #endif
407 dbg_printk("MOXART Ethernet: moxart_mac_get_stats:\n");
408 dbg_printk(
409 "rx_desc_now=%d, desc phy=0x%x, virt=0x%x, buf phy=0x%x\n"
410 "virt=0x%x Now Rx desc des0=0x%x, des1=0x%x\n", desc,
411 priv->phy_rx_desc_baseaddr+(desc*sizeof(rx_desc_t)),
412 (unsigned int)&priv->virt_rx_desc_baseaddr[desc],
413 priv->virt_rx_desc_baseaddr[desc].rxdes2.phy_rx_buf_baseaddr,
414 (unsigned int)priv->virt_rx_desc_baseaddr[desc]
415 .rxdes2.virt_rx_buf_baseaddr,
416 priv->virt_rx_desc_baseaddr[desc].rxdes0.ui,
417 priv->virt_rx_desc_baseaddr[desc].rxdes1.ui);
418 desc++;
419 desc &= RX_DESC_NUM_MASK;
420 dbg_printk(
421 "rx_desc_now=%d, desc phy=0x%x, virt=0x%x, buf phy=0x%x\n"
422 "virt=0x%x Now Rx desc des0=0x%x, des1=0x%x (desc++)\n",
423 desc, priv->phy_rx_desc_baseaddr+(desc*sizeof(rx_desc_t)),
424 (unsigned int)&priv->virt_rx_desc_baseaddr[desc],
425 priv->virt_rx_desc_baseaddr[desc].rxdes2.phy_rx_buf_baseaddr,
426 (unsigned int)priv->virt_rx_desc_baseaddr[desc]
427 .rxdes2.virt_rx_buf_baseaddr,
428 priv->virt_rx_desc_baseaddr[desc].rxdes0.ui,
429 priv->virt_rx_desc_baseaddr[desc].rxdes1.ui);
430 dbg_printk(
431 "TX_MCOL_TX_SCOL=0x%x RPF_AEP=0x%x XM_PG=0x%x\n"
432 " RUNT_CNT_TLCC=0x%x CRCER_CNT_FTL_CNT=0x%x RLC_RCC=0x%x\n"
433 " BROC=0x%x MUCLA=0x%x RP=0x%x XP=0x%x\n",
434 inl(base+TX_MCOL_TX_SCOL_REG_OFFSET),
435 inl(base+RPF_AEP_REG_OFFSET), inl(base+XM_PG_REG_OFFSET),
436 inl(base+RUNT_CNT_TLCC_REG_OFFSET),
437 inl(base+CRCER_CNT_FTL_CNT_REG_OFFSET),
438 inl(base+RLC_RCC_REG_OFFSET), inl(base+BROC_REG_OFFSET),
439 inl(base+MULCA_REG_OFFSET), inl(base+RP_REG_OFFSET),
440 inl(base+XP_REG_OFFSET));
442 return &priv->stats;
445 #ifdef HAVE_MULTICAST
447 static int crc32(char *s, int length)
449 int per_byte;
450 int per_bit;
452 /* crc polynomial */
453 const unsigned long poly = 0xedb88320;
455 /* crc value - preinitialized to all 1's */
456 unsigned long crc_value = 0xffffffff;
458 for (per_byte = 0; per_byte < length; per_byte++) {
459 unsigned char c;
460 c = *(s++);
461 for (per_bit = 0; per_bit < 8; per_bit++) {
462 crc_value = (crc_value >> 1) ^
463 (((crc_value ^ c) & 0x01) ? poly : 0);
464 c >>= 1;
467 return crc_value;
470 static void moxart_mac_setmulticast(unsigned int ioaddr,
471 int count, struct dev_mc_list *addrs)
473 struct dev_mc_list *cur_addr;
474 int crc_val;
476 for (cur_addr = addrs; cur_addr != NULL; cur_addr = cur_addr->next) {
477 if (!(*cur_addr->dmi_addr & 1))
478 continue;
479 crc_val = crc32(cur_addr->dmi_addr, 6);
480 crc_val = (crc_val >> 26) & 0x3f; /* MSB 6 bit */
481 if (crc_val >= 32) {
482 outl(inl(ioaddr + MATH1_REG_OFFSET) |
483 (1UL << (crc_val - 32)),
484 ioaddr + MATH1_REG_OFFSET);
485 } else {
486 outl(inl(ioaddr + MATH0_REG_OFFSET) | (1UL << crc_val),
487 ioaddr + MATH0_REG_OFFSET);
492 static void moxart_mac_set_multicast_list(struct net_device *dev)
494 struct moxart_mac_priv_t *priv = netdev_priv(dev);
496 spin_lock_irq(&priv->txlock);
498 (dev->flags & IFF_PROMISC) ? (priv->maccr |= RCV_ALL) :
499 (priv->maccr &= ~RCV_ALL);
500 (dev->flags & IFF_ALLMULTI) ? (priv->maccr |= RX_MULTIPKT) :
501 (priv->maccr &= ~RX_MULTIPKT);
503 if (dev->mc_count) {
504 priv->maccr |= HT_MULTI_EN;
505 moxart_mac_setmulticast(dev->base_addr,
506 dev->mc_count, dev->mc_list);
507 } else {
508 priv->maccr &= ~HT_MULTI_EN;
511 outl(priv->maccr, dev->base_addr + MACCR_REG_OFFSET);
513 spin_unlock_irq(&priv->txlock);
516 #endif /* HAVE_MULTICAST */
518 static struct net_device_ops moxart_netdev_ops = {
519 .ndo_open = moxart_mac_open,
520 .ndo_stop = moxart_mac_stop,
521 .ndo_start_xmit = moxart_mac_start_xmit,
522 .ndo_get_stats = moxart_mac_get_stats,
523 #ifdef HAVE_MULTICAST
524 .ndo_set_multicast_list = moxart_mac_set_multicast_list,
525 #endif
526 .ndo_set_mac_address = moxart_set_mac_address,
527 /* .ndo_do_ioctl = moxart_mac_iotcl, */
528 .ndo_validate_addr = eth_validate_addr,
529 .ndo_change_mtu = eth_change_mtu,
530 /* .ndo_tx_timeout = moxart_mac_tx_timeout,
531 .ndo_init = moxart_mac_init,
535 /*static struct net_device moxart_mac1_dev = {
536 .name = "eth0",
537 .netdev_ops = &moxart_netdev_ops,
540 static struct net_device moxart_mac2_dev = {
541 .name = "eth1",
542 .netdev_ops = &moxart_netdev_ops,
546 /* Get MAC address stored in flash memory and write it to net_device */
547 static void __init moxart_get_mac_address(struct net_device *dev,
548 u8 mac_addr_flash_offset)
550 int i;
551 for (i = 0; i <= 5; i++)
552 dev->dev_addr[i] = inb(IO_ADDRESS(MOXART_FLASH_BASE)
553 + mac_addr_flash_offset + i);
554 dbg_printk(
555 "MOXART Ethernet: get_mac_address dev->base_addr=%x\n"
556 , (unsigned int) dev->base_addr);
559 static int __init moxart_mac_probe(struct platform_device *pdev)
561 struct net_device *dev;
562 struct moxart_mac_priv_t *priv;
563 struct moxart_eth_data *pdata = (struct moxart_eth_data *)
564 pdev->dev.platform_data;
566 dev = alloc_etherdev(sizeof(struct moxart_mac_priv_t));
567 if (!dev)
568 return -ENOMEM;
570 dev->base_addr = pdata->base_addr;
571 dev->irq = pdata->irq;
573 priv = netdev_priv(dev);
575 /* initialize the private variable to zero */
576 /* memset((void *) priv, 0, sizeof(struct moxart_mac_priv_t)); */
578 spin_lock_init(&priv->txlock);
579 priv->virt_tx_desc_baseaddr = (struct tx_desc_t *)
580 dma_alloc_coherent(NULL, sizeof(struct tx_desc_t) * TX_DESC_NUM,
581 (dma_addr_t *)&priv->phy_tx_desc_baseaddr,
582 GFP_DMA | GFP_KERNEL);
583 if (priv->virt_tx_desc_baseaddr == NULL ||
584 (priv->phy_tx_desc_baseaddr & 0x0f)) {
585 netdev_info(dev, "Allocate the Tx descriptor memory fail !\n");
586 goto init_fail;
588 priv->virt_rx_desc_baseaddr = (struct rx_desc_t *)
589 dma_alloc_coherent(NULL, sizeof(struct rx_desc_t) * RX_DESC_NUM,
590 (dma_addr_t *)&priv->phy_rx_desc_baseaddr,
591 GFP_DMA | GFP_KERNEL);
592 if (priv->virt_rx_desc_baseaddr == NULL ||
593 (priv->phy_rx_desc_baseaddr & 0x0f)) {
594 netdev_info(dev, "Allocate the Rx descriptor memory fail !\n");
595 goto init_fail;
597 priv->virt_tx_buf_baseaddr = (unsigned char *)
598 dma_alloc_coherent(NULL, TX_BUF_SIZE * TX_DESC_NUM,
599 (dma_addr_t *)&priv->phy_tx_buf_baseaddr, GFP_DMA | GFP_KERNEL);
600 if (priv->virt_tx_buf_baseaddr == NULL ||
601 (priv->phy_tx_buf_baseaddr & 0x03)) {
602 netdev_info(dev, "Allocate the Tx buffer memory fail !\n");
603 goto init_fail;
605 priv->virt_rx_buf_baseaddr = (unsigned char *)
606 dma_alloc_coherent(NULL, RX_BUF_SIZE * RX_DESC_NUM,
607 (dma_addr_t *)&priv->phy_rx_buf_baseaddr, GFP_DMA | GFP_KERNEL);
608 if (priv->virt_rx_buf_baseaddr == NULL ||
609 (priv->phy_rx_buf_baseaddr & 0x03)) {
610 netdev_info(dev, "Allocate the Rx buffer memory fail !\n");
611 goto init_fail;
613 platform_set_drvdata(pdev, dev);
615 ether_setup(dev);
616 dev->netdev_ops = &moxart_netdev_ops;
618 SET_NETDEV_DEV(dev, &pdev->dev);
620 moxart_get_mac_address(dev, pdata->mac_addr_flash_offset);
621 moxart_update_mac_address(dev);
623 if (register_netdev(dev)) {
624 free_netdev(dev);
625 goto init_fail;
628 if (request_irq(dev->irq, &moxart_mac_interrupt,
629 IRQF_DISABLED, dev->name, dev)) {
630 netdev_info(dev, "MOXART Ethernet: request_irq failed\n");
631 free_netdev(dev);
632 return -EBUSY;
635 netdev_info(dev, "MOXART Ethernet: moxart_mac_probe %s IRQ=%d\n"
636 " address=%02x:%02x:%02x:%02x:%02x:%02x\n", dev->name,
637 dev->irq, dev->dev_addr[0], dev->dev_addr[1], dev->dev_addr[2],
638 dev->dev_addr[3], dev->dev_addr[4], dev->dev_addr[5]);
639 return 0;
641 init_fail:
642 netdev_info(dev, "MOXART Ethernet: init_fail!\n");
643 moxart_mac_free_memory(dev);
644 return -ENOMEM;
647 static int moxart_remove(struct platform_device *pdev)
649 struct net_device *dev = platform_get_drvdata(pdev);
650 unregister_netdev(dev);
651 free_irq(dev->irq, dev);
652 moxart_mac_free_memory(dev);
653 platform_set_drvdata(pdev, NULL);
654 free_netdev(dev);
655 return 0;
658 struct __initdata platform_driver moxart_mac_driver = {
659 .probe = &moxart_mac_probe,
660 /* .suspend = NULL,
661 .resume = NULL,
663 .remove = __devexit_p(moxart_remove),
664 .driver = {
665 .name = "MOXART_RTL8201CP",
666 .owner = THIS_MODULE,
670 static int __init moxart_mac_init(void)
672 return platform_driver_register(&moxart_mac_driver);
675 static void __exit moxart_mac_exit(void)
677 platform_driver_unregister(&moxart_mac_driver);
680 module_init(moxart_mac_init)
681 module_exit(moxart_mac_exit)
683 MODULE_LICENSE("GPL");
684 MODULE_DESCRIPTION("MOXART RTL8201CP Ethernet driver");
685 MODULE_AUTHOR("Jonas Jensen");
686 MODULE_ALIAS("platform:" DRV_NAME);