Commit 1d22e05df8183b36b3cc0760344774040abc74d5

Authored by Lennert Buytenhek
Committed by Jeff Garzik
1 parent 28eb177dfa

[PATCH] Cirrus Logic ep93xx ethernet driver

The Cirrus Logic ep93xx is an ARM SoC that includes an ethernet MAC
-- this patch adds a driver for that ethernet MAC.

Signed-off-by: Lennert Buytenhek <buytenh@wantstofly.org>
Signed-off-by: Jeff Garzik <jeff@garzik.org>

Showing 5 changed files with 959 additions and 0 deletions Side-by-side Diff

drivers/net/arm/Kconfig
... ... @@ -39,4 +39,11 @@
39 39 help
40 40 If you wish to compile a kernel for the AT91RM9200 and enable
41 41 ethernet support, then you should always answer Y to this.
  42 +
  43 +config EP93XX_ETH
  44 + tristate "EP93xx Ethernet support"
  45 + depends on NET_ETHERNET && ARM && ARCH_EP93XX
  46 + help
  47 + This is a driver for the ethernet hardware included in EP93xx CPUs.
  48 + Say Y if you are building a kernel for EP93xx based devices.
drivers/net/arm/Makefile
... ... @@ -8,4 +8,5 @@
8 8 obj-$(CONFIG_ARM_ETHER3) += ether3.o
9 9 obj-$(CONFIG_ARM_ETHER1) += ether1.o
10 10 obj-$(CONFIG_ARM_AT91_ETHER) += at91_ether.o
  11 +obj-$(CONFIG_EP93XX_ETH) += ep93xx_eth.o
drivers/net/arm/ep93xx_eth.c
  1 +/*
  2 + * EP93xx ethernet network device driver
  3 + * Copyright (C) 2006 Lennert Buytenhek <buytenh@wantstofly.org>
  4 + * Dedicated to Marija Kulikova.
  5 + *
  6 + * This program is free software; you can redistribute it and/or modify
  7 + * it under the terms of the GNU General Public License as published by
  8 + * the Free Software Foundation; either version 2 of the License, or
  9 + * (at your option) any later version.
  10 + */
  11 +
  12 +#include <linux/config.h>
  13 +#include <linux/dma-mapping.h>
  14 +#include <linux/module.h>
  15 +#include <linux/kernel.h>
  16 +#include <linux/netdevice.h>
  17 +#include <linux/mii.h>
  18 +#include <linux/etherdevice.h>
  19 +#include <linux/ethtool.h>
  20 +#include <linux/init.h>
  21 +#include <linux/moduleparam.h>
  22 +#include <linux/platform_device.h>
  23 +#include <linux/delay.h>
  24 +#include <asm/arch/ep93xx-regs.h>
  25 +#include <asm/arch/platform.h>
  26 +#include <asm/io.h>
  27 +
  28 +#define DRV_MODULE_NAME "ep93xx-eth"
  29 +#define DRV_MODULE_VERSION "0.1"
  30 +
  31 +#define RX_QUEUE_ENTRIES 64
  32 +#define TX_QUEUE_ENTRIES 8
  33 +
  34 +#define MAX_PKT_SIZE 2044
  35 +#define PKT_BUF_SIZE 2048
  36 +
  37 +#define REG_RXCTL 0x0000
  38 +#define REG_RXCTL_DEFAULT 0x00073800
  39 +#define REG_TXCTL 0x0004
  40 +#define REG_TXCTL_ENABLE 0x00000001
  41 +#define REG_MIICMD 0x0010
  42 +#define REG_MIICMD_READ 0x00008000
  43 +#define REG_MIICMD_WRITE 0x00004000
  44 +#define REG_MIIDATA 0x0014
  45 +#define REG_MIISTS 0x0018
  46 +#define REG_MIISTS_BUSY 0x00000001
  47 +#define REG_SELFCTL 0x0020
  48 +#define REG_SELFCTL_RESET 0x00000001
  49 +#define REG_INTEN 0x0024
  50 +#define REG_INTEN_TX 0x00000008
  51 +#define REG_INTEN_RX 0x00000007
  52 +#define REG_INTSTSP 0x0028
  53 +#define REG_INTSTS_TX 0x00000008
  54 +#define REG_INTSTS_RX 0x00000004
  55 +#define REG_INTSTSC 0x002c
  56 +#define REG_AFP 0x004c
  57 +#define REG_INDAD0 0x0050
  58 +#define REG_INDAD1 0x0051
  59 +#define REG_INDAD2 0x0052
  60 +#define REG_INDAD3 0x0053
  61 +#define REG_INDAD4 0x0054
  62 +#define REG_INDAD5 0x0055
  63 +#define REG_GIINTMSK 0x0064
  64 +#define REG_GIINTMSK_ENABLE 0x00008000
  65 +#define REG_BMCTL 0x0080
  66 +#define REG_BMCTL_ENABLE_TX 0x00000100
  67 +#define REG_BMCTL_ENABLE_RX 0x00000001
  68 +#define REG_BMSTS 0x0084
  69 +#define REG_BMSTS_RX_ACTIVE 0x00000008
  70 +#define REG_RXDQBADD 0x0090
  71 +#define REG_RXDQBLEN 0x0094
  72 +#define REG_RXDCURADD 0x0098
  73 +#define REG_RXDENQ 0x009c
  74 +#define REG_RXSTSQBADD 0x00a0
  75 +#define REG_RXSTSQBLEN 0x00a4
  76 +#define REG_RXSTSQCURADD 0x00a8
  77 +#define REG_RXSTSENQ 0x00ac
  78 +#define REG_TXDQBADD 0x00b0
  79 +#define REG_TXDQBLEN 0x00b4
  80 +#define REG_TXDQCURADD 0x00b8
  81 +#define REG_TXDENQ 0x00bc
  82 +#define REG_TXSTSQBADD 0x00c0
  83 +#define REG_TXSTSQBLEN 0x00c4
  84 +#define REG_TXSTSQCURADD 0x00c8
  85 +#define REG_MAXFRMLEN 0x00e8
  86 +
  87 +struct ep93xx_rdesc
  88 +{
  89 + u32 buf_addr;
  90 + u32 rdesc1;
  91 +};
  92 +
  93 +#define RDESC1_NSOF 0x80000000
  94 +#define RDESC1_BUFFER_INDEX 0x7fff0000
  95 +#define RDESC1_BUFFER_LENGTH 0x0000ffff
  96 +
  97 +struct ep93xx_rstat
  98 +{
  99 + u32 rstat0;
  100 + u32 rstat1;
  101 +};
  102 +
  103 +#define RSTAT0_RFP 0x80000000
  104 +#define RSTAT0_RWE 0x40000000
  105 +#define RSTAT0_EOF 0x20000000
  106 +#define RSTAT0_EOB 0x10000000
  107 +#define RSTAT0_AM 0x00c00000
  108 +#define RSTAT0_RX_ERR 0x00200000
  109 +#define RSTAT0_OE 0x00100000
  110 +#define RSTAT0_FE 0x00080000
  111 +#define RSTAT0_RUNT 0x00040000
  112 +#define RSTAT0_EDATA 0x00020000
  113 +#define RSTAT0_CRCE 0x00010000
  114 +#define RSTAT0_CRCI 0x00008000
  115 +#define RSTAT0_HTI 0x00003f00
  116 +#define RSTAT1_RFP 0x80000000
  117 +#define RSTAT1_BUFFER_INDEX 0x7fff0000
  118 +#define RSTAT1_FRAME_LENGTH 0x0000ffff
  119 +
  120 +struct ep93xx_tdesc
  121 +{
  122 + u32 buf_addr;
  123 + u32 tdesc1;
  124 +};
  125 +
  126 +#define TDESC1_EOF 0x80000000
  127 +#define TDESC1_BUFFER_INDEX 0x7fff0000
  128 +#define TDESC1_BUFFER_ABORT 0x00008000
  129 +#define TDESC1_BUFFER_LENGTH 0x00000fff
  130 +
  131 +struct ep93xx_tstat
  132 +{
  133 + u32 tstat0;
  134 +};
  135 +
  136 +#define TSTAT0_TXFP 0x80000000
  137 +#define TSTAT0_TXWE 0x40000000
  138 +#define TSTAT0_FA 0x20000000
  139 +#define TSTAT0_LCRS 0x10000000
  140 +#define TSTAT0_OW 0x04000000
  141 +#define TSTAT0_TXU 0x02000000
  142 +#define TSTAT0_ECOLL 0x01000000
  143 +#define TSTAT0_NCOLL 0x001f0000
  144 +#define TSTAT0_BUFFER_INDEX 0x00007fff
  145 +
  146 +struct ep93xx_descs
  147 +{
  148 + struct ep93xx_rdesc rdesc[RX_QUEUE_ENTRIES];
  149 + struct ep93xx_tdesc tdesc[TX_QUEUE_ENTRIES];
  150 + struct ep93xx_rstat rstat[RX_QUEUE_ENTRIES];
  151 + struct ep93xx_tstat tstat[TX_QUEUE_ENTRIES];
  152 +};
  153 +
  154 +struct ep93xx_priv
  155 +{
  156 + struct resource *res;
  157 + void *base_addr;
  158 + int irq;
  159 +
  160 + struct ep93xx_descs *descs;
  161 + dma_addr_t descs_dma_addr;
  162 +
  163 + void *rx_buf[RX_QUEUE_ENTRIES];
  164 + void *tx_buf[TX_QUEUE_ENTRIES];
  165 +
  166 + spinlock_t rx_lock;
  167 + unsigned int rx_pointer;
  168 + unsigned int tx_clean_pointer;
  169 + unsigned int tx_pointer;
  170 + spinlock_t tx_pending_lock;
  171 + unsigned int tx_pending;
  172 +
  173 + struct net_device_stats stats;
  174 +
  175 + struct mii_if_info mii;
  176 + u8 mdc_divisor;
  177 +};
  178 +
  179 +#define rdb(ep, off) __raw_readb((ep)->base_addr + (off))
  180 +#define rdw(ep, off) __raw_readw((ep)->base_addr + (off))
  181 +#define rdl(ep, off) __raw_readl((ep)->base_addr + (off))
  182 +#define wrb(ep, off, val) __raw_writeb((val), (ep)->base_addr + (off))
  183 +#define wrw(ep, off, val) __raw_writew((val), (ep)->base_addr + (off))
  184 +#define wrl(ep, off, val) __raw_writel((val), (ep)->base_addr + (off))
  185 +
  186 +static int ep93xx_mdio_read(struct net_device *dev, int phy_id, int reg);
  187 +
  188 +static struct net_device_stats *ep93xx_get_stats(struct net_device *dev)
  189 +{
  190 + struct ep93xx_priv *ep = netdev_priv(dev);
  191 + return &(ep->stats);
  192 +}
  193 +
  194 +static int ep93xx_rx(struct net_device *dev, int *budget)
  195 +{
  196 + struct ep93xx_priv *ep = netdev_priv(dev);
  197 + int tail_offset;
  198 + int rx_done;
  199 + int processed;
  200 +
  201 + tail_offset = rdl(ep, REG_RXSTSQCURADD) - ep->descs_dma_addr;
  202 +
  203 + rx_done = 0;
  204 + processed = 0;
  205 + while (*budget > 0) {
  206 + int entry;
  207 + struct ep93xx_rstat *rstat;
  208 + u32 rstat0;
  209 + u32 rstat1;
  210 + int length;
  211 + struct sk_buff *skb;
  212 +
  213 + entry = ep->rx_pointer;
  214 + rstat = ep->descs->rstat + entry;
  215 + if ((void *)rstat - (void *)ep->descs == tail_offset) {
  216 + rx_done = 1;
  217 + break;
  218 + }
  219 +
  220 + rstat0 = rstat->rstat0;
  221 + rstat1 = rstat->rstat1;
  222 + rstat->rstat0 = 0;
  223 + rstat->rstat1 = 0;
  224 +
  225 + if (!(rstat0 & RSTAT0_RFP))
  226 + printk(KERN_CRIT "ep93xx_rx: buffer not done "
  227 + " %.8x %.8x\n", rstat0, rstat1);
  228 + if (!(rstat0 & RSTAT0_EOF))
  229 + printk(KERN_CRIT "ep93xx_rx: not end-of-frame "
  230 + " %.8x %.8x\n", rstat0, rstat1);
  231 + if (!(rstat0 & RSTAT0_EOB))
  232 + printk(KERN_CRIT "ep93xx_rx: not end-of-buffer "
  233 + " %.8x %.8x\n", rstat0, rstat1);
  234 + if (!(rstat1 & RSTAT1_RFP))
  235 + printk(KERN_CRIT "ep93xx_rx: buffer1 not done "
  236 + " %.8x %.8x\n", rstat0, rstat1);
  237 + if ((rstat1 & RSTAT1_BUFFER_INDEX) >> 16 != entry)
  238 + printk(KERN_CRIT "ep93xx_rx: entry mismatch "
  239 + " %.8x %.8x\n", rstat0, rstat1);
  240 +
  241 + if (!(rstat0 & RSTAT0_RWE)) {
  242 + printk(KERN_NOTICE "ep93xx_rx: receive error "
  243 + " %.8x %.8x\n", rstat0, rstat1);
  244 +
  245 + ep->stats.rx_errors++;
  246 + if (rstat0 & RSTAT0_OE)
  247 + ep->stats.rx_fifo_errors++;
  248 + if (rstat0 & RSTAT0_FE)
  249 + ep->stats.rx_frame_errors++;
  250 + if (rstat0 & (RSTAT0_RUNT | RSTAT0_EDATA))
  251 + ep->stats.rx_length_errors++;
  252 + if (rstat0 & RSTAT0_CRCE)
  253 + ep->stats.rx_crc_errors++;
  254 + goto err;
  255 + }
  256 +
  257 + length = rstat1 & RSTAT1_FRAME_LENGTH;
  258 + if (length > MAX_PKT_SIZE) {
  259 + printk(KERN_NOTICE "ep93xx_rx: invalid length "
  260 + " %.8x %.8x\n", rstat0, rstat1);
  261 + goto err;
  262 + }
  263 +
  264 + /* Strip FCS. */
  265 + if (rstat0 & RSTAT0_CRCI)
  266 + length -= 4;
  267 +
  268 + skb = dev_alloc_skb(length + 2);
  269 + if (likely(skb != NULL)) {
  270 + skb->dev = dev;
  271 + skb_reserve(skb, 2);
  272 + dma_sync_single(NULL, ep->descs->rdesc[entry].buf_addr,
  273 + length, DMA_FROM_DEVICE);
  274 + eth_copy_and_sum(skb, ep->rx_buf[entry], length, 0);
  275 + skb_put(skb, length);
  276 + skb->protocol = eth_type_trans(skb, dev);
  277 +
  278 + dev->last_rx = jiffies;
  279 +
  280 + netif_receive_skb(skb);
  281 +
  282 + ep->stats.rx_packets++;
  283 + ep->stats.rx_bytes += length;
  284 + } else {
  285 + ep->stats.rx_dropped++;
  286 + }
  287 +
  288 +err:
  289 + ep->rx_pointer = (entry + 1) & (RX_QUEUE_ENTRIES - 1);
  290 + processed++;
  291 + dev->quota--;
  292 + (*budget)--;
  293 + }
  294 +
  295 + if (processed) {
  296 + wrw(ep, REG_RXDENQ, processed);
  297 + wrw(ep, REG_RXSTSENQ, processed);
  298 + }
  299 +
  300 + return !rx_done;
  301 +}
  302 +
  303 +static int ep93xx_have_more_rx(struct ep93xx_priv *ep)
  304 +{
  305 + struct ep93xx_rstat *rstat;
  306 + int tail_offset;
  307 +
  308 + rstat = ep->descs->rstat + ep->rx_pointer;
  309 + tail_offset = rdl(ep, REG_RXSTSQCURADD) - ep->descs_dma_addr;
  310 +
  311 + return !((void *)rstat - (void *)ep->descs == tail_offset);
  312 +}
  313 +
  314 +static int ep93xx_poll(struct net_device *dev, int *budget)
  315 +{
  316 + struct ep93xx_priv *ep = netdev_priv(dev);
  317 +
  318 + /*
  319 + * @@@ Have to stop polling if device is downed while we
  320 + * are polling.
  321 + */
  322 +
  323 +poll_some_more:
  324 + if (ep93xx_rx(dev, budget))
  325 + return 1;
  326 +
  327 + netif_rx_complete(dev);
  328 +
  329 + spin_lock_irq(&ep->rx_lock);
  330 + wrl(ep, REG_INTEN, REG_INTEN_TX | REG_INTEN_RX);
  331 + if (ep93xx_have_more_rx(ep)) {
  332 + wrl(ep, REG_INTEN, REG_INTEN_TX);
  333 + wrl(ep, REG_INTSTSP, REG_INTSTS_RX);
  334 + spin_unlock_irq(&ep->rx_lock);
  335 +
  336 + if (netif_rx_reschedule(dev, 0))
  337 + goto poll_some_more;
  338 +
  339 + return 0;
  340 + }
  341 + spin_unlock_irq(&ep->rx_lock);
  342 +
  343 + return 0;
  344 +}
  345 +
  346 +static int ep93xx_xmit(struct sk_buff *skb, struct net_device *dev)
  347 +{
  348 + struct ep93xx_priv *ep = netdev_priv(dev);
  349 + int entry;
  350 +
  351 + if (unlikely(skb->len) > MAX_PKT_SIZE) {
  352 + ep->stats.tx_dropped++;
  353 + dev_kfree_skb(skb);
  354 + return NETDEV_TX_OK;
  355 + }
  356 +
  357 + entry = ep->tx_pointer;
  358 + ep->tx_pointer = (ep->tx_pointer + 1) & (TX_QUEUE_ENTRIES - 1);
  359 +
  360 + ep->descs->tdesc[entry].tdesc1 =
  361 + TDESC1_EOF | (entry << 16) | (skb->len & 0xfff);
  362 + skb_copy_and_csum_dev(skb, ep->tx_buf[entry]);
  363 + dma_sync_single(NULL, ep->descs->tdesc[entry].buf_addr,
  364 + skb->len, DMA_TO_DEVICE);
  365 + dev_kfree_skb(skb);
  366 +
  367 + dev->trans_start = jiffies;
  368 +
  369 + spin_lock_irq(&ep->tx_pending_lock);
  370 + ep->tx_pending++;
  371 + if (ep->tx_pending == TX_QUEUE_ENTRIES)
  372 + netif_stop_queue(dev);
  373 + spin_unlock_irq(&ep->tx_pending_lock);
  374 +
  375 + wrl(ep, REG_TXDENQ, 1);
  376 +
  377 + return NETDEV_TX_OK;
  378 +}
  379 +
  380 +static void ep93xx_tx_complete(struct net_device *dev)
  381 +{
  382 + struct ep93xx_priv *ep = netdev_priv(dev);
  383 + int tail_offset;
  384 + int wake;
  385 +
  386 + tail_offset = rdl(ep, REG_TXSTSQCURADD) - ep->descs_dma_addr;
  387 + wake = 0;
  388 +
  389 + spin_lock(&ep->tx_pending_lock);
  390 + while (1) {
  391 + int entry;
  392 + struct ep93xx_tstat *tstat;
  393 + u32 tstat0;
  394 +
  395 + entry = ep->tx_clean_pointer;
  396 + tstat = ep->descs->tstat + entry;
  397 + if ((void *)tstat - (void *)ep->descs == tail_offset)
  398 + break;
  399 +
  400 + tstat0 = tstat->tstat0;
  401 + tstat->tstat0 = 0;
  402 +
  403 + if (!(tstat0 & TSTAT0_TXFP))
  404 + printk(KERN_CRIT "ep93xx_tx_complete: buffer not done "
  405 + " %.8x\n", tstat0);
  406 + if (tstat0 & TSTAT0_FA)
  407 + printk(KERN_CRIT "ep93xx_tx_complete: frame aborted "
  408 + " %.8x\n", tstat0);
  409 + if ((tstat0 & TSTAT0_BUFFER_INDEX) != entry)
  410 + printk(KERN_CRIT "ep93xx_tx_complete: entry mismatch "
  411 + " %.8x\n", tstat0);
  412 +
  413 + if (tstat0 & TSTAT0_TXWE) {
  414 + int length = ep->descs->tdesc[entry].tdesc1 & 0xfff;
  415 +
  416 + ep->stats.tx_packets++;
  417 + ep->stats.tx_bytes += length;
  418 + } else {
  419 + ep->stats.tx_errors++;
  420 + }
  421 +
  422 + if (tstat0 & TSTAT0_OW)
  423 + ep->stats.tx_window_errors++;
  424 + if (tstat0 & TSTAT0_TXU)
  425 + ep->stats.tx_fifo_errors++;
  426 + ep->stats.collisions += (tstat0 >> 16) & 0x1f;
  427 +
  428 + ep->tx_clean_pointer = (entry + 1) & (TX_QUEUE_ENTRIES - 1);
  429 + if (ep->tx_pending == TX_QUEUE_ENTRIES)
  430 + wake = 1;
  431 + ep->tx_pending--;
  432 + }
  433 + spin_unlock(&ep->tx_pending_lock);
  434 +
  435 + if (wake)
  436 + netif_wake_queue(dev);
  437 +}
  438 +
  439 +static irqreturn_t ep93xx_irq(int irq, void *dev_id, struct pt_regs *regs)
  440 +{
  441 + struct net_device *dev = dev_id;
  442 + struct ep93xx_priv *ep = netdev_priv(dev);
  443 + u32 status;
  444 +
  445 + status = rdl(ep, REG_INTSTSC);
  446 + if (status == 0)
  447 + return IRQ_NONE;
  448 +
  449 + if (status & REG_INTSTS_RX) {
  450 + spin_lock(&ep->rx_lock);
  451 + if (likely(__netif_rx_schedule_prep(dev))) {
  452 + wrl(ep, REG_INTEN, REG_INTEN_TX);
  453 + __netif_rx_schedule(dev);
  454 + }
  455 + spin_unlock(&ep->rx_lock);
  456 + }
  457 +
  458 + if (status & REG_INTSTS_TX)
  459 + ep93xx_tx_complete(dev);
  460 +
  461 + return IRQ_HANDLED;
  462 +}
  463 +
  464 +static void ep93xx_free_buffers(struct ep93xx_priv *ep)
  465 +{
  466 + int i;
  467 +
  468 + for (i = 0; i < RX_QUEUE_ENTRIES; i += 2) {
  469 + dma_addr_t d;
  470 +
  471 + d = ep->descs->rdesc[i].buf_addr;
  472 + if (d)
  473 + dma_unmap_single(NULL, d, PAGE_SIZE, DMA_FROM_DEVICE);
  474 +
  475 + if (ep->rx_buf[i] != NULL)
  476 + free_page((unsigned long)ep->rx_buf[i]);
  477 + }
  478 +
  479 + for (i = 0; i < TX_QUEUE_ENTRIES; i += 2) {
  480 + dma_addr_t d;
  481 +
  482 + d = ep->descs->tdesc[i].buf_addr;
  483 + if (d)
  484 + dma_unmap_single(NULL, d, PAGE_SIZE, DMA_TO_DEVICE);
  485 +
  486 + if (ep->tx_buf[i] != NULL)
  487 + free_page((unsigned long)ep->tx_buf[i]);
  488 + }
  489 +
  490 + dma_free_coherent(NULL, sizeof(struct ep93xx_descs), ep->descs,
  491 + ep->descs_dma_addr);
  492 +}
  493 +
  494 +/*
  495 + * The hardware enforces a sub-2K maximum packet size, so we put
  496 + * two buffers on every hardware page.
  497 + */
  498 +static int ep93xx_alloc_buffers(struct ep93xx_priv *ep)
  499 +{
  500 + int i;
  501 +
  502 + ep->descs = dma_alloc_coherent(NULL, sizeof(struct ep93xx_descs),
  503 + &ep->descs_dma_addr, GFP_KERNEL | GFP_DMA);
  504 + if (ep->descs == NULL)
  505 + return 1;
  506 +
  507 + for (i = 0; i < RX_QUEUE_ENTRIES; i += 2) {
  508 + void *page;
  509 + dma_addr_t d;
  510 +
  511 + page = (void *)__get_free_page(GFP_KERNEL | GFP_DMA);
  512 + if (page == NULL)
  513 + goto err;
  514 +
  515 + d = dma_map_single(NULL, page, PAGE_SIZE, DMA_FROM_DEVICE);
  516 + if (dma_mapping_error(d)) {
  517 + free_page((unsigned long)page);
  518 + goto err;
  519 + }
  520 +
  521 + ep->rx_buf[i] = page;
  522 + ep->descs->rdesc[i].buf_addr = d;
  523 + ep->descs->rdesc[i].rdesc1 = (i << 16) | PKT_BUF_SIZE;
  524 +
  525 + ep->rx_buf[i + 1] = page + PKT_BUF_SIZE;
  526 + ep->descs->rdesc[i + 1].buf_addr = d + PKT_BUF_SIZE;
  527 + ep->descs->rdesc[i + 1].rdesc1 = ((i + 1) << 16) | PKT_BUF_SIZE;
  528 + }
  529 +
  530 + for (i = 0; i < TX_QUEUE_ENTRIES; i += 2) {
  531 + void *page;
  532 + dma_addr_t d;
  533 +
  534 + page = (void *)__get_free_page(GFP_KERNEL | GFP_DMA);
  535 + if (page == NULL)
  536 + goto err;
  537 +
  538 + d = dma_map_single(NULL, page, PAGE_SIZE, DMA_TO_DEVICE);
  539 + if (dma_mapping_error(d)) {
  540 + free_page((unsigned long)page);
  541 + goto err;
  542 + }
  543 +
  544 + ep->tx_buf[i] = page;
  545 + ep->descs->tdesc[i].buf_addr = d;
  546 +
  547 + ep->tx_buf[i + 1] = page + PKT_BUF_SIZE;
  548 + ep->descs->tdesc[i + 1].buf_addr = d + PKT_BUF_SIZE;
  549 + }
  550 +
  551 + return 0;
  552 +
  553 +err:
  554 + ep93xx_free_buffers(ep);
  555 + return 1;
  556 +}
  557 +
  558 +static int ep93xx_start_hw(struct net_device *dev)
  559 +{
  560 + struct ep93xx_priv *ep = netdev_priv(dev);
  561 + unsigned long addr;
  562 + int i;
  563 +
  564 + wrl(ep, REG_SELFCTL, REG_SELFCTL_RESET);
  565 + for (i = 0; i < 10; i++) {
  566 + if ((rdl(ep, REG_SELFCTL) & REG_SELFCTL_RESET) == 0)
  567 + break;
  568 + msleep(1);
  569 + }
  570 +
  571 + if (i == 10) {
  572 + printk(KERN_CRIT DRV_MODULE_NAME ": hw failed to reset\n");
  573 + return 1;
  574 + }
  575 +
  576 + wrl(ep, REG_SELFCTL, ((ep->mdc_divisor - 1) << 9));
  577 +
  578 + /* Does the PHY support preamble suppress? */
  579 + if ((ep93xx_mdio_read(dev, ep->mii.phy_id, MII_BMSR) & 0x0040) != 0)
  580 + wrl(ep, REG_SELFCTL, ((ep->mdc_divisor - 1) << 9) | (1 << 8));
  581 +
  582 + /* Receive descriptor ring. */
  583 + addr = ep->descs_dma_addr + offsetof(struct ep93xx_descs, rdesc);
  584 + wrl(ep, REG_RXDQBADD, addr);
  585 + wrl(ep, REG_RXDCURADD, addr);
  586 + wrw(ep, REG_RXDQBLEN, RX_QUEUE_ENTRIES * sizeof(struct ep93xx_rdesc));
  587 +
  588 + /* Receive status ring. */
  589 + addr = ep->descs_dma_addr + offsetof(struct ep93xx_descs, rstat);
  590 + wrl(ep, REG_RXSTSQBADD, addr);
  591 + wrl(ep, REG_RXSTSQCURADD, addr);
  592 + wrw(ep, REG_RXSTSQBLEN, RX_QUEUE_ENTRIES * sizeof(struct ep93xx_rstat));
  593 +
  594 + /* Transmit descriptor ring. */
  595 + addr = ep->descs_dma_addr + offsetof(struct ep93xx_descs, tdesc);
  596 + wrl(ep, REG_TXDQBADD, addr);
  597 + wrl(ep, REG_TXDQCURADD, addr);
  598 + wrw(ep, REG_TXDQBLEN, TX_QUEUE_ENTRIES * sizeof(struct ep93xx_tdesc));
  599 +
  600 + /* Transmit status ring. */
  601 + addr = ep->descs_dma_addr + offsetof(struct ep93xx_descs, tstat);
  602 + wrl(ep, REG_TXSTSQBADD, addr);
  603 + wrl(ep, REG_TXSTSQCURADD, addr);
  604 + wrw(ep, REG_TXSTSQBLEN, TX_QUEUE_ENTRIES * sizeof(struct ep93xx_tstat));
  605 +
  606 + wrl(ep, REG_BMCTL, REG_BMCTL_ENABLE_TX | REG_BMCTL_ENABLE_RX);
  607 + wrl(ep, REG_INTEN, REG_INTEN_TX | REG_INTEN_RX);
  608 + wrl(ep, REG_GIINTMSK, 0);
  609 +
  610 + for (i = 0; i < 10; i++) {
  611 + if ((rdl(ep, REG_BMSTS) & REG_BMSTS_RX_ACTIVE) != 0)
  612 + break;
  613 + msleep(1);
  614 + }
  615 +
  616 + if (i == 10) {
  617 + printk(KERN_CRIT DRV_MODULE_NAME ": hw failed to start\n");
  618 + return 1;
  619 + }
  620 +
  621 + wrl(ep, REG_RXDENQ, RX_QUEUE_ENTRIES);
  622 + wrl(ep, REG_RXSTSENQ, RX_QUEUE_ENTRIES);
  623 +
  624 + wrb(ep, REG_INDAD0, dev->dev_addr[0]);
  625 + wrb(ep, REG_INDAD1, dev->dev_addr[1]);
  626 + wrb(ep, REG_INDAD2, dev->dev_addr[2]);
  627 + wrb(ep, REG_INDAD3, dev->dev_addr[3]);
  628 + wrb(ep, REG_INDAD4, dev->dev_addr[4]);
  629 + wrb(ep, REG_INDAD5, dev->dev_addr[5]);
  630 + wrl(ep, REG_AFP, 0);
  631 +
  632 + wrl(ep, REG_MAXFRMLEN, (MAX_PKT_SIZE << 16) | MAX_PKT_SIZE);
  633 +
  634 + wrl(ep, REG_RXCTL, REG_RXCTL_DEFAULT);
  635 + wrl(ep, REG_TXCTL, REG_TXCTL_ENABLE);
  636 +
  637 + return 0;
  638 +}
  639 +
  640 +static void ep93xx_stop_hw(struct net_device *dev)
  641 +{
  642 + struct ep93xx_priv *ep = netdev_priv(dev);
  643 + int i;
  644 +
  645 + wrl(ep, REG_SELFCTL, REG_SELFCTL_RESET);
  646 + for (i = 0; i < 10; i++) {
  647 + if ((rdl(ep, REG_SELFCTL) & REG_SELFCTL_RESET) == 0)
  648 + break;
  649 + msleep(1);
  650 + }
  651 +
  652 + if (i == 10)
  653 + printk(KERN_CRIT DRV_MODULE_NAME ": hw failed to reset\n");
  654 +}
  655 +
  656 +static int ep93xx_open(struct net_device *dev)
  657 +{
  658 + struct ep93xx_priv *ep = netdev_priv(dev);
  659 + int err;
  660 +
  661 + if (ep93xx_alloc_buffers(ep))
  662 + return -ENOMEM;
  663 +
  664 + if (is_zero_ether_addr(dev->dev_addr)) {
  665 + random_ether_addr(dev->dev_addr);
  666 + printk(KERN_INFO "%s: generated random MAC address "
  667 + "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x.\n", dev->name,
  668 + dev->dev_addr[0], dev->dev_addr[1],
  669 + dev->dev_addr[2], dev->dev_addr[3],
  670 + dev->dev_addr[4], dev->dev_addr[5]);
  671 + }
  672 +
  673 + if (ep93xx_start_hw(dev)) {
  674 + ep93xx_free_buffers(ep);
  675 + return -EIO;
  676 + }
  677 +
  678 + spin_lock_init(&ep->rx_lock);
  679 + ep->rx_pointer = 0;
  680 + ep->tx_clean_pointer = 0;
  681 + ep->tx_pointer = 0;
  682 + spin_lock_init(&ep->tx_pending_lock);
  683 + ep->tx_pending = 0;
  684 +
  685 + err = request_irq(ep->irq, ep93xx_irq, IRQF_SHARED, dev->name, dev);
  686 + if (err) {
  687 + ep93xx_stop_hw(dev);
  688 + ep93xx_free_buffers(ep);
  689 + return err;
  690 + }
  691 +
  692 + wrl(ep, REG_GIINTMSK, REG_GIINTMSK_ENABLE);
  693 +
  694 + netif_start_queue(dev);
  695 +
  696 + return 0;
  697 +}
  698 +
  699 +static int ep93xx_close(struct net_device *dev)
  700 +{
  701 + struct ep93xx_priv *ep = netdev_priv(dev);
  702 +
  703 + netif_stop_queue(dev);
  704 +
  705 + wrl(ep, REG_GIINTMSK, 0);
  706 + free_irq(ep->irq, dev);
  707 + ep93xx_stop_hw(dev);
  708 + ep93xx_free_buffers(ep);
  709 +
  710 + return 0;
  711 +}
  712 +
  713 +static int ep93xx_ioctl(struct net_device *dev, struct ifreq *ifr, int cmd)
  714 +{
  715 + struct ep93xx_priv *ep = netdev_priv(dev);
  716 + struct mii_ioctl_data *data = if_mii(ifr);
  717 +
  718 + return generic_mii_ioctl(&ep->mii, data, cmd, NULL);
  719 +}
  720 +
  721 +static int ep93xx_mdio_read(struct net_device *dev, int phy_id, int reg)
  722 +{
  723 + struct ep93xx_priv *ep = netdev_priv(dev);
  724 + int data;
  725 + int i;
  726 +
  727 + wrl(ep, REG_MIICMD, REG_MIICMD_READ | (phy_id << 5) | reg);
  728 +
  729 + for (i = 0; i < 10; i++) {
  730 + if ((rdl(ep, REG_MIISTS) & REG_MIISTS_BUSY) == 0)
  731 + break;
  732 + msleep(1);
  733 + }
  734 +
  735 + if (i == 10) {
  736 + printk(KERN_INFO DRV_MODULE_NAME ": mdio read timed out\n");
  737 + data = 0xffff;
  738 + } else {
  739 + data = rdl(ep, REG_MIIDATA);
  740 + }
  741 +
  742 + return data;
  743 +}
  744 +
  745 +static void ep93xx_mdio_write(struct net_device *dev, int phy_id, int reg, int data)
  746 +{
  747 + struct ep93xx_priv *ep = netdev_priv(dev);
  748 + int i;
  749 +
  750 + wrl(ep, REG_MIIDATA, data);
  751 + wrl(ep, REG_MIICMD, REG_MIICMD_WRITE | (phy_id << 5) | reg);
  752 +
  753 + for (i = 0; i < 10; i++) {
  754 + if ((rdl(ep, REG_MIISTS) & REG_MIISTS_BUSY) == 0)
  755 + break;
  756 + msleep(1);
  757 + }
  758 +
  759 + if (i == 10)
  760 + printk(KERN_INFO DRV_MODULE_NAME ": mdio write timed out\n");
  761 +}
  762 +
  763 +static void ep93xx_get_drvinfo(struct net_device *dev, struct ethtool_drvinfo *info)
  764 +{
  765 + strcpy(info->driver, DRV_MODULE_NAME);
  766 + strcpy(info->version, DRV_MODULE_VERSION);
  767 +}
  768 +
  769 +static int ep93xx_get_settings(struct net_device *dev, struct ethtool_cmd *cmd)
  770 +{
  771 + struct ep93xx_priv *ep = netdev_priv(dev);
  772 + return mii_ethtool_gset(&ep->mii, cmd);
  773 +}
  774 +
  775 +static int ep93xx_set_settings(struct net_device *dev, struct ethtool_cmd *cmd)
  776 +{
  777 + struct ep93xx_priv *ep = netdev_priv(dev);
  778 + return mii_ethtool_sset(&ep->mii, cmd);
  779 +}
  780 +
  781 +static int ep93xx_nway_reset(struct net_device *dev)
  782 +{
  783 + struct ep93xx_priv *ep = netdev_priv(dev);
  784 + return mii_nway_restart(&ep->mii);
  785 +}
  786 +
  787 +static u32 ep93xx_get_link(struct net_device *dev)
  788 +{
  789 + struct ep93xx_priv *ep = netdev_priv(dev);
  790 + return mii_link_ok(&ep->mii);
  791 +}
  792 +
  793 +static struct ethtool_ops ep93xx_ethtool_ops = {
  794 + .get_drvinfo = ep93xx_get_drvinfo,
  795 + .get_settings = ep93xx_get_settings,
  796 + .set_settings = ep93xx_set_settings,
  797 + .nway_reset = ep93xx_nway_reset,
  798 + .get_link = ep93xx_get_link,
  799 +};
  800 +
  801 +struct net_device *ep93xx_dev_alloc(struct ep93xx_eth_data *data)
  802 +{
  803 + struct net_device *dev;
  804 + struct ep93xx_priv *ep;
  805 +
  806 + dev = alloc_etherdev(sizeof(struct ep93xx_priv));
  807 + if (dev == NULL)
  808 + return NULL;
  809 + ep = netdev_priv(dev);
  810 +
  811 + memcpy(dev->dev_addr, data->dev_addr, ETH_ALEN);
  812 +
  813 + dev->get_stats = ep93xx_get_stats;
  814 + dev->ethtool_ops = &ep93xx_ethtool_ops;
  815 + dev->poll = ep93xx_poll;
  816 + dev->hard_start_xmit = ep93xx_xmit;
  817 + dev->open = ep93xx_open;
  818 + dev->stop = ep93xx_close;
  819 + dev->do_ioctl = ep93xx_ioctl;
  820 +
  821 + dev->features |= NETIF_F_SG | NETIF_F_HW_CSUM;
  822 + dev->weight = 64;
  823 +
  824 + return dev;
  825 +}
  826 +
  827 +
  828 +static int ep93xx_eth_remove(struct platform_device *pdev)
  829 +{
  830 + struct net_device *dev;
  831 + struct ep93xx_priv *ep;
  832 +
  833 + dev = platform_get_drvdata(pdev);
  834 + if (dev == NULL)
  835 + return 0;
  836 + platform_set_drvdata(pdev, NULL);
  837 +
  838 + ep = netdev_priv(dev);
  839 +
  840 + /* @@@ Force down. */
  841 + unregister_netdev(dev);
  842 + ep93xx_free_buffers(ep);
  843 +
  844 + if (ep->base_addr != NULL)
  845 + iounmap(ep->base_addr);
  846 +
  847 + if (ep->res != NULL) {
  848 + release_resource(ep->res);
  849 + kfree(ep->res);
  850 + }
  851 +
  852 + free_netdev(dev);
  853 +
  854 + return 0;
  855 +}
  856 +
  857 +static int ep93xx_eth_probe(struct platform_device *pdev)
  858 +{
  859 + struct ep93xx_eth_data *data;
  860 + struct net_device *dev;
  861 + struct ep93xx_priv *ep;
  862 + int err;
  863 +
  864 + data = pdev->dev.platform_data;
  865 + if (pdev == NULL)
  866 + return -ENODEV;
  867 +
  868 + dev = ep93xx_dev_alloc(data);
  869 + if (dev == NULL) {
  870 + err = -ENOMEM;
  871 + goto err_out;
  872 + }
  873 + ep = netdev_priv(dev);
  874 +
  875 + platform_set_drvdata(pdev, dev);
  876 +
  877 + ep->res = request_mem_region(pdev->resource[0].start,
  878 + pdev->resource[0].end - pdev->resource[0].start + 1,
  879 + pdev->dev.bus_id);
  880 + if (ep->res == NULL) {
  881 + dev_err(&pdev->dev, "Could not reserve memory region\n");
  882 + err = -ENOMEM;
  883 + goto err_out;
  884 + }
  885 +
  886 + ep->base_addr = ioremap(pdev->resource[0].start,
  887 + pdev->resource[0].end - pdev->resource[0].start);
  888 + if (ep->base_addr == NULL) {
  889 + dev_err(&pdev->dev, "Failed to ioremap ethernet registers\n");
  890 + err = -EIO;
  891 + goto err_out;
  892 + }
  893 + ep->irq = pdev->resource[1].start;
  894 +
  895 + ep->mii.phy_id = data->phy_id;
  896 + ep->mii.phy_id_mask = 0x1f;
  897 + ep->mii.reg_num_mask = 0x1f;
  898 + ep->mii.dev = dev;
  899 + ep->mii.mdio_read = ep93xx_mdio_read;
  900 + ep->mii.mdio_write = ep93xx_mdio_write;
  901 + ep->mdc_divisor = 40; /* Max HCLK 100 MHz, min MDIO clk 2.5 MHz. */
  902 +
  903 + err = register_netdev(dev);
  904 + if (err) {
  905 + dev_err(&pdev->dev, "Failed to register netdev\n");
  906 + goto err_out;
  907 + }
  908 +
  909 + printk(KERN_INFO "%s: ep93xx on-chip ethernet, IRQ %d, "
  910 + "%.2x:%.2x:%.2x:%.2x:%.2x:%.2x.\n", dev->name,
  911 + ep->irq, data->dev_addr[0], data->dev_addr[1],
  912 + data->dev_addr[2], data->dev_addr[3],
  913 + data->dev_addr[4], data->dev_addr[5]);
  914 +
  915 + return 0;
  916 +
  917 +err_out:
  918 + ep93xx_eth_remove(pdev);
  919 + return err;
  920 +}
  921 +
  922 +
  923 +static struct platform_driver ep93xx_eth_driver = {
  924 + .probe = ep93xx_eth_probe,
  925 + .remove = ep93xx_eth_remove,
  926 + .driver = {
  927 + .name = "ep93xx-eth",
  928 + },
  929 +};
  930 +
  931 +static int __init ep93xx_eth_init_module(void)
  932 +{
  933 + printk(KERN_INFO DRV_MODULE_NAME " version " DRV_MODULE_VERSION " loading\n");
  934 + return platform_driver_register(&ep93xx_eth_driver);
  935 +}
  936 +
  937 +static void __exit ep93xx_eth_cleanup_module(void)
  938 +{
  939 + platform_driver_unregister(&ep93xx_eth_driver);
  940 +}
  941 +
  942 +module_init(ep93xx_eth_init_module);
  943 +module_exit(ep93xx_eth_cleanup_module);
  944 +MODULE_LICENSE("GPL");
include/asm-arm/arch-ep93xx/ep93xx-regs.h
... ... @@ -27,6 +27,7 @@
27 27 #define EP93XX_DMA_BASE (EP93XX_AHB_VIRT_BASE + 0x00000000)
28 28  
29 29 #define EP93XX_ETHERNET_BASE (EP93XX_AHB_VIRT_BASE + 0x00010000)
  30 +#define EP93XX_ETHERNET_PHYS_BASE (EP93XX_AHB_PHYS_BASE + 0x00010000)
30 31  
31 32 #define EP93XX_USB_BASE (EP93XX_AHB_VIRT_BASE + 0x00020000)
32 33 #define EP93XX_USB_PHYS_BASE (EP93XX_AHB_PHYS_BASE + 0x00020000)
include/asm-arm/arch-ep93xx/platform.h
... ... @@ -11,6 +11,12 @@
11 11 void ep93xx_clock_init(void);
12 12 extern struct sys_timer ep93xx_timer;
13 13  
  14 +struct ep93xx_eth_data
  15 +{
  16 + unsigned char dev_addr[6];
  17 + unsigned char phy_id;
  18 +};
  19 +
14 20  
15 21 #endif