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.
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
,
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])));
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
);
67 "MOXART Ethernet: moxart_set_mac_address dev->base_addr=%x\n"
68 , (unsigned int) dev
->base_addr
);
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
)
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
;
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
);
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
;
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
);
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
));
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");
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
;
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);
251 rxdesc
= &priv
->virt_rx_desc_baseaddr
[rxnow
];
252 ui
= rxdesc
->rxdes0
.ui
;
254 /* if ( rxdesc->rxdes0.ubit.RxDMAOwn ) { */
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
++;
267 if (len
> RX_BUF_SIZE
)
270 skb
= dev_alloc_skb(len
+ 2);
272 dbg_printk("Allocate memory fail !\n");
273 priv
->stats
.rx_dropped
++;
279 memcpy(skb_put(skb
, len
), rxdesc
->rxdes2
.virt_rx_buf_baseaddr
, len
);
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
++;
294 rxdesc
->rxdes0
.ui
= RXDMA_OWN
;
296 rxnow
&= RX_DESC_NUM_MASK
;
297 priv
->rx_desc_now
= rxnow
;
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
);
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
);
319 dbg_printk("MOXART Ethernet: AHB_ERR interrupt.\n");
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
;
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
) {
338 "MOXART Ethernet: no Tx space for packet!\n");
339 priv
->stats
.tx_dropped
++;
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
);
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)
381 priv->virt_tx_desc_baseaddr[(priv->tx_desc_now-1)
382 &TX_DESC_NUM_MASK].txdes0.ui);
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
;
393 spin_unlock_irq(&priv
->txlock
);
394 dev_kfree_skb_any(skb
);
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
;
404 unsigned int base
= dev
->base_addr
;
407 dbg_printk("MOXART Ethernet: moxart_mac_get_stats:\n");
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
);
419 desc
&= RX_DESC_NUM_MASK
;
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
);
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
));
445 #ifdef HAVE_MULTICAST
447 static int crc32(char *s
, int length
)
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
++) {
461 for (per_bit
= 0; per_bit
< 8; per_bit
++) {
462 crc_value
= (crc_value
>> 1) ^
463 (((crc_value
^ c
) & 0x01) ? poly
: 0);
470 static void moxart_mac_setmulticast(unsigned int ioaddr
,
471 int count
, struct dev_mc_list
*addrs
)
473 struct dev_mc_list
*cur_addr
;
476 for (cur_addr
= addrs
; cur_addr
!= NULL
; cur_addr
= cur_addr
->next
) {
477 if (!(*cur_addr
->dmi_addr
& 1))
479 crc_val
= crc32(cur_addr
->dmi_addr
, 6);
480 crc_val
= (crc_val
>> 26) & 0x3f; /* MSB 6 bit */
482 outl(inl(ioaddr
+ MATH1_REG_OFFSET
) |
483 (1UL << (crc_val
- 32)),
484 ioaddr
+ MATH1_REG_OFFSET
);
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
);
504 priv
->maccr
|= HT_MULTI_EN
;
505 moxart_mac_setmulticast(dev
->base_addr
,
506 dev
->mc_count
, dev
->mc_list
);
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
,
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 = {
537 .netdev_ops = &moxart_netdev_ops,
540 static struct net_device moxart_mac2_dev = {
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
)
551 for (i
= 0; i
<= 5; i
++)
552 dev
->dev_addr
[i
] = inb(IO_ADDRESS(MOXART_FLASH_BASE
)
553 + mac_addr_flash_offset
+ i
);
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
));
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 pr_info("Allocate the Tx descriptor memory fail !\n");
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 pr_info("Allocate the Rx descriptor memory fail !\n");
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 pr_info("Allocate the Tx buffer memory fail !\n");
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 pr_info("Allocate the Rx buffer memory fail !\n");
613 platform_set_drvdata(pdev
, 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
)) {
628 if (request_irq(dev
->irq
, &moxart_mac_interrupt
,
629 IRQF_DISABLED
, dev
->name
, dev
)) {
630 pr_info("MOXART Ethernet: request_irq failed\n");
635 pr_info("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]);
642 pr_info("MOXART Ethernet: init_fail!\n");
643 moxart_mac_free_memory(dev
);
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
);
658 struct __initdata platform_driver moxart_mac_driver
= {
659 .probe
= &moxart_mac_probe
,
663 .remove
= __devexit_p(moxart_remove
),
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
);