Add mac driver for w90p910
Subsystems (2)
PATCH 1/1 Add mac driver for w90p910
Dear David,
This is a MAC driver patch for supporting my evaluation board based on w90p910 SoC, which is a Winbond(nuvoton) ARM SoC.
Thanks!
Add mac driver support for evaluation board based on w90p910.
--- drivers/net/arm/Kconfig | 8 + drivers/net/arm/Makefile | 1 + drivers/net/arm/w90p910_ether.c | 1105 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 1114 insertions(+), 0 deletions(-) create mode 100644 drivers/net/arm/w90p910_ether.c
drivers/net/arm/Kconfig +8 -0
@@ -63,3 +63,11 @@ config IXP4XX_ETH help Say Y here if you want to use built-in Ethernet ports on IXP4xx processor. + +config W90P910_ETH + tristate "Nuvoton w90p910 Ethernet support" + depends on ARM && ARCH_W90X900 + select PHYLIB + help + Say Y here if you want to use built-in Ethernet ports + on w90p910 processor.
drivers/net/arm/Makefile +1 -0
@@ -11,3 +11,4 @@ obj-$(CONFIG_ARM_AT91_ETHER) += at91_ether.o obj-$(CONFIG_ARM_KS8695_ETHER) += ks8695net.o obj-$(CONFIG_EP93XX_ETH) += ep93xx_eth.o obj-$(CONFIG_IXP4XX_ETH) += ixp4xx_eth.o +obj-$(CONFIG_W90P910_ETH) += w90p910_ether.o
drivers/net/arm/w90p910_ether.c new file +1105 -0
1,105 lines not on this page · raw message
Signature · 1 line
1.5.6.3
Hi Wan,
Quoted 177 lines
drivers/net/arm/Makefile +0
-0@@ -11,3 +11,4 @@ obj-$(CONFIG_ARM_AT91_ETHER) += at91_ether.oobj-$(CONFIG_ARM_KS8695_ETHER) += ks8695net.o
obj-$(CONFIG_EP93XX_ETH) += ep93xx_eth.o
obj-$(CONFIG_IXP4XX_ETH) += ixp4xx_eth.odrivers/net/arm/Makefile +1
-0+obj-$(CONFIG_W90P910_ETH) += w90p910_ether.odrivers/net/arm/w90p910_ether.c new file +162
-0@@ -0,0 +1,1105 @@ +/* +* Copyright (c) 2008-2009 Nuvoton technology corporation. +* +* Wan ZongShun <[email protected]> +* +* This program is free software; you can redistribute it and/or modify +* it under the terms of the GNU General Public License as published by +* the Free Software Foundation;version 2 of the License. +* +*/ + +#include <linux/module.h> +#include <linux/init.h> +#include <linux/mii.h> +#include <linux/netdevice.h> +#include <linux/etherdevice.h> +#include <linux/skbuff.h> +#include <linux/ethtool.h> +#include <linux/platform_device.h> +#include <linux/clk.h> + +#define DRV_MODULE_NAME "w90p910-emc" +#define DRV_MODULE_VERSION "0.1" + +/* Ethernet MAC Registers */ +#define REG_CAMCMR 0x00 +#define REG_CAMEN 0x04 +#define REG_CAMM_BASE 0x08 +#define REG_CAML_BASE 0x0c +#define REG_TXDLSA 0x88 +#define REG_RXDLSA 0x8C +#define REG_MCMDR 0x90 +#define REG_MIID 0x94 +#define REG_MIIDA 0x98 +#define REG_FFTCR 0x9C +#define REG_TSDR 0xa0 +#define REG_RSDR 0xa4 +#define REG_DMARFC 0xa8 +#define REG_MIEN 0xac +#define REG_MISTA 0xb0 +#define REG_CTXDSA 0xcc +#define REG_CTXBSA 0xd0 +#define REG_CRXDSA 0xd4 +#define REG_CRXBSA 0xd8 + +/* mac controller bit */ +#define MCMDR_RXON 0x01 +#define MCMDR_ACP (0x01 << 3) +#define MCMDR_SPCRC (0x01 << 5) +#define MCMDR_TXON (0x01 << 8) +#define MCMDR_FDUP (0x01 << 18) +#define MCMDR_ENMDC (0x01 << 19) +#define MCMDR_OPMOD (0x01 << 20) +#define SWR (0x01 << 24) + +/* cam command regiser */ +#define CAMCMR_AUP 0x01 +#define CAMCMR_AMP (0x01 << 1) +#define CAMCMR_ABP (0x01 << 2) +#define CAMCMR_CCAM (0x01 << 3) +#define CAMCMR_ECMP (0x01 << 4) +#define CAM0EN 0x01 + +/* mac mii controller bit */ +#define MDCCR (0x0a << 20) +#define PHYAD (0x01 << 8) +#define PHYWR (0x01 << 16) +#define PHYBUSY (0x01 << 17) +#define PHYPRESP (0x01 << 18) +#define CAM_ENTRY_SIZE 0x08 + +/* rx and tx status */ +#define TXDS_TXCP (0x01 << 19) +#define RXDS_CRCE (0x01 << 17) +#define RXDS_PTLE (0x01 << 19) +#define RXDS_RXGD (0x01 << 20) +#define RXDS_ALIE (0x01 << 21) +#define RXDS_RP (0x01 << 22) + +/* mac interrupt status*/ +#define MISTA_EXDEF (0x01 << 19) +#define MISTA_TXBERR (0x01 << 24) +#define MISTA_TDU (0x01 << 23) +#define MISTA_RDU (0x01 << 10) +#define MISTA_RXBERR (0x01 << 11) + +#define ENSTART 0x01 +#define ENRXINTR 0x01 +#define ENRXGD (0x01 << 4) +#define ENRXBERR (0x01 << 11) +#define ENTXINTR (0x01 << 16) +#define ENTXCP (0x01 << 18) +#define ENTXABT (0x01 << 21) +#define ENTXBERR (0x01 << 24) +#define ENMDC (0x01 << 19) +#define PHYBUSY (0x01 << 17) +#define MDCCR_VAL 0xa00000 + +/* rx and tx owner bit */ +#define RX_OWEN_DMA (0x01 << 31) +#define RX_OWEN_CPU (~(0x03 << 30)) +#define TX_OWEN_DMA (0x01 << 31) +#define TX_OWEN_CPU (~(0x01 << 31)) + +/* tx frame desc controller bit */ +#define MACTXINTEN 0x04 +#define CRCMODE 0x02 +#define PADDINGMODE 0x01 + +/* fftcr controller bit */ +#define TXTHD (0x03 << 8) +#define BLENGTH (0x01 << 20) + +/* global setting for driver */ +#define RX_DESC_SIZE 50 +#define TX_DESC_SIZE 10 +#define MAX_RBUFF_SZ 0x600 +#define MAX_TBUFF_SZ 0x600 +#define TX_TIMEOUT 50 +#define DELAY 1000 +#define CAM0 0x0 + +static int w90p910_mdio_read (struct net_device *dev,int phy_id,int reg); + +struct w90p910_rxbd { + unsigned int sl; + unsigned int buffer; + unsigned int reserved; + unsigned int next; +}; + +struct w90p910_txbd { + unsigned int mode; + unsigned int buffer; + unsigned int sl; + unsigned int next; +}; + +struct recv_pdesc { + struct w90p910_rxbd desclist[RX_DESC_SIZE]; + char recv_buf[RX_DESC_SIZE][MAX_RBUFF_SZ]; +}; + +struct tran_pdesc { + struct w90p910_txbd desclist[TX_DESC_SIZE]; + char tran_buf[RX_DESC_SIZE][MAX_TBUFF_SZ]; +}; + +struct w90p910_ether { + struct recv_pdesc *rdesc; + struct recv_pdesc *rdesc_phys; + struct tran_pdesc *tdesc; + struct tran_pdesc *tdesc_phys; + struct net_device_stats stats; + struct platform_device *pdev; + struct sk_buff *skb; + struct clk *clk; + struct clk *rmiiclk; + struct mii_if_info mii; + struct timer_list check_timer; + void __iomem *reg; + unsigned int rxirq;
drivers/net/arm/w90p910_ether.c line 172
Quoted 10 lines
drivers/net/arm/w90p910_ether.c new file +10
-0+ unsigned int txirq; + unsigned int cur_tx; + unsigned int cur_rx; + unsigned int finish_tx; + unsigned int rx_packets; + unsigned int rx_bytes; + unsigned int start_tx_ptr; + unsigned int start_rx_ptr; + unsigned int linkflag; + spinlock_t lock;
describe what lock protects.
Quoted 6 lines
drivers/net/arm/w90p910_ether.c new file +5
-0+}; + + +static void w90p910_init_desc (struct net_device *dev) +{
drivers/net/arm/w90p910_ether.c line 289
Quoted 10 lines
drivers/net/arm/w90p910_ether.c new file +10
-0+ struct w90p910_ether *ether; + struct w90p910_txbd *tdesc, *tdesc_phys; + struct w90p910_rxbd *rdesc, *rdesc_phys; + unsigned int i, j; + + ether = netdev_priv(dev); + + ether->tdesc = (struct tran_pdesc *) + dma_alloc_coherent(NULL, sizeof(struct tran_pdesc), + (dma_addr_t *) ðer->tdesc_phys, GFP_KERNEL);
no-need of casting I think.
Quoted 4 lines
+
+ether->rdesc= (structrecv_pdesc*)
+ dma_alloc_coherent(NULL,sizeof(struct recv_pdesc),
+ (dma_addr_t*)ðer->rdesc_phys,GFP_KERNEL);
Ditto.
Quoted 77 lines
drivers/net/arm/w90p910_ether.c new file +77
-0+ + for (i = 0; i < TX_DESC_SIZE; i++) { + tdesc = &(ether->tdesc->desclist[i]); + + j = ((i + 1) / TX_DESC_SIZE); + + if (j != 0) { + tdesc_phys = &(ether->tdesc_phys->desclist[0]); + ether->start_tx_ptr = (unsigned int)tdesc_phys; + tdesc->next = (unsigned int)ether->start_tx_ptr; + } else { + tdesc_phys = &(ether->tdesc_phys->desclist[i+1]); + tdesc->next = (unsigned int)tdesc_phys; + } + + tdesc->buffer = (unsigned int)ether->tdesc_phys->tran_buf[i]; + tdesc->sl = 0; + tdesc->mode = 0; + } + + for (i = 0; i < RX_DESC_SIZE; i++) { + rdesc = &(ether->rdesc->desclist[i]); + + j = ((i + 1) / RX_DESC_SIZE); + + if (j != 0) { + rdesc_phys = &(ether->rdesc_phys->desclist[0]); + ether->start_rx_ptr = (unsigned int)rdesc_phys; + rdesc->next = (unsigned int)ether->start_rx_ptr; + } else { + rdesc_phys = &(ether->rdesc_phys->desclist[i+1]); + rdesc->next = (unsigned int)rdesc_phys; + } + + rdesc->sl = RX_OWEN_DMA; + rdesc->buffer = (unsigned int)ether->rdesc_phys->recv_buf[i]; + } +} + +static void w90p910_set_fifo_threshold (struct net_device *dev) +{ + struct w90p910_ether *ether = netdev_priv(dev); + unsigned int val; + + val = TXTHD | BLENGTH; + __raw_writel(val, ether->reg + REG_FFTCR); +} + +static void w90p910_return_default_idle (struct net_device *dev) +{ + struct w90p910_ether *ether = netdev_priv(dev); + unsigned int val; + + val = __raw_readl(ether->reg + REG_MCMDR); + val |= SWR; + __raw_writel(val, ether->reg + REG_MCMDR); +} + +static void w90p910_trigger_rx (struct net_device *dev) +{ + struct w90p910_ether *ether = netdev_priv(dev); + + __raw_writel(ENSTART, ether->reg + REG_RSDR); +} + +static void w90p910_trigger_tx (struct net_device *dev) +{ + struct w90p910_ether *ether = netdev_priv(dev); + + __raw_writel(ENSTART, ether->reg + REG_TSDR); +} + +static void w90p910_enable_mac_interrupt (struct net_device *dev) +{ + struct w90p910_ether *ether = netdev_priv(dev); + unsigned int val; +
drivers/net/arm/w90p910_ether.c line 379
Quoted 10 lines
drivers/net/arm/w90p910_ether.c new file +8
-0+ val = ENTXINTR | ENRXINTR | ENRXGD | ENTXCP; + val |= ENTXBERR | ENRXBERR | ENTXABT; + + __raw_writel(val, ether->reg + REG_MIEN); +} + +static int set_mac_address (struct net_device *dev,void *addr) +{
how about naming it as w90p910_set_mac_address for consistency.
Quoted 14 lines
+ struct sockaddr *address = addr;
drivers/net/arm/w90p910_ether.c new file +11
-0+ + if (!is_valid_ether_addr(address->sa_data)) + return -EADDRNOTAVAIL; + + memcpy(dev->dev_addr, address->sa_data, dev->addr_len); + w90p910_write_cam(dev, CAM0, dev->dev_addr); + + return 0; +} + +
drivers/net/arm/w90p910_ether.c line 635
Quoted 10 lines
drivers/net/arm/w90p910_ether.c new file +10
-0+static int w90p910_ether_start_xmit (struct sk_buff *skb,struct net_device *dev) +{ + struct w90p910_ether *ether = netdev_priv(dev); + + if (!(w90p910_send_frame(dev, skb->data, skb->len))) { + ether->skb = skb; + dev_kfree_skb_irq(skb); + return 0; + } + return -1;
better error code?
drivers/net/arm/w90p910_ether.c line 647
Quoted 12 lines
drivers/net/arm/w90p910_ether.c new file +12
-0+} + +static irqreturn_t w90p910_tx_interrupt (int irq,void *dev_id) +{ + struct w90p910_ether *ether; + struct w90p910_txbd *txbd; + struct platform_device *pdev; + struct tran_pdesc *tran_pdesc; + struct net_device *dev; + unsigned int cur_entry, entry, status; + + dev = (struct net_device *)dev_id;
un-necessary casting.
Quoted 32 lines
+ ether =
netdev_priv(dev);
+ pdev =ether->pdev;drivers/net/arm/w90p910_ether.c new file +30
-0+ + spin_lock(ðer->lock); + + w90p910_get_and_clear_int(dev, &status); + + cur_entry = __raw_readl(ether->reg + REG_CTXDSA); + + tran_pdesc = ether->tdesc_phys; + entry = (unsigned int)(&tran_pdesc->desclist[ether->finish_tx]); + + while (entry != cur_entry) { + txbd = ðer->tdesc->desclist[ether->finish_tx]; + + ether->finish_tx = (ether->finish_tx + 1) % TX_DESC_SIZE; + + if (txbd->sl & TXDS_TXCP) { + ether->stats.tx_packets++; + ether->stats.tx_bytes += txbd->sl & 0xFFFF; + } else { + ether->stats.tx_errors++; + } + + txbd->sl = 0x0; + txbd->mode = 0x0; + + if (netif_queue_stopped(dev)) + netif_wake_queue(dev); + + entry = (unsigned int)(&tran_pdesc->desclist[ether->finish_tx]); + }
drivers/net/arm/w90p910_ether.c line 689
Quoted 10 lines
drivers/net/arm/w90p910_ether.c new file +10
-0+ + if (status & MISTA_EXDEF) { + dev_err(&pdev->dev, "emc defer exceed interrupt\n"); + } else if (status & MISTA_TXBERR) { + dev_err(&pdev->dev, "emc bus error interrupt\n"); + w90p910_reset_mac(dev); + } else if (status & MISTA_TDU) { + if (netif_queue_stopped(dev)) + netif_wake_queue(dev); + }
indentation doesn't look correct.
Quoted 6 lines
drivers/net/arm/w90p910_ether.c new file +6
-0+ + spin_unlock(ðer->lock); + + return IRQ_HANDLED; +} +
drivers/net/arm/w90p910_ether.c line 775
Quoted 10 lines
drivers/net/arm/w90p910_ether.c new file +9
-0+ +static irqreturn_t w90p910_rx_interrupt (int irq,void *dev_id) +{ + struct net_device *dev; + struct w90p910_ether *ether; + struct platform_device *pdev; + unsigned int status; + + dev = (struct net_device *)dev_id;
No need of casting.
Quoted 8 lines
+ ether =
netdev_priv(dev);
+ pdev =ether->pdev;drivers/net/arm/w90p910_ether.c new file +6
-0+ + spin_lock(ðer->lock); + + w90p910_get_and_clear_int(dev, &status); + + if (status & MISTA_RDU) {
drivers/net/arm/w90p910_ether.c line 793
Quoted 10 lines
drivers/net/arm/w90p910_ether.c new file +10
-0+ netdev_rx(dev); + + w90p910_trigger_rx(dev); + + spin_unlock(ðer->lock); + return IRQ_HANDLED; + } else if (status & MISTA_RXBERR) { + dev_err(&pdev->dev, "emc rx bus error\n"); + w90p910_reset_mac(dev); + }
indentation problem.
Quoted 26 lines
drivers/net/arm/w90p910_ether.c new file +26
-0+ + netdev_rx(dev); + spin_unlock(ðer->lock); + return IRQ_HANDLED; +} + +static int w90p910_ether_open (struct net_device *dev) +{ + struct w90p910_ether *ether; + struct platform_device *pdev; + + ether = netdev_priv(dev); + pdev = ether->pdev; + + w90p910_reset_mac(dev); + w90p910_set_fifo_threshold(dev); + w90p910_set_curdest(dev); + w90p910_enable_cam(dev); + w90p910_enable_cam_command(dev); + w90p910_enable_mac_interrupt(dev); + w90p910_set_global_maccmd(dev); + w90p910_enable_rx(dev, 1); + + ether->rx_packets = 0x0; + ether->rx_bytes = 0x0; +
drivers/net/arm/w90p910_ether.c line 829
Quoted 10 lines
drivers/net/arm/w90p910_ether.c new file +10
-0+ if (request_irq(ether->txirq, w90p910_tx_interrupt, + 0x0, pdev->name, dev)) { + dev_err(&pdev->dev, "register irq tx failed\n"); + return -EAGAIN; + } + + if (request_irq(ether->rxirq, w90p910_rx_interrupt, + 0x0, pdev->name, dev)) { + dev_err(&pdev->dev, "register irq rx failed\n"); + return -EAGAIN;
error path problem. You should do free_irq(ether->txirq);
Quoted 110 lines
+ }
drivers/net/arm/w90p910_ether.c new file +106
-0+ + mod_timer(ðer->check_timer, jiffies + msecs_to_jiffies(1000)); + netif_start_queue(dev); + w90p910_trigger_rx(dev); + + dev_info(&pdev->dev, "%s is OPENED\n", dev->name); + + return 0; +} + + +static int __devinit w90p910_ether_probe (struct platform_device *pdev) +{ + struct w90p910_ether *ether; + struct net_device *dev; + struct resource *res; + int error; + + dev = alloc_etherdev(sizeof(struct w90p910_ether)); + if (!dev) + return -ENOMEM; + + res = platform_get_resource(pdev, IORESOURCE_MEM, 0); + if (res == NULL) { + dev_err(&pdev->dev, "failed to get I/O memory\n"); + error = -ENXIO; + goto failed_free; + } + + res = request_mem_region(res->start, resource_size(res), pdev->name); + if (res == NULL) { + dev_err(&pdev->dev, "failed to request I/O memory\n"); + error = -EBUSY; + goto failed_free; + } + + ether = netdev_priv(dev); + + ether->reg = ioremap(res->start, resource_size(res)); + if (ether->reg == NULL) { + dev_err(&pdev->dev, "failed to remap I/O memory\n"); + error = -ENXIO; + goto failed_free_mem; + } + + ether->txirq = platform_get_irq(pdev, 0); + if (ether->txirq < 0) { + dev_err(&pdev->dev, "failed to get ether tx irq\n"); + error = -ENXIO; + goto failed_free_io; + } + + ether->rxirq = platform_get_irq(pdev, 1); + if (ether->rxirq < 0) { + dev_err(&pdev->dev, "failed to get ether rx irq\n"); + error = -ENXIO; + goto failed_free_txirq; + } + + platform_set_drvdata(pdev, dev); + + ether->clk = clk_get(&pdev->dev, NULL); + if (IS_ERR(ether->clk)) { + dev_err(&pdev->dev, "failed to get ether clock\n"); + error = PTR_ERR(ether->clk); + goto failed_free_rxirq; + } + + ether->rmiiclk = clk_get(&pdev->dev, "RMII"); + if (IS_ERR(ether->rmiiclk)) { + dev_err(&pdev->dev, "failed to get ether clock\n"); + error = PTR_ERR(ether->rmiiclk); + goto failed_put_clk; + } + + ether->pdev = pdev; + + w90p910_ether_setup(dev); + + error = register_netdev(dev); + if (error != 0) { + dev_err(&pdev->dev, "Regiter EMC w90p910 FAILED\n"); + error = -ENODEV; + goto failed_put_rmiiclk; + } + + return 0; +failed_put_rmiiclk: + clk_put(ether->rmiiclk); +failed_put_clk: + clk_put(ether->clk); +failed_free_rxirq: + free_irq(ether->rxirq, pdev); + platform_set_drvdata(pdev, NULL); +failed_free_txirq: + free_irq(ether->txirq, pdev); +failed_free_io: + iounmap(ether->reg); +failed_free_mem: + release_mem_region(res->start, resource_size(res)); +failed_free: + free_netdev(dev); + return error; +} + +static int __devexit w90p910_ether_remove(struct platform_device *pdev)
drivers/net/arm/w90p910_ether.c line 1075
Quoted 10 lines
drivers/net/arm/w90p910_ether.c new file +10
-0+{ + struct net_device *dev = platform_get_drvdata(pdev); + struct w90p910_ether *ether = netdev_priv(dev); + + unregister_netdev(dev); + clk_put(ether->rmiiclk); + clk_put(ether->clk); + del_timer_sync(ðer->check_timer); + platform_set_drvdata(pdev, NULL); + free_netdev(dev);
I don't see free_irq for two irqs.
Quoted 2 lines
+ return 0;
+}
Signature · 8 lines
---Trilok Soni http://triloksoni.wordpress.com http://www.linkedin.com/in/triloksoni ------------------------------------------------------------------- List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
Dear Trilok,
Some locks seems useless, So I remove them, and regarding the casting,
I have to keep "(dma_addr_t *)" here, as I remove it, a "warning occurs, as following:
"warning: passing argument 3 of 'dma_alloc_coherent' from incompatible pointer type"
So, I keep using it.
Now, I fixed up my patch and resubmitted it.
patch text:
Add mac driver support for evaluation board based on w90p910.
--- drivers/net/arm/Kconfig | 8 + drivers/net/arm/Makefile | 1 + drivers/net/arm/w90p910_ether.c | 1090 +++++++++++++++++++++++++++++++++++++++ 3 files changed, 1099 insertions(+), 0 deletions(-) create mode 100644 drivers/net/arm/w90p910_ether.c
drivers/net/arm/Kconfig +8 -0
@@ -63,3 +63,11 @@ config IXP4XX_ETH help Say Y here if you want to use built-in Ethernet ports on IXP4xx processor. + +config W90P910_ETH + tristate "Nuvoton w90p910 Ethernet support" + depends on ARM && ARCH_W90X900 + select PHYLIB + help + Say Y here if you want to use built-in Ethernet ports + on w90p910 processor.
drivers/net/arm/Makefile +1 -0
@@ -11,3 +11,4 @@ obj-$(CONFIG_ARM_AT91_ETHER) += at91_ether.o obj-$(CONFIG_ARM_KS8695_ETHER) += ks8695net.o obj-$(CONFIG_EP93XX_ETH) += ep93xx_eth.o obj-$(CONFIG_IXP4XX_ETH) += ixp4xx_eth.o +obj-$(CONFIG_W90P910_ETH) += w90p910_ether.o
drivers/net/arm/w90p910_ether.c new file +1090 -0
1,090 lines not on this page · raw message
Signature · 1 line
1.5.6.3
Quoted 3 lines · Wan ZongShun
Some locks seems useless, So I remove them, and regarding the casting,
I have to keep "(dma_addr_t*)" here, as I remove it, a "warning occurs, as following:
"warning: passing argument 3 of 'dma_alloc_coherent' from incompatible pointer type"
This tends to mean you don't have things quite right then. Below are some suggestions which should resolve this.
drivers/net/arm/w90p910_ether.c line 151
Quoted 3 lines
drivers/net/arm/w90p910_ether.c new file +3
-0+struct w90p910_ether { +struct recv_pdesc *rdesc; +struct recv_pdesc *rdesc_phys;
dma_addr_t rdesc_phys;
drivers/net/arm/w90p910_ether.c line 153
Quoted 2 lines
drivers/net/arm/w90p910_ether.c new file +2
-0+struct tran_pdesc *tdesc; +struct tran_pdesc *tdesc_phys;
dma_addr_t tdesc_phys;
Quoted 19 lines
drivers/net/arm/w90p910_ether.c new file +19
-0+struct net_device_stats stats; +struct platform_device *pdev; +struct sk_buff *skb; +struct clk *clk; +struct clk *rmiiclk; +struct mii_if_info mii; +struct timer_list check_timer; +void __iomem *reg; +unsigned int rxirq; +unsigned int txirq; +unsigned int cur_tx; +unsigned int cur_rx; +unsigned int finish_tx; +unsigned int rx_packets; +unsigned int rx_bytes; +unsigned int start_tx_ptr; +unsigned int start_rx_ptr; +unsigned int linkflag; +};
...
Quoted 6 lines
drivers/net/arm/w90p910_ether.c new file +6
-0+static void w90p910_init_desc (struct net_device *dev) +{ +struct w90p910_ether *ether; +struct w90p910_txbd *tdesc, *tdesc_phys; +struct w90p910_rxbd *rdesc, *rdesc_phys; +unsigned int i, j;
drivers/net/arm/w90p910_ether.c line 292
Quoted 10 lines
drivers/net/arm/w90p910_ether.c new file +10
-0+ + ether =netdev_priv (dev); + + ether->tdesc = (struct tran_pdesc *) +dma_alloc_coherent (NULL ,sizeof (struct tran_pdesc ), + (dma_addr_t *)ðer->tdesc_phys,GFP_KERNEL ); + + ether->rdesc = (struct recv_pdesc *) +dma_alloc_coherent (NULL ,sizeof (struct recv_pdesc ), + (dma_addr_t *)ðer->rdesc_phys,GFP_KERNEL );
ether->tdesc = dma_alloc_cohernet(NULL, sizeof(struct tran_pdesc), ðer->tdesc_phys, GFP_KERNEL); ether->rdesc = dma_alloc_cohernet(NULL, sizeof(struct recv_pdesc), ðer->rdesc_phys, GFP_KERNEL);
Note that these functions can fail and return a NULL pointer - you need to check for that. Also I wonder why you're not passing ðer->pdev->dev as the first argument.
drivers/net/arm/w90p910_ether.c line 299
Quoted 7 lines
drivers/net/arm/w90p910_ether.c new file +7
-0+ +for (i =0 ; i <TX_DESC_SIZE ; i++) { + tdesc = &(ether->tdesc->desclist[i]); + + j = ((i +1 ) /TX_DESC_SIZE ); + +if (j !=0 ) {
This is a weird way of detecting the last interation in the loop. Wouldn't:
if (i == TX_DESC_SIZE - 1) {be sufficient?
drivers/net/arm/w90p910_ether.c line 311
Quoted 12 lines
drivers/net/arm/w90p910_ether.c new file +12
-0+ tdesc_phys = &(ether->tdesc_phys->desclist[0 ]); + ether->start_tx_ptr = (unsigned int )tdesc_phys; + tdesc->next = (unsigned int )ether->start_tx_ptr; + }else { + tdesc_phys = &(ether->tdesc_phys->desclist[i+1 ]); + tdesc->next = (unsigned int )tdesc_phys; + } + + tdesc->buffer = (unsigned int )ether->tdesc_phys->tran_buf[i]; + tdesc->sl =0 ; + tdesc->mode =0 ; + }
How about this instead:
for (i = 0; i < TX_DESC_SIZE; i++) {
unsigned int offset;
tdesc = &(ether->tdesc->desclist[i]);
if (i == TX_DESC_SIZE - 1)
offset = offsetof(struct tran_pdesc, desclist[0]);
else
offset = offsetof(struct tran_pdesc, desclist[i + 1]);
tdesc->next = ether->tdesc_phys + offset;
tdesc->buffer = ether->tdesc_phys +
offsetof(struct tran_pdesc, tran_buf[i]);
tdesc->sl = 0;
tdesc->mode = 0;
}
ether->start_tx_ptr = ether->tdesc_phys;Quoted 8 lines
drivers/net/arm/w90p910_ether.c new file +8
-0+ +for (i =0 ; i <RX_DESC_SIZE ; i++) { + rdesc = &(ether->rdesc->desclist[i]); + + j = ((i +1 ) /RX_DESC_SIZE ); + +if (j !=0 ) { + rdesc_phys = &(ether->rdesc_phys->desclist[0 ]);
drivers/net/arm/w90p910_ether.c line 329
Quoted 10 lines
drivers/net/arm/w90p910_ether.c new file +10
-0+ ether->start_rx_ptr = (unsigned int )rdesc_phys; + rdesc->next = (unsigned int )ether->start_rx_ptr; + }else { + rdesc_phys = &(ether->rdesc_phys->desclist[i+1 ]); + rdesc->next = (unsigned int )rdesc_phys; + } + + rdesc->sl =RX_OWEN_DMA ; + rdesc->buffer = (unsigned int )ether->rdesc_phys->recv_buf[i]; + }
Same kind of fixup here.
Quoted 1 line
+}
...
drivers/net/arm/w90p910_ether.c line 559
Quoted 8 lines
drivers/net/arm/w90p910_ether.c new file +8
-0+static int w90p910_ether_close (struct net_device *dev) +{ +struct w90p910_ether *ether =netdev_priv (dev); + +dma_free_writecombine (NULL ,sizeof (struct w90p910_rxbd ), + ether->rdesc, (dma_addr_t )ether->rdesc_phys); +dma_free_writecombine (NULL ,sizeof (struct w90p910_txbd ), + ether->tdesc, (dma_addr_t )ether->tdesc_phys);
With rdesc_phys and tdesc_phys correctly typed, these casts can go away. These functions should also be dma_free_cohernet(), and also note comment about first argument for dma_alloc_coherent() also applies here.
Quoted 12 lines
drivers/net/arm/w90p910_ether.c new file +12
-0+ +netif_stop_queue (dev); + +del_timer_sync (ðer->check_timer); +clk_disable (ether->rmiiclk); +clk_disable (ether->clk); + +free_irq (ether->txirq, dev); +free_irq (ether->rxirq, dev); + +return 0 ; +}
...
Quoted 9 lines
drivers/net/arm/w90p910_ether.c new file +9
-0+static irqreturn_t w90p910_tx_interrupt (int irq,void *dev_id) +{ +struct w90p910_ether *ether; +struct w90p910_txbd *txbd; +struct platform_device *pdev; +struct tran_pdesc *tran_pdesc; +struct net_device *dev; +unsigned int cur_entry, entry, status; +
drivers/net/arm/w90p910_ether.c line 651
Quoted 10 lines
drivers/net/arm/w90p910_ether.c new file +10
-0+ dev = dev_id; + ether =netdev_priv (dev); + pdev = ether->pdev; + +w90p910_get_and_clear_int (dev, &status); + + cur_entry =__raw_readl (ether->reg +REG_CTXDSA ); + + tran_pdesc = ether->tdesc_phys; + entry = (unsigned int )(&tran_pdesc->desclist[ether->finish_tx]);
entry = ether->tdesc_phys + offsetof(struct tran_pdesc, desclist[ether->finish_tx]);
drivers/net/arm/w90p910_ether.c line 656
Quoted 5 lines
drivers/net/arm/w90p910_ether.c new file +5
-0+ +while (entry != cur_entry) { + txbd = ðer->tdesc->desclist[ether->finish_tx]; + + ether->finish_tx = (ether->finish_tx +1 ) %TX_DESC_SIZE ;
Division and modulus can be expensive when not powers of two. Would:
if (++ether->finish_tx >= TX_DESC_SIZE) ether->finish_tx = 0;
be better?
Quoted 5 lines
drivers/net/arm/w90p910_ether.c new file +5
-0+ +if (txbd->sl &TXDS_TXCP ) { + ether->stats.tx_packets++; + ether->stats.tx_bytes += txbd->sl &0xFFFF ; + }else {
drivers/net/arm/w90p910_ether.c line 671
Quoted 10 lines
drivers/net/arm/w90p910_ether.c new file +10
-0+ ether->stats.tx_errors++; + } + + txbd->sl =0x0 ; + txbd->mode =0x0 ; + +if (netif_queue_stopped (dev)) +netif_wake_queue (dev); + + entry = (unsigned int )(&tran_pdesc->desclist[ether->finish_tx]);
entry = ether->tdesc_phys + offsetof(struct tran_pdesc, desclist[ether->finish_tx]);
Quoted 24 lines
drivers/net/arm/w90p910_ether.c new file +24
-0+ } + +if (status &MISTA_EXDEF ) { +dev_err (&pdev->dev,"emc defer exceed interrupt\n" ); + }else if (status &MISTA_TXBERR ) { +dev_err (&pdev->dev,"emc bus error interrupt\n" ); +w90p910_reset_mac (dev); + }else if (status &MISTA_TDU ) { +if (netif_queue_stopped (dev)) +netif_wake_queue (dev); + } + +return IRQ_HANDLED ; +} + +static void netdev_rx (struct net_device *dev) +{ +struct w90p910_ether *ether; +struct w90p910_rxbd *rxbd; +struct platform_device *pdev; +struct recv_pdesc *rdesc_phys; +struct sk_buff *skb; +unsigned char *data; +unsigned int length, status, val, entry;
drivers/net/arm/w90p910_ether.c line 705
Quoted 10 lines
drivers/net/arm/w90p910_ether.c new file +10
-0+ + ether =netdev_priv (dev); + pdev = ether->pdev; + rdesc_phys = ether->rdesc_phys; + + rxbd = ðer->rdesc->desclist[ether->cur_rx]; + + do { + val = __raw_readl(ether->reg + REG_CRXDSA); + entry = (unsigned int)&rdesc_phys->desclist[ether->cur_rx];
Same kind of fixups as above.
Quoted 50 lines
drivers/net/arm/w90p910_ether.c new file +50
-0+ +if (val == entry) +break ; + + status = rxbd->sl; + length = status &0xFFFF ; + +if (status &RXDS_RXGD ) { + data = ether->rdesc->recv_buf[ether->cur_rx]; + skb =dev_alloc_skb (length+2 ); +if (!skb) { +dev_err (&pdev->dev,"get skb buffer error\n" ); + ether->stats.rx_dropped++; +return ; + } + + skb->dev = dev; +skb_reserve (skb,2 ); +skb_put (skb, length); +skb_copy_to_linear_data (skb, data, length); + skb->protocol =eth_type_trans (skb, dev); + ether->stats.rx_packets++; + ether->stats.rx_bytes += length; +netif_rx (skb); + }else { + ether->stats.rx_errors++; + +if (status &RXDS_RP ) { +dev_err (&pdev->dev,"rx runt err\n" ); + ether->stats.rx_length_errors++; + }else if (status &RXDS_CRCE ) { +dev_err (&pdev->dev,"rx crc err\n" ); + ether->stats.rx_crc_errors++; + }else if (status &RXDS_ALIE ) { +dev_err (&pdev->dev,"rx aligment err\n" ); + ether->stats.rx_frame_errors++; + }else if (status &RXDS_PTLE ) { +dev_err (&pdev->dev,"rx longer err\n" ); + ether->stats.rx_over_errors++; + } + } + + rxbd->sl =RX_OWEN_DMA ; + rxbd->reserved =0x0 ; + ether->cur_rx = (ether->cur_rx+1 ) %RX_DESC_SIZE ; + rxbd = ðer->rdesc->desclist[ether->cur_rx]; + + dev->last_rx = jiffies; + }while (1 ); +}
...
drivers/net/arm/w90p910_ether.c line 1059
Quoted 12 lines
drivers/net/arm/w90p910_ether.c new file +12
-0+static int __devexit w90p910_ether_remove(struct platform_device *pdev) +{ +struct net_device *dev =platform_get_drvdata (pdev); +struct w90p910_ether *ether =netdev_priv (dev); + +unregister_netdev (dev); +clk_put (ether->rmiiclk); +clk_put (ether->clk); +del_timer_sync (ðer->check_timer); +platform_set_drvdata (pdev,NULL ); +free_irq (ether->txirq, dev); +free_irq (ether->rxirq, dev);
iounmap? release_mem_region?
Quoted 3 lines
drivers/net/arm/w90p910_ether.c new file +3
-0+free_netdev (dev); +return 0 ; +}
From: Wan ZongShun <[email protected]>
Date: Thu, 16 Jul 2009 20:55:05 +0800
Quoted 3 lines
Add mac driver support for evaluation board based on w90p910.
Signed-off-by Wan ZongShun <[email protected]>
Applied, thanks.
Hi David,
Quoted 8 lines · David Miller
From: Wan ZongShun <[email protected]>
Date: Thu, 16 Jul 2009 20:55:05 +0800Quoted 3 lines
Add mac driver support for evaluation board based on w90p910.
Signed-off-by Wan ZongShun <[email protected]>Applied, thanks.
I thought Wan will send us the updated patch with fixing comments as pointed by Russell.
Wan, could you please send updated patch.
Signature · 3 lines
---Trilok Soni http://triloksoni.wordpress.com http://www.linkedin.com/in/triloksoni
David Miller
maintainerFrom: Trilok Soni <[email protected]>
Date: Mon, 20 Jul 2009 23:19:38 +0530
Quoted 8 lines
Hi David,
Quoted 5 lines · David Miller
From: Wan ZongShun <[email protected]>
Date: Thu, 16 Jul 2009 20:55:05 +0800Quoted 2 lines
Add mac driver support for evaluation board based on w90p910.
Quoted 8 lines
Quoted 3 lines
Quoted 1 line
Signed-off-by Wan ZongShun <[email protected]>Applied, thanks.
I thought Wan will send us the updated patch with fixing comments as pointed by Russell.
Wan, could you please send updated patch.
Send me a relative patch as I've already pushed this driver commit publicly and that cannot be undone without a lot of pain.
Dear sirs,
Thank Russell, Trilok for reviewing my patch.
Thank David for applying my patch.
Thanks for your help regarding this patch, a bit busy to do other job, so late to updte
this patch, I will submitted a patch relative to the previous patch.
2009/7/21 David Miller <[email protected]>:
Quoted 23 lines
From: Trilok Soni <[email protected]>
Date: Mon, 20 Jul 2009 23:19:38 +0530Quoted 8 lines
Hi David,
Quoted 5 lines · David Miller
From: Wan ZongShun <[email protected]>
Date: Thu, 16 Jul 2009 20:55:05 +0800Quoted 2 lines
Add mac driver support for evaluation board based on w90p910.
Quoted 8 lines
Quoted 3 lines
Quoted 1 line
Signed-off-by Wan ZongShun <[email protected]>Applied, thanks.
I thought Wan will send us the updated patch with fixing comments as pointed by Russell.
Wan, could you please send updated patch.
Send me a relative patch as I've already pushed this driver commit publicly and that cannot be undone without a lot of pain.
Signature · 6 lines
Wan z.s ------------------------------------------------------------------- List admin: http://lists.arm.linux.org.uk/mailman/listinfo/linux-arm-kernel FAQ: http://www.arm.linux.org.uk/mailinglists/faq.php Etiquette: http://www.arm.linux.org.uk/mailinglists/etiquette.php
PATCH 1/1 fixed up the previous mac driver for w90p910
In reply to David MillerDear Russell&David,
Due to having a bit busy, when David has applied this mac patch, however,I did not fix it based on comments as pointed by Russell.
So, I have to resubmit a new patch relative to previous patch.
patch text:
According to Russell's advice, I fixed up mac driver, which relatives to previous mac driver patch, and the evaluation board based on w90p910.
drivers/net/arm/w90p910_ether.c +91 -58
@@ -143,16 +143,17 @@ struct recv_pdesc {struct tran_pdesc {struct w90p910_txbd desclist[TX_DESC_SIZE ]; -char tran_buf[RX_DESC_SIZE ][MAX_TBUFF_SZ ]; +char tran_buf[TX_DESC_SIZE ][MAX_TBUFF_SZ ]; };struct w90p910_ether {struct recv_pdesc *rdesc; -struct recv_pdesc *rdesc_phys;struct tran_pdesc *tdesc; -struct tran_pdesc *tdesc_phys; +dma_addr_t rdesc_phys; +dma_addr_t tdesc_phys;struct net_device_stats stats;struct platform_device *pdev; +struct resource *res;struct sk_buff *skb;struct clk *clk;struct clk *rmiiclk;
@@ -274,59 +275,75 @@ static void w90p910_write_cam(struct net_device *dev,__raw_writel (msw, ether->reg +REG_CAMM_BASE + x *CAM_ENTRY_SIZE ); } -static void w90p910_init_desc (struct net_device *dev) +static int w90p910_init_desc (struct net_device *dev) {struct w90p910_ether *ether; -struct w90p910_txbd *tdesc, *tdesc_phys; -struct w90p910_rxbd *rdesc, *rdesc_phys; -unsigned int i, j; +struct w90p910_txbd *tdesc; +struct w90p910_rxbd *rdesc; +struct platform_device *pdev; +unsigned int i; ether =netdev_priv (dev); + pdev = ether->pdev; ether->tdesc = (struct tran_pdesc *) -dma_alloc_coherent (NULL ,sizeof (struct tran_pdesc ), - (dma_addr_t *)ðer->tdesc_phys,GFP_KERNEL ); +dma_alloc_coherent (&pdev->dev,sizeof (struct tran_pdesc ), + ðer->tdesc_phys,GFP_KERNEL ); + +if (!ether->tdesc) { +dev_err (&pdev->dev,"Failed to allocate memory for tx desc\n" ); +return -ENOMEM ; + } ether->rdesc = (struct recv_pdesc *) -dma_alloc_coherent (NULL ,sizeof (struct recv_pdesc ), - (dma_addr_t *)ðer->rdesc_phys,GFP_KERNEL ); +dma_alloc_coherent (&pdev->dev,sizeof (struct recv_pdesc ), + ðer->rdesc_phys,GFP_KERNEL ); + +if (!ether->rdesc) { +dev_err (&pdev->dev,"Failed to allocate memory for rx desc\n" ); +dma_free_coherent (&pdev->dev,sizeof (struct tran_pdesc ), + ether->tdesc, ether->tdesc_phys); +return -ENOMEM ; + }for (i =0 ; i <TX_DESC_SIZE ; i++) { - tdesc = &(ether->tdesc->desclist[i]); +unsigned int offset; - j = ((i +1 ) /TX_DESC_SIZE ); + tdesc = &(ether->tdesc->desclist[i]); -if (j !=0 ) { - tdesc_phys = &(ether->tdesc_phys->desclist[0 ]); - ether->start_tx_ptr = (unsigned int )tdesc_phys; - tdesc->next = (unsigned int )ether->start_tx_ptr; - }else { - tdesc_phys = &(ether->tdesc_phys->desclist[i+1 ]); - tdesc->next = (unsigned int )tdesc_phys; - } +if (i ==TX_DESC_SIZE -1 ) + offset = offsetof(struct tran_pdesc, desclist[0]); +else + offset = offsetof(struct tran_pdesc, desclist[i + 1]); - tdesc->buffer = (unsigned int )ether->tdesc_phys->tran_buf[i]; + tdesc->next = ether->tdesc_phys + offset; + tdesc->buffer = ether->tdesc_phys + + offsetof(struct tran_pdesc, tran_buf[i]); tdesc->sl =0 ; tdesc->mode =0 ; } + ether->start_tx_ptr = ether->tdesc_phys; +for (i =0 ; i <RX_DESC_SIZE ; i++) { - rdesc = &(ether->rdesc->desclist[i]); +unsigned int offset; - j = ((i +1 ) /RX_DESC_SIZE ); + rdesc = &(ether->rdesc->desclist[i]); -if (j !=0 ) { - rdesc_phys = &(ether->rdesc_phys->desclist[0 ]); - ether->start_rx_ptr = (unsigned int )rdesc_phys; - rdesc->next = (unsigned int )ether->start_rx_ptr; - }else { - rdesc_phys = &(ether->rdesc_phys->desclist[i+1 ]); - rdesc->next = (unsigned int )rdesc_phys; - } +if (i ==RX_DESC_SIZE -1 ) + offset = offsetof(struct recv_pdesc, desclist[0]); +else + offset = offsetof(struct recv_pdesc, desclist[i + 1]); + rdesc->next = ether->rdesc_phys + offset; rdesc->sl =RX_OWEN_DMA ; - rdesc->buffer = (unsigned int )ether->rdesc_phys->recv_buf[i]; + rdesc->buffer = ether->rdesc_phys + + offsetof(struct recv_pdesc, recv_buf[i]); } + + ether->start_rx_ptr = ether->rdesc_phys; + +return 0 ; }static void w90p910_set_fifo_threshold (struct net_device *dev)
@@ -552,11 +569,14 @@ static int w90p910_set_mac_address(struct net_device *dev, void *addr)static int w90p910_ether_close (struct net_device *dev) {struct w90p910_ether *ether =netdev_priv (dev); +struct platform_device *pdev; + + pdev = ether->pdev; -dma_free_writecombine (NULL ,sizeof (struct w90p910_rxbd ), - ether->rdesc, (dma_addr_t )ether->rdesc_phys); -dma_free_writecombine (NULL ,sizeof (struct w90p910_txbd ), - ether->tdesc, (dma_addr_t )ether->tdesc_phys); +dma_free_coherent (&pdev->dev,sizeof (struct recv_pdesc ), + ether->rdesc, ether->rdesc_phys); +dma_free_coherent (&pdev->dev,sizeof (struct tran_pdesc ), + ether->tdesc, ether->tdesc_phys);netif_stop_queue (dev);
@@ -592,6 +612,7 @@ static int w90p910_send_frame(struct net_device *dev, txbd = ðer->tdesc->desclist[ether->cur_tx]; buffer = ether->tdesc->tran_buf[ether->cur_tx]; +if (length >1514 ) {dev_err (&pdev->dev,"send data %d bytes, check it\n" , length); length =1514 ;
@@ -607,7 +628,9 @@ static int w90p910_send_frame(struct net_device *dev,w90p910_trigger_tx (dev); - ether->cur_tx = (ether->cur_tx+1 ) %TX_DESC_SIZE ; +if (++ether->cur_tx >=TX_DESC_SIZE ) + ether->cur_tx =0 ; + txbd = ðer->tdesc->desclist[ether->cur_tx]; dev->trans_start = jiffies;
@@ -635,7 +658,6 @@ static irqreturn_t w90p910_tx_interrupt(int irq, void *dev_id)struct w90p910_ether *ether;struct w90p910_txbd *txbd;struct platform_device *pdev; -struct tran_pdesc *tran_pdesc;struct net_device *dev;unsigned int cur_entry, entry, status;
@@ -647,13 +669,14 @@ static irqreturn_t w90p910_tx_interrupt(int irq, void *dev_id) cur_entry =__raw_readl (ether->reg +REG_CTXDSA ); - tran_pdesc = ether->tdesc_phys; - entry = (unsigned int )(&tran_pdesc->desclist[ether->finish_tx]); + entry = ether->tdesc_phys + + offsetof(struct tran_pdesc, desclist[ether->finish_tx]);while (entry != cur_entry) { txbd = ðer->tdesc->desclist[ether->finish_tx]; - ether->finish_tx = (ether->finish_tx +1 ) %TX_DESC_SIZE ; +if (++ether->finish_tx >=TX_DESC_SIZE ) + ether->finish_tx =0 ;if (txbd->sl &TXDS_TXCP ) { ether->stats.tx_packets++;
@@ -668,7 +691,8 @@ static irqreturn_t w90p910_tx_interrupt(int irq, void *dev_id)if (netif_queue_stopped (dev))netif_wake_queue (dev); - entry = (unsigned int )(&tran_pdesc->desclist[ether->finish_tx]); + entry = ether->tdesc_phys + + offsetof(struct tran_pdesc, desclist[ether->finish_tx]); }if (status &MISTA_EXDEF ) {
@@ -689,20 +713,20 @@ static void netdev_rx(struct net_device *dev)struct w90p910_ether *ether;struct w90p910_rxbd *rxbd;struct platform_device *pdev; -struct recv_pdesc *rdesc_phys;struct sk_buff *skb;unsigned char *data;unsigned int length, status, val, entry; ether =netdev_priv (dev); pdev = ether->pdev; - rdesc_phys = ether->rdesc_phys; rxbd = ðer->rdesc->desclist[ether->cur_rx]; do { val = __raw_readl(ether->reg + REG_CRXDSA); - entry = (unsigned int)&rdesc_phys->desclist[ether->cur_rx]; + + entry = ether->rdesc_phys + + offsetof(struct recv_pdesc, desclist[ether->cur_rx]); if (val == entry) break;
@@ -747,7 +771,10 @@ static void netdev_rx(struct net_device *dev) rxbd->sl =RX_OWEN_DMA ; rxbd->reserved =0x0 ; - ether->cur_rx = (ether->cur_rx+1 ) %RX_DESC_SIZE ; + +if (++ether->cur_rx >=RX_DESC_SIZE ) + ether->cur_rx =0 ; + rxbd = ðer->rdesc->desclist[ether->cur_rx]; dev->last_rx = jiffies;
@@ -955,30 +982,29 @@ static int __devinit w90p910_ether_probe(struct platform_device *pdev) {struct w90p910_ether *ether;struct net_device *dev; -struct resource *res;int error; dev =alloc_etherdev (sizeof (struct w90p910_ether ));if (!dev)return -ENOMEM ; - res =platform_get_resource (pdev,IORESOURCE_MEM ,0 ); -if (res ==NULL ) { + ether =netdev_priv (dev); + + ether->res =platform_get_resource (pdev,IORESOURCE_MEM ,0 ); +if (ether->res ==NULL ) {dev_err (&pdev->dev,"failed to get I/O memory\n" ); error = -ENXIO ; goto failed_free; } - res =request_mem_region (res->start,resource_size (res), pdev->name); -if (res ==NULL ) { +if (!request_mem_region (ether->res->start, +resource_size (ether->res), pdev->name)) {dev_err (&pdev->dev,"failed to request I/O memory\n" ); error = -EBUSY ; goto failed_free; } - ether =netdev_priv (dev); - - ether->reg =ioremap (res->start,resource_size (res)); + ether->reg =ioremap (ether->res->start,resource_size (ether->res));if (ether->reg ==NULL ) {dev_err (&pdev->dev,"failed to remap I/O memory\n" ); error = -ENXIO ;
@@ -1039,7 +1065,7 @@ failed_free_txirq: failed_free_io:iounmap (ether->reg); failed_free_mem: -release_mem_region (res->start,resource_size (res)); +release_mem_region (ether->res->start,resource_size (ether->res)); failed_free:free_netdev (dev);return error;
@@ -1051,12 +1077,19 @@ static int __devexit w90p910_ether_remove(struct platform_device *pdev)struct w90p910_ether *ether =netdev_priv (dev);unregister_netdev (dev); +clk_put (ether->rmiiclk);clk_put (ether->clk); -del_timer_sync (ðer->check_timer); -platform_set_drvdata (pdev,NULL ); + +iounmap (ether->reg); +release_mem_region (ether->res->start,resource_size (ether->res)); +free_irq (ether->txirq, dev);free_irq (ether->rxirq, dev); + +del_timer_sync (ðer->check_timer); +platform_set_drvdata (pdev,NULL ); +free_netdev (dev);return 0 ; }
Signature · 1 line
1.5.6.3
Quoted 21 lines
From: Trilok Soni <[email protected]>
Date: Mon, 20 Jul 2009 23:19:38 +0530Quoted 6 lines
Hi David,
Quoted 3 lines · David Miller
From: Wan ZongShun <[email protected]>
Date: Thu, 16 Jul 2009 20:55:05 +0800Quoted 8 lines
Quoted 4 lines
Quoted 3 lines
Add mac driver support for evaluation board based on w90p910.
Signed-off-by Wan ZongShun <[email protected]>Applied, thanks.
I thought Wan will send us the updated patch with fixing comments as pointed by Russell.
Wan, could you please send updated patch.
Send me a relative patch as I've already pushed this driver commit publicly and that cannot be undone without a lot of pain.
PATCH 1/1 Add mac driver patch fixed for w90p910
Dear Russell&David,
"[PATCH] fixed up the previous mac driver for w90p910"
Just now sent above patch failed, so resent it.
Due to having a bit busy, when David has applied this mac patch, however,I did not fix it based on comments as pointed by Russell.
So, I have to resubmit a new patch relative to previous patch.
patch text:
According to Russell's advice, I fixed up mac driver, which relatives to previous mac driver patch, and the evaluation board based on w90p910.
drivers/net/arm/w90p910_ether.c +91 -58
@@ -143,16 +143,17 @@ struct recv_pdesc {struct tran_pdesc {struct w90p910_txbd desclist[TX_DESC_SIZE ]; -char tran_buf[RX_DESC_SIZE ][MAX_TBUFF_SZ ]; +char tran_buf[TX_DESC_SIZE ][MAX_TBUFF_SZ ]; };struct w90p910_ether {struct recv_pdesc *rdesc; -struct recv_pdesc *rdesc_phys;struct tran_pdesc *tdesc; -struct tran_pdesc *tdesc_phys; +dma_addr_t rdesc_phys; +dma_addr_t tdesc_phys;struct net_device_stats stats;struct platform_device *pdev; +struct resource *res;struct sk_buff *skb;struct clk *clk;struct clk *rmiiclk;
@@ -274,59 +275,75 @@ static void w90p910_write_cam(struct net_device *dev,__raw_writel (msw, ether->reg +REG_CAMM_BASE + x *CAM_ENTRY_SIZE ); } -static void w90p910_init_desc (struct net_device *dev) +static int w90p910_init_desc (struct net_device *dev) {struct w90p910_ether *ether; -struct w90p910_txbd *tdesc, *tdesc_phys; -struct w90p910_rxbd *rdesc, *rdesc_phys; -unsigned int i, j; +struct w90p910_txbd *tdesc; +struct w90p910_rxbd *rdesc; +struct platform_device *pdev; +unsigned int i; ether =netdev_priv (dev); + pdev = ether->pdev; ether->tdesc = (struct tran_pdesc *) -dma_alloc_coherent (NULL ,sizeof (struct tran_pdesc ), - (dma_addr_t *)ðer->tdesc_phys,GFP_KERNEL ); +dma_alloc_coherent (&pdev->dev,sizeof (struct tran_pdesc ), + ðer->tdesc_phys,GFP_KERNEL ); + +if (!ether->tdesc) { +dev_err (&pdev->dev,"Failed to allocate memory for tx desc\n" ); +return -ENOMEM ; + } ether->rdesc = (struct recv_pdesc *) -dma_alloc_coherent (NULL ,sizeof (struct recv_pdesc ), - (dma_addr_t *)ðer->rdesc_phys,GFP_KERNEL ); +dma_alloc_coherent (&pdev->dev,sizeof (struct recv_pdesc ), + ðer->rdesc_phys,GFP_KERNEL ); + +if (!ether->rdesc) { +dev_err (&pdev->dev,"Failed to allocate memory for rx desc\n" ); +dma_free_coherent (&pdev->dev,sizeof (struct tran_pdesc ), + ether->tdesc, ether->tdesc_phys); +return -ENOMEM ; + }for (i =0 ; i <TX_DESC_SIZE ; i++) { - tdesc = &(ether->tdesc->desclist[i]); +unsigned int offset; - j = ((i +1 ) /TX_DESC_SIZE ); + tdesc = &(ether->tdesc->desclist[i]); -if (j !=0 ) { - tdesc_phys = &(ether->tdesc_phys->desclist[0 ]); - ether->start_tx_ptr = (unsigned int )tdesc_phys; - tdesc->next = (unsigned int )ether->start_tx_ptr; - }else { - tdesc_phys = &(ether->tdesc_phys->desclist[i+1 ]); - tdesc->next = (unsigned int )tdesc_phys; - } +if (i ==TX_DESC_SIZE -1 ) + offset = offsetof(struct tran_pdesc, desclist[0]); +else + offset = offsetof(struct tran_pdesc, desclist[i + 1]); - tdesc->buffer = (unsigned int )ether->tdesc_phys->tran_buf[i]; + tdesc->next = ether->tdesc_phys + offset; + tdesc->buffer = ether->tdesc_phys + + offsetof(struct tran_pdesc, tran_buf[i]); tdesc->sl =0 ; tdesc->mode =0 ; } + ether->start_tx_ptr = ether->tdesc_phys; +for (i =0 ; i <RX_DESC_SIZE ; i++) { - rdesc = &(ether->rdesc->desclist[i]); +unsigned int offset; - j = ((i +1 ) /RX_DESC_SIZE ); + rdesc = &(ether->rdesc->desclist[i]); -if (j !=0 ) { - rdesc_phys = &(ether->rdesc_phys->desclist[0 ]); - ether->start_rx_ptr = (unsigned int )rdesc_phys; - rdesc->next = (unsigned int )ether->start_rx_ptr; - }else { - rdesc_phys = &(ether->rdesc_phys->desclist[i+1 ]); - rdesc->next = (unsigned int )rdesc_phys; - } +if (i ==RX_DESC_SIZE -1 ) + offset = offsetof(struct recv_pdesc, desclist[0]); +else + offset = offsetof(struct recv_pdesc, desclist[i + 1]); + rdesc->next = ether->rdesc_phys + offset; rdesc->sl =RX_OWEN_DMA ; - rdesc->buffer = (unsigned int )ether->rdesc_phys->recv_buf[i]; + rdesc->buffer = ether->rdesc_phys + + offsetof(struct recv_pdesc, recv_buf[i]); } + + ether->start_rx_ptr = ether->rdesc_phys; + +return 0 ; }static void w90p910_set_fifo_threshold (struct net_device *dev)
@@ -552,11 +569,14 @@ static int w90p910_set_mac_address(struct net_device *dev, void *addr)static int w90p910_ether_close (struct net_device *dev) {struct w90p910_ether *ether =netdev_priv (dev); +struct platform_device *pdev; + + pdev = ether->pdev; -dma_free_writecombine (NULL ,sizeof (struct w90p910_rxbd ), - ether->rdesc, (dma_addr_t )ether->rdesc_phys); -dma_free_writecombine (NULL ,sizeof (struct w90p910_txbd ), - ether->tdesc, (dma_addr_t )ether->tdesc_phys); +dma_free_coherent (&pdev->dev,sizeof (struct recv_pdesc ), + ether->rdesc, ether->rdesc_phys); +dma_free_coherent (&pdev->dev,sizeof (struct tran_pdesc ), + ether->tdesc, ether->tdesc_phys);netif_stop_queue (dev);
@@ -592,6 +612,7 @@ static int w90p910_send_frame(struct net_device *dev, txbd = ðer->tdesc->desclist[ether->cur_tx]; buffer = ether->tdesc->tran_buf[ether->cur_tx]; +if (length >1514 ) {dev_err (&pdev->dev,"send data %d bytes, check it\n" , length); length =1514 ;
@@ -607,7 +628,9 @@ static int w90p910_send_frame(struct net_device *dev,w90p910_trigger_tx (dev); - ether->cur_tx = (ether->cur_tx+1 ) %TX_DESC_SIZE ; +if (++ether->cur_tx >=TX_DESC_SIZE ) + ether->cur_tx =0 ; + txbd = ðer->tdesc->desclist[ether->cur_tx]; dev->trans_start = jiffies;
@@ -635,7 +658,6 @@ static irqreturn_t w90p910_tx_interrupt(int irq, void *dev_id)struct w90p910_ether *ether;struct w90p910_txbd *txbd;struct platform_device *pdev; -struct tran_pdesc *tran_pdesc;struct net_device *dev;unsigned int cur_entry, entry, status;
@@ -647,13 +669,14 @@ static irqreturn_t w90p910_tx_interrupt(int irq, void *dev_id) cur_entry =__raw_readl (ether->reg +REG_CTXDSA ); - tran_pdesc = ether->tdesc_phys; - entry = (unsigned int )(&tran_pdesc->desclist[ether->finish_tx]); + entry = ether->tdesc_phys + + offsetof(struct tran_pdesc, desclist[ether->finish_tx]);while (entry != cur_entry) { txbd = ðer->tdesc->desclist[ether->finish_tx]; - ether->finish_tx = (ether->finish_tx +1 ) %TX_DESC_SIZE ; +if (++ether->finish_tx >=TX_DESC_SIZE ) + ether->finish_tx =0 ;if (txbd->sl &TXDS_TXCP ) { ether->stats.tx_packets++;
@@ -668,7 +691,8 @@ static irqreturn_t w90p910_tx_interrupt(int irq, void *dev_id)if (netif_queue_stopped (dev))netif_wake_queue (dev); - entry = (unsigned int )(&tran_pdesc->desclist[ether->finish_tx]); + entry = ether->tdesc_phys + + offsetof(struct tran_pdesc, desclist[ether->finish_tx]); }if (status &MISTA_EXDEF ) {
@@ -689,20 +713,20 @@ static void netdev_rx(struct net_device *dev)struct w90p910_ether *ether;struct w90p910_rxbd *rxbd;struct platform_device *pdev; -struct recv_pdesc *rdesc_phys;struct sk_buff *skb;unsigned char *data;unsigned int length, status, val, entry; ether =netdev_priv (dev); pdev = ether->pdev; - rdesc_phys = ether->rdesc_phys; rxbd = ðer->rdesc->desclist[ether->cur_rx]; do { val = __raw_readl(ether->reg + REG_CRXDSA); - entry = (unsigned int)&rdesc_phys->desclist[ether->cur_rx]; + + entry = ether->rdesc_phys + + offsetof(struct recv_pdesc, desclist[ether->cur_rx]); if (val == entry) break;
@@ -747,7 +771,10 @@ static void netdev_rx(struct net_device *dev) rxbd->sl =RX_OWEN_DMA ; rxbd->reserved =0x0 ; - ether->cur_rx = (ether->cur_rx+1 ) %RX_DESC_SIZE ; + +if (++ether->cur_rx >=RX_DESC_SIZE ) + ether->cur_rx =0 ; + rxbd = ðer->rdesc->desclist[ether->cur_rx]; dev->last_rx = jiffies;
@@ -955,30 +982,29 @@ static int __devinit w90p910_ether_probe(struct platform_device *pdev) {struct w90p910_ether *ether;struct net_device *dev; -struct resource *res;int error; dev =alloc_etherdev (sizeof (struct w90p910_ether ));if (!dev)return -ENOMEM ; - res =platform_get_resource (pdev,IORESOURCE_MEM ,0 ); -if (res ==NULL ) { + ether =netdev_priv (dev); + + ether->res =platform_get_resource (pdev,IORESOURCE_MEM ,0 ); +if (ether->res ==NULL ) {dev_err (&pdev->dev,"failed to get I/O memory\n" ); error = -ENXIO ; goto failed_free; } - res =request_mem_region (res->start,resource_size (res), pdev->name); -if (res ==NULL ) { +if (!request_mem_region (ether->res->start, +resource_size (ether->res), pdev->name)) {dev_err (&pdev->dev,"failed to request I/O memory\n" ); error = -EBUSY ; goto failed_free; } - ether =netdev_priv (dev); - - ether->reg =ioremap (res->start,resource_size (res)); + ether->reg =ioremap (ether->res->start,resource_size (ether->res));if (ether->reg ==NULL ) {dev_err (&pdev->dev,"failed to remap I/O memory\n" ); error = -ENXIO ;
@@ -1039,7 +1065,7 @@ failed_free_txirq: failed_free_io:iounmap (ether->reg); failed_free_mem: -release_mem_region (res->start,resource_size (res)); +release_mem_region (ether->res->start,resource_size (ether->res)); failed_free:free_netdev (dev);return error;
@@ -1051,12 +1077,19 @@ static int __devexit w90p910_ether_remove(struct platform_device *pdev)struct w90p910_ether *ether =netdev_priv (dev);unregister_netdev (dev); +clk_put (ether->rmiiclk);clk_put (ether->clk); -del_timer_sync (ðer->check_timer); -platform_set_drvdata (pdev,NULL ); + +iounmap (ether->reg); +release_mem_region (ether->res->start,resource_size (ether->res)); +free_irq (ether->txirq, dev);free_irq (ether->rxirq, dev); + +del_timer_sync (ðer->check_timer); +platform_set_drvdata (pdev,NULL ); +free_netdev (dev);return 0 ; }
Signature · 1 line
1.5.6.3
Dear sirs,
I have to sent this patch third times and really didn't know why previous two mails were held by arm-linux-kernel. but it look like sending linux-netdev is successful, For any inconvenience caused, please forgive.
I fixed up previous mac driver and make a patch relative to it.
thanks for your help.
According to Russell's advice, I fixed up mac driver, which relatives to previous mac driver patch, and the evaluation board based on w90p910.
drivers/net/arm/w90p910_ether.c +91 -58
@@ -143,16 +143,17 @@ struct recv_pdesc {struct tran_pdesc {struct w90p910_txbd desclist[TX_DESC_SIZE ]; -char tran_buf[RX_DESC_SIZE ][MAX_TBUFF_SZ ]; +char tran_buf[TX_DESC_SIZE ][MAX_TBUFF_SZ ]; };struct w90p910_ether {struct recv_pdesc *rdesc; -struct recv_pdesc *rdesc_phys;struct tran_pdesc *tdesc; -struct tran_pdesc *tdesc_phys; +dma_addr_t rdesc_phys; +dma_addr_t tdesc_phys;struct net_device_stats stats;struct platform_device *pdev; +struct resource *res;struct sk_buff *skb;struct clk *clk;struct clk *rmiiclk;
@@ -274,59 +275,75 @@ static void w90p910_write_cam(struct net_device *dev,__raw_writel (msw, ether->reg +REG_CAMM_BASE + x *CAM_ENTRY_SIZE ); } -static void w90p910_init_desc (struct net_device *dev) +static int w90p910_init_desc (struct net_device *dev) {struct w90p910_ether *ether; -struct w90p910_txbd *tdesc, *tdesc_phys; -struct w90p910_rxbd *rdesc, *rdesc_phys; -unsigned int i, j; +struct w90p910_txbd *tdesc; +struct w90p910_rxbd *rdesc; +struct platform_device *pdev; +unsigned int i; ether =netdev_priv (dev); + pdev = ether->pdev; ether->tdesc = (struct tran_pdesc *) -dma_alloc_coherent (NULL ,sizeof (struct tran_pdesc ), - (dma_addr_t *)ðer->tdesc_phys,GFP_KERNEL ); +dma_alloc_coherent (&pdev->dev,sizeof (struct tran_pdesc ), + ðer->tdesc_phys,GFP_KERNEL ); + +if (!ether->tdesc) { +dev_err (&pdev->dev,"Failed to allocate memory for tx desc\n" ); +return -ENOMEM ; + } ether->rdesc = (struct recv_pdesc *) -dma_alloc_coherent (NULL ,sizeof (struct recv_pdesc ), - (dma_addr_t *)ðer->rdesc_phys,GFP_KERNEL ); +dma_alloc_coherent (&pdev->dev,sizeof (struct recv_pdesc ), + ðer->rdesc_phys,GFP_KERNEL ); + +if (!ether->rdesc) { +dev_err (&pdev->dev,"Failed to allocate memory for rx desc\n" ); +dma_free_coherent (&pdev->dev,sizeof (struct tran_pdesc ), + ether->tdesc, ether->tdesc_phys); +return -ENOMEM ; + }for (i =0 ; i <TX_DESC_SIZE ; i++) { - tdesc = &(ether->tdesc->desclist[i]); +unsigned int offset; - j = ((i +1 ) /TX_DESC_SIZE ); + tdesc = &(ether->tdesc->desclist[i]); -if (j !=0 ) { - tdesc_phys = &(ether->tdesc_phys->desclist[0 ]); - ether->start_tx_ptr = (unsigned int )tdesc_phys; - tdesc->next = (unsigned int )ether->start_tx_ptr; - }else { - tdesc_phys = &(ether->tdesc_phys->desclist[i+1 ]); - tdesc->next = (unsigned int )tdesc_phys; - } +if (i ==TX_DESC_SIZE -1 ) + offset = offsetof(struct tran_pdesc, desclist[0]); +else + offset = offsetof(struct tran_pdesc, desclist[i + 1]); - tdesc->buffer = (unsigned int )ether->tdesc_phys->tran_buf[i]; + tdesc->next = ether->tdesc_phys + offset; + tdesc->buffer = ether->tdesc_phys + + offsetof(struct tran_pdesc, tran_buf[i]); tdesc->sl =0 ; tdesc->mode =0 ; } + ether->start_tx_ptr = ether->tdesc_phys; +for (i =0 ; i <RX_DESC_SIZE ; i++) { - rdesc = &(ether->rdesc->desclist[i]); +unsigned int offset; - j = ((i +1 ) /RX_DESC_SIZE ); + rdesc = &(ether->rdesc->desclist[i]); -if (j !=0 ) { - rdesc_phys = &(ether->rdesc_phys->desclist[0 ]); - ether->start_rx_ptr = (unsigned int )rdesc_phys; - rdesc->next = (unsigned int )ether->start_rx_ptr; - }else { - rdesc_phys = &(ether->rdesc_phys->desclist[i+1 ]); - rdesc->next = (unsigned int )rdesc_phys; - } +if (i ==RX_DESC_SIZE -1 ) + offset = offsetof(struct recv_pdesc, desclist[0]); +else + offset = offsetof(struct recv_pdesc, desclist[i + 1]); + rdesc->next = ether->rdesc_phys + offset; rdesc->sl =RX_OWEN_DMA ; - rdesc->buffer = (unsigned int )ether->rdesc_phys->recv_buf[i]; + rdesc->buffer = ether->rdesc_phys + + offsetof(struct recv_pdesc, recv_buf[i]); } + + ether->start_rx_ptr = ether->rdesc_phys; + +return 0 ; }static void w90p910_set_fifo_threshold (struct net_device *dev)
@@ -552,11 +569,14 @@ static int w90p910_set_mac_address(struct net_device *dev, void *addr)static int w90p910_ether_close (struct net_device *dev) {struct w90p910_ether *ether =netdev_priv (dev); +struct platform_device *pdev; + + pdev = ether->pdev; -dma_free_writecombine (NULL ,sizeof (struct w90p910_rxbd ), - ether->rdesc, (dma_addr_t )ether->rdesc_phys); -dma_free_writecombine (NULL ,sizeof (struct w90p910_txbd ), - ether->tdesc, (dma_addr_t )ether->tdesc_phys); +dma_free_coherent (&pdev->dev,sizeof (struct recv_pdesc ), + ether->rdesc, ether->rdesc_phys); +dma_free_coherent (&pdev->dev,sizeof (struct tran_pdesc ), + ether->tdesc, ether->tdesc_phys);netif_stop_queue (dev);
@@ -592,6 +612,7 @@ static int w90p910_send_frame(struct net_device *dev, txbd = ðer->tdesc->desclist[ether->cur_tx]; buffer = ether->tdesc->tran_buf[ether->cur_tx]; +if (length >1514 ) {dev_err (&pdev->dev,"send data %d bytes, check it\n" , length); length =1514 ;
@@ -607,7 +628,9 @@ static int w90p910_send_frame(struct net_device *dev,w90p910_trigger_tx (dev); - ether->cur_tx = (ether->cur_tx+1 ) %TX_DESC_SIZE ; +if (++ether->cur_tx >=TX_DESC_SIZE ) + ether->cur_tx =0 ; + txbd = ðer->tdesc->desclist[ether->cur_tx]; dev->trans_start = jiffies;
@@ -635,7 +658,6 @@ static irqreturn_t w90p910_tx_interrupt(int irq, void *dev_id)struct w90p910_ether *ether;struct w90p910_txbd *txbd;struct platform_device *pdev; -struct tran_pdesc *tran_pdesc;struct net_device *dev;unsigned int cur_entry, entry, status;
@@ -647,13 +669,14 @@ static irqreturn_t w90p910_tx_interrupt(int irq, void *dev_id) cur_entry =__raw_readl (ether->reg +REG_CTXDSA ); - tran_pdesc = ether->tdesc_phys; - entry = (unsigned int )(&tran_pdesc->desclist[ether->finish_tx]); + entry = ether->tdesc_phys + + offsetof(struct tran_pdesc, desclist[ether->finish_tx]);while (entry != cur_entry) { txbd = ðer->tdesc->desclist[ether->finish_tx]; - ether->finish_tx = (ether->finish_tx +1 ) %TX_DESC_SIZE ; +if (++ether->finish_tx >=TX_DESC_SIZE ) + ether->finish_tx =0 ;if (txbd->sl &TXDS_TXCP ) { ether->stats.tx_packets++;
@@ -668,7 +691,8 @@ static irqreturn_t w90p910_tx_interrupt(int irq, void *dev_id)if (netif_queue_stopped (dev))netif_wake_queue (dev); - entry = (unsigned int )(&tran_pdesc->desclist[ether->finish_tx]); + entry = ether->tdesc_phys + + offsetof(struct tran_pdesc, desclist[ether->finish_tx]); }if (status &MISTA_EXDEF ) {
@@ -689,20 +713,20 @@ static void netdev_rx(struct net_device *dev)struct w90p910_ether *ether;struct w90p910_rxbd *rxbd;struct platform_device *pdev; -struct recv_pdesc *rdesc_phys;struct sk_buff *skb;unsigned char *data;unsigned int length, status, val, entry; ether =netdev_priv (dev); pdev = ether->pdev; - rdesc_phys = ether->rdesc_phys; rxbd = ðer->rdesc->desclist[ether->cur_rx]; do { val = __raw_readl(ether->reg + REG_CRXDSA); - entry = (unsigned int)&rdesc_phys->desclist[ether->cur_rx]; + + entry = ether->rdesc_phys + + offsetof(struct recv_pdesc, desclist[ether->cur_rx]); if (val == entry) break;
@@ -747,7 +771,10 @@ static void netdev_rx(struct net_device *dev) rxbd->sl =RX_OWEN_DMA ; rxbd->reserved =0x0 ; - ether->cur_rx = (ether->cur_rx+1 ) %RX_DESC_SIZE ; + +if (++ether->cur_rx >=RX_DESC_SIZE ) + ether->cur_rx =0 ; + rxbd = ðer->rdesc->desclist[ether->cur_rx]; dev->last_rx = jiffies;
@@ -955,30 +982,29 @@ static int __devinit w90p910_ether_probe(struct platform_device *pdev) {struct w90p910_ether *ether;struct net_device *dev; -struct resource *res;int error; dev =alloc_etherdev (sizeof (struct w90p910_ether ));if (!dev)return -ENOMEM ; - res =platform_get_resource (pdev,IORESOURCE_MEM ,0 ); -if (res ==NULL ) { + ether =netdev_priv (dev); + + ether->res =platform_get_resource (pdev,IORESOURCE_MEM ,0 ); +if (ether->res ==NULL ) {dev_err (&pdev->dev,"failed to get I/O memory\n" ); error = -ENXIO ; goto failed_free; } - res =request_mem_region (res->start,resource_size (res), pdev->name); -if (res ==NULL ) { +if (!request_mem_region (ether->res->start, +resource_size (ether->res), pdev->name)) {dev_err (&pdev->dev,"failed to request I/O memory\n" ); error = -EBUSY ; goto failed_free; } - ether =netdev_priv (dev); - - ether->reg =ioremap (res->start,resource_size (res)); + ether->reg =ioremap (ether->res->start,resource_size (ether->res));if (ether->reg ==NULL ) {dev_err (&pdev->dev,"failed to remap I/O memory\n" ); error = -ENXIO ;
@@ -1039,7 +1065,7 @@ failed_free_txirq: failed_free_io:iounmap (ether->reg); failed_free_mem: -release_mem_region (res->start,resource_size (res)); +release_mem_region (ether->res->start,resource_size (ether->res)); failed_free:free_netdev (dev);return error;
@@ -1051,12 +1077,19 @@ static int __devexit w90p910_ether_remove(struct platform_device *pdev)struct w90p910_ether *ether =netdev_priv (dev);unregister_netdev (dev); +clk_put (ether->rmiiclk);clk_put (ether->clk); -del_timer_sync (ðer->check_timer); -platform_set_drvdata (pdev,NULL ); + +iounmap (ether->reg); +release_mem_region (ether->res->start,resource_size (ether->res)); +free_irq (ether->txirq, dev);free_irq (ether->rxirq, dev); + +del_timer_sync (ðer->check_timer); +platform_set_drvdata (pdev,NULL ); +free_netdev (dev);return 0 ; }
Signature · 1 line
1.5.6.3
David Miller
maintainerFrom: Wan ZongShun <[email protected]>
Date: Thu, 23 Jul 2009 12:52:24 +0800
Quoted 1 line
I fixed up previous mac driver and make a patch relative to it.
This patch does not apply to the code actually in the tree, for example:
drivers/net/arm/w90p910_ether.c static void w90p910_write_cam(struct net_device *dev, · line 292
Quoted 6 lines
drivers/net/arm/w90p910_ether.c +3
-2ether->tdesc = (struct tran_pdesc *) -dma_alloc_coherent (NULL ,sizeof (struct tran_pdesc ), - (dma_addr_t *)ðer->tdesc_phys,GFP_KERNEL ); +dma_alloc_coherent (&pdev->dev,sizeof (struct tran_pdesc ), + ðer->tdesc_phys,GFP_KERNEL ); +
in the tree there is a space between '(dma_addr_t *)' and 'ðer->tdesc_phys', but the code you are patching against does not have that space.
Please do two things:
1) Generate your patch properly against the code actually in the tree.
2) Create a coherent, verbose, commit message and proper subject line which describes one-by-one the bug fixes you are making to the driver.
Thanks.