2 * linux/arch/arc/drivers/arcvmac.c
\r
4 * Copyright (C) 2003-2006 Codito Technologies, for linux-2.4 port
\r
5 * Copyright (C) 2006-2007 Celunite Inc, for linux-2.6 port
\r
6 * Copyright (C) 2007-2008 Sagem Communications, Fehmi HAFSI
\r
7 * Copyright (C) 2009 Sagem Communications, Andreas Fenkart
\r
8 * All Rights Reserved.
\r
10 * This program is free software; you can redistribute it and/or modify
\r
11 * it under the terms of the GNU General Public License as published by
\r
12 * the Free Software Foundation; either version 2 of the License, or
\r
13 * (at your option) any later version.
\r
15 * This program is distributed in the hope that it will be useful,
\r
16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
18 * GNU General Public License for more details.
\r
20 * You should have received a copy of the GNU General Public License
\r
21 * along with this program; if not, write to the Free Software
\r
22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
\r
24 * external PHY support based on dnet.c
\r
25 * ring management based on bcm63xx_enet.c
\r
27 * Authors: amit.bhor@celunite.com, sameer.dhavale@celunite.com
\r
32 #include <linux/clk.h>
\r
33 #include <linux/crc32.h>
\r
34 #include <linux/delay.h>
\r
35 #include <linux/dma-mapping.h>
\r
36 #include <linux/etherdevice.h>
\r
37 #include <linux/init.h>
\r
38 #include <linux/io.h>
\r
39 #include <linux/kernel.h>
\r
40 #include <linux/module.h>
\r
41 #include <linux/moduleparam.h>
\r
42 #include <linux/netdevice.h>
\r
43 #include <linux/phy.h>
\r
44 #include <linux/platform_device.h>
\r
45 #include <linux/slab.h>
\r
46 #include <linux/types.h>
\r
47 #include <linux/wakelock.h>
\r
48 #include <linux/version.h>
\r
50 #include <mach/iomux.h>
\r
51 #include <mach/gpio.h>
\r
52 #include <mach/cru.h>
\r
53 #include <mach/board.h>
\r
55 #include "rk29_vmac.h"
\r
56 #include "eth_mac/eth_mac.h"
\r
58 static struct wake_lock idlelock; /* add by lyx @ 20110302 */
\r
60 /* Register access macros */
\r
61 #define vmac_writel(port, value, reg) \
\r
62 writel((value), (port)->regs + reg##_OFFSET)
\r
63 #define vmac_readl(port, reg) readl((port)->regs + reg##_OFFSET)
\r
65 static unsigned char *read_mac_reg(struct net_device *dev,
\r
66 unsigned char hwaddr[ETH_ALEN])
\r
68 struct vmac_priv *ap = netdev_priv(dev);
\r
69 unsigned mac_lo, mac_hi;
\r
72 mac_lo = vmac_readl(ap, ADDRL);
\r
73 mac_hi = vmac_readl(ap, ADDRH);
\r
75 hwaddr[0] = (mac_lo >> 0) & 0xff;
\r
76 hwaddr[1] = (mac_lo >> 8) & 0xff;
\r
77 hwaddr[2] = (mac_lo >> 16) & 0xff;
\r
78 hwaddr[3] = (mac_lo >> 24) & 0xff;
\r
79 hwaddr[4] = (mac_hi >> 0) & 0xff;
\r
80 hwaddr[5] = (mac_hi >> 8) & 0xff;
\r
84 static void write_mac_reg(struct net_device *dev, unsigned char* hwaddr)
\r
86 struct vmac_priv *ap = netdev_priv(dev);
\r
87 unsigned mac_lo, mac_hi;
\r
89 mac_lo = hwaddr[3] << 24 | hwaddr[2] << 16 | hwaddr[1] << 8 | hwaddr[0];
\r
90 mac_hi = hwaddr[5] << 8 | hwaddr[4];
\r
92 vmac_writel(ap, mac_lo, ADDRL);
\r
93 vmac_writel(ap, mac_hi, ADDRH);
\r
96 static void vmac_mdio_xmit(struct vmac_priv *ap, unsigned val)
\r
98 init_completion(&ap->mdio_complete);
\r
99 vmac_writel(ap, val, MDIO_DATA);
\r
100 if(!wait_for_completion_timeout(&ap->mdio_complete, msecs_to_jiffies(1000)))
\r
101 printk("Time out for waiting mdio completion\n");
\r
104 static int vmac_mdio_read(struct mii_bus *bus, int phy_id, int phy_reg)
\r
106 struct vmac_priv *vmac = bus->priv;
\r
108 /* only 5 bits allowed for phy-addr and reg_offset */
\r
109 WARN_ON(phy_id & ~0x1f || phy_reg & ~0x1f);
\r
111 val = MDIO_BASE | MDIO_OP_READ;
\r
112 val |= phy_id << 23 | phy_reg << 18;
\r
113 vmac_mdio_xmit(vmac, val);
\r
115 val = vmac_readl(vmac, MDIO_DATA);
\r
116 return val & MDIO_DATA_MASK;
\r
119 static int vmac_mdio_write(struct mii_bus *bus, int phy_id, int phy_reg,
\r
122 struct vmac_priv *vmac = bus->priv;
\r
124 /* only 5 bits allowed for phy-addr and reg_offset */
\r
125 WARN_ON(phy_id & ~0x1f || phy_reg & ~0x1f);
\r
127 val = MDIO_BASE | MDIO_OP_WRITE;
\r
128 val |= phy_id << 23 | phy_reg << 18;
\r
129 val |= (value & MDIO_DATA_MASK);
\r
130 vmac_mdio_xmit(vmac, val);
\r
134 static void vmac_handle_link_change(struct net_device *dev)
\r
136 struct vmac_priv *ap = netdev_priv(dev);
\r
137 struct phy_device *phydev = ap->phy_dev;
\r
138 unsigned long flags;
\r
139 int report_change = 0;
\r
140 struct rk29_vmac_platform_data *pdata = ap->pdev->dev.platform_data;
\r
142 spin_lock_irqsave(&ap->lock, flags);
\r
144 if (phydev->duplex != ap->duplex) {
\r
147 tmp = vmac_readl(ap, CONTROL);
\r
149 if (phydev->duplex)
\r
154 vmac_writel(ap, tmp, CONTROL);
\r
156 ap->duplex = phydev->duplex;
\r
160 if (phydev->speed != ap->speed) {
\r
161 ap->speed = phydev->speed;
\r
165 if (pdata && pdata->rmii_speed_switch)
\r
166 pdata->rmii_speed_switch(phydev->speed);
\r
168 if (phydev->link != ap->link) {
\r
169 ap->link = phydev->link;
\r
173 spin_unlock_irqrestore(&ap->lock, flags);
\r
176 phy_print_status(ap->phy_dev);
\r
179 static int __devinit vmac_mii_probe(struct net_device *dev)
\r
181 struct vmac_priv *ap = netdev_priv(dev);
\r
182 struct phy_device *phydev = NULL;
\r
183 //struct clk *sys_clk;
\r
184 //unsigned long clock_rate;
\r
187 /* find the first phy */
\r
188 for (phy_addr = 0; phy_addr < PHY_MAX_ADDR; phy_addr++) {
\r
189 if (ap->mii_bus->phy_map[phy_addr]) {
\r
190 phydev = ap->mii_bus->phy_map[phy_addr];
\r
196 dev_err(&dev->dev, "no PHY found\n");
\r
200 /* add pin_irq, if avail */
\r
201 phydev = phy_connect(dev, dev_name(&phydev->dev),
\r
202 &vmac_handle_link_change, 0,
\r
203 //PHY_INTERFACE_MODE_MII);
\r
204 PHY_INTERFACE_MODE_RMII);//????????
\r
205 if (IS_ERR(phydev)) {
\r
206 err = PTR_ERR(phydev);
\r
207 dev_err(&dev->dev, "could not attach to PHY %d\n", err);
\r
211 phydev->supported &= PHY_BASIC_FEATURES;
\r
212 phydev->supported |= SUPPORTED_Asym_Pause | SUPPORTED_Pause;
\r
215 sys_clk = clk_get(NULL, "mac_ref");////////
\r
216 if (IS_ERR(sys_clk)) {
\r
217 err = PTR_ERR(sys_clk);
\r
218 goto err_disconnect;
\r
221 clk_set_rate(sys_clk,50000000);
\r
222 clock_rate = clk_get_rate(sys_clk);
\r
225 printk("%s::%d --mac clock = %d\n",__func__, __LINE__, clock_rate);
\r
226 dev_dbg(&ap->pdev->dev, "clk_get: dev_name : %s %lu\n",
\r
227 dev_name(&ap->pdev->dev),
\r
230 if (clock_rate < 25000000)
\r
231 phydev->supported &= ~(SUPPORTED_100baseT_Half |
\r
232 SUPPORTED_100baseT_Full);
\r
235 phydev->advertising = phydev->supported;
\r
240 ap->phy_dev = phydev;
\r
244 // phy_disconnect(phydev);
\r
249 static int __devinit vmac_mii_init(struct vmac_priv *ap)
\r
253 ap->mii_bus = mdiobus_alloc();
\r
255 if (ap->mii_bus == NULL)
\r
258 ap->mii_bus->name = "vmac_mii_bus";
\r
259 ap->mii_bus->read = &vmac_mdio_read;
\r
260 ap->mii_bus->write = &vmac_mdio_write;
\r
262 snprintf(ap->mii_bus->id, MII_BUS_ID_SIZE, "%x", 0);
\r
264 ap->mii_bus->priv = ap;
\r
267 ap->mii_bus->irq = kmalloc(sizeof(int) * PHY_MAX_ADDR, GFP_KERNEL);
\r
268 if (!ap->mii_bus->irq)
\r
271 for (i = 0; i < PHY_MAX_ADDR; i++)
\r
272 ap->mii_bus->irq[i] = PHY_POLL;
\r
275 /* FIXME: what is it used for? */
\r
276 platform_set_drvdata(ap->dev, ap->mii_bus);
\r
279 err = mdiobus_register(ap->mii_bus);
\r
281 goto err_out_free_mdio_irq;
\r
283 err = vmac_mii_probe(ap->dev);
\r
285 goto err_out_unregister_bus;
\r
289 err_out_unregister_bus:
\r
290 mdiobus_unregister(ap->mii_bus);
\r
291 err_out_free_mdio_irq:
\r
292 kfree(ap->mii_bus->irq);
\r
294 mdiobus_free(ap->mii_bus);
\r
295 ap->mii_bus = NULL;
\r
299 static void vmac_mii_exit(struct net_device *dev)
\r
301 struct vmac_priv *ap = netdev_priv(dev);
\r
304 phy_disconnect(ap->phy_dev);
\r
306 mdiobus_unregister(ap->mii_bus);
\r
307 kfree(ap->mii_bus->irq);
\r
308 mdiobus_free(ap->mii_bus);
\r
309 ap->mii_bus = NULL;
\r
313 static int vmacether_get_settings(struct net_device *dev,
\r
314 struct ethtool_cmd *cmd)
\r
316 struct vmac_priv *ap = netdev_priv(dev);
\r
317 struct phy_device *phydev = ap->phy_dev;
\r
322 return phy_ethtool_gset(phydev, cmd);
\r
325 static int vmacether_set_settings(struct net_device *dev,
\r
326 struct ethtool_cmd *cmd)
\r
328 struct vmac_priv *ap = netdev_priv(dev);
\r
329 struct phy_device *phydev = ap->phy_dev;
\r
334 return phy_ethtool_sset(phydev, cmd);
\r
337 static int vmac_ioctl(struct net_device *dev, struct ifreq *rq, int cmd)
\r
339 struct vmac_priv *ap = netdev_priv(dev);
\r
340 struct phy_device *phydev = ap->phy_dev;
\r
342 if (!netif_running(dev))
\r
348 return phy_mii_ioctl(phydev, rq, cmd);
\r
351 static void vmacether_get_drvinfo(struct net_device *dev,
\r
352 struct ethtool_drvinfo *info)
\r
354 struct vmac_priv *ap = netdev_priv(dev);
\r
356 strlcpy(info->driver, VMAC_NAME, sizeof(info->driver));
\r
357 strlcpy(info->version, VMAC_VERSION, sizeof(info->version));
\r
358 snprintf(info->bus_info, sizeof(info->bus_info),
\r
359 "platform 0x%x", ap->mem_base);
\r
362 static int update_error_counters(struct net_device *dev, int status)
\r
364 struct vmac_priv *ap = netdev_priv(dev);
\r
365 dev_dbg(&ap->pdev->dev, "rx error counter overrun. status = 0x%x\n",
\r
368 /* programming error */
\r
369 WARN_ON(status & TXCH_MASK);
\r
370 WARN_ON(!(status & (MSER_MASK | RXCR_MASK | RXFR_MASK | RXFL_MASK)));
\r
372 if (status & MSER_MASK)
\r
373 ap->stats.rx_over_errors += 256; /* ran out of BD */
\r
374 if (status & RXCR_MASK)
\r
375 ap->stats.rx_crc_errors += 256;
\r
376 if (status & RXFR_MASK)
\r
377 ap->stats.rx_frame_errors += 256;
\r
378 if (status & RXFL_MASK)
\r
379 ap->stats.rx_fifo_errors += 256;
\r
384 static void update_tx_errors(struct net_device *dev, int status)
\r
386 struct vmac_priv *ap = netdev_priv(dev);
\r
389 ap->stats.tx_fifo_errors++;
\r
394 /* half duplex flags */
\r
396 ap->stats.tx_window_errors++;
\r
397 if (status & RETRY_CT)
\r
398 ap->stats.collisions += (status & RETRY_CT) >> 24;
\r
399 if (status & DROP) /* too many retries */
\r
400 ap->stats.tx_aborted_errors++;
\r
401 if (status & DEFER)
\r
402 dev_vdbg(&ap->pdev->dev, "\"defer to traffic\"\n");
\r
403 if (status & CARLOSS)
\r
404 ap->stats.tx_carrier_errors++;
\r
407 static int vmac_rx_reclaim_force(struct net_device *dev)
\r
409 struct vmac_priv *ap = netdev_priv(dev);
\r
414 dev_dbg(&ap->pdev->dev, "%s need to release %d rx sk_buff\n",
\r
415 __func__, fifo_used(&ap->rx_ring));
\r
417 while (!fifo_empty(&ap->rx_ring) && ct++ < ap->rx_ring.size) {
\r
418 struct vmac_buffer_desc *desc;
\r
419 struct sk_buff *skb;
\r
422 desc_idx = ap->rx_ring.tail;
\r
423 desc = &ap->rxbd[desc_idx];
\r
424 fifo_inc_tail(&ap->rx_ring);
\r
426 if (!ap->rx_skbuff[desc_idx]) {
\r
427 dev_err(&ap->pdev->dev, "non-populated rx_skbuff found %d\n",
\r
432 skb = ap->rx_skbuff[desc_idx];
\r
433 ap->rx_skbuff[desc_idx] = NULL;
\r
435 dma_unmap_single(&ap->pdev->dev, desc->data, skb->len,
\r
438 dev_kfree_skb(skb);
\r
441 if (!fifo_empty(&ap->rx_ring)) {
\r
442 dev_err(&ap->pdev->dev, "failed to reclaim %d rx sk_buff\n",
\r
443 fifo_used(&ap->rx_ring));
\r
449 static int vmac_rx_refill(struct net_device *dev)
\r
451 struct vmac_priv *ap = netdev_priv(dev);
\r
453 WARN_ON(fifo_full(&ap->rx_ring));
\r
455 while (!fifo_full(&ap->rx_ring)) {
\r
456 struct vmac_buffer_desc *desc;
\r
457 struct sk_buff *skb;
\r
461 desc_idx = ap->rx_ring.head;
\r
462 desc = &ap->rxbd[desc_idx];
\r
464 /* make sure we read the actual descriptor status */
\r
467 if (ap->rx_skbuff[desc_idx]) {
\r
468 /* dropped packet / buffer chaining */
\r
469 fifo_inc_head(&ap->rx_ring);
\r
471 /* return to DMA */
\r
473 desc->info = OWN_MASK | ap->rx_skb_size;
\r
477 skb = netdev_alloc_skb(dev, ap->rx_skb_size + 2);
\r
479 dev_info(&ap->pdev->dev, "failed to allocate rx_skb, skb's left %d\n",
\r
480 fifo_used(&ap->rx_ring));
\r
484 /* IP header Alignment (14 byte Ethernet header) */
\r
485 skb_reserve(skb, 2);
\r
486 WARN_ON(skb->len != 0); /* nothing received yet */
\r
488 ap->rx_skbuff[desc_idx] = skb;
\r
490 p = dma_map_single(&ap->pdev->dev, skb->data, ap->rx_skb_size,
\r
496 desc->info = OWN_MASK | ap->rx_skb_size;
\r
498 fifo_inc_head(&ap->rx_ring);
\r
501 /* If rx ring is still empty, set a timer to try allocating
\r
502 * again at a later time. */
\r
503 if (fifo_empty(&ap->rx_ring) && netif_running(dev)) {
\r
504 dev_warn(&ap->pdev->dev, "unable to refill rx ring\n");
\r
505 ap->rx_timeout.expires = jiffies + HZ;
\r
506 add_timer(&ap->rx_timeout);
\r
513 * timer callback to defer refill rx queue in case we're OOM
\r
515 static void vmac_refill_rx_timer(unsigned long data)
\r
517 struct net_device *dev;
\r
518 struct vmac_priv *ap;
\r
520 dev = (struct net_device *)data;
\r
521 ap = netdev_priv(dev);
\r
523 spin_lock(&ap->rx_lock);
\r
524 vmac_rx_refill(dev);
\r
525 spin_unlock(&ap->rx_lock);
\r
528 /* merge buffer chaining */
\r
529 struct sk_buff *vmac_merge_rx_buffers(struct net_device *dev,
\r
530 struct vmac_buffer_desc *after,
\r
531 int pkt_len) /* data */
\r
533 struct vmac_priv *ap = netdev_priv(dev);
\r
534 struct sk_buff *merge_skb, *cur_skb;
\r
535 struct dma_fifo *rx_ring;
\r
536 struct vmac_buffer_desc *desc;
\r
538 rx_ring = &ap->rx_ring;
\r
539 desc = &ap->rxbd[rx_ring->tail];
\r
541 WARN_ON(desc == after);
\r
546 /* IP header Alignment (14 byte Ethernet header) */
\r
547 merge_skb = netdev_alloc_skb(dev, pkt_len + 2);
\r
549 dev_err(&ap->pdev->dev, "failed to allocate merged rx_skb, rx skb's left %d\n",
\r
550 fifo_used(rx_ring));
\r
555 skb_reserve(merge_skb, 2);
\r
557 while (desc != after && pkt_len) {
\r
558 struct vmac_buffer_desc *desc;
\r
559 int buf_len, valid;
\r
561 /* desc needs wrapping */
\r
562 desc = &ap->rxbd[rx_ring->tail];
\r
563 cur_skb = ap->rx_skbuff[rx_ring->tail];
\r
566 dma_unmap_single(&ap->pdev->dev, desc->data, ap->rx_skb_size,
\r
569 /* do not copy FCS */
\r
570 buf_len = desc->info & LEN_MASK;
\r
571 valid = min(pkt_len, buf_len);
\r
574 memcpy(skb_put(merge_skb, valid), cur_skb->data, valid);
\r
576 fifo_inc_tail(rx_ring);
\r
579 /* merging_pressure++ */
\r
581 if (unlikely(pkt_len != 0))
\r
582 dev_err(&ap->pdev->dev, "buffer chaining bytes missing %d\n",
\r
585 WARN_ON(desc != after);
\r
590 int vmac_rx_receive(struct net_device *dev, int budget)
\r
592 struct vmac_priv *ap = netdev_priv(dev);
\r
593 struct vmac_buffer_desc *first;
\r
594 int processed, pkt_len, pkt_err;
\r
595 struct dma_fifo lookahead;
\r
600 pkt_err = pkt_len = 0;
\r
602 /* look ahead, till packet complete */
\r
603 lookahead = ap->rx_ring;
\r
606 struct vmac_buffer_desc *desc; /* cur_ */
\r
607 int desc_idx; /* cur_ */
\r
608 struct sk_buff *skb; /* pkt_ */
\r
610 desc_idx = lookahead.tail;
\r
611 desc = &ap->rxbd[desc_idx];
\r
613 /* make sure we read the actual descriptor status */
\r
616 /* break if dma ownership belongs to hw */
\r
617 if (desc->info & OWN_MASK) {
\r
618 ap->mac_rxring_head = vmac_readl(ap, MAC_RXRING_HEAD);
\r
622 if (desc->info & FRST_MASK) {
\r
626 /* don't free current */
\r
627 ap->rx_ring.tail = lookahead.tail;
\r
631 fifo_inc_tail(&lookahead);
\r
635 pkt_len += desc->info & LEN_MASK;
\r
636 pkt_err |= (desc->info & BUFF);
\r
638 if (!(desc->info & LAST_MASK))
\r
641 /* received complete packet */
\r
643 if (unlikely(pkt_err || !first)) {
\r
644 /* recycle buffers */
\r
645 ap->rx_ring.tail = lookahead.tail;
\r
649 WARN_ON(!(first->info & FRST_MASK) ||
\r
650 !(desc->info & LAST_MASK));
\r
653 /* -- valid packet -- */
\r
655 if (first != desc) {
\r
656 skb = vmac_merge_rx_buffers(dev, desc, pkt_len);
\r
660 ap->rx_ring.tail = lookahead.tail;
\r
661 ap->rx_merge_error++;
\r
665 dma_unmap_single(&ap->pdev->dev, desc->data,
\r
666 ap->rx_skb_size, DMA_FROM_DEVICE);
\r
668 skb = ap->rx_skbuff[desc_idx];
\r
669 ap->rx_skbuff[desc_idx] = NULL;
\r
670 /* desc->data != skb->data => desc->data DMA mapped */
\r
673 skb_put(skb, pkt_len - 4);
\r
677 ap->rx_ring.tail = lookahead.tail;
\r
679 WARN_ON(skb->len != pkt_len - 4);
\r
682 skb->protocol = eth_type_trans(skb, dev);
\r
683 ap->stats.rx_packets++;
\r
684 ap->stats.rx_bytes += skb->len;
\r
685 dev->last_rx = jiffies;
\r
688 } while (!fifo_empty(&lookahead) && (processed < budget));
\r
690 dev_vdbg(&ap->pdev->dev, "processed pkt %d, remaining rx buff %d\n",
\r
692 fifo_used(&ap->rx_ring));
\r
694 if (processed || fifo_empty(&ap->rx_ring))
\r
695 vmac_rx_refill(dev);
\r
700 static void vmac_toggle_irqmask(struct net_device *dev, int enable, int mask)
\r
702 struct vmac_priv *ap = netdev_priv(dev);
\r
705 tmp = vmac_readl(ap, ENABLE);
\r
710 vmac_writel(ap, tmp, ENABLE);
\r
713 static void vmac_toggle_txint(struct net_device *dev, int enable)
\r
715 struct vmac_priv *ap = netdev_priv(dev);
\r
716 unsigned long flags;
\r
718 spin_lock_irqsave(&ap->lock, flags);
\r
719 vmac_toggle_irqmask(dev, enable, TXINT_MASK);
\r
720 spin_unlock_irqrestore(&ap->lock, flags);
\r
723 static void vmac_toggle_rxint(struct net_device *dev, int enable)
\r
725 vmac_toggle_irqmask(dev, enable, RXINT_MASK);
\r
728 static int vmac_poll(struct napi_struct *napi, int budget)
\r
730 struct vmac_priv *ap;
\r
731 struct net_device *dev;
\r
733 unsigned long flags;
\r
735 ap = container_of(napi, struct vmac_priv, napi);
\r
738 /* ack interrupt */
\r
739 vmac_writel(ap, RXINT_MASK, STAT);
\r
741 spin_lock(&ap->rx_lock);
\r
742 rx_work_done = vmac_rx_receive(dev, budget);
\r
743 spin_unlock(&ap->rx_lock);
\r
745 #ifdef VERBOSE_DEBUG
\r
746 if (printk_ratelimit()) {
\r
747 dev_vdbg(&ap->pdev->dev, "poll budget %d receive rx_work_done %d\n",
\r
753 if (rx_work_done >= budget) {
\r
754 /* rx queue is not yet empty/clean */
\r
755 return rx_work_done;
\r
758 /* no more packet in rx/tx queue, remove device from poll
\r
760 spin_lock_irqsave(&ap->lock, flags);
\r
761 napi_complete(napi);
\r
762 vmac_toggle_rxint(dev, 1);
\r
763 spin_unlock_irqrestore(&ap->lock, flags);
\r
765 return rx_work_done;
\r
768 static int vmac_tx_reclaim(struct net_device *dev, int force);
\r
770 static irqreturn_t vmac_intr(int irq, void *dev_instance)
\r
772 struct net_device *dev = dev_instance;
\r
773 struct vmac_priv *ap = netdev_priv(dev);
\r
774 unsigned int status;
\r
776 spin_lock(&ap->lock);
\r
778 status = vmac_readl(ap, STAT);
\r
779 vmac_writel(ap, status, STAT);
\r
782 if (unlikely(ap->shutdown))
\r
783 dev_err(&ap->pdev->dev, "ISR during close\n");
\r
785 if (unlikely(!status & (RXINT_MASK|MDIO_MASK|ERR_MASK)))
\r
786 dev_err(&ap->pdev->dev, "No source of IRQ found\n");
\r
789 if ((status & RXINT_MASK) &&
\r
790 (ap->mac_rxring_head !=
\r
791 vmac_readl(ap, MAC_RXRING_HEAD))) {
\r
792 vmac_toggle_rxint(dev, 0);
\r
793 napi_schedule(&ap->napi);
\r
796 if (unlikely(netif_queue_stopped(dev) && (status & TXINT_MASK)))
\r
797 vmac_tx_reclaim(dev, 0);
\r
799 if (status & MDIO_MASK)
\r
800 complete(&ap->mdio_complete);
\r
802 if (unlikely(status & ERR_MASK))
\r
803 update_error_counters(dev, status);
\r
805 spin_unlock(&ap->lock);
\r
807 return IRQ_HANDLED;
\r
810 static int vmac_tx_reclaim(struct net_device *dev, int force)
\r
812 struct vmac_priv *ap = netdev_priv(dev);
\r
815 /* buffer chaining not used, see vmac_start_xmit */
\r
817 while (!fifo_empty(&ap->tx_ring)) {
\r
818 struct vmac_buffer_desc *desc;
\r
819 struct sk_buff *skb;
\r
822 desc_idx = ap->tx_ring.tail;
\r
823 desc = &ap->txbd[desc_idx];
\r
825 /* ensure other field of the descriptor were not read
\r
826 * before we checked ownership */
\r
829 if ((desc->info & OWN_MASK) && !force)
\r
832 if (desc->info & ERR_MSK_TX) {
\r
833 update_tx_errors(dev, desc->info);
\r
834 /* recycle packet, let upper level deal with it */
\r
837 skb = ap->tx_skbuff[desc_idx];
\r
838 ap->tx_skbuff[desc_idx] = NULL;
\r
841 dma_unmap_single(&ap->pdev->dev, desc->data, skb->len,
\r
844 dev_kfree_skb_any(skb);
\r
847 fifo_inc_tail(&ap->tx_ring);
\r
850 if (netif_queue_stopped(dev) && released) {
\r
851 netif_wake_queue(dev);
\r
852 vmac_toggle_txint(dev, 0);
\r
855 if (unlikely(force && !fifo_empty(&ap->tx_ring))) {
\r
856 dev_err(&ap->pdev->dev, "failed to reclaim %d tx sk_buff\n",
\r
857 fifo_used(&ap->tx_ring));
\r
863 int vmac_start_xmit(struct sk_buff *skb, struct net_device *dev)
\r
865 struct vmac_priv *ap = netdev_priv(dev);
\r
866 struct vmac_buffer_desc *desc;
\r
869 /* running under xmit lock */
\r
871 /* no scatter/gatter see features below */
\r
872 WARN_ON(skb_shinfo(skb)->nr_frags != 0);
\r
873 WARN_ON(skb->len > MAX_TX_BUFFER_LEN);
\r
875 if (unlikely(fifo_full(&ap->tx_ring))) {
\r
876 netif_stop_queue(dev);
\r
877 vmac_toggle_txint(dev, 1);
\r
878 dev_err(&ap->pdev->dev, "xmit called with no tx desc available\n");
\r
879 return NETDEV_TX_BUSY;
\r
882 if (unlikely(skb->len < ETH_ZLEN)) {
\r
883 struct sk_buff *short_skb;
\r
884 short_skb = netdev_alloc_skb(dev, ETH_ZLEN);
\r
886 return NETDEV_TX_LOCKED;
\r
888 memset(short_skb->data, 0, ETH_ZLEN);
\r
889 memcpy(skb_put(short_skb, ETH_ZLEN), skb->data, skb->len);
\r
890 dev_kfree_skb(skb);
\r
894 /* fill descriptor */
\r
895 ap->tx_skbuff[ap->tx_ring.head] = skb;
\r
897 desc = &ap->txbd[ap->tx_ring.head];
\r
898 desc->data = dma_map_single(&ap->pdev->dev, skb->data, skb->len,
\r
901 /* dma might already be polling */
\r
903 desc->info = OWN_MASK | FRST_MASK | LAST_MASK | skb->len;
\r
907 tmp = vmac_readl(ap, STAT);
\r
908 vmac_writel(ap, tmp | TXPL_MASK, STAT);
\r
910 ap->stats.tx_packets++;
\r
911 ap->stats.tx_bytes += skb->len;
\r
912 dev->trans_start = jiffies;
\r
913 fifo_inc_head(&ap->tx_ring);
\r
915 /* vmac_tx_reclaim independent of vmac_tx_timeout */
\r
916 if (fifo_used(&ap->tx_ring) > 8)
\r
917 vmac_tx_reclaim(dev, 0);
\r
919 /* stop queue if no more desc available */
\r
920 if (fifo_full(&ap->tx_ring)) {
\r
921 netif_stop_queue(dev);
\r
922 vmac_toggle_txint(dev, 1);
\r
925 return NETDEV_TX_OK;
\r
928 static int alloc_buffers(struct net_device *dev)
\r
930 struct vmac_priv *ap = netdev_priv(dev);
\r
934 fifo_init(&ap->rx_ring, RX_BDT_LEN);
\r
935 fifo_init(&ap->tx_ring, TX_BDT_LEN);
\r
937 /* initialize skb list */
\r
938 memset(ap->rx_skbuff, 0, sizeof(ap->rx_skbuff));
\r
939 memset(ap->tx_skbuff, 0, sizeof(ap->tx_skbuff));
\r
941 /* allocate DMA received descriptors */
\r
942 size = sizeof(*ap->rxbd) * ap->rx_ring.size;
\r
943 ap->rxbd = dma_alloc_coherent(&ap->pdev->dev, size,
\r
946 if (ap->rxbd == NULL)
\r
949 /* allocate DMA transmit descriptors */
\r
950 size = sizeof(*ap->txbd) * ap->tx_ring.size;
\r
951 ap->txbd = dma_alloc_coherent(&ap->pdev->dev, size,
\r
954 if (ap->txbd == NULL)
\r
955 goto err_free_rxbd;
\r
957 /* ensure 8-byte aligned */
\r
958 WARN_ON(((int)ap->txbd & 0x7) || ((int)ap->rxbd & 0x7));
\r
960 memset(ap->txbd, 0, sizeof(*ap->txbd) * ap->tx_ring.size);
\r
961 memset(ap->rxbd, 0, sizeof(*ap->rxbd) * ap->rx_ring.size);
\r
963 /* allocate rx skb */
\r
964 err = vmac_rx_refill(dev);
\r
966 goto err_free_txbd;
\r
971 dma_free_coherent(&ap->pdev->dev, sizeof(*ap->txbd) * ap->tx_ring.size,
\r
972 ap->txbd, ap->txbd_dma);
\r
974 dma_free_coherent(&ap->pdev->dev, sizeof(*ap->rxbd) * ap->rx_ring.size,
\r
975 ap->rxbd, ap->rxbd_dma);
\r
980 static int free_buffers(struct net_device *dev)
\r
982 struct vmac_priv *ap = netdev_priv(dev);
\r
985 vmac_tx_reclaim(dev, 1);
\r
986 vmac_rx_reclaim_force(dev);
\r
988 /* free DMA ring */
\r
989 dma_free_coherent(&ap->pdev->dev, sizeof(ap->txbd) * ap->tx_ring.size,
\r
990 ap->txbd, ap->txbd_dma);
\r
991 dma_free_coherent(&ap->pdev->dev, sizeof(ap->rxbd) * ap->rx_ring.size,
\r
992 ap->rxbd, ap->rxbd_dma);
\r
997 static int vmac_hw_init(struct net_device *dev)
\r
999 struct vmac_priv *priv = netdev_priv(dev);
\r
1001 /* clear IRQ mask */
\r
1002 vmac_writel(priv, 0, ENABLE);
\r
1004 /* clear pending IRQ */
\r
1005 vmac_writel(priv, 0xffffffff, STAT);
\r
1007 /* Initialize logical address filter */
\r
1008 vmac_writel(priv, 0x0, LAFL);
\r
1009 vmac_writel(priv, 0x0, LAFH);
\r
1015 static int vmac_register_print(struct net_device *dev)
\r
1017 struct vmac_priv *ap = netdev_priv(dev);
\r
1019 printk("func::%s vmac register %s value = 0x%x\n", __func__, "ID", vmac_readl(ap, ID));
\r
1020 printk("func::%s vmac register %s value = 0x%x\n", __func__, "STAT", vmac_readl(ap, STAT));
\r
1021 printk("func::%s vmac register %s value = 0x%x\n", __func__, "ENABLE", vmac_readl(ap, ENABLE));
\r
1022 printk("func::%s vmac register %s value = 0x%x\n", __func__, "CONTROL", vmac_readl(ap, CONTROL));
\r
1023 printk("func::%s vmac register %s value = 0x%x\n", __func__, "ADDRL", vmac_readl(ap, ADDRL));
\r
1024 printk("func::%s vmac register %s value = 0x%x\n", __func__, "ADDRH", vmac_readl(ap, ADDRH));
\r
1030 int vmac_open(struct net_device *dev)
\r
1032 struct vmac_priv *ap = netdev_priv(dev);
\r
1033 struct phy_device *phydev;
\r
1034 unsigned int temp;
\r
1036 struct clk *mac_clk = NULL;
\r
1037 struct clk *mac_parent = NULL;
\r
1038 struct clk *arm_clk = NULL;
\r
1039 struct rk29_vmac_platform_data *pdata = ap->pdev->dev.platform_data;
\r
1041 printk("enter func %s...\n", __func__);
\r
1046 wake_lock_timeout(&ap->resume_lock, 5*HZ);
\r
1050 //set rmii ref clock 50MHz
\r
1051 mac_clk = clk_get(NULL, "mac_ref_div");
\r
1052 if (IS_ERR(mac_clk))
\r
1054 arm_clk = clk_get(NULL, "arm_pll");
\r
1055 if (IS_ERR(arm_clk))
\r
1058 mac_parent = clk_get_parent(mac_clk);
\r
1059 if (IS_ERR(mac_parent))
\r
1060 mac_parent = NULL;
\r
1062 if (arm_clk && mac_parent && (arm_clk == mac_parent))
\r
1063 wake_lock(&idlelock);
\r
1065 clk_set_rate(mac_clk, 50000000);
\r
1066 clk_enable(mac_clk);
\r
1067 clk_enable(clk_get(NULL,"mii_rx"));
\r
1068 clk_enable(clk_get(NULL,"mii_tx"));
\r
1069 clk_enable(clk_get(NULL,"hclk_mac"));
\r
1070 clk_enable(clk_get(NULL,"mac_ref"));
\r
1073 if (pdata && pdata->rmii_power_control)
\r
1074 pdata->rmii_power_control(1);
\r
1078 vmac_hw_init(dev);
\r
1080 /* mac address changed? */
\r
1081 write_mac_reg(dev, dev->dev_addr);
\r
1083 err = alloc_buffers(dev);
\r
1087 err = request_irq(dev->irq, &vmac_intr, 0, dev->name, dev);
\r
1089 dev_err(&ap->pdev->dev, "Unable to request IRQ %d (error %d)\n",
\r
1091 goto err_free_buffers;
\r
1094 /* install DMA ring pointers */
\r
1095 vmac_writel(ap, ap->rxbd_dma, RXRINGPTR);
\r
1096 vmac_writel(ap, ap->txbd_dma, TXRINGPTR);
\r
1098 /* set poll rate to 1 ms */
\r
1099 vmac_writel(ap, POLLRATE_TIME, POLLRATE);
\r
1101 /* make sure we enable napi before rx interrupt */
\r
1102 napi_enable(&ap->napi);
\r
1105 temp = RXINT_MASK | ERR_MASK | TXCH_MASK | MDIO_MASK;
\r
1106 vmac_writel(ap, temp, ENABLE);
\r
1109 temp = (RX_BDT_LEN << 24) | (TX_BDT_LEN << 16) | TXRN_MASK | RXRN_MASK;
\r
1110 vmac_writel(ap, temp, CONTROL);
\r
1112 /* enable, after all other bits are set */
\r
1113 vmac_writel(ap, temp | EN_MASK, CONTROL);
\r
1115 netif_start_queue(dev);
\r
1116 netif_carrier_off(dev);
\r
1119 vmac_register_print(dev);
\r
1122 /* register the PHY board fixup, if needed */
\r
1123 err = vmac_mii_init(ap);
\r
1125 goto err_free_irq;
\r
1127 /* schedule a link state check */
\r
1128 phy_start(ap->phy_dev);
\r
1130 phydev = ap->phy_dev;
\r
1131 dev_info(&ap->pdev->dev, "PHY driver [%s] (mii_bus:phy_addr=%s, irq=%d)\n",
\r
1132 phydev->drv->name, dev_name(&phydev->dev), phydev->irq);
\r
1134 ap->suspending = 0;
\r
1135 ap->open_flag = 1;
\r
1140 free_irq(dev->irq, dev);
\r
1142 free_buffers(dev);
\r
1144 if (arm_clk && mac_parent && (arm_clk == mac_parent))
\r
1145 wake_unlock(&idlelock);
\r
1150 int vmac_close(struct net_device *dev)
\r
1152 struct vmac_priv *ap = netdev_priv(dev);
\r
1153 unsigned int temp;
\r
1154 struct clk *mac_clk = NULL;
\r
1155 struct clk *arm_clk = NULL;
\r
1156 struct clk *mac_parent = NULL;
\r
1157 struct rk29_vmac_platform_data *pdata = ap->pdev->dev.platform_data;
\r
1159 printk("enter func %s...\n", __func__);
\r
1161 if (ap->suspending == 1)
\r
1164 ap->open_flag = 0;
\r
1166 netif_stop_queue(dev);
\r
1167 napi_disable(&ap->napi);
\r
1169 /* stop running transfers */
\r
1170 temp = vmac_readl(ap, CONTROL);
\r
1171 temp &= ~(TXRN_MASK | RXRN_MASK);
\r
1172 vmac_writel(ap, temp, CONTROL);
\r
1174 del_timer_sync(&ap->rx_timeout);
\r
1177 phy_stop(ap->phy_dev);
\r
1178 vmac_mii_exit(dev);
\r
1179 netif_carrier_off(dev);
\r
1181 /* disable interrupts */
\r
1182 vmac_writel(ap, 0, ENABLE);
\r
1183 free_irq(dev->irq, dev);
\r
1185 /* turn off vmac */
\r
1186 vmac_writel(ap, 0, CONTROL);
\r
1187 /* vmac_reset_hw(vmac) */
\r
1192 free_buffers(dev);
\r
1195 if (pdata && pdata->rmii_power_control)
\r
1196 pdata->rmii_power_control(0);
\r
1199 mac_clk = clk_get(NULL, "mac_ref_div");
\r
1200 if (IS_ERR(mac_clk))
\r
1203 mac_parent = clk_get_parent(mac_clk);
\r
1204 if (IS_ERR(mac_parent))
\r
1205 mac_parent = NULL;
\r
1207 arm_clk = clk_get(NULL, "arm_pll");
\r
1208 if (IS_ERR(arm_clk))
\r
1211 if (arm_clk && mac_parent && (arm_clk == mac_parent))
\r
1212 wake_unlock(&idlelock);
\r
1214 clk_disable(mac_clk);
\r
1215 clk_disable(clk_get(NULL,"mii_rx"));
\r
1216 clk_disable(clk_get(NULL,"mii_tx"));
\r
1217 clk_disable(clk_get(NULL,"hclk_mac"));
\r
1218 clk_disable(clk_get(NULL,"mac_ref"));
\r
1223 int vmac_shutdown(struct net_device *dev)
\r
1225 struct vmac_priv *ap = netdev_priv(dev);
\r
1226 unsigned int temp;
\r
1228 printk("enter func %s...\n", __func__);
\r
1230 netif_stop_queue(dev);
\r
1231 napi_disable(&ap->napi);
\r
1233 /* stop running transfers */
\r
1234 temp = vmac_readl(ap, CONTROL);
\r
1235 temp &= ~(TXRN_MASK | RXRN_MASK);
\r
1236 vmac_writel(ap, temp, CONTROL);
\r
1238 del_timer_sync(&ap->rx_timeout);
\r
1241 phy_stop(ap->phy_dev);
\r
1242 vmac_mii_exit(dev);
\r
1243 netif_carrier_off(dev);
\r
1245 /* disable interrupts */
\r
1246 vmac_writel(ap, 0, ENABLE);
\r
1247 free_irq(dev->irq, dev);
\r
1249 /* turn off vmac */
\r
1250 vmac_writel(ap, 0, CONTROL);
\r
1251 /* vmac_reset_hw(vmac) */
\r
1256 free_buffers(dev);
\r
1261 void vmac_update_stats(struct vmac_priv *ap)
\r
1263 struct net_device_stats *_stats = &ap->stats;
\r
1264 unsigned long miss, rxerr;
\r
1265 unsigned long rxfram, rxcrc, rxoflow;
\r
1267 /* compare with /proc/net/dev,
\r
1268 * see net/core/dev.c:dev_seq_printf_stats */
\r
1271 rxerr = vmac_readl(ap, RXERR);
\r
1272 miss = vmac_readl(ap, MISS);
\r
1274 rxcrc = (rxerr & RXERR_CRC);
\r
1275 rxfram = (rxerr & RXERR_FRM) >> 8;
\r
1276 rxoflow = (rxerr & RXERR_OFLO) >> 16;
\r
1278 _stats->rx_length_errors = 0;
\r
1279 _stats->rx_over_errors += miss;
\r
1280 _stats->rx_crc_errors += rxcrc;
\r
1281 _stats->rx_frame_errors += rxfram;
\r
1282 _stats->rx_fifo_errors += rxoflow;
\r
1283 _stats->rx_missed_errors = 0;
\r
1285 /* TODO check rx_dropped/rx_errors/tx_dropped/tx_errors have not
\r
1286 * been updated elsewhere */
\r
1287 _stats->rx_dropped = _stats->rx_over_errors +
\r
1288 _stats->rx_fifo_errors +
\r
1289 ap->rx_merge_error;
\r
1291 _stats->rx_errors = _stats->rx_length_errors + _stats->rx_crc_errors +
\r
1292 _stats->rx_frame_errors +
\r
1293 _stats->rx_missed_errors +
\r
1294 _stats->rx_dropped;
\r
1297 _stats->tx_dropped = 0; /* otherwise queue stopped */
\r
1299 _stats->tx_errors = _stats->tx_aborted_errors +
\r
1300 _stats->tx_carrier_errors +
\r
1301 _stats->tx_fifo_errors +
\r
1302 _stats->tx_heartbeat_errors +
\r
1303 _stats->tx_window_errors +
\r
1304 _stats->tx_dropped +
\r
1305 ap->tx_timeout_error;
\r
1308 struct net_device_stats *vmac_stats(struct net_device *dev)
\r
1310 struct vmac_priv *ap = netdev_priv(dev);
\r
1311 unsigned long flags;
\r
1313 spin_lock_irqsave(&ap->lock, flags);
\r
1314 vmac_update_stats(ap);
\r
1315 spin_unlock_irqrestore(&ap->lock, flags);
\r
1317 return &ap->stats;
\r
1320 void vmac_tx_timeout(struct net_device *dev)
\r
1322 struct vmac_priv *ap = netdev_priv(dev);
\r
1323 unsigned int status;
\r
1324 unsigned long flags;
\r
1326 spin_lock_irqsave(&ap->lock, flags);
\r
1328 /* queue did not progress for timeo jiffies */
\r
1329 WARN_ON(!netif_queue_stopped(dev));
\r
1330 WARN_ON(!fifo_full(&ap->tx_ring));
\r
1332 /* TX IRQ lost? */
\r
1333 status = vmac_readl(ap, STAT);
\r
1334 if (status & TXINT_MASK) {
\r
1335 dev_err(&ap->pdev->dev, "lost tx interrupt, IRQ mask %x\n",
\r
1336 vmac_readl(ap, ENABLE));
\r
1337 vmac_writel(ap, TXINT_MASK, STAT);
\r
1340 /* TODO RX/MDIO/ERR as well? */
\r
1342 vmac_tx_reclaim(dev, 0);
\r
1343 if (fifo_full(&ap->tx_ring))
\r
1344 dev_err(&ap->pdev->dev, "DMA state machine not active\n");
\r
1346 /* We can accept TX packets again */
\r
1347 ap->tx_timeout_error++;
\r
1348 dev->trans_start = jiffies;
\r
1349 netif_wake_queue(dev);
\r
1351 spin_unlock_irqrestore(&ap->lock, flags);
\r
1354 static void create_multicast_filter(struct net_device *dev,
\r
1355 unsigned long *bitmask)
\r
1357 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 34))
\r
1358 struct netdev_hw_addr *ha;
\r
1359 unsigned long crc;
\r
1361 struct netdev_hw_addr_list *list = &dev->dev_addrs;
\r
1363 //printk("-----------------func %s-------------------\n", __func__);
\r
1365 WARN_ON(dev->mc_count == 0);
\r
1366 WARN_ON(dev->flags & IFF_ALLMULTI);
\r
1368 bitmask[0] = bitmask[1] = 0;
\r
1370 list_for_each_entry(ha, &list->list, list) {
\r
1373 /* skip non-multicast addresses */
\r
1374 if (!(*addrs & 1))
\r
1377 crc = ether_crc_le(ETH_ALEN, addrs);
\r
1378 set_bit(crc >> 26, bitmask);
\r
1382 struct netdev_hw_addr *ha;
\r
1383 unsigned long crc;
\r
1386 WARN_ON(netdev_mc_count(dev) == 0);
\r
1387 WARN_ON(dev->flags & IFF_ALLMULTI);
\r
1389 bitmask[0] = bitmask[1] = 0;
\r
1391 netdev_for_each_mc_addr(ha, dev) {
\r
1394 /* skip non-multicast addresses */
\r
1395 if (!(*addrs & 1))
\r
1398 crc = ether_crc_le(ETH_ALEN, addrs);
\r
1399 set_bit(crc >> 26, bitmask);
\r
1403 static void vmac_set_multicast_list(struct net_device *dev)
\r
1405 #if (LINUX_VERSION_CODE < KERNEL_VERSION(2, 6, 34))
\r
1406 struct vmac_priv *ap = netdev_priv(dev);
\r
1407 unsigned long flags, bitmask[2];
\r
1410 //printk("-----------------func %s-------------------\n", __func__);
\r
1412 spin_lock_irqsave(&ap->lock, flags);
\r
1414 promisc = !!(dev->flags & IFF_PROMISC);
\r
1415 reg = vmac_readl(ap, CONTROL);
\r
1416 if (promisc != !!(reg & PROM_MASK)) {
\r
1418 vmac_writel(ap, reg, CONTROL);
\r
1421 if (dev->flags & IFF_ALLMULTI)
\r
1422 memset(bitmask, 1, sizeof(bitmask));
\r
1423 else if (dev->mc_count == 0)
\r
1424 memset(bitmask, 0, sizeof(bitmask));
\r
1426 create_multicast_filter(dev, bitmask);
\r
1428 vmac_writel(ap, bitmask[0], LAFL);
\r
1429 vmac_writel(ap, bitmask[1], LAFH);
\r
1431 spin_unlock_irqrestore(&ap->lock, flags);
\r
1433 struct vmac_priv *ap = netdev_priv(dev);
\r
1434 unsigned long flags, bitmask[2];
\r
1437 spin_lock_irqsave(&ap->lock, flags);
\r
1439 promisc = !!(dev->flags & IFF_PROMISC);
\r
1440 reg = vmac_readl(ap, CONTROL);
\r
1441 if (promisc != !!(reg & PROM_MASK)) {
\r
1443 vmac_writel(ap, reg, CONTROL);
\r
1446 if (dev->flags & IFF_ALLMULTI)
\r
1447 memset(bitmask, 1, sizeof(bitmask));
\r
1448 else if (netdev_mc_count(dev) == 0)
\r
1449 memset(bitmask, 0, sizeof(bitmask));
\r
1451 create_multicast_filter(dev, bitmask);
\r
1453 vmac_writel(ap, bitmask[0], LAFL);
\r
1454 vmac_writel(ap, bitmask[1], LAFH);
\r
1456 spin_unlock_irqrestore(&ap->lock, flags);
\r
1460 static struct ethtool_ops vmac_ethtool_ops = {
\r
1461 .get_settings = vmacether_get_settings,
\r
1462 .set_settings = vmacether_set_settings,
\r
1463 .get_drvinfo = vmacether_get_drvinfo,
\r
1464 .get_link = ethtool_op_get_link,
\r
1467 static const struct net_device_ops vmac_netdev_ops = {
\r
1468 .ndo_open = vmac_open,
\r
1469 .ndo_stop = vmac_close,
\r
1470 .ndo_get_stats = vmac_stats,
\r
1471 .ndo_start_xmit = vmac_start_xmit,
\r
1472 .ndo_do_ioctl = vmac_ioctl,
\r
1473 .ndo_set_mac_address = eth_mac_addr,
\r
1474 .ndo_tx_timeout = vmac_tx_timeout,
\r
1475 .ndo_set_multicast_list = vmac_set_multicast_list,
\r
1476 .ndo_validate_addr = eth_validate_addr,
\r
1477 .ndo_change_mtu = eth_change_mtu,
\r
1480 static int __devinit vmac_probe(struct platform_device *pdev)
\r
1482 struct net_device *dev;
\r
1483 struct vmac_priv *ap;
\r
1484 struct resource *res;
\r
1485 unsigned int mem_base, mem_size, irq;
\r
1487 struct rk29_vmac_platform_data *pdata = pdev->dev.platform_data;
\r
1489 dev = alloc_etherdev(sizeof(*ap));
\r
1491 dev_err(&pdev->dev, "etherdev alloc failed, aborting.\n");
\r
1495 ap = netdev_priv(dev);
\r
1498 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
\r
1500 dev_err(&pdev->dev, "no mmio resource defined\n");
\r
1503 mem_base = res->start;
\r
1504 mem_size = resource_size(res);
\r
1505 irq = platform_get_irq(pdev, 0);
\r
1508 if (!request_mem_region(mem_base, mem_size, VMAC_NAME)) {
\r
1509 dev_err(&pdev->dev, "no memory region available\n");
\r
1514 ap->regs = ioremap(mem_base, mem_size);
\r
1516 dev_err(&pdev->dev, "failed to map registers, aborting.\n");
\r
1517 goto err_out_release_mem;
\r
1520 /* no checksum support, hence no scatter/gather */
\r
1521 dev->features |= NETIF_F_HIGHDMA;
\r
1523 spin_lock_init(&ap->lock);
\r
1525 SET_NETDEV_DEV(dev, &pdev->dev);
\r
1529 /* init rx timeout (used for oom) */
\r
1530 init_timer(&ap->rx_timeout);
\r
1531 ap->rx_timeout.function = vmac_refill_rx_timer;
\r
1532 ap->rx_timeout.data = (unsigned long)dev;
\r
1534 netif_napi_add(dev, &ap->napi, vmac_poll, 2);
\r
1535 dev->netdev_ops = &vmac_netdev_ops;
\r
1536 dev->ethtool_ops = &vmac_ethtool_ops;
\r
1539 dev->flags |= IFF_MULTICAST;////////////////////
\r
1541 dev->base_addr = (unsigned long)ap->regs;
\r
1542 ap->mem_base = mem_base;
\r
1544 /* prevent buffer chaining, favor speed over space */
\r
1545 ap->rx_skb_size = ETH_FRAME_LEN + VMAC_BUFFER_PAD;
\r
1547 /* private struct functional */
\r
1549 /* mac address intialize, set vmac_open */
\r
1550 read_mac_reg(dev, dev->dev_addr);
\r
1552 if (!is_valid_ether_addr(dev->dev_addr)) {
\r
1553 //add by cx@rock-chips.com
\r
1555 #ifdef CONFIG_ETH_MAC_FROM_EEPROM
\r
1556 ret = eeprom_read_data(0,dev->dev_addr,6);
\r
1558 printk("read mac from Eeprom fail.\n");
\r
1560 if (is_valid_ether_addr(dev->dev_addr)){
\r
1561 printk("eth_mac_from_eeprom***********:%X:%X:%X:%X:%X:%X\n",dev->dev_addr[0],
\r
1562 dev->dev_addr[1],dev->dev_addr[2],dev->dev_addr[3],
\r
1563 dev->dev_addr[4],dev->dev_addr[5] );
\r
1568 #ifdef CONFIG_ETH_MAC_FROM_IDB
\r
1569 err = eth_mac_idb(dev->dev_addr);
\r
1571 printk("read mac from IDB fail.\n");
\r
1573 if (is_valid_ether_addr(dev->dev_addr)) {
\r
1574 printk("eth_mac_from_idb***********:%X:%X:%X:%X:%X:%X\n",dev->dev_addr[0],
\r
1575 dev->dev_addr[1],dev->dev_addr[2],dev->dev_addr[3],
\r
1576 dev->dev_addr[4],dev->dev_addr[5] );
\r
1581 /*#ifdef CONFIG_ETH_MAC_FROM_WIFI_MAC
\r
1582 err = eth_mac_wifi(dev->dev_addr);
\r
1584 printk("read mac from Wifi fail.\n");
\r
1586 if (is_valid_ether_addr(dev->dev_addr)) {
\r
1587 printk("eth_mac_from_wifi_mac***********:%X:%X:%X:%X:%X:%X\n",dev->dev_addr[0],
\r
1588 dev->dev_addr[1],dev->dev_addr[2],dev->dev_addr[3],
\r
1589 dev->dev_addr[4],dev->dev_addr[5] );
\r
1594 #ifdef CONFIG_ETH_MAC_FROM_RANDOM
\r
1595 random_ether_addr(dev->dev_addr);
\r
1596 printk("random_ether_addr***********:%X:%X:%X:%X:%X:%X\n",dev->dev_addr[0],
\r
1597 dev->dev_addr[1],dev->dev_addr[2],dev->dev_addr[3],
\r
1598 dev->dev_addr[4],dev->dev_addr[5] );
\r
1603 err = register_netdev(dev);
\r
1605 dev_err(&pdev->dev, "Cannot register net device, aborting.\n");
\r
1606 goto err_out_iounmap;
\r
1609 dev_info(&pdev->dev, "ARC VMAC at 0x%08x irq %d %pM\n", mem_base,
\r
1610 dev->irq, dev->dev_addr);
\r
1611 platform_set_drvdata(pdev, dev);
\r
1613 ap->suspending = 0;
\r
1614 ap->open_flag = 0;
\r
1615 wake_lock_init(&idlelock, WAKE_LOCK_IDLE, "vmac");
\r
1616 wake_lock_init(&ap->resume_lock, WAKE_LOCK_SUSPEND, "vmac_resume");
\r
1618 //config rk29 vmac as rmii, 100MHz
\r
1619 if (pdata && pdata->vmac_register_set)
\r
1620 pdata->vmac_register_set();
\r
1622 //power gpio init, phy power off default for power reduce
\r
1623 if (pdata && pdata->rmii_io_init)
\r
1624 pdata->rmii_io_init();
\r
1629 iounmap(ap->regs);
\r
1630 err_out_release_mem:
\r
1631 release_mem_region(mem_base, mem_size);
\r
1637 static int __devexit vmac_remove(struct platform_device *pdev)
\r
1639 struct net_device *dev;
\r
1640 struct vmac_priv *ap;
\r
1641 struct resource *res;
\r
1642 struct rk29_vmac_platform_data *pdata = pdev->dev.platform_data;
\r
1644 wake_lock_destroy(&idlelock);
\r
1646 //power gpio deinit, phy power off
\r
1647 if (pdata && pdata->rmii_io_deinit)
\r
1648 pdata->rmii_io_deinit();
\r
1650 dev = platform_get_drvdata(pdev);
\r
1652 dev_err(&pdev->dev, "%s no valid dev found\n", __func__);
\r
1656 ap = netdev_priv(dev);
\r
1659 unregister_netdev(dev);
\r
1660 iounmap(ap->regs);
\r
1662 res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
\r
1663 release_mem_region(res->start, resource_size(res));
\r
1665 platform_set_drvdata(pdev, NULL);
\r
1670 static void rk29_vmac_power_off(struct net_device *dev)
\r
1672 struct vmac_priv *ap = netdev_priv(dev);
\r
1673 struct rk29_vmac_platform_data *pdata = ap->pdev->dev.platform_data;
\r
1675 printk("enter func %s...\n", __func__);
\r
1678 if (pdata && pdata->rmii_power_control)
\r
1679 pdata->rmii_power_control(0);
\r
1682 clk_disable(clk_get(NULL, "mac_ref_div"));
\r
1683 clk_disable(clk_get(NULL,"mii_rx"));
\r
1684 clk_disable(clk_get(NULL,"mii_tx"));
\r
1685 clk_disable(clk_get(NULL,"hclk_mac"));
\r
1686 clk_disable(clk_get(NULL,"mac_ref"));
\r
1691 rk29_vmac_suspend(struct device *dev)
\r
1693 struct platform_device *pdev = to_platform_device(dev);
\r
1694 struct net_device *ndev = platform_get_drvdata(pdev);
\r
1695 struct vmac_priv *ap = netdev_priv(ndev);
\r
1698 if (ap->open_flag == 1) {
\r
1699 netif_stop_queue(ndev);
\r
1700 netif_device_detach(ndev);
\r
1701 if (ap->suspending == 0) {
\r
1702 vmac_shutdown(ndev);
\r
1703 rk29_vmac_power_off(ndev);
\r
1704 ap->suspending = 1;
\r
1712 rk29_vmac_resume(struct device *dev)
\r
1714 struct platform_device *pdev = to_platform_device(dev);
\r
1715 struct net_device *ndev = platform_get_drvdata(pdev);
\r
1716 struct vmac_priv *ap = netdev_priv(ndev);
\r
1719 if (ap->open_flag == 1) {
\r
1720 netif_device_attach(ndev);
\r
1721 netif_start_queue(ndev);
\r
1727 static struct dev_pm_ops rk29_vmac_pm_ops = {
\r
1728 .suspend = rk29_vmac_suspend,
\r
1729 .resume = rk29_vmac_resume,
\r
1733 static struct platform_driver rk29_vmac_driver = {
\r
1734 .probe = vmac_probe,
\r
1735 .remove = __devexit_p(vmac_remove),
\r
1737 .name = "rk29 vmac",
\r
1738 .owner = THIS_MODULE,
\r
1739 .pm = &rk29_vmac_pm_ops,
\r
1743 static int __init vmac_init(void)
\r
1745 return platform_driver_register(&rk29_vmac_driver);
\r
1748 static void __exit vmac_exit(void)
\r
1750 platform_driver_unregister(&rk29_vmac_driver);
\r
1753 module_init(vmac_init);
\r
1754 module_exit(vmac_exit);
\r
1756 MODULE_LICENSE("GPL");
\r
1757 MODULE_DESCRIPTION("RK29 VMAC Ethernet driver");
\r
1758 MODULE_AUTHOR("amit.bhor@celunite.com, sameer.dhavale@celunite.com, andreas.fenkart@streamunlimited.com");
\r