Linux Device Driver for Xilinx LL TEMAC 10/100/1000 Ethernet NIC
Subsystems (3)
PATCH 1/1 Linux Device Driver for Xilinx LL TEMAC 10/100/1000 Ethernet NIC
Pass II
Linux Device Driver for Xilinx LL TEMAC 10/100/1000 Ethernet NIC
Original Author Yoshio Kashiwagi
Updated and Maintained by David Lynch
---
drivers/net/Kconfig | 5 drivers/net/Makefile | 1 drivers/net/xps_lltemac.c | 1562 ++++++++++++++++++++++++++++++++++++++++ include/linux/xilinx_devices.h | 2 4 files changed, 1569 insertions(+), 1 deletions(-)
drivers/net/Kconfig +5 -0
@@ -2332,6 +2332,11 @@ config MV643XX_ETH Some boards that use the Discovery chipset are the Momenco Ocelot C and Jaguar ATX and Pegasos II. +config XPS_LLTEMAC + tristate "Xilinx LLTEMAC 10/100/1000 Ethernet MAC driver" + help + This driver supports the Xilinx 10/100/1000 LLTEMAC found in Virtex 4 FPGAs + config QLA3XXX tristate "QLogic QLA3XXX Network Driver Support" depends on PCI
drivers/net/Makefile +1 -0
@@ -126,6 +126,7 @@ obj-$(CONFIG_AX88796) += ax88796.o obj-$(CONFIG_TSI108_ETH) += tsi108_eth.o obj-$(CONFIG_PICO_TEMAC) += pico_temac.o obj-$(CONFIG_MV643XX_ETH) += mv643xx_eth.o +obj-$(CONFIG_XPS_LLTEMAC) += xps_lltemac.o obj-$(CONFIG_QLA3XXX) += qla3xxx.o obj-$(CONFIG_PPP) += ppp_generic.o
drivers/net/xps_lltemac.c new file +1562 -0
1,562 lines not on this page · raw message
include/linux/xilinx_devices.h +1 -1
@@ -94,7 +94,7 @@ struct xtemac_platform_data {#define XTEMAC_DMA_SGDMA 3/* scatter gather DMA */ #endif -#if defined(CONFIG_XILINX_LLTEMAC) +#if defined(CONFIG_XILINX_LLTEMAC) || defined(CONFIG_XPS_LLTEMAC) /* LLTEMAC platform data */ struct xlltemac_platform_data { u8 tx_csum;
A message that is not in the archive (sent off-list or not yet received): [email protected]
A message that is not in the archive (sent off-list or not yet received): [email protected]
A message that is not in the archive (sent off-list or not yet received): [email protected]
A message that is not in the archive (sent off-list or not yet received): [email protected]
RE: [PATCH] Linux Device Driver for Xilinx LL TEMAC 10/100/1000 EthernetNIC
I screwed up and forgot to copy all on this previously.
Quoted 5 lines
-----Original Message-----
From: David H. Lynch Jr. [mailto:[email protected]]
Sent: Tuesday, August 19, 2008 3:19 PM
To: John Linn
Subject: Re: [PATCH] Linux Device Driver for Xilinx LL TEMAC
10/100/1000 EthernetNIC
Quoted 3 lines
Quoted 1 line · John Linn
Quoted 1 line
Stephen wants OF support -which is fine, but I can not test
that.
Quoted 3 lines
Quoted 3 lines
Quoted 1 line
I definitely agree with Stephen that OF support is needed since
arch/ppc
Quoted 3 lines
Quoted 3 lines
has gone away. We aren't doing any new work on
arch/ppc.Are you not planning to move to
arch/powerpcanytime soon? I could
help
Quoted 6 lines
Quoted 4 lines
you with that transition which would be better in the long run. I'd rather do that than do testing for you as I think it would be more productive, but I've been wrong before.
We will move to powerpc, but not in the time-frame I am hoping for
this
Quoted 2 lines
driver.
In the context of Linux and Pico, "we" means me, and there is no time
to
Quoted 2 lines
do the work anytime soon.
<snip>
What about you getting all the review & testing done and then we (Xilinx) will add the OF support to the driver?
I doubt the powerpc mainline will take the driver without OF support. In fact, we had to remove the platform bus support from the last driver that we put into mainline for arch/powerpc.
Quoted 8 lines
Quoted 8 lines
Quoted 7 lines
I would like
one and only one tag that can be used end-end.Is there something xilinx will object to ? Prefer ? ....
xilinx_<device name>, (
xilinx_lltemacorxilinx_ps2) is what we use
for
Quoted 1 line
Quoted 1 line
file names. The device tree does use "xlnx" to identify xilinx
devices,
Quoted 3 lines
Quoted 3 lines
but I don't think that should dictate file names.
We have a driver in out GIT tree that is not flat (as most know) for
the
Quoted 1 line
Quoted 1 line
LL TEMAC and we are working on creating flat drivers for future
devices.
Quoted 7 lines
Quoted 2 lines
Ideally this new driver would be a replacement for our driver.
Give me a name and I will go with it. the
xps_lltemacname came from Yoshio,
It is not in stone.
Quoted 5 lines
If I name the module "
xilinx_lltemac" and go withxilinx_lltemac.cfor the file name,
is that going to cause problems with xilinx ?I will use whatever you recomend.
xilinx_lltemac is the preferred.
I don't think using xilinx_lltemac should cause problems. Our Xilinx Git tree has a xilinx_lltemac subdir that contains the non-flat driver but that should be ok with your xilinx_lltemac.c file in the net directory.
Quoted 4 lines
--
Dave Lynch DLA Systems
Software Development:
Embedded Linux
Quoted 3 lines
717.627.3770 [email protected] http://www.dlasys.net
fax: 1.253.369.9244 Cell: 1.717.587.7774
Over 25 years' experience in platforms, languages, and technologies
too numerous to list.
Quoted 2 lines
"Any intelligent fool can make things bigger and more complex... It
takes a touch of genius - and a
Quoted 3 lines
lot of courage to move in the opposite direction." Albert Einstein
This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.
Re: [PATCH] Linux Device Driver for Xilinx LL TEMAC 10/100/1000 EthernetNIC
Quoted 8 lines · John Linn
What about you getting all the review & testing done and then we (Xilinx) will add the OF support to the driver?
I doubt the powerpc mainline will take the driver without OF support. In fact, we had to remove the platform bus support from the last driver that we put into mainline for
arch/powerpc.
That is perfectly fine with me. i will try to pull the xilinx git tree and see how much closer I can make the probe so that converting will be easier.
Quoted 9 lines
xilinx_lltemacis the preferred.I don't think using
xilinx_lltemacshould cause problems. Our Xilinx Git tree has axilinx_lltemacsubdir that contains the non-flat driver but that should be ok with yourxilinx_lltemac.cfile in the net directory.
The next patch incarnation will have everything as xilinx_lltemac - including the file as xilinx_lltemac.c
Signature · 8 lines
Dave Lynch DLA Systems Software Development: Embedded Linux 717.627.3770 [email protected] http://www.dlasys.net fax: 1.253.369.9244 Cell: 1.717.587.7774 Over 25 years' experience in platforms, languages, and technologies too numerous to list. "Any intelligent fool can make things bigger and more complex... It takes a touch of genius - and a lot of courage to move in the opposite direction." Albert Einstein
RE: [PATCH] Linux Device Driver for Xilinx LL TEMAC 10/100/1000 EthernetNIC
In reply to David H. Lynch Jr.I'm not claiming to be a Linux driver expert as I'm still learning. Some of the comments are nits.
Thanks for the effort you're putting in on this.
Quoted 5 lines
Linux Device Driver for Xilinx LL TEMAC 10/100/1000 Ethernet NIC
Original Author Yoshio Kashiwagi
Updated and Maintained by David Lynch
Quoted 7 lines
Signed-off-by David H. Lynch Jr. <[email protected]>---
drivers/net/Kconfig | 5 drivers/net/Makefile | 1 drivers/net/xps_lltemac.c | 1562
++++++++++++++++++++++++++++++++++++++++
Quoted 8 lines
include/linux/xilinx_devices.h | 2 4 files changed, 1569 insertions(+), 1 deletions(-)drivers/net/Kconfig +0
-0
drivers/net/Kconfig config MV643XX_ETH · line 2338
Quoted 7 lines
drivers/net/Kconfig +4
-0@@ -2332,6 +2332,11 @@ config MV643XX_ETH Some boards that use the Discovery chipset are the Momenco Ocelot C and Jaguar ATX and Pegasos II. +config XPS_LLTEMAC + tristate "Xilinx LLTEMAC 10/100/1000 Ethernet MAC driver" + help + This driver supports the Xilinx 10/100/1000 LLTEMAC found in
Virtex 4 FPGAs
It might be helpful to say only in DMA mode as our traditional drivers support FIFO mode and DMA.
Since the FPGA is pretty flexible people tend to do things different than I sometimes expect.
drivers/net/xps_lltemac.c
Quoted 23 lines
drivers/net/Kconfig +1
-0+ config QLA3XXX tristate "QLogic QLA3XXX Network Driver Support" depends on PCIdrivers/net/Makefile +1
-0@@ -126,6 +126,7 @@ obj-$(CONFIG_AX88796) += ax88796.o obj-$(CONFIG_TSI108_ETH) += tsi108_eth.o obj-$(CONFIG_PICO_TEMAC) += pico_temac.o obj-$(CONFIG_MV643XX_ETH) += mv643xx_eth.o +obj-$(CONFIG_XPS_LLTEMAC) += xps_lltemac.o obj-$(CONFIG_QLA3XXX) += qla3xxx.o obj-$(CONFIG_PPP) += ppp_generic.odrivers/net/xps_lltemac.c new file +0
-0@@ -0,0 +1,1562 @@
+/*===================================================================== =
drivers/net/xps_lltemac.c line 3
Quoted 2 lines
drivers/net/xps_lltemac.c new file +2
-0+ + Driver for Xilinx temac ethernet NIC's
Saying LL TEMAC would be clearer as we having older TEMACs that are yet different and not local link (LL).
It's definitely not a NIC in the traditional sense of a PCI card, but is an SOC core.
drivers/net/xps_lltemac.c line 10
Quoted 8 lines
drivers/net/xps_lltemac.c new file +7
-0+ + Author: Yoshio Kashiwagi + Copyright (c) 2008 Nissin Systems Co.,Ltd. + + Revisons: David H. Lynch Jr. <[email protected]> + Copyright (C) 2005-2008 DLA Systems +
+======================================================================*
/
Quoted 16 lines
drivers/net/xps_lltemac.c new file +16
-0+/* DRV_NAME is for compatibility with existing xilinx ll temac driver +* also with of/dtc object names */ +#define DRV_NAME "xilinx_lltemac" +#define DRV_AUTHOR "Yoshio Kashiwagi" +#define DRV_EMAIL "" + +#include <linux/module.h> +#include <linux/netdevice.h> +#include <linux/etherdevice.h> +#include <linux/init.h> +#include <linux/skbuff.h> +#include <linux/platform_device.h> +#include <linux/spinlock.h> + +#include <linux/mii.h> +#include <linux/in.h>
drivers/net/xps_lltemac.c line 37
Quoted 10 lines
drivers/net/xps_lltemac.c new file +10
-0+#include <linux/pci.h> + +#include <linux/ip.h> +#include <linux/tcp.h> /* just needed for sizeof(tcphdr) */ +#include <linux/udp.h> /* needed for sizeof(udphdr) */ +#include <linux/delay.h> +#include <linux/io.h> + +#define MII_ANI 0x10 +#define PHY_NUM 0
This phy number, (phy address), won't work for a number of Xilinx boards. It seems like this should be either pulled from the platform data (and device tree), or the driver should try to find the PHY address by trying each one.
Otherwise the users will have to edit the driver all the time when their phy is not address 0.
Quoted 2 lines
drivers/net/xps_lltemac.c new file +2
-0+#define PHY_TIMEOUT 10000 +
<snip>
drivers/net/xps_lltemac.c line 495
Quoted 10 lines
drivers/net/xps_lltemac.c new file +10
-0+static unsigned int +mdio_read (struct net_device *ndev,int phy_id,int reg_num) +{ +struct temac_local *lp =netdev_priv (ndev); +u32 timeout =PHY_TIMEOUT ; +u32 rv =0 ; +unsigned long flags; + +if ((reg_num >MII_REG_MAX ) || + (phy_id ==PHY_ADDR_INVALID )) {
The phy_id never gets set to PHY_ADDR_INVALID, is there something I'm missing or should this be removed? Maybe this is related to the PHY_NUM hard coded value that could be set invalid.
drivers/net/xps_lltemac.c
Quoted 2 lines
drivers/net/xps_lltemac.c new file +2
-0+ dev_err(&ndev->dev, + "mdio_read(%x, %x) invalid reg_num or invalid
phy_id\n",
drivers/net/xps_lltemac.c
Quoted 2 lines
drivers/net/xps_lltemac.c new file +2
-0+ reg_num, phy_id); +return -1 ;
Returning a negative value for failure makes sense, but not when the return type is unsigned int, should it be an int instead?
I put in nits about return types and I realize their nits, but should make the driver better was my
hope.
drivers/net/xps_lltemac.c
Quoted 12 lines
drivers/net/xps_lltemac.c new file +12
-0+ } + +spin_lock_irqsave (&lp->lock, flags); + +tiow (ndev,XTE_LSW0_OFFSET , + ((phy_id <<5 ) | (reg_num))); +tiow (ndev,XTE_CTL0_OFFSET , +XTE_MIIMAI_OFFSET | (lp->emac_num <<10 )); +while (!(tior (ndev,XTE_RDY0_OFFSET ) &XTE_RSE_MIIM_RR_MASK )) { +udelay (1 ); +if (--timeout ==0 ) { + dev_err(&ndev->dev, "read_MII busy
timeout!!\n");
drivers/net/xps_lltemac.c
Quoted 11 lines
drivers/net/xps_lltemac.c new file +11
-0+return -1 ; + } + } + rv =tior (ndev,XTE_LSW0_OFFSET ); + +spin_unlock_irqrestore (&lp->lock, flags); +return rv; +} + +static void +mdio_write(struct net_device *ndev, int phy_id, int reg_num, int
reg_val)
drivers/net/xps_lltemac.c
Quoted 9 lines
drivers/net/xps_lltemac.c new file +9
-0+{ +struct temac_local *lp =netdev_priv (ndev); +u32 timeout =PHY_TIMEOUT , status; +unsigned long flags; + +if ((reg_num >MII_REG_MAX ) || + (phy_id ==PHY_ADDR_INVALID )) { + dev_err(&ndev->dev, + "mdio_write(%x, %x)invalid reg_num or invalid
phy_id\n",
drivers/net/xps_lltemac.c
Quoted 2 lines
drivers/net/xps_lltemac.c new file +2
-0+ reg_num, phy_id); +return -1 ;
The return type is void yet it tries to return -1, should it be int return?
Quoted 5 lines
drivers/net/xps_lltemac.c new file +5
-0+ } + +spin_lock_irqsave (&lp->lock, flags); + + tiow(ndev, XTE_LSW0_OFFSET,
drivers/net/xps_lltemac.c
Quoted 10 lines
drivers/net/xps_lltemac.c new file +10
-0+ reg_val); +tiow (ndev,XTE_CTL0_OFFSET , +CNTLREG_WRITE_ENABLE_MASK |XTE_MGTDR_OFFSET ); +tiow (ndev,XTE_LSW0_OFFSET , + ((phy_id <<5 ) | (reg_num))); +tiow (ndev,XTE_CTL0_OFFSET , +CNTLREG_WRITE_ENABLE_MASK + |XTE_MIIMAI_OFFSET + | (lp->emac_num <<10 )); + while (!(status = tior(ndev, XTE_RDY0_OFFSET) &
XTE_RSE_MIIM_WR_MASK)) {
drivers/net/xps_lltemac.c
Quoted 3 lines
drivers/net/xps_lltemac.c new file +3
-0+udelay (1 ); +if (--timeout ==0 ) { + dev_err(&ndev->dev, "write_MII busy
timeout!!\n");
drivers/net/xps_lltemac.c
Quoted 1 line
drivers/net/xps_lltemac.c new file +1
-0+return ;
Seems like this should return -1 as a failure and be consistent with read().
Quoted 9 lines
drivers/net/xps_lltemac.c new file +9
-0+ } + } + +spin_unlock_irqrestore (&lp->lock, flags); +} + +static u32 +emac_cfg_read (struct net_device *ndev,u16 reg_num) +{
drivers/net/xps_lltemac.c line 571
Quoted 10 lines
drivers/net/xps_lltemac.c new file +10
-0+struct temac_local *lp =netdev_priv (ndev); +u32 timeout =PHY_TIMEOUT ; + +if (reg_num >TEMAC_REG_MAX ) { +dev_err (&ndev->dev, +"emac_cfg_read(%x) invalid reg_num\n" , + reg_num); +return -1 ; + } +
Can the register value read be -1 by accident such that a valid register return
looks like a failure?
drivers/net/xps_lltemac.c
Quoted 5 lines
drivers/net/xps_lltemac.c new file +5
-0+tiow (ndev,XTE_CTL0_OFFSET , (lp->emac_num <<10 ) | reg_num); +while (!(tior (ndev,XTE_RDY0_OFFSET ) &XTE_RSE_CFG_RR_MASK )) { +udelay (1 ); +if (--timeout ==0 ) { + dev_err(&ndev->dev, "read temac busy
timeout!!\n");
Quoted 10 lines
drivers/net/xps_lltemac.c new file +10
-0+return -1 ; + } + } +return (u32 )tior (ndev,XTE_LSW0_OFFSET ); + +} + +static void +emac_cfg_write (struct net_device *ndev,u32 reg_num,u32 val) +{
drivers/net/xps_lltemac.c line 596
Quoted 10 lines
drivers/net/xps_lltemac.c new file +10
-0+struct temac_local *lp =netdev_priv (ndev); +u32 timeout =PHY_TIMEOUT ; + +if (reg_num >TEMAC_REG_MAX ) { +dev_err (&ndev->dev, +"emac_cfg_write(%x) invalid reg_num\n" , + reg_num); +return -1 ; + } +
Same thing returning a value when void return, and timeout below again should
return failure? It would seem like these be compiler warnings?
drivers/net/xps_lltemac.c
Quoted 10 lines
drivers/net/xps_lltemac.c new file +10
-0+tiow (ndev,XTE_LSW0_OFFSET , val); +tiow (ndev, +XTE_CTL0_OFFSET , + (CNTLREG_WRITE_ENABLE_MASK + | (lp->emac_num <<10 ) + | reg_num)); +while (!(tior (ndev,XTE_RDY0_OFFSET ) &XTE_RSE_CFG_WR_MASK )) { +udelay (1 ); +if (--timeout ==0 ) { + dev_err(&ndev->dev, "write temac busy
timeout!!\n");
drivers/net/xps_lltemac.c
Quoted 7 lines
drivers/net/xps_lltemac.c new file +7
-0+return ; + } + } +} + +static u32 +emac_cfg_setclr(struct net_device *ndev, u32 reg_num, u32 val, int
flg)
drivers/net/xps_lltemac.c line 621
Quoted 8 lines
drivers/net/xps_lltemac.c new file +8
-0+{ +u32 Reg; +if (reg_num >TEMAC_REG_MAX ) { +dev_err (&ndev->dev, +"emac_cfg_setclr(%x) invalid reg_num\n" , + reg_num); +return -1 ; + }
Nit.
Sorry to pick on return values so much, but they seem real inconsistent. seems like an int would be more appropriate here as there's no register value
to be returned.
Quoted 8 lines
drivers/net/xps_lltemac.c new file +8
-0+ + Reg =emac_cfg_read (ndev, reg_num) & ~val; +if (flg) + Reg |= val; +emac_cfg_write (ndev, reg_num, Reg); +return 0 ; +} +
<snip>
drivers/net/xps_lltemac.c
Quoted 8 lines
drivers/net/xps_lltemac.c new file +8
-0+static int +temac_bd_init (struct net_device *ndev) +{ +struct temac_local *lp =netdev_priv (ndev); +struct sk_buff *skb; +int ii; + + lp->rx_skb = kzalloc(sizeof(struct sk_buff)*RX_BD_NUM,
GFP_KERNEL);
drivers/net/xps_lltemac.c line 805
Quoted 10 lines
drivers/net/xps_lltemac.c new file +10
-0+/* allocate the tx and rx ring buffer descriptors. */ +/* returns a virtual addres and a physical address. */ + lp->tx_bd_v =dma_alloc_coherent (NULL , +sizeof (struct cdmac_bd ) *TX_BD_NUM , + (dma_addr_t *)&lp->tx_bd_p, +GFP_KERNEL ); + lp->rx_bd_v =dma_alloc_coherent (NULL , +sizeof (struct cdmac_bd ) *RX_BD_NUM , + (dma_addr_t *)&lp->rx_bd_p, +GFP_KERNEL );
Not sure this is a big deal, BDs have to be cacheline aligned, but since there are 8 words for each, it's not a problem on 405 and 440 (32 byte cacheline). Other powerpc processors might be a problem. A more specific dependency on 4xx might be useful?
drivers/net/xps_lltemac.c
Quoted 3 lines
drivers/net/xps_lltemac.c new file +3
-0+ +for (ii =0 ; ii <TX_BD_NUM ; ii++) { + memset((char *)&lp->tx_bd_v[ii], 0, sizeof(struct
cdmac_bd));
Quoted 6 lines
drivers/net/xps_lltemac.c new file +6
-0+if (ii == (TX_BD_NUM -1 )) + lp->tx_bd_v[ii].next = &lp->tx_bd_p[0 ]; +else + lp->tx_bd_v[ii].next = &lp->tx_bd_p[ii +1 ]; + + }
<snip>
drivers/net/xps_lltemac.c line 996
Quoted 13 lines
drivers/net/xps_lltemac.c new file +13
-0+ +/* Initilize temac */ +static void +temac_device_reset (struct net_device *ndev) +{ +struct temac_local *lp =netdev_priv (ndev); +u32 timeout =1000 ; + +/* Perform a software reset */ + +/* 0x300 host enable bit ? */ +/* reset PHY through control register ?:1 */ +
Seems like the above comments should be removed.
drivers/net/xps_lltemac.c
Quoted 4 lines
drivers/net/xps_lltemac.c new file +4
-0+/* Reset the device */ +emac_cfg_write (ndev,XTE_RXC1_OFFSET ,XTE_RXC1_RXRST_MASK ); +/* Wait for the receiver to finish reset */ + while (emac_cfg_read(ndev, XTE_RXC1_OFFSET) &
XTE_RXC1_RXRST_MASK) {
drivers/net/xps_lltemac.c
Quoted 4 lines
drivers/net/xps_lltemac.c new file +4
-0+udelay (1 ); +if (--timeout ==0 ) { + dev_err(&ndev->dev, + "temac_device_reset RX reset
timeout!!\n");
drivers/net/xps_lltemac.c
Quoted 8 lines
drivers/net/xps_lltemac.c new file +8
-0+break ; + } + } + +emac_cfg_write (ndev,XTE_TXC_OFFSET ,XTE_TXC_TXRST_MASK ); +/* Wait for the transmitter to finish reset */ + timeout =1000 ; +while (emac_cfg_read (ndev,XTE_TXC_OFFSET ) &XTE_TXC_TXRST_MASK )
{
drivers/net/xps_lltemac.c
Quoted 4 lines
drivers/net/xps_lltemac.c new file +4
-0+udelay (1 ); +if (--timeout ==0 ) { + dev_err(&ndev->dev, + "temac_device_reset TX reset
timeout!!\n");
Quoted 9 lines
drivers/net/xps_lltemac.c new file +9
-0+break ; + } + } + +/* Disable the receiver */ +emac_cfg_write (ndev, +XTE_RXC1_OFFSET , +emac_cfg_read (ndev,XTE_RXC1_OFFSET ) + & ~XTE_RXC1_RXEN_MASK );
drivers/net/xps_lltemac.c
Quoted 10 lines
drivers/net/xps_lltemac.c new file +10
-0+ +/* reset */ +tiow (ndev,XTE_RAF0_OFFSET ,1 ); +/* wait for reset */ + timeout =1000 ; +while (tior (ndev,XTE_RAF0_OFFSET ) &1 ) { +udelay (1 ); +if (--timeout ==0 ) { + dev_err(&ndev->dev, + "temac_device_reset RAF reset
timeout!!\n");
Quoted 9 lines
drivers/net/xps_lltemac.c new file +9
-0+break ; + } + } + +/* ISR0/IER0/IPR0 bits */ +/* b1 autoneg complete */ +/* b2 receive complete */ +/* b5 transmit complete */ +/* b0 = interrupts from TIS/TIE registers */
drivers/net/xps_lltemac.c
Quoted 10 lines
drivers/net/xps_lltemac.c new file +10
-0+ + +/* Reset */ +sd_iow (ndev,DMA_CONTROL_REG ,DMA_CONTROL_RST ); + timeout =1000 ; +while (sd_ior (ndev,DMA_CONTROL_REG ) &DMA_CONTROL_RST ) { +udelay (1 ); +if (--timeout ==0 ) { + dev_err(&ndev->dev, + "temac_device_reset DMA reset
timeout!!\n");
drivers/net/xps_lltemac.c
Quoted 6 lines
drivers/net/xps_lltemac.c new file +6
-0+break ; + } + } + + dev_info(&ndev->dev, + "%s: Xilinx Embedded Tri-Mode Ethernet MAC %s
%s\n",
Quoted 8 lines
drivers/net/xps_lltemac.c new file +8
-0+ ndev->name, + __DATE__, + __TIME__); +dev_info (&ndev->dev,"temac %08x sdma %08x\n" , + lp->regs.addr, + lp->sdma.addr); + +temac_bd_init (ndev);
drivers/net/xps_lltemac.c
Quoted 10 lines
drivers/net/xps_lltemac.c new file +10
-0+ +emac_cfg_write (ndev,XTE_RXC0_OFFSET ,0 ); +emac_cfg_write (ndev,XTE_RXC1_OFFSET ,0 ); +emac_cfg_write (ndev,XTE_TXC_OFFSET ,0 ); +emac_cfg_write (ndev,XTE_FCC_OFFSET ,XTE_FCC_RXFLO_MASK ); + +/* Sync default options with HW +* but leave receiver and transmitter disabled. */ + temac_setoptions(ndev, + lp->options & ~(XTE_OPTION_TXEN |
XTE_OPTION_RXEN));
Quoted 20 lines
drivers/net/xps_lltemac.c new file +20
-0+ +temac_phy_init (ndev); + +temac_set_mac_address (ndev,0 ); +/* Set address filter table */ +temac_set_multicast_list (ndev); +if (temac_setoptions (ndev, lp->options)) +dev_err (&ndev->dev,"Error setting TEMAC options\n" ); + +/* Init Driver variable */ + ndev->trans_start =0 ; +spin_lock_init (&lp->lock); +spin_lock_init (&lp->rx_lock); +} + +static void +temac_hard_start_xmit_done (struct net_device *ndev) +{ +struct temac_local *lp =netdev_priv (ndev); +struct cdmac_bd *cur_p;
drivers/net/xps_lltemac.c line 1108
Quoted 10 lines
drivers/net/xps_lltemac.c new file +10
-0+unsigned int stat =0 ; + + cur_p = &lp->tx_bd_v[lp->tx_bd_ci]; + stat = cur_p->app0; + +while (stat &STS_CTRL_APP0_CMPLT ) { +pci_unmap_single (NULL , + (unsigned long )cur_p->phys, + cur_p->len, +PCI_DMA_TODEVICE );
It seems like the PCI calls would be better replaced with dma_unmap_single()
and dma_map_single to be more accurate and probably less overhead?
The dma functions, not sure on the pci, should handle when we change the driver
to cache the BDs as that will be needed eventually for good performance.
drivers/net/xps_lltemac.c
Quoted 2 lines
drivers/net/xps_lltemac.c new file +2
-0+if (cur_p->app4) + dev_kfree_skb_irq((struct sk_buff
*)cur_p->app4);
Quoted 16 lines
drivers/net/xps_lltemac.c new file +16
-0+ cur_p->app0 =0 ; + + lp->stats.tx_packets++; + lp->stats.tx_bytes += cur_p->len; + + lp->tx_bd_ci++; +if (lp->tx_bd_ci >=TX_BD_NUM ) + lp->tx_bd_ci =0 ; + + cur_p = &lp->tx_bd_v[lp->tx_bd_ci]; + stat = cur_p->app0; + } + +netif_wake_queue (ndev); +} +
<snip>
drivers/net/xps_lltemac.c
Quoted 2 lines
drivers/net/xps_lltemac.c new file +2
-0+static int __init +temac_device_map(struct platform_device *pdev, struct net_device
*ndev,
Quoted 11 lines
drivers/net/xps_lltemac.c new file +11
-0+ int num, struct temac_region *reg) +{ + struct resource *res; +int erC =0 ; + + res =platform_get_resource (pdev,IORESOURCE_MEM , num); +if (res ==0 ) { + erC = -ENODEV ; + goto fail; + } + if (request_mem_region(res->start, res->end - res->start,
drivers/net/xps_lltemac.c line 1396
Quoted 10 lines
drivers/net/xps_lltemac.c new file +10
-0+ pdev->name) == 0) { +dev_err (&pdev->dev, +"%s: failed to request registers\n" , + pdev->name); + erC = -ENXIO ; + goto fail; + } + + reg->base = (uintptr_t )res->start; + reg->len = res->end - res->start;
Should this really be res->end - res->start + 1 to include the memory region? It's also used up above in the mem_region call.
Quoted 13 lines
drivers/net/xps_lltemac.c new file +13
-0+ reg->addr =ioremap_nocache ((uintptr_t )reg->base, reg->len); +if (reg->addr ==0 ) { +dev_err (&pdev->dev, +"%s: failed to remap registers\n" , pdev->name); + erC = -ENXIO ; + goto fail_remap; + } +return 0 ; +fail_remap: +release_region ((u32 )reg->addr, reg->len); +fail: +return erC; +}
<snip>
Quoted 2 lines
-----Original Message-----
From: [email protected]
[mailto:linuxppc-embedded-
Quoted 1 line
[email protected]] On Behalf Of David H. Lynch
Jr.
Quoted 3 lines
Sent: Tuesday, August 19, 2008 3:34 AM
To: linuxppc-embedded; [email protected]
Subject: [PATCH] Linux Device Driver for Xilinx LL TEMAC 10/100/1000
EthernetNIC
Quoted 2 lines
Pass II
This email and any attachments are intended for the sole use of the named recipient(s) and contain(s) confidential information that may be proprietary, privileged or copyrighted under applicable law. If you are not the intended recipient, do not read, copy, or forward this email message or any attachments. Delete this email message and any attachments immediately.
Quoted 8 lines · On Tuesday 19 August 2008 13:34:04 David H. Lynch Jr. wrote:
Pass II
drivers/net/xps_lltemac.c new file +6
-0+ cur_p->phys = (unsigned char *)pci_map_single (NULL , + skb->data, skb->len, +PCI_DMA_TODEVICE ); + cur_p->app4 = (unsigned long )skb; + +for (ii =0 ; ii < num_frag; ii++) {
drivers/net/xps_lltemac.c line 1200
Quoted 10 lines
drivers/net/xps_lltemac.c new file +10
-0+ lp->tx_bd_tail++; +if (lp->tx_bd_tail >=TX_BD_NUM ) + lp->tx_bd_tail =0 ; + + cur_p = &lp->tx_bd_v[lp->tx_bd_tail]; + cur_p->phys = (unsigned char *)pci_map_single (NULL , + (void *)page_address (frag->page) + + frag->page_offset, + frag->size, +PCI_DMA_TODEVICE );
1. Why is pci_* API is used instead of dma_*?
2. Why pci_map_single() in skb_shinfo(skb)->frags processing instead of dma_map_page()?
drivers/net/xps_lltemac.c line 812
Quoted 4 lines
drivers/net/xps_lltemac.c new file +4
-0+if (ii == (TX_BD_NUM -1 )) + lp->tx_bd_v[ii].next = &lp->tx_bd_p[0 ]; +else + lp->tx_bd_v[ii].next = &lp->tx_bd_p[ii +1 ];
3. It would be much simpler to use masking by (TX_BD_NUM - 1) instead of "if (ii == (TX_BD_NUM - 1))" constructs.
4. There is a need of global locking mechanism for indirect registers access, as according to Xilinx documentation only one hard core at a a time can be accessed.
T24gVHVlc2RheSAxOSBBdWd1c3QgMjAwOCAxMzozNDowNCBEYXZpZCBILiBMeW5jaCBKci4gd3Jv dGU6Cj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoHN3aXRjaCAoaXAtPnByb3RvY29s KSB7Cj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoGNhc2UgSVBQUk9UT19UQ1A6Cj4g K8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqBzdGFydCA9IHNp emVvZihzdHJ1Y3QgaXBoZHIpICsgRVRIX0hMRU47Cj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqBpbnNlcnQgPSBzaXplb2Yoc3RydWN0IGlwaGRyKSArIEVU SF9ITEVOICsgMTY7Cj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqBsZW5ndGggPSBpcC0+dG90X2xlbiAtIHNpemVvZihzdHJ1Y3QgaXBoZHIpOwo+ICvCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgaGVhZGxlbiA9IEVUSF9I TEVOCj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgKyBzaXplb2Yoc3RydWN0IGlwaGRyKQo+ICvCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoCsgc2l6ZW9mKHN0cnVj dCB0Y3BoZHIpOwo+ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgYnJlYWs7Cj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoGNhc2UgSVBQUk9UT19V RFA6Cj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqBzdGFy dCA9IHNpemVvZihzdHJ1Y3QgaXBoZHIpICsgRVRIX0hMRU47Cj4gK8KgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqBpbnNlcnQgPSBzaXplb2Yoc3RydWN0IGlwaGRy KSArIEVUSF9ITEVOICsgNjsKPiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoGxlbmd0aCA9IGlwLT50b3RfbGVuIC0gc2l6ZW9mKHN0cnVjdCBpcGhkcik7Cj4g K8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqBoZWFkbGVuID0g RVRIX0hMRU4KPiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDC oMKgwqDCoMKgwqDCoMKgwqArIHNpemVvZihzdHJ1Y3QgaXBoZHIpCj4gK8KgwqDCoMKgwqDCoMKg wqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgKyBzaXplb2Yo c3RydWN0IHVkcGhkcik7Cj4gK8KgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKg wqDCoMKgwqBicmVhazsKPiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgZGVmYXVsdDoK PiArwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoGJyZWFrOwo+ ICvCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqDCoMKgwqB9CgpXaHkgYWxsIHRoZXNlIGNhbGN1bGF0 aW9ucyBpbnN0ZWFkIG9mIHNrYl90cmFuc3BvcnRfb2Zmc2V0KHNrYikgYW5kIApza2ItPmNzdW1f b2Zmc2V0IHVzYWdlPwoK
Patch looks good -- ACK -- but I cannot apply since I do not have include/linux/xilinx_devices.h