* Re: [PATCH] virtio: use __GFP_NOWARN for try_fill_recv in virtnet_poll
From: Rusty Russell @ 2011-02-15 10:11 UTC (permalink / raw)
To: Michal Hocko; +Cc: Michael S. Tsirkin, virtualization, netdev, linux-kernel
In-Reply-To: <20110215093527.GB8341@tiehlicka.suse.cz>
On Tue, 15 Feb 2011 08:05:27 pm Michal Hocko wrote:
> Hi,
> we have started seeing a lot of allocator messages complaining about
> failed allocations from virtnet_poll in soft IRQ. Could you consider the
> following patch, please?
Do we really want to silence this? Isn't warning about it kind of the
point? Your network is probably sucking if this happens...
Cheers,
Rusty.
^ permalink raw reply
* Re: Process for subsystem maintainers to get Hyper-V code out of staging.
From: Christoph Hellwig @ 2011-02-15 10:21 UTC (permalink / raw)
To: Hank Janssen
Cc: shemminger@linux-foundation.org, netdev@vger.kernel.org,
davem@davemloft.net, linux-ide@vger.kernel.org,
Jame.Bottomley@HansenPartnership.com, linux-scsi@vger.kernel.org,
KY Srinivasan, Hashir Abdi, Mike Sterling, Haiyang Zhang,
gregkh@suse.de
In-Reply-To: <8AFC7968D54FB448A30D8F38F259C56233F95737@TK5EX14MBXC114.redmond.corp.microsoft.com>
Please give all the driver a unique prefix, hv_ is a bit to generic.
mshv might be better.
What's the point of the blksvc driver? It is implemented as a block
driver, steals the major number of the IDE driver, which is a big no-no
and speaks a SCSI-like protocol to the host. In what way does this
protocol differ from the full SCSI protocol in the storvsc driver?
As far as the storsvc driver is converned: please merge the storvsc.c
and storvsc_drv.c, as they are only used together. Also please try to
clean up the way you use function pointers. E.g. the
OnDeviceAdd/OnDeviceRemove/OnCleanup methods should be part of a
mshv_driver structure, and not store into individual objects.
Please get rid of the *_context structure that only have a single
intance anyway. In generaly a Linux driver should not have any global
state except for maybe module paramters or a list of devices in cases
where the device model can't handle that.
Please clean up the calling convention for the init code, there is
absolutely no reason to pass stor_vsc_initialize as a function pointer
to storvsc_drv_init instead of calling it directly, and in fact there
is no reason to not just inline both of those into storvsc_init. One
all the function pointers are moved into a driver struct and the global
context is gone there will be almost no code left in there anyway.
Similarly the exit routine is implemented entirely wrong. The core
bus layer should iterate over all devices for the driver beeing
unregister and call back into the ->remove callback just for that
device. Try to follow common real hardware busses like pci, usb or for
a really simple one eisa in your design.
There is no reason to have a per-device slab cache, a global one is
enough. But for per-I/O allocations you'll need a mempool to make it
deadlock-free.
Do you really need scsi_scan_host for a virtualized scsi transport? Is
there no way for the host to tell you which LUNs actually are present?
Why do you bother to linearize S/G lists? If your host can't handle it
just tell the scsi layer that you have a sg_tablesize of 1, which means
you'll never get multiple S/G elements. (Not doing SG is really, really
sad for new virtual hardware btw, please take the crack away from the
person who designed it).
Also can you please avoid forward declaration of functions as much as
possible? They really make the code hard to read if used as much as in
these drivers.
That's it for the first round, I'm pretty sure there will be more
comments once the code is better structured and more readabke.
^ permalink raw reply
* Re: [PATCH] virtio: use __GFP_NOWARN for try_fill_recv in virtnet_poll
From: Michal Hocko @ 2011-02-15 10:25 UTC (permalink / raw)
To: Rusty Russell; +Cc: Michael S. Tsirkin, virtualization, netdev, linux-kernel
In-Reply-To: <201102152041.29179.rusty@rustcorp.com.au>
On Tue 15-02-11 20:41:29, Rusty Russell wrote:
> On Tue, 15 Feb 2011 08:05:27 pm Michal Hocko wrote:
> > Hi,
> > we have started seeing a lot of allocator messages complaining about
> > failed allocations from virtnet_poll in soft IRQ. Could you consider the
> > following patch, please?
>
> Do we really want to silence this? Isn't warning about it kind of the
> point? Your network is probably sucking if this happens...
What can user do about it? Is the low level memory allocator message
very much usefull for him? Maybe we can add a printk_once in the fail
path with some more useful and virtio specific message.
Thanks
--
Michal Hocko
SUSE Labs
SUSE LINUX s.r.o.
Lihovarska 1060/12
190 00 Praha 9
Czech Republic
^ permalink raw reply
* Re: Process for subsystem maintainers to get Hyper-V code out of staging.
From: Alan Cox @ 2011-02-15 10:33 UTC (permalink / raw)
To: Hank Janssen
Cc: shemminger@linux-foundation.org, netdev@vger.kernel.org,
davem@davemloft.net, linux-ide@vger.kernel.org,
Jame.Bottomley@HansenPartnership.com, linux-scsi@vger.kernel.org,
KY Srinivasan, Hashir Abdi, Mike Sterling, Haiyang Zhang,
gregkh@suse.de
In-Reply-To: <8AFC7968D54FB448A30D8F38F259C56233F95737@TK5EX14MBXC114.redmond.corp.microsoft.com>
> 1. Most important thing of course, did we contact the correct subsystem
> maintainers?
> i. IDE/Blkvsc David Miller
Libata - Jeff Garzik & linux-ide@vger.kernel.org
drivers/ide is obsolete and on its way out.
drivers/ata replaced it as the old code couldn't really cope with things
like SATA NCQ or hotplug. The new stuff can which is probably handy in a
hypervisor.
> ii. SCSI/Storvsc James Bottomley
Yes & linux-scsi@vger.kernel.org
> iii. Network/Netvsc Stephen Hemminger
> 2. What is the process to submit the code for review?
See: Documentation/SubmittingPatches in your kernel tree
That should answer the rest. If not then keep a tag on things that should
have been in there but weren't and that can also get updated.
^ permalink raw reply
* Re: [PATCH] virtio: use __GFP_NOWARN for try_fill_recv in virtnet_poll
From: Rusty Russell @ 2011-02-15 11:09 UTC (permalink / raw)
To: Michal Hocko; +Cc: Michael S. Tsirkin, virtualization, netdev, linux-kernel
In-Reply-To: <20110215102549.GD8341@tiehlicka.suse.cz>
On Tue, 15 Feb 2011 08:55:50 pm Michal Hocko wrote:
> On Tue 15-02-11 20:41:29, Rusty Russell wrote:
> > On Tue, 15 Feb 2011 08:05:27 pm Michal Hocko wrote:
> > > Hi,
> > > we have started seeing a lot of allocator messages complaining about
> > > failed allocations from virtnet_poll in soft IRQ. Could you consider the
> > > following patch, please?
> >
> > Do we really want to silence this? Isn't warning about it kind of the
> > point? Your network is probably sucking if this happens...
>
> What can user do about it? Is the low level memory allocator message
> very much usefull for him? Maybe we can add a printk_once in the fail
> path with some more useful and virtio specific message.
That's an argument against ever printing any message.
What we need to know is why does this happen with virtio_net and not other
cards? If it happens to them too, and they silently fall back, all good.
I want to make sure we're not papering over a real problem...
Thanks,
Rusty.
^ permalink raw reply
* [RFC, PATCH 1/4] net: sh_eth: modify the definitions of register
From: Yoshihiro Shimoda @ 2011-02-15 11:47 UTC (permalink / raw)
To: netdev; +Cc: SH-Linux
The previous code cannot handle the ETHER and GETHER both as same time
because the definitions of register was hardcoded.
Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
---
arch/sh/include/asm/sh_eth.h | 7 +
drivers/net/sh_eth.c | 322 +++++++++++-----------
drivers/net/sh_eth.h | 623 ++++++++++++++++++++++++------------------
3 files changed, 537 insertions(+), 415 deletions(-)
diff --git a/arch/sh/include/asm/sh_eth.h b/arch/sh/include/asm/sh_eth.h
index f739061..44d64c0 100644
--- a/arch/sh/include/asm/sh_eth.h
+++ b/arch/sh/include/asm/sh_eth.h
@@ -2,10 +2,17 @@
#define __ASM_SH_ETH_H__
enum {EDMAC_LITTLE_ENDIAN, EDMAC_BIG_ENDIAN};
+enum {
+ SH_ETH_REG_DEFAULT = 0,
+ SH_ETH_REG_GIGABIT,
+ SH_ETH_REG_FAST_SH4,
+ SH_ETH_REG_FAST_SH3_SH2
+};
struct sh_eth_plat_data {
int phy;
int edmac_endian;
+ int register_type;
unsigned char mac_addr[6];
unsigned no_ether_link:1;
diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c
index 819c175..3b6d545 100644
--- a/drivers/net/sh_eth.c
+++ b/drivers/net/sh_eth.c
@@ -42,25 +42,23 @@
static void sh_eth_set_duplex(struct net_device *ndev)
{
struct sh_eth_private *mdp = netdev_priv(ndev);
- u32 ioaddr = ndev->base_addr;
if (mdp->duplex) /* Full */
- writel(readl(ioaddr + ECMR) | ECMR_DM, ioaddr + ECMR);
+ sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | ECMR_DM, ECMR);
else /* Half */
- writel(readl(ioaddr + ECMR) & ~ECMR_DM, ioaddr + ECMR);
+ sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~ECMR_DM, ECMR);
}
static void sh_eth_set_rate(struct net_device *ndev)
{
struct sh_eth_private *mdp = netdev_priv(ndev);
- u32 ioaddr = ndev->base_addr;
switch (mdp->speed) {
case 10: /* 10BASE */
- writel(readl(ioaddr + ECMR) & ~ECMR_RTM, ioaddr + ECMR);
+ sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~ECMR_RTM, ECMR);
break;
case 100:/* 100BASE */
- writel(readl(ioaddr + ECMR) | ECMR_RTM, ioaddr + ECMR);
+ sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | ECMR_RTM, ECMR);
break;
default:
break;
@@ -93,25 +91,23 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
static void sh_eth_set_duplex(struct net_device *ndev)
{
struct sh_eth_private *mdp = netdev_priv(ndev);
- u32 ioaddr = ndev->base_addr;
if (mdp->duplex) /* Full */
- writel(readl(ioaddr + ECMR) | ECMR_DM, ioaddr + ECMR);
+ sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | ECMR_DM, ECMR);
else /* Half */
- writel(readl(ioaddr + ECMR) & ~ECMR_DM, ioaddr + ECMR);
+ sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~ECMR_DM, ECMR);
}
static void sh_eth_set_rate(struct net_device *ndev)
{
struct sh_eth_private *mdp = netdev_priv(ndev);
- u32 ioaddr = ndev->base_addr;
switch (mdp->speed) {
case 10: /* 10BASE */
- writel(0, ioaddr + RTRATE);
+ sh_eth_write(ndev, 0, RTRATE);
break;
case 100:/* 100BASE */
- writel(1, ioaddr + RTRATE);
+ sh_eth_write(ndev, 1, RTRATE);
break;
default:
break;
@@ -149,13 +145,12 @@ static void sh_eth_chip_reset(struct net_device *ndev)
static void sh_eth_reset(struct net_device *ndev)
{
- u32 ioaddr = ndev->base_addr;
int cnt = 100;
- writel(EDSR_ENALL, ioaddr + EDSR);
- writel(readl(ioaddr + EDMR) | EDMR_SRST, ioaddr + EDMR);
+ sh_eth_write(ndev, EDSR_ENALL, EDSR);
+ sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST, EDMR);
while (cnt > 0) {
- if (!(readl(ioaddr + EDMR) & 0x3))
+ if (!(sh_eth_read(ndev, EDMR) & 0x3))
break;
mdelay(1);
cnt--;
@@ -164,41 +159,39 @@ static void sh_eth_reset(struct net_device *ndev)
printk(KERN_ERR "Device reset fail\n");
/* Table Init */
- writel(0x0, ioaddr + TDLAR);
- writel(0x0, ioaddr + TDFAR);
- writel(0x0, ioaddr + TDFXR);
- writel(0x0, ioaddr + TDFFR);
- writel(0x0, ioaddr + RDLAR);
- writel(0x0, ioaddr + RDFAR);
- writel(0x0, ioaddr + RDFXR);
- writel(0x0, ioaddr + RDFFR);
+ sh_eth_write(ndev, 0x0, TDLAR);
+ sh_eth_write(ndev, 0x0, TDFAR);
+ sh_eth_write(ndev, 0x0, TDFXR);
+ sh_eth_write(ndev, 0x0, TDFFR);
+ sh_eth_write(ndev, 0x0, RDLAR);
+ sh_eth_write(ndev, 0x0, RDFAR);
+ sh_eth_write(ndev, 0x0, RDFXR);
+ sh_eth_write(ndev, 0x0, RDFFR);
}
static void sh_eth_set_duplex(struct net_device *ndev)
{
struct sh_eth_private *mdp = netdev_priv(ndev);
- u32 ioaddr = ndev->base_addr;
if (mdp->duplex) /* Full */
- writel(readl(ioaddr + ECMR) | ECMR_DM, ioaddr + ECMR);
+ sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | ECMR_DM, ECMR);
else /* Half */
- writel(readl(ioaddr + ECMR) & ~ECMR_DM, ioaddr + ECMR);
+ sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~ECMR_DM, ECMR);
}
static void sh_eth_set_rate(struct net_device *ndev)
{
struct sh_eth_private *mdp = netdev_priv(ndev);
- u32 ioaddr = ndev->base_addr;
switch (mdp->speed) {
case 10: /* 10BASE */
- writel(GECMR_10, ioaddr + GECMR);
+ sh_eth_write(ndev, GECMR_10, GECMR);
break;
case 100:/* 100BASE */
- writel(GECMR_100, ioaddr + GECMR);
+ sh_eth_write(ndev, GECMR_100, GECMR);
break;
case 1000: /* 1000BASE */
- writel(GECMR_1000, ioaddr + GECMR);
+ sh_eth_write(ndev, GECMR_1000, GECMR);
break;
default:
break;
@@ -281,11 +274,9 @@ static void sh_eth_set_default_cpu_data(struct sh_eth_cpu_data *cd)
/* Chip Reset */
static void sh_eth_reset(struct net_device *ndev)
{
- u32 ioaddr = ndev->base_addr;
-
- writel(readl(ioaddr + EDMR) | EDMR_SRST, ioaddr + EDMR);
+ sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST, EDMR);
mdelay(3);
- writel(readl(ioaddr + EDMR) & ~EDMR_SRST, ioaddr + EDMR);
+ sh_eth_write(ndev, sh_eth_read(ndev, EDMR) & ~EDMR_SRST, EDMR);
}
#endif
@@ -334,13 +325,11 @@ static inline __u32 edmac_to_cpu(struct sh_eth_private *mdp, u32 x)
*/
static void update_mac_address(struct net_device *ndev)
{
- u32 ioaddr = ndev->base_addr;
-
- writel((ndev->dev_addr[0] << 24) | (ndev->dev_addr[1] << 16) |
- (ndev->dev_addr[2] << 8) | (ndev->dev_addr[3]),
- ioaddr + MAHR);
- writel((ndev->dev_addr[4] << 8) | (ndev->dev_addr[5]),
- ioaddr + MALR);
+ sh_eth_write(ndev,
+ (ndev->dev_addr[0] << 24) | (ndev->dev_addr[1] << 16) |
+ (ndev->dev_addr[2] << 8) | (ndev->dev_addr[3]), MAHR);
+ sh_eth_write(ndev,
+ (ndev->dev_addr[4] << 8) | (ndev->dev_addr[5]), MALR);
}
/*
@@ -353,17 +342,15 @@ static void update_mac_address(struct net_device *ndev)
*/
static void read_mac_address(struct net_device *ndev, unsigned char *mac)
{
- u32 ioaddr = ndev->base_addr;
-
if (mac[0] || mac[1] || mac[2] || mac[3] || mac[4] || mac[5]) {
memcpy(ndev->dev_addr, mac, 6);
} else {
- ndev->dev_addr[0] = (readl(ioaddr + MAHR) >> 24);
- ndev->dev_addr[1] = (readl(ioaddr + MAHR) >> 16) & 0xFF;
- ndev->dev_addr[2] = (readl(ioaddr + MAHR) >> 8) & 0xFF;
- ndev->dev_addr[3] = (readl(ioaddr + MAHR) & 0xFF);
- ndev->dev_addr[4] = (readl(ioaddr + MALR) >> 8) & 0xFF;
- ndev->dev_addr[5] = (readl(ioaddr + MALR) & 0xFF);
+ ndev->dev_addr[0] = (sh_eth_read(ndev, MAHR) >> 24);
+ ndev->dev_addr[1] = (sh_eth_read(ndev, MAHR) >> 16) & 0xFF;
+ ndev->dev_addr[2] = (sh_eth_read(ndev, MAHR) >> 8) & 0xFF;
+ ndev->dev_addr[3] = (sh_eth_read(ndev, MAHR) & 0xFF);
+ ndev->dev_addr[4] = (sh_eth_read(ndev, MALR) >> 8) & 0xFF;
+ ndev->dev_addr[5] = (sh_eth_read(ndev, MALR) & 0xFF);
}
}
@@ -470,7 +457,6 @@ static void sh_eth_ring_free(struct net_device *ndev)
/* format skb and descriptor buffer */
static void sh_eth_ring_format(struct net_device *ndev)
{
- u32 ioaddr = ndev->base_addr;
struct sh_eth_private *mdp = netdev_priv(ndev);
int i;
struct sk_buff *skb;
@@ -506,9 +492,9 @@ static void sh_eth_ring_format(struct net_device *ndev)
rxdesc->buffer_length = ALIGN(mdp->rx_buf_sz, 16);
/* Rx descriptor address set */
if (i == 0) {
- writel(mdp->rx_desc_dma, ioaddr + RDLAR);
+ sh_eth_write(ndev, mdp->rx_desc_dma, RDLAR);
#if defined(CONFIG_CPU_SUBTYPE_SH7763)
- writel(mdp->rx_desc_dma, ioaddr + RDFAR);
+ sh_eth_write(ndev, mdp->rx_desc_dma, RDFAR);
#endif
}
}
@@ -528,9 +514,9 @@ static void sh_eth_ring_format(struct net_device *ndev)
txdesc->buffer_length = 0;
if (i == 0) {
/* Tx descriptor address set */
- writel(mdp->tx_desc_dma, ioaddr + TDLAR);
+ sh_eth_write(ndev, mdp->tx_desc_dma, TDLAR);
#if defined(CONFIG_CPU_SUBTYPE_SH7763)
- writel(mdp->tx_desc_dma, ioaddr + TDFAR);
+ sh_eth_write(ndev, mdp->tx_desc_dma, TDFAR);
#endif
}
}
@@ -613,7 +599,6 @@ static int sh_eth_dev_init(struct net_device *ndev)
{
int ret = 0;
struct sh_eth_private *mdp = netdev_priv(ndev);
- u32 ioaddr = ndev->base_addr;
u_int32_t rx_int_var, tx_int_var;
u32 val;
@@ -623,71 +608,71 @@ static int sh_eth_dev_init(struct net_device *ndev)
/* Descriptor format */
sh_eth_ring_format(ndev);
if (mdp->cd->rpadir)
- writel(mdp->cd->rpadir_value, ioaddr + RPADIR);
+ sh_eth_write(ndev, mdp->cd->rpadir_value, RPADIR);
/* all sh_eth int mask */
- writel(0, ioaddr + EESIPR);
+ sh_eth_write(ndev, 0, EESIPR);
#if defined(__LITTLE_ENDIAN__)
if (mdp->cd->hw_swap)
- writel(EDMR_EL, ioaddr + EDMR);
+ sh_eth_write(ndev, EDMR_EL, EDMR);
else
#endif
- writel(0, ioaddr + EDMR);
+ sh_eth_write(ndev, 0, EDMR);
/* FIFO size set */
- writel(mdp->cd->fdr_value, ioaddr + FDR);
- writel(0, ioaddr + TFTR);
+ sh_eth_write(ndev, mdp->cd->fdr_value, FDR);
+ sh_eth_write(ndev, 0, TFTR);
/* Frame recv control */
- writel(mdp->cd->rmcr_value, ioaddr + RMCR);
+ sh_eth_write(ndev, mdp->cd->rmcr_value, RMCR);
rx_int_var = mdp->rx_int_var = DESC_I_RINT8 | DESC_I_RINT5;
tx_int_var = mdp->tx_int_var = DESC_I_TINT2;
- writel(rx_int_var | tx_int_var, ioaddr + TRSCER);
+ sh_eth_write(ndev, rx_int_var | tx_int_var, TRSCER);
if (mdp->cd->bculr)
- writel(0x800, ioaddr + BCULR); /* Burst sycle set */
+ sh_eth_write(ndev, 0x800, BCULR); /* Burst sycle set */
- writel(mdp->cd->fcftr_value, ioaddr + FCFTR);
+ sh_eth_write(ndev, mdp->cd->fcftr_value, FCFTR);
if (!mdp->cd->no_trimd)
- writel(0, ioaddr + TRIMD);
+ sh_eth_write(ndev, 0, TRIMD);
/* Recv frame limit set register */
- writel(RFLR_VALUE, ioaddr + RFLR);
+ sh_eth_write(ndev, RFLR_VALUE, RFLR);
- writel(readl(ioaddr + EESR), ioaddr + EESR);
- writel(mdp->cd->eesipr_value, ioaddr + EESIPR);
+ sh_eth_write(ndev, sh_eth_read(ndev, EESR), EESR);
+ sh_eth_write(ndev, mdp->cd->eesipr_value, EESIPR);
/* PAUSE Prohibition */
- val = (readl(ioaddr + ECMR) & ECMR_DM) |
+ val = (sh_eth_read(ndev, ECMR) & ECMR_DM) |
ECMR_ZPF | (mdp->duplex ? ECMR_DM : 0) | ECMR_TE | ECMR_RE;
- writel(val, ioaddr + ECMR);
+ sh_eth_write(ndev, val, ECMR);
if (mdp->cd->set_rate)
mdp->cd->set_rate(ndev);
/* E-MAC Status Register clear */
- writel(mdp->cd->ecsr_value, ioaddr + ECSR);
+ sh_eth_write(ndev, mdp->cd->ecsr_value, ECSR);
/* E-MAC Interrupt Enable register */
- writel(mdp->cd->ecsipr_value, ioaddr + ECSIPR);
+ sh_eth_write(ndev, mdp->cd->ecsipr_value, ECSIPR);
/* Set MAC address */
update_mac_address(ndev);
/* mask reset */
if (mdp->cd->apr)
- writel(APR_AP, ioaddr + APR);
+ sh_eth_write(ndev, APR_AP, APR);
if (mdp->cd->mpr)
- writel(MPR_MP, ioaddr + MPR);
+ sh_eth_write(ndev, MPR_MP, MPR);
if (mdp->cd->tpauser)
- writel(TPAUSER_UNLIMITED, ioaddr + TPAUSER);
+ sh_eth_write(ndev, TPAUSER_UNLIMITED, TPAUSER);
/* Setting the Rx mode will start the Rx process. */
- writel(EDRRR_R, ioaddr + EDRRR);
+ sh_eth_write(ndev, EDRRR_R, EDRRR);
netif_start_queue(ndev);
@@ -811,8 +796,8 @@ static int sh_eth_rx(struct net_device *ndev)
/* Restart Rx engine if stopped. */
/* If we don't need to check status, don't. -KDU */
- if (!(readl(ndev->base_addr + EDRRR) & EDRRR_R))
- writel(EDRRR_R, ndev->base_addr + EDRRR);
+ if (!(sh_eth_read(ndev, EDRRR) & EDRRR_R))
+ sh_eth_write(ndev, EDRRR_R, EDRRR);
return 0;
}
@@ -821,14 +806,13 @@ static int sh_eth_rx(struct net_device *ndev)
static void sh_eth_error(struct net_device *ndev, int intr_status)
{
struct sh_eth_private *mdp = netdev_priv(ndev);
- u32 ioaddr = ndev->base_addr;
u32 felic_stat;
u32 link_stat;
u32 mask;
if (intr_status & EESR_ECI) {
- felic_stat = readl(ioaddr + ECSR);
- writel(felic_stat, ioaddr + ECSR); /* clear int */
+ felic_stat = sh_eth_read(ndev, ECSR);
+ sh_eth_write(ndev, felic_stat, ECSR); /* clear int */
if (felic_stat & ECSR_ICD)
mdp->stats.tx_carrier_errors++;
if (felic_stat & ECSR_LCHNG) {
@@ -839,26 +823,26 @@ static void sh_eth_error(struct net_device *ndev, int intr_status)
else
link_stat = PHY_ST_LINK;
} else {
- link_stat = (readl(ioaddr + PSR));
+ link_stat = (sh_eth_read(ndev, PSR));
if (mdp->ether_link_active_low)
link_stat = ~link_stat;
}
if (!(link_stat & PHY_ST_LINK)) {
/* Link Down : disable tx and rx */
- writel(readl(ioaddr + ECMR) &
- ~(ECMR_RE | ECMR_TE), ioaddr + ECMR);
+ sh_eth_write(ndev, sh_eth_read(ndev, ECMR) &
+ ~(ECMR_RE | ECMR_TE), ECMR);
} else {
/* Link Up */
- writel(readl(ioaddr + EESIPR) &
- ~DMAC_M_ECI, ioaddr + EESIPR);
+ sh_eth_write(ndev, sh_eth_read(ndev, EESIPR) &
+ ~DMAC_M_ECI, EESIPR);
/*clear int */
- writel(readl(ioaddr + ECSR),
- ioaddr + ECSR);
- writel(readl(ioaddr + EESIPR) |
- DMAC_M_ECI, ioaddr + EESIPR);
+ sh_eth_write(ndev, sh_eth_read(ndev, ECSR),
+ ECSR);
+ sh_eth_write(ndev, sh_eth_read(ndev, EESIPR) |
+ DMAC_M_ECI, EESIPR);
/* enable tx and rx */
- writel(readl(ioaddr + ECMR) |
- (ECMR_RE | ECMR_TE), ioaddr + ECMR);
+ sh_eth_write(ndev, sh_eth_read(ndev, ECMR) |
+ (ECMR_RE | ECMR_TE), ECMR);
}
}
}
@@ -888,8 +872,8 @@ static void sh_eth_error(struct net_device *ndev, int intr_status)
/* Receive Descriptor Empty int */
mdp->stats.rx_over_errors++;
- if (readl(ioaddr + EDRRR) ^ EDRRR_R)
- writel(EDRRR_R, ioaddr + EDRRR);
+ if (sh_eth_read(ndev, EDRRR) ^ EDRRR_R)
+ sh_eth_write(ndev, EDRRR_R, EDRRR);
dev_err(&ndev->dev, "Receive Descriptor Empty\n");
}
if (intr_status & EESR_RFE) {
@@ -903,7 +887,7 @@ static void sh_eth_error(struct net_device *ndev, int intr_status)
mask &= ~EESR_ADE;
if (intr_status & mask) {
/* Tx error */
- u32 edtrr = readl(ndev->base_addr + EDTRR);
+ u32 edtrr = sh_eth_read(ndev, EDTRR);
/* dmesg */
dev_err(&ndev->dev, "TX error. status=%8.8x cur_tx=%8.8x ",
intr_status, mdp->cur_tx);
@@ -915,7 +899,7 @@ static void sh_eth_error(struct net_device *ndev, int intr_status)
/* SH7712 BUG */
if (edtrr ^ EDTRR_TRNS) {
/* tx dma start */
- writel(EDTRR_TRNS, ndev->base_addr + EDTRR);
+ sh_eth_write(ndev, EDTRR_TRNS, EDTRR);
}
/* wakeup */
netif_wake_queue(ndev);
@@ -928,18 +912,17 @@ static irqreturn_t sh_eth_interrupt(int irq, void *netdev)
struct sh_eth_private *mdp = netdev_priv(ndev);
struct sh_eth_cpu_data *cd = mdp->cd;
irqreturn_t ret = IRQ_NONE;
- u32 ioaddr, intr_status = 0;
+ u32 intr_status = 0;
- ioaddr = ndev->base_addr;
spin_lock(&mdp->lock);
/* Get interrpt stat */
- intr_status = readl(ioaddr + EESR);
+ intr_status = sh_eth_read(ndev, EESR);
/* Clear interrupt */
if (intr_status & (EESR_FRC | EESR_RMAF | EESR_RRF |
EESR_RTLF | EESR_RTSF | EESR_PRE | EESR_CERF |
cd->tx_check | cd->eesr_err_check)) {
- writel(intr_status, ioaddr + EESR);
+ sh_eth_write(ndev, intr_status, EESR);
ret = IRQ_HANDLED;
} else
goto other_irq;
@@ -982,7 +965,6 @@ static void sh_eth_adjust_link(struct net_device *ndev)
{
struct sh_eth_private *mdp = netdev_priv(ndev);
struct phy_device *phydev = mdp->phydev;
- u32 ioaddr = ndev->base_addr;
int new_state = 0;
if (phydev->link != PHY_DOWN) {
@@ -1000,8 +982,8 @@ static void sh_eth_adjust_link(struct net_device *ndev)
mdp->cd->set_rate(ndev);
}
if (mdp->link == PHY_DOWN) {
- writel((readl(ioaddr + ECMR) & ~ECMR_TXF)
- | ECMR_DM, ioaddr + ECMR);
+ sh_eth_write(ndev, (sh_eth_read(ndev, ECMR) & ~ECMR_TXF)
+ | ECMR_DM, ECMR);
new_state = 1;
mdp->link = phydev->link;
}
@@ -1117,7 +1099,6 @@ out_free_irq:
static void sh_eth_tx_timeout(struct net_device *ndev)
{
struct sh_eth_private *mdp = netdev_priv(ndev);
- u32 ioaddr = ndev->base_addr;
struct sh_eth_rxdesc *rxdesc;
int i;
@@ -1125,7 +1106,7 @@ static void sh_eth_tx_timeout(struct net_device *ndev)
/* worning message out. */
printk(KERN_WARNING "%s: transmit timed out, status %8.8x,"
- " resetting...\n", ndev->name, (int)readl(ioaddr + EESR));
+ " resetting...\n", ndev->name, (int)sh_eth_read(ndev, EESR));
/* tx_errors count up */
mdp->stats.tx_errors++;
@@ -1196,8 +1177,8 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev)
mdp->cur_tx++;
- if (!(readl(ndev->base_addr + EDTRR) & EDTRR_TRNS))
- writel(EDTRR_TRNS, ndev->base_addr + EDTRR);
+ if (!(sh_eth_read(ndev, EDTRR) & EDTRR_TRNS))
+ sh_eth_write(ndev, EDTRR_TRNS, EDTRR);
return NETDEV_TX_OK;
}
@@ -1206,17 +1187,16 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev)
static int sh_eth_close(struct net_device *ndev)
{
struct sh_eth_private *mdp = netdev_priv(ndev);
- u32 ioaddr = ndev->base_addr;
int ringsize;
netif_stop_queue(ndev);
/* Disable interrupts by clearing the interrupt mask. */
- writel(0x0000, ioaddr + EESIPR);
+ sh_eth_write(ndev, 0x0000, EESIPR);
/* Stop the chip's Tx and Rx processes. */
- writel(0, ioaddr + EDTRR);
- writel(0, ioaddr + EDRRR);
+ sh_eth_write(ndev, 0, EDTRR);
+ sh_eth_write(ndev, 0, EDRRR);
/* PHY Disconnect */
if (mdp->phydev) {
@@ -1247,24 +1227,23 @@ static int sh_eth_close(struct net_device *ndev)
static struct net_device_stats *sh_eth_get_stats(struct net_device *ndev)
{
struct sh_eth_private *mdp = netdev_priv(ndev);
- u32 ioaddr = ndev->base_addr;
pm_runtime_get_sync(&mdp->pdev->dev);
- mdp->stats.tx_dropped += readl(ioaddr + TROCR);
- writel(0, ioaddr + TROCR); /* (write clear) */
- mdp->stats.collisions += readl(ioaddr + CDCR);
- writel(0, ioaddr + CDCR); /* (write clear) */
- mdp->stats.tx_carrier_errors += readl(ioaddr + LCCR);
- writel(0, ioaddr + LCCR); /* (write clear) */
+ mdp->stats.tx_dropped += sh_eth_read(ndev, TROCR);
+ sh_eth_write(ndev, 0, TROCR); /* (write clear) */
+ mdp->stats.collisions += sh_eth_read(ndev, CDCR);
+ sh_eth_write(ndev, 0, CDCR); /* (write clear) */
+ mdp->stats.tx_carrier_errors += sh_eth_read(ndev, LCCR);
+ sh_eth_write(ndev, 0, LCCR); /* (write clear) */
#if defined(CONFIG_CPU_SUBTYPE_SH7763)
- mdp->stats.tx_carrier_errors += readl(ioaddr + CERCR);/* CERCR */
- writel(0, ioaddr + CERCR); /* (write clear) */
- mdp->stats.tx_carrier_errors += readl(ioaddr + CEECR);/* CEECR */
- writel(0, ioaddr + CEECR); /* (write clear) */
+ mdp->stats.tx_carrier_errors += sh_eth_read(ndev, CERCR);/* CERCR */
+ sh_eth_write(ndev, 0, CERCR); /* (write clear) */
+ mdp->stats.tx_carrier_errors += sh_eth_read(ndev, CEECR);/* CEECR */
+ sh_eth_write(ndev, 0, CEECR); /* (write clear) */
#else
- mdp->stats.tx_carrier_errors += readl(ioaddr + CNDCR);
- writel(0, ioaddr + CNDCR); /* (write clear) */
+ mdp->stats.tx_carrier_errors += sh_eth_read(ndev, CNDCR);
+ sh_eth_write(ndev, 0, CNDCR); /* (write clear) */
#endif
pm_runtime_put_sync(&mdp->pdev->dev);
@@ -1291,46 +1270,44 @@ static int sh_eth_do_ioctl(struct net_device *ndev, struct ifreq *rq,
/* Multicast reception directions set */
static void sh_eth_set_multicast_list(struct net_device *ndev)
{
- u32 ioaddr = ndev->base_addr;
-
if (ndev->flags & IFF_PROMISC) {
/* Set promiscuous. */
- writel((readl(ioaddr + ECMR) & ~ECMR_MCT) | ECMR_PRM,
- ioaddr + ECMR);
+ sh_eth_write(ndev, (sh_eth_read(ndev, ECMR) & ~ECMR_MCT) |
+ ECMR_PRM, ECMR);
} else {
/* Normal, unicast/broadcast-only mode. */
- writel((readl(ioaddr + ECMR) & ~ECMR_PRM) | ECMR_MCT,
- ioaddr + ECMR);
+ sh_eth_write(ndev, (sh_eth_read(ndev, ECMR) & ~ECMR_PRM) |
+ ECMR_MCT, ECMR);
}
}
/* SuperH's TSU register init function */
-static void sh_eth_tsu_init(u32 ioaddr)
+static void sh_eth_tsu_init(struct sh_eth_private *mdp)
{
- writel(0, ioaddr + TSU_FWEN0); /* Disable forward(0->1) */
- writel(0, ioaddr + TSU_FWEN1); /* Disable forward(1->0) */
- writel(0, ioaddr + TSU_FCM); /* forward fifo 3k-3k */
- writel(0xc, ioaddr + TSU_BSYSL0);
- writel(0xc, ioaddr + TSU_BSYSL1);
- writel(0, ioaddr + TSU_PRISL0);
- writel(0, ioaddr + TSU_PRISL1);
- writel(0, ioaddr + TSU_FWSL0);
- writel(0, ioaddr + TSU_FWSL1);
- writel(TSU_FWSLC_POSTENU | TSU_FWSLC_POSTENL, ioaddr + TSU_FWSLC);
+ sh_eth_tsu_write(mdp, 0, TSU_FWEN0); /* Disable forward(0->1) */
+ sh_eth_tsu_write(mdp, 0, TSU_FWEN1); /* Disable forward(1->0) */
+ sh_eth_tsu_write(mdp, 0, TSU_FCM); /* forward fifo 3k-3k */
+ sh_eth_tsu_write(mdp, 0xc, TSU_BSYSL0);
+ sh_eth_tsu_write(mdp, 0xc, TSU_BSYSL1);
+ sh_eth_tsu_write(mdp, 0, TSU_PRISL0);
+ sh_eth_tsu_write(mdp, 0, TSU_PRISL1);
+ sh_eth_tsu_write(mdp, 0, TSU_FWSL0);
+ sh_eth_tsu_write(mdp, 0, TSU_FWSL1);
+ sh_eth_tsu_write(mdp, TSU_FWSLC_POSTENU | TSU_FWSLC_POSTENL, TSU_FWSLC);
#if defined(CONFIG_CPU_SUBTYPE_SH7763)
- writel(0, ioaddr + TSU_QTAG0); /* Disable QTAG(0->1) */
- writel(0, ioaddr + TSU_QTAG1); /* Disable QTAG(1->0) */
+ sh_eth_tsu_write(mdp, 0, TSU_QTAG0); /* Disable QTAG(0->1) */
+ sh_eth_tsu_write(mdp, 0, TSU_QTAG1); /* Disable QTAG(1->0) */
#else
- writel(0, ioaddr + TSU_QTAGM0); /* Disable QTAG(0->1) */
- writel(0, ioaddr + TSU_QTAGM1); /* Disable QTAG(1->0) */
+ sh_eth_tsu_write(mdp, 0, TSU_QTAGM0); /* Disable QTAG(0->1) */
+ sh_eth_tsu_write(mdp, 0, TSU_QTAGM1); /* Disable QTAG(1->0) */
#endif
- writel(0, ioaddr + TSU_FWSR); /* all interrupt status clear */
- writel(0, ioaddr + TSU_FWINMK); /* Disable all interrupt */
- writel(0, ioaddr + TSU_TEN); /* Disable all CAM entry */
- writel(0, ioaddr + TSU_POST1); /* Disable CAM entry [ 0- 7] */
- writel(0, ioaddr + TSU_POST2); /* Disable CAM entry [ 8-15] */
- writel(0, ioaddr + TSU_POST3); /* Disable CAM entry [16-23] */
- writel(0, ioaddr + TSU_POST4); /* Disable CAM entry [24-31] */
+ sh_eth_tsu_write(mdp, 0, TSU_FWSR); /* all interrupt status clear */
+ sh_eth_tsu_write(mdp, 0, TSU_FWINMK); /* Disable all interrupt */
+ sh_eth_tsu_write(mdp, 0, TSU_TEN); /* Disable all CAM entry */
+ sh_eth_tsu_write(mdp, 0, TSU_POST1); /* Disable CAM entry [ 0- 7] */
+ sh_eth_tsu_write(mdp, 0, TSU_POST2); /* Disable CAM entry [ 8-15] */
+ sh_eth_tsu_write(mdp, 0, TSU_POST3); /* Disable CAM entry [16-23] */
+ sh_eth_tsu_write(mdp, 0, TSU_POST4); /* Disable CAM entry [24-31] */
}
#endif /* SH_ETH_HAS_TSU */
@@ -1369,7 +1346,7 @@ static int sh_mdio_init(struct net_device *ndev, int id)
}
/* bitbang init */
- bitbang->addr = ndev->base_addr + PIR;
+ bitbang->addr = ndev->base_addr + mdp->reg_offset[PIR];
bitbang->mdi_msk = 0x08;
bitbang->mdo_msk = 0x04;
bitbang->mmd_msk = 0x02;/* MMD */
@@ -1420,6 +1397,37 @@ out:
return ret;
}
+static const u16 *sh_eth_get_register_offset(int register_type)
+{
+ const u16 *reg_offset = NULL;
+
+ switch (register_type) {
+ case SH_ETH_REG_GIGABIT:
+ reg_offset = sh_eth_offset_gigabit;
+ break;
+ case SH_ETH_REG_FAST_SH4:
+ reg_offset = sh_eth_offset_fast_sh4;
+ break;
+ case SH_ETH_REG_FAST_SH3_SH2:
+ reg_offset = sh_eth_offset_fast_sh3_sh2;
+ break;
+ case SH_ETH_REG_DEFAULT:
+#if defined(CONFIG_CPU_SUBTYPE_SH7763)
+ reg_offset = sh_eth_offset_gigabit;
+#elif defined(CONFIG_CPU_SH4)
+ reg_offset = sh_eth_offset_fast_sh4;
+#else
+ reg_offset = sh_eth_offset_fast_sh3_sh2;
+#endif
+ break;
+ default:
+ printk(KERN_ERR "Unknown register type (%d)\n", register_type);
+ break;
+ }
+
+ return reg_offset;
+}
+
static const struct net_device_ops sh_eth_netdev_ops = {
.ndo_open = sh_eth_open,
.ndo_stop = sh_eth_close,
@@ -1490,6 +1498,7 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
mdp->edmac_endian = pd->edmac_endian;
mdp->no_ether_link = pd->no_ether_link;
mdp->ether_link_active_low = pd->ether_link_active_low;
+ mdp->reg_offset = sh_eth_get_register_offset(pd->register_type);
/* set cpu data */
mdp->cd = &sh_eth_my_cpu_data;
@@ -1512,7 +1521,8 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
#if defined(SH_ETH_HAS_TSU)
/* TSU init (Init only)*/
- sh_eth_tsu_init(SH_TSU_ADDR);
+ mdp->tsu_addr = SH_TSU_ADDR;
+ sh_eth_tsu_init(mdp);
#endif
}
diff --git a/drivers/net/sh_eth.h b/drivers/net/sh_eth.h
index efa6422..1510a7c 100644
--- a/drivers/net/sh_eth.h
+++ b/drivers/net/sh_eth.h
@@ -2,7 +2,7 @@
* SuperH Ethernet device driver
*
* Copyright (C) 2006-2008 Nobuhiro Iwamatsu
- * Copyright (C) 2008-2009 Renesas Solutions Corp.
+ * Copyright (C) 2008-2011 Renesas Solutions Corp.
*
* This program is free software; you can redistribute it and/or modify it
* under the terms and conditions of the GNU General Public License,
@@ -38,162 +38,345 @@
#define ETHERSMALL 60
#define PKT_BUF_SZ 1538
+enum {
+ /* E-DMAC registers */
+ EDSR = 0,
+ EDMR,
+ EDTRR,
+ EDRRR,
+ EESR,
+ EESIPR,
+ TDLAR,
+ TDFAR,
+ TDFXR,
+ TDFFR,
+ RDLAR,
+ RDFAR,
+ RDFXR,
+ RDFFR,
+ TRSCER,
+ RMFCR,
+ TFTR,
+ FDR,
+ RMCR,
+ EDOCR,
+ TFUCR,
+ RFOCR,
+ FCFTR,
+ RPADIR,
+ TRIMD,
+ RBWAR,
+ TBRAR,
+
+ /* Ether registers */
+ ECMR,
+ ECSR,
+ ECSIPR,
+ PIR,
+ PSR,
+ RDMLR,
+ PIPR,
+ RFLR,
+ IPGR,
+ APR,
+ MPR,
+ PFTCR,
+ PFRCR,
+ RFCR,
+ RFCF,
+ TPAUSER,
+ TPAUSECR,
+ BCFR,
+ BCFRR,
+ GECMR,
+ BCULR,
+ MAHR,
+ MALR,
+ TROCR,
+ CDCR,
+ LCCR,
+ CNDCR,
+ CEFCR,
+ FRECR,
+ TSFRCR,
+ TLFRCR,
+ CERCR,
+ CEECR,
+ MAFCR,
+ RTRATE,
+
+ /* TSU Absolute address */
+ ARSTR,
+ TSU_CTRST,
+ TSU_FWEN0,
+ TSU_FWEN1,
+ TSU_FCM,
+ TSU_BSYSL0,
+ TSU_BSYSL1,
+ TSU_PRISL0,
+ TSU_PRISL1,
+ TSU_FWSL0,
+ TSU_FWSL1,
+ TSU_FWSLC,
+ TSU_QTAG0,
+ TSU_QTAG1,
+ TSU_QTAGM0,
+ TSU_QTAGM1,
+ TSU_FWSR,
+ TSU_FWINMK,
+ TSU_ADQT0,
+ TSU_ADQT1,
+ TSU_VTAG0,
+ TSU_VTAG1,
+ TSU_ADSBSY,
+ TSU_TEN,
+ TSU_POST1,
+ TSU_POST2,
+ TSU_POST3,
+ TSU_POST4,
+ TSU_ADRH0,
+ TSU_ADRL0,
+ TSU_ADRH31,
+ TSU_ADRL31,
+
+ TXNLCR0,
+ TXALCR0,
+ RXNLCR0,
+ RXALCR0,
+ FWNLCR0,
+ FWALCR0,
+ TXNLCR1,
+ TXALCR1,
+ RXNLCR1,
+ RXALCR1,
+ FWNLCR1,
+ FWALCR1,
+
+ /* This value must be written at last. */
+ SH_ETH_MAX_REGISTER_OFFSET,
+};
+
+static const u16 sh_eth_offset_gigabit[SH_ETH_MAX_REGISTER_OFFSET] = {
+ [EDSR] = 0x0000,
+ [EDMR] = 0x0400,
+ [EDTRR] = 0x0408,
+ [EDRRR] = 0x0410,
+ [EESR] = 0x0428,
+ [EESIPR] = 0x0430,
+ [TDLAR] = 0x0010,
+ [TDFAR] = 0x0014,
+ [TDFXR] = 0x0018,
+ [TDFFR] = 0x001c,
+ [RDLAR] = 0x0030,
+ [RDFAR] = 0x0034,
+ [RDFXR] = 0x0038,
+ [RDFFR] = 0x003c,
+ [TRSCER] = 0x0438,
+ [RMFCR] = 0x0440,
+ [TFTR] = 0x0448,
+ [FDR] = 0x0450,
+ [RMCR] = 0x0458,
+ [RPADIR] = 0x0460,
+ [FCFTR] = 0x0468,
+
+ [ECMR] = 0x0500,
+ [ECSR] = 0x0510,
+ [ECSIPR] = 0x0518,
+ [PIR] = 0x0520,
+ [PSR] = 0x0528,
+ [PIPR] = 0x052c,
+ [RFLR] = 0x0508,
+ [APR] = 0x0554,
+ [MPR] = 0x0558,
+ [PFTCR] = 0x055c,
+ [PFRCR] = 0x0560,
+ [TPAUSER] = 0x0564,
+ [GECMR] = 0x05b0,
+ [BCULR] = 0x05b4,
+ [MAHR] = 0x05c0,
+ [MALR] = 0x05c8,
+ [TROCR] = 0x0700,
+ [CDCR] = 0x0708,
+ [LCCR] = 0x0710,
+ [CEFCR] = 0x0740,
+ [FRECR] = 0x0748,
+ [TSFRCR] = 0x0750,
+ [TLFRCR] = 0x0758,
+ [RFCR] = 0x0760,
+ [CERCR] = 0x0768,
+ [CEECR] = 0x0770,
+ [MAFCR] = 0x0778,
+
+ [TSU_CTRST] = 0x0004,
+ [TSU_FWEN0] = 0x0010,
+ [TSU_FWEN1] = 0x0014,
+ [TSU_FCM] = 0x0018,
+ [TSU_BSYSL0] = 0x0020,
+ [TSU_BSYSL1] = 0x0024,
+ [TSU_PRISL0] = 0x0028,
+ [TSU_PRISL1] = 0x002c,
+ [TSU_FWSL0] = 0x0030,
+ [TSU_FWSL1] = 0x0034,
+ [TSU_FWSLC] = 0x0038,
+ [TSU_QTAG0] = 0x0040,
+ [TSU_QTAG1] = 0x0044,
+ [TSU_FWSR] = 0x0050,
+ [TSU_FWINMK] = 0x0054,
+ [TSU_ADQT0] = 0x0048,
+ [TSU_ADQT1] = 0x004c,
+ [TSU_VTAG0] = 0x0058,
+ [TSU_VTAG1] = 0x005c,
+ [TSU_ADSBSY] = 0x0060,
+ [TSU_TEN] = 0x0064,
+ [TSU_POST1] = 0x0070,
+ [TSU_POST2] = 0x0074,
+ [TSU_POST3] = 0x0078,
+ [TSU_POST4] = 0x007c,
+ [TSU_ADRH0] = 0x0100,
+ [TSU_ADRL0] = 0x0104,
+ [TSU_ADRH31] = 0x01f8,
+ [TSU_ADRL31] = 0x01fc,
+
+ [TXNLCR0] = 0x0080,
+ [TXALCR0] = 0x0084,
+ [RXNLCR0] = 0x0088,
+ [RXALCR0] = 0x008c,
+ [FWNLCR0] = 0x0090,
+ [FWALCR0] = 0x0094,
+ [TXNLCR1] = 0x00a0,
+ [TXALCR1] = 0x00a0,
+ [RXNLCR1] = 0x00a8,
+ [RXALCR1] = 0x00ac,
+ [FWNLCR1] = 0x00b0,
+ [FWALCR1] = 0x00b4,
+};
+
+static const u16 sh_eth_offset_fast_sh4[SH_ETH_MAX_REGISTER_OFFSET] = {
+ [ECMR] = 0x0100,
+ [RFLR] = 0x0108,
+ [ECSR] = 0x0110,
+ [ECSIPR] = 0x0118,
+ [PIR] = 0x0120,
+ [PSR] = 0x0128,
+ [RDMLR] = 0x0140,
+ [IPGR] = 0x0150,
+ [APR] = 0x0154,
+ [MPR] = 0x0158,
+ [TPAUSER] = 0x0164,
+ [RFCF] = 0x0160,
+ [TPAUSECR] = 0x0168,
+ [BCFRR] = 0x016c,
+ [MAHR] = 0x01c0,
+ [MALR] = 0x01c8,
+ [TROCR] = 0x01d0,
+ [CDCR] = 0x01d4,
+ [LCCR] = 0x01d8,
+ [CNDCR] = 0x01dc,
+ [CEFCR] = 0x01e4,
+ [FRECR] = 0x01e8,
+ [TSFRCR] = 0x01ec,
+ [TLFRCR] = 0x01f0,
+ [RFCR] = 0x01f4,
+ [MAFCR] = 0x01f8,
+ [RTRATE] = 0x01fc,
+
+ [EDMR] = 0x0000,
+ [EDTRR] = 0x0008,
+ [EDRRR] = 0x0010,
+ [TDLAR] = 0x0018,
+ [RDLAR] = 0x0020,
+ [EESR] = 0x0028,
+ [EESIPR] = 0x0030,
+ [TRSCER] = 0x0038,
+ [RMFCR] = 0x0040,
+ [TFTR] = 0x0048,
+ [FDR] = 0x0050,
+ [RMCR] = 0x0058,
+ [TFUCR] = 0x0064,
+ [RFOCR] = 0x0068,
+ [FCFTR] = 0x0070,
+ [RPADIR] = 0x0078,
+ [TRIMD] = 0x007c,
+ [RBWAR] = 0x00c8,
+ [RDFAR] = 0x00cc,
+ [TBRAR] = 0x00d4,
+ [TDFAR] = 0x00d8,
+};
+
+static const u16 sh_eth_offset_fast_sh3_sh2[SH_ETH_MAX_REGISTER_OFFSET] = {
+ [ECMR] = 0x0160,
+ [ECSR] = 0x0164,
+ [ECSIPR] = 0x0168,
+ [PIR] = 0x016c,
+ [MAHR] = 0x0170,
+ [MALR] = 0x0174,
+ [RFLR] = 0x0178,
+ [PSR] = 0x017c,
+ [TROCR] = 0x0180,
+ [CDCR] = 0x0184,
+ [LCCR] = 0x0188,
+ [CNDCR] = 0x018c,
+ [CEFCR] = 0x0194,
+ [FRECR] = 0x0198,
+ [TSFRCR] = 0x019c,
+ [TLFRCR] = 0x01a0,
+ [RFCR] = 0x01a4,
+ [MAFCR] = 0x01a8,
+ [IPGR] = 0x01b4,
+ [APR] = 0x01b8,
+ [MPR] = 0x01bc,
+ [TPAUSER] = 0x01c4,
+ [BCFR] = 0x01cc,
+
+ [TSU_CTRST] = 0x0004,
+ [TSU_FWEN0] = 0x0010,
+ [TSU_FWEN1] = 0x0014,
+ [TSU_FCM] = 0x0018,
+ [TSU_BSYSL0] = 0x0020,
+ [TSU_BSYSL1] = 0x0024,
+ [TSU_PRISL0] = 0x0028,
+ [TSU_PRISL1] = 0x002c,
+ [TSU_FWSL0] = 0x0030,
+ [TSU_FWSL1] = 0x0034,
+ [TSU_FWSLC] = 0x0038,
+ [TSU_QTAGM0] = 0x0040,
+ [TSU_QTAGM1] = 0x0044,
+ [TSU_ADQT0] = 0x0048,
+ [TSU_ADQT1] = 0x004c,
+ [TSU_FWSR] = 0x0050,
+ [TSU_FWINMK] = 0x0054,
+ [TSU_ADSBSY] = 0x0060,
+ [TSU_TEN] = 0x0064,
+ [TSU_POST1] = 0x0070,
+ [TSU_POST2] = 0x0074,
+ [TSU_POST3] = 0x0078,
+ [TSU_POST4] = 0x007c,
+
+ [TXNLCR0] = 0x0080,
+ [TXALCR0] = 0x0084,
+ [RXNLCR0] = 0x0088,
+ [RXALCR0] = 0x008c,
+ [FWNLCR0] = 0x0090,
+ [FWALCR0] = 0x0094,
+ [TXNLCR1] = 0x00a0,
+ [TXALCR1] = 0x00a0,
+ [RXNLCR1] = 0x00a8,
+ [RXALCR1] = 0x00ac,
+ [FWNLCR1] = 0x00b0,
+ [FWALCR1] = 0x00b4,
+
+ [TSU_ADRH0] = 0x0100,
+ [TSU_ADRL0] = 0x0104,
+ [TSU_ADRL31] = 0x01fc,
+
+};
+
#if defined(CONFIG_CPU_SUBTYPE_SH7763)
/* This CPU register maps is very difference by other SH4 CPU */
-
/* Chip Base Address */
# define SH_TSU_ADDR 0xFEE01800
# define ARSTR SH_TSU_ADDR
-
-/* Chip Registers */
-/* E-DMAC */
-# define EDSR 0x000
-# define EDMR 0x400
-# define EDTRR 0x408
-# define EDRRR 0x410
-# define EESR 0x428
-# define EESIPR 0x430
-# define TDLAR 0x010
-# define TDFAR 0x014
-# define TDFXR 0x018
-# define TDFFR 0x01C
-# define RDLAR 0x030
-# define RDFAR 0x034
-# define RDFXR 0x038
-# define RDFFR 0x03C
-# define TRSCER 0x438
-# define RMFCR 0x440
-# define TFTR 0x448
-# define FDR 0x450
-# define RMCR 0x458
-# define RPADIR 0x460
-# define FCFTR 0x468
-
-/* Ether Register */
-# define ECMR 0x500
-# define ECSR 0x510
-# define ECSIPR 0x518
-# define PIR 0x520
-# define PSR 0x528
-# define PIPR 0x52C
-# define RFLR 0x508
-# define APR 0x554
-# define MPR 0x558
-# define PFTCR 0x55C
-# define PFRCR 0x560
-# define TPAUSER 0x564
-# define GECMR 0x5B0
-# define BCULR 0x5B4
-# define MAHR 0x5C0
-# define MALR 0x5C8
-# define TROCR 0x700
-# define CDCR 0x708
-# define LCCR 0x710
-# define CEFCR 0x740
-# define FRECR 0x748
-# define TSFRCR 0x750
-# define TLFRCR 0x758
-# define RFCR 0x760
-# define CERCR 0x768
-# define CEECR 0x770
-# define MAFCR 0x778
-
-/* TSU Absolute Address */
-# define TSU_CTRST 0x004
-# define TSU_FWEN0 0x010
-# define TSU_FWEN1 0x014
-# define TSU_FCM 0x18
-# define TSU_BSYSL0 0x20
-# define TSU_BSYSL1 0x24
-# define TSU_PRISL0 0x28
-# define TSU_PRISL1 0x2C
-# define TSU_FWSL0 0x30
-# define TSU_FWSL1 0x34
-# define TSU_FWSLC 0x38
-# define TSU_QTAG0 0x40
-# define TSU_QTAG1 0x44
-# define TSU_FWSR 0x50
-# define TSU_FWINMK 0x54
-# define TSU_ADQT0 0x48
-# define TSU_ADQT1 0x4C
-# define TSU_VTAG0 0x58
-# define TSU_VTAG1 0x5C
-# define TSU_ADSBSY 0x60
-# define TSU_TEN 0x64
-# define TSU_POST1 0x70
-# define TSU_POST2 0x74
-# define TSU_POST3 0x78
-# define TSU_POST4 0x7C
-# define TSU_ADRH0 0x100
-# define TSU_ADRL0 0x104
-# define TSU_ADRH31 0x1F8
-# define TSU_ADRL31 0x1FC
-
-# define TXNLCR0 0x80
-# define TXALCR0 0x84
-# define RXNLCR0 0x88
-# define RXALCR0 0x8C
-# define FWNLCR0 0x90
-# define FWALCR0 0x94
-# define TXNLCR1 0xA0
-# define TXALCR1 0xA4
-# define RXNLCR1 0xA8
-# define RXALCR1 0xAC
-# define FWNLCR1 0xB0
-# define FWALCR1 0x40
-
#elif defined(CONFIG_CPU_SH4) /* #if defined(CONFIG_CPU_SUBTYPE_SH7763) */
-/* EtherC */
-#define ECMR 0x100
-#define RFLR 0x108
-#define ECSR 0x110
-#define ECSIPR 0x118
-#define PIR 0x120
-#define PSR 0x128
-#define RDMLR 0x140
-#define IPGR 0x150
-#define APR 0x154
-#define MPR 0x158
-#define TPAUSER 0x164
-#define RFCF 0x160
-#define TPAUSECR 0x168
-#define BCFRR 0x16c
-#define MAHR 0x1c0
-#define MALR 0x1c8
-#define TROCR 0x1d0
-#define CDCR 0x1d4
-#define LCCR 0x1d8
-#define CNDCR 0x1dc
-#define CEFCR 0x1e4
-#define FRECR 0x1e8
-#define TSFRCR 0x1ec
-#define TLFRCR 0x1f0
-#define RFCR 0x1f4
-#define MAFCR 0x1f8
-#define RTRATE 0x1fc
-
-/* E-DMAC */
-#define EDMR 0x000
-#define EDTRR 0x008
-#define EDRRR 0x010
-#define TDLAR 0x018
-#define RDLAR 0x020
-#define EESR 0x028
-#define EESIPR 0x030
-#define TRSCER 0x038
-#define RMFCR 0x040
-#define TFTR 0x048
-#define FDR 0x050
-#define RMCR 0x058
-#define TFUCR 0x064
-#define RFOCR 0x068
-#define FCFTR 0x070
-#define RPADIR 0x078
-#define TRIMD 0x07c
-#define RBWAR 0x0c8
-#define RDFAR 0x0cc
-#define TBRAR 0x0d4
-#define TDFAR 0x0d8
#else /* #elif defined(CONFIG_CPU_SH4) */
/* This section is SH3 or SH2 */
#ifndef CONFIG_CPU_SUBTYPE_SH7619
@@ -201,116 +384,8 @@
# define SH_TSU_ADDR 0xA7000804
# define ARSTR 0xA7000800
#endif
-/* Chip Registers */
-/* E-DMAC */
-# define EDMR 0x0000
-# define EDTRR 0x0004
-# define EDRRR 0x0008
-# define TDLAR 0x000C
-# define RDLAR 0x0010
-# define EESR 0x0014
-# define EESIPR 0x0018
-# define TRSCER 0x001C
-# define RMFCR 0x0020
-# define TFTR 0x0024
-# define FDR 0x0028
-# define RMCR 0x002C
-# define EDOCR 0x0030
-# define FCFTR 0x0034
-# define RPADIR 0x0038
-# define TRIMD 0x003C
-# define RBWAR 0x0040
-# define RDFAR 0x0044
-# define TBRAR 0x004C
-# define TDFAR 0x0050
-
-/* Ether Register */
-# define ECMR 0x0160
-# define ECSR 0x0164
-# define ECSIPR 0x0168
-# define PIR 0x016C
-# define MAHR 0x0170
-# define MALR 0x0174
-# define RFLR 0x0178
-# define PSR 0x017C
-# define TROCR 0x0180
-# define CDCR 0x0184
-# define LCCR 0x0188
-# define CNDCR 0x018C
-# define CEFCR 0x0194
-# define FRECR 0x0198
-# define TSFRCR 0x019C
-# define TLFRCR 0x01A0
-# define RFCR 0x01A4
-# define MAFCR 0x01A8
-# define IPGR 0x01B4
-# if defined(CONFIG_CPU_SUBTYPE_SH7710)
-# define APR 0x01B8
-# define MPR 0x01BC
-# define TPAUSER 0x1C4
-# define BCFR 0x1CC
-# endif /* CONFIG_CPU_SH7710 */
-
-/* TSU */
-# define TSU_CTRST 0x004
-# define TSU_FWEN0 0x010
-# define TSU_FWEN1 0x014
-# define TSU_FCM 0x018
-# define TSU_BSYSL0 0x020
-# define TSU_BSYSL1 0x024
-# define TSU_PRISL0 0x028
-# define TSU_PRISL1 0x02C
-# define TSU_FWSL0 0x030
-# define TSU_FWSL1 0x034
-# define TSU_FWSLC 0x038
-# define TSU_QTAGM0 0x040
-# define TSU_QTAGM1 0x044
-# define TSU_ADQT0 0x048
-# define TSU_ADQT1 0x04C
-# define TSU_FWSR 0x050
-# define TSU_FWINMK 0x054
-# define TSU_ADSBSY 0x060
-# define TSU_TEN 0x064
-# define TSU_POST1 0x070
-# define TSU_POST2 0x074
-# define TSU_POST3 0x078
-# define TSU_POST4 0x07C
-# define TXNLCR0 0x080
-# define TXALCR0 0x084
-# define RXNLCR0 0x088
-# define RXALCR0 0x08C
-# define FWNLCR0 0x090
-# define FWALCR0 0x094
-# define TXNLCR1 0x0A0
-# define TXALCR1 0x0A4
-# define RXNLCR1 0x0A8
-# define RXALCR1 0x0AC
-# define FWNLCR1 0x0B0
-# define FWALCR1 0x0B4
-
-#define TSU_ADRH0 0x0100
-#define TSU_ADRL0 0x0104
-#define TSU_ADRL31 0x01FC
-
#endif /* CONFIG_CPU_SUBTYPE_SH7763 */
-/* There are avoid compile error... */
-#if !defined(BCULR)
-#define BCULR 0x0fc
-#endif
-#if !defined(TRIMD)
-#define TRIMD 0x0fc
-#endif
-#if !defined(APR)
-#define APR 0x0fc
-#endif
-#if !defined(MPR)
-#define MPR 0x0fc
-#endif
-#if !defined(TPAUSER)
-#define TPAUSER 0x0fc
-#endif
-
/* Driver's parameters */
#if defined(CONFIG_CPU_SH4)
#define SH4_SKB_RX_ALIGN 32
@@ -704,6 +779,8 @@ struct sh_eth_cpu_data {
struct sh_eth_private {
struct platform_device *pdev;
struct sh_eth_cpu_data *cd;
+ const u16 *reg_offset;
+ void __iomem *tsu_addr;
dma_addr_t rx_desc_dma;
dma_addr_t tx_desc_dma;
struct sh_eth_rxdesc *rx_ring;
@@ -746,4 +823,32 @@ static inline void sh_eth_soft_swap(char *src, int len)
#endif
}
+static inline void sh_eth_write(struct net_device *ndev, unsigned long data,
+ int enum_index)
+{
+ struct sh_eth_private *mdp = netdev_priv(ndev);
+
+ writel(data, ndev->base_addr + mdp->reg_offset[enum_index]);
+}
+
+static inline unsigned long sh_eth_read(struct net_device *ndev,
+ int enum_index)
+{
+ struct sh_eth_private *mdp = netdev_priv(ndev);
+
+ return readl(ndev->base_addr + mdp->reg_offset[enum_index]);
+}
+
+static inline void sh_eth_tsu_write(struct sh_eth_private *mdp,
+ unsigned long data, int enum_index)
+{
+ writel(data, mdp->tsu_addr + mdp->reg_offset[enum_index]);
+}
+
+static inline unsigned long sh_eth_tsu_read(struct sh_eth_private *mdp,
+ int enum_index)
+{
+ return readl(mdp->tsu_addr + mdp->reg_offset[enum_index]);
+}
+
#endif /* #ifndef __SH_ETH_H__ */
--
1.7.1
^ permalink raw reply related
* [RFC, PATCH 0/4] net: sh_eth: modify for both modules
From: Yoshihiro Shimoda @ 2011-02-15 11:47 UTC (permalink / raw)
To: netdev; +Cc: SH-Linux
This current driver supports ETHER and GETHER. But we cannot
use them at same time because the defination of registers is
hardcoded by #ifdef in sh_eth.h.
The patches modify the defination to arrays of const. Then
we can choose the array by platform_device's data.
The patches also modify for GETHER. The current driver used
the "#ifdef CONFIG_CPU_SUBTYPE_SH7763". The patches remove it
and check by other method for GETHER.
^ permalink raw reply
* [RFC, PATCH 2/4] net: sh_eth: remove the SH_TSU_ADDR
From: Yoshihiro Shimoda @ 2011-02-15 11:47 UTC (permalink / raw)
To: netdev; +Cc: SH-Linux
The defination is hardcoded in this driver for some CPUs. This patch
modifies to get resource of TSU address from platform_device.
Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
---
drivers/net/sh_eth.c | 16 ++++++++++++----
drivers/net/sh_eth.h | 15 ---------------
2 files changed, 12 insertions(+), 19 deletions(-)
diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c
index 3b6d545..0593f29 100644
--- a/drivers/net/sh_eth.c
+++ b/drivers/net/sh_eth.c
@@ -1446,7 +1446,7 @@ static const struct net_device_ops sh_eth_netdev_ops = {
static int sh_eth_drv_probe(struct platform_device *pdev)
{
int ret, devno = 0;
- struct resource *res;
+ struct resource *res, *res_tsu;
struct net_device *ndev = NULL;
struct sh_eth_private *mdp;
struct sh_eth_plat_data *pd;
@@ -1520,9 +1520,13 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
mdp->cd->chip_reset(ndev);
#if defined(SH_ETH_HAS_TSU)
- /* TSU init (Init only)*/
- mdp->tsu_addr = SH_TSU_ADDR;
- sh_eth_tsu_init(mdp);
+ res_tsu = platform_get_resource(pdev, IORESOURCE_MEM, 1);
+ if (res_tsu) {
+ mdp->tsu_addr = ioremap(res_tsu->start,
+ resource_size(res_tsu));
+ /* TSU init (Init only)*/
+ sh_eth_tsu_init(mdp);
+ }
#endif
}
@@ -1549,6 +1553,8 @@ out_unregister:
out_release:
/* net_dev free */
+ if (mdp->tsu_addr)
+ iounmap(mdp->tsu_addr);
if (ndev)
free_netdev(ndev);
@@ -1559,7 +1565,9 @@ out:
static int sh_eth_drv_remove(struct platform_device *pdev)
{
struct net_device *ndev = platform_get_drvdata(pdev);
+ struct sh_eth_private *mdp = netdev_priv(ndev);
+ iounmap(mdp->tsu_addr);
sh_mdio_release(ndev);
unregister_netdev(ndev);
pm_runtime_disable(&pdev->dev);
diff --git a/drivers/net/sh_eth.h b/drivers/net/sh_eth.h
index 1510a7c..1a32dc0 100644
--- a/drivers/net/sh_eth.h
+++ b/drivers/net/sh_eth.h
@@ -371,21 +371,6 @@ static const u16 sh_eth_offset_fast_sh3_sh2[SH_ETH_MAX_REGISTER_OFFSET] = {
};
-#if defined(CONFIG_CPU_SUBTYPE_SH7763)
-/* This CPU register maps is very difference by other SH4 CPU */
-/* Chip Base Address */
-# define SH_TSU_ADDR 0xFEE01800
-# define ARSTR SH_TSU_ADDR
-#elif defined(CONFIG_CPU_SH4) /* #if defined(CONFIG_CPU_SUBTYPE_SH7763) */
-#else /* #elif defined(CONFIG_CPU_SH4) */
-/* This section is SH3 or SH2 */
-#ifndef CONFIG_CPU_SUBTYPE_SH7619
-/* Chip base address */
-# define SH_TSU_ADDR 0xA7000804
-# define ARSTR 0xA7000800
-#endif
-#endif /* CONFIG_CPU_SUBTYPE_SH7763 */
-
/* Driver's parameters */
#if defined(CONFIG_CPU_SH4)
#define SH4_SKB_RX_ALIGN 32
--
1.7.1
^ permalink raw reply related
* [RFC, PATCH 3/4] net: sh_eth: remove almost #ifdef of SH7763
From: Yoshihiro Shimoda @ 2011-02-15 11:47 UTC (permalink / raw)
To: netdev; +Cc: SH-Linux
The SH7763 has GETHER. So the specification of some registers differs than
other CPUs. This patch removes almost #ifdef of CONFIG_CPU_SUBTYPE_SH7763.
Then we are able to add other CPU's GETHER easily.
Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
---
drivers/net/sh_eth.c | 72 +++++++++++++++++++++++++++++--------------------
drivers/net/sh_eth.h | 14 +++-------
2 files changed, 47 insertions(+), 39 deletions(-)
diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c
index 0593f29..ca7ff4e 100644
--- a/drivers/net/sh_eth.c
+++ b/drivers/net/sh_eth.c
@@ -148,7 +148,7 @@ static void sh_eth_reset(struct net_device *ndev)
int cnt = 100;
sh_eth_write(ndev, EDSR_ENALL, EDSR);
- sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST, EDMR);
+ sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_GETHER, EDMR);
while (cnt > 0) {
if (!(sh_eth_read(ndev, EDMR) & 0x3))
break;
@@ -274,9 +274,9 @@ static void sh_eth_set_default_cpu_data(struct sh_eth_cpu_data *cd)
/* Chip Reset */
static void sh_eth_reset(struct net_device *ndev)
{
- sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST, EDMR);
+ sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_ETHER, EDMR);
mdelay(3);
- sh_eth_write(ndev, sh_eth_read(ndev, EDMR) & ~EDMR_SRST, EDMR);
+ sh_eth_write(ndev, sh_eth_read(ndev, EDMR) & ~EDMR_SRST_ETHER, EDMR);
}
#endif
@@ -354,6 +354,22 @@ static void read_mac_address(struct net_device *ndev, unsigned char *mac)
}
}
+static int sh_eth_is_gether(struct sh_eth_private *mdp)
+{
+ if (mdp->reg_offset == sh_eth_offset_gigabit)
+ return 1;
+ else
+ return 0;
+}
+
+static unsigned long sh_eth_get_edtrr_trns(struct sh_eth_private *mdp)
+{
+ if (sh_eth_is_gether(mdp))
+ return EDTRR_TRNS_GETHER;
+ else
+ return EDTRR_TRNS_ETHER;
+}
+
struct bb_info {
struct mdiobb_ctrl ctrl;
u32 addr;
@@ -493,9 +509,8 @@ static void sh_eth_ring_format(struct net_device *ndev)
/* Rx descriptor address set */
if (i == 0) {
sh_eth_write(ndev, mdp->rx_desc_dma, RDLAR);
-#if defined(CONFIG_CPU_SUBTYPE_SH7763)
- sh_eth_write(ndev, mdp->rx_desc_dma, RDFAR);
-#endif
+ if (sh_eth_is_gether(mdp))
+ sh_eth_write(ndev, mdp->rx_desc_dma, RDFAR);
}
}
@@ -515,9 +530,8 @@ static void sh_eth_ring_format(struct net_device *ndev)
if (i == 0) {
/* Tx descriptor address set */
sh_eth_write(ndev, mdp->tx_desc_dma, TDLAR);
-#if defined(CONFIG_CPU_SUBTYPE_SH7763)
- sh_eth_write(ndev, mdp->tx_desc_dma, TDFAR);
-#endif
+ if (sh_eth_is_gether(mdp))
+ sh_eth_write(ndev, mdp->tx_desc_dma, TDFAR);
}
}
@@ -897,9 +911,9 @@ static void sh_eth_error(struct net_device *ndev, int intr_status)
sh_eth_txfree(ndev);
/* SH7712 BUG */
- if (edtrr ^ EDTRR_TRNS) {
+ if (edtrr ^ sh_eth_get_edtrr_trns(mdp)) {
/* tx dma start */
- sh_eth_write(ndev, EDTRR_TRNS, EDTRR);
+ sh_eth_write(ndev, sh_eth_get_edtrr_trns(mdp), EDTRR);
}
/* wakeup */
netif_wake_queue(ndev);
@@ -1177,8 +1191,8 @@ static int sh_eth_start_xmit(struct sk_buff *skb, struct net_device *ndev)
mdp->cur_tx++;
- if (!(sh_eth_read(ndev, EDTRR) & EDTRR_TRNS))
- sh_eth_write(ndev, EDTRR_TRNS, EDTRR);
+ if (!(sh_eth_read(ndev, EDTRR) & sh_eth_get_edtrr_trns(mdp)))
+ sh_eth_write(ndev, sh_eth_get_edtrr_trns(mdp), EDTRR);
return NETDEV_TX_OK;
}
@@ -1236,15 +1250,15 @@ static struct net_device_stats *sh_eth_get_stats(struct net_device *ndev)
sh_eth_write(ndev, 0, CDCR); /* (write clear) */
mdp->stats.tx_carrier_errors += sh_eth_read(ndev, LCCR);
sh_eth_write(ndev, 0, LCCR); /* (write clear) */
-#if defined(CONFIG_CPU_SUBTYPE_SH7763)
- mdp->stats.tx_carrier_errors += sh_eth_read(ndev, CERCR);/* CERCR */
- sh_eth_write(ndev, 0, CERCR); /* (write clear) */
- mdp->stats.tx_carrier_errors += sh_eth_read(ndev, CEECR);/* CEECR */
- sh_eth_write(ndev, 0, CEECR); /* (write clear) */
-#else
- mdp->stats.tx_carrier_errors += sh_eth_read(ndev, CNDCR);
- sh_eth_write(ndev, 0, CNDCR); /* (write clear) */
-#endif
+ if (sh_eth_is_gether(mdp)) {
+ mdp->stats.tx_carrier_errors += sh_eth_read(ndev, CERCR);
+ sh_eth_write(ndev, 0, CERCR); /* (write clear) */
+ mdp->stats.tx_carrier_errors += sh_eth_read(ndev, CEECR);
+ sh_eth_write(ndev, 0, CEECR); /* (write clear) */
+ } else {
+ mdp->stats.tx_carrier_errors += sh_eth_read(ndev, CNDCR);
+ sh_eth_write(ndev, 0, CNDCR); /* (write clear) */
+ }
pm_runtime_put_sync(&mdp->pdev->dev);
return &mdp->stats;
@@ -1294,13 +1308,13 @@ static void sh_eth_tsu_init(struct sh_eth_private *mdp)
sh_eth_tsu_write(mdp, 0, TSU_FWSL0);
sh_eth_tsu_write(mdp, 0, TSU_FWSL1);
sh_eth_tsu_write(mdp, TSU_FWSLC_POSTENU | TSU_FWSLC_POSTENL, TSU_FWSLC);
-#if defined(CONFIG_CPU_SUBTYPE_SH7763)
- sh_eth_tsu_write(mdp, 0, TSU_QTAG0); /* Disable QTAG(0->1) */
- sh_eth_tsu_write(mdp, 0, TSU_QTAG1); /* Disable QTAG(1->0) */
-#else
- sh_eth_tsu_write(mdp, 0, TSU_QTAGM0); /* Disable QTAG(0->1) */
- sh_eth_tsu_write(mdp, 0, TSU_QTAGM1); /* Disable QTAG(1->0) */
-#endif
+ if (sh_eth_is_gether(mdp)) {
+ sh_eth_tsu_write(mdp, 0, TSU_QTAG0); /* Disable QTAG(0->1) */
+ sh_eth_tsu_write(mdp, 0, TSU_QTAG1); /* Disable QTAG(1->0) */
+ } else {
+ sh_eth_tsu_write(mdp, 0, TSU_QTAGM0); /* Disable QTAG(0->1) */
+ sh_eth_tsu_write(mdp, 0, TSU_QTAGM1); /* Disable QTAG(1->0) */
+ }
sh_eth_tsu_write(mdp, 0, TSU_FWSR); /* all interrupt status clear */
sh_eth_tsu_write(mdp, 0, TSU_FWINMK); /* Disable all interrupt */
sh_eth_tsu_write(mdp, 0, TSU_TEN); /* Disable all CAM entry */
diff --git a/drivers/net/sh_eth.h b/drivers/net/sh_eth.h
index 1a32dc0..1e7d90a 100644
--- a/drivers/net/sh_eth.h
+++ b/drivers/net/sh_eth.h
@@ -398,20 +398,14 @@ enum GECMR_BIT {
enum DMAC_M_BIT {
EDMR_EL = 0x40, /* Litte endian */
EDMR_DL1 = 0x20, EDMR_DL0 = 0x10,
-#ifdef CONFIG_CPU_SUBTYPE_SH7763
- EDMR_SRST = 0x03,
-#else /* CONFIG_CPU_SUBTYPE_SH7763 */
- EDMR_SRST = 0x01,
-#endif
+ EDMR_SRST_GETHER = 0x03,
+ EDMR_SRST_ETHER = 0x01,
};
/* EDTRR */
enum DMAC_T_BIT {
-#ifdef CONFIG_CPU_SUBTYPE_SH7763
- EDTRR_TRNS = 0x03,
-#else
- EDTRR_TRNS = 0x01,
-#endif
+ EDTRR_TRNS_GETHER = 0x03,
+ EDTRR_TRNS_ETHER = 0x01,
};
/* EDRRR*/
--
1.7.1
^ permalink raw reply related
* [RFC, PATCH 4/4] net: sh_eth: add support for SH7757's GETHER
From: Yoshihiro Shimoda @ 2011-02-15 11:47 UTC (permalink / raw)
To: netdev; +Cc: SH-Linux
The SH7757 have GETHER and ETHER both. This patch supports them.
Signed-off-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
---
drivers/net/sh_eth.c | 136 +++++++++++++++++++++++++++++++++++++++++++++++++-
1 files changed, 135 insertions(+), 1 deletions(-)
diff --git a/drivers/net/sh_eth.c b/drivers/net/sh_eth.c
index ca7ff4e..330f608 100644
--- a/drivers/net/sh_eth.c
+++ b/drivers/net/sh_eth.c
@@ -87,7 +87,8 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
.rpadir_value = 0x00020000, /* NET_IP_ALIGN assumed to be 2 */
};
#elif defined(CONFIG_CPU_SUBTYPE_SH7757)
-#define SH_ETH_RESET_DEFAULT 1
+#define SH_ETH_HAS_BOTH_MODULES 1
+#define SH_ETH_HAS_TSU 1
static void sh_eth_set_duplex(struct net_device *ndev)
{
struct sh_eth_private *mdp = netdev_priv(ndev);
@@ -134,6 +135,135 @@ static struct sh_eth_cpu_data sh_eth_my_cpu_data = {
.no_ade = 1,
};
+#define SH_GIGA_ETH_BASE 0xfee00000
+#define GIGA_MALR(port) (SH_GIGA_ETH_BASE + 0x800 * (port) + 0x05c8)
+#define GIGA_MAHR(port) (SH_GIGA_ETH_BASE + 0x800 * (port) + 0x05c0)
+static void sh_eth_chip_reset_giga(struct net_device *ndev)
+{
+ int i;
+ unsigned long mahr[2], malr[2];
+
+ /* save MAHR and MALR */
+ for (i = 0; i < 2; i++) {
+ malr[i] = readl(GIGA_MALR(i));
+ mahr[i] = readl(GIGA_MAHR(i));
+ }
+
+ /* reset device */
+ writel(ARSTR_ARSTR, SH_GIGA_ETH_BASE + 0x1800);
+ mdelay(1);
+
+ /* restore MAHR and MALR */
+ for (i = 0; i < 2; i++) {
+ writel(malr[i], GIGA_MALR(i));
+ writel(mahr[i], GIGA_MAHR(i));
+ }
+}
+
+static int sh_eth_is_gether(struct sh_eth_private *mdp);
+static void sh_eth_reset(struct net_device *ndev)
+{
+ struct sh_eth_private *mdp = netdev_priv(ndev);
+ int cnt = 100;
+
+ if (sh_eth_is_gether(mdp)) {
+ sh_eth_write(ndev, 0x03, EDSR);
+ sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_GETHER,
+ EDMR);
+ while (cnt > 0) {
+ if (!(sh_eth_read(ndev, EDMR) & 0x3))
+ break;
+ mdelay(1);
+ cnt--;
+ }
+ if (cnt < 0)
+ printk(KERN_ERR "Device reset fail\n");
+
+ /* Table Init */
+ sh_eth_write(ndev, 0x0, TDLAR);
+ sh_eth_write(ndev, 0x0, TDFAR);
+ sh_eth_write(ndev, 0x0, TDFXR);
+ sh_eth_write(ndev, 0x0, TDFFR);
+ sh_eth_write(ndev, 0x0, RDLAR);
+ sh_eth_write(ndev, 0x0, RDFAR);
+ sh_eth_write(ndev, 0x0, RDFXR);
+ sh_eth_write(ndev, 0x0, RDFFR);
+ } else {
+ sh_eth_write(ndev, sh_eth_read(ndev, EDMR) | EDMR_SRST_ETHER,
+ EDMR);
+ mdelay(3);
+ sh_eth_write(ndev, sh_eth_read(ndev, EDMR) & ~EDMR_SRST_ETHER,
+ EDMR);
+ }
+}
+
+static void sh_eth_set_duplex_giga(struct net_device *ndev)
+{
+ struct sh_eth_private *mdp = netdev_priv(ndev);
+
+ if (mdp->duplex) /* Full */
+ sh_eth_write(ndev, sh_eth_read(ndev, ECMR) | ECMR_DM, ECMR);
+ else /* Half */
+ sh_eth_write(ndev, sh_eth_read(ndev, ECMR) & ~ECMR_DM, ECMR);
+}
+
+static void sh_eth_set_rate_giga(struct net_device *ndev)
+{
+ struct sh_eth_private *mdp = netdev_priv(ndev);
+
+ switch (mdp->speed) {
+ case 10: /* 10BASE */
+ sh_eth_write(ndev, 0x00000000, GECMR);
+ break;
+ case 100:/* 100BASE */
+ sh_eth_write(ndev, 0x00000010, GECMR);
+ break;
+ case 1000: /* 1000BASE */
+ sh_eth_write(ndev, 0x00000020, GECMR);
+ break;
+ default:
+ break;
+ }
+}
+
+/* SH7757(GETHERC) */
+static struct sh_eth_cpu_data sh_eth_my_cpu_data_giga = {
+ .chip_reset = sh_eth_chip_reset_giga,
+ .set_duplex = sh_eth_set_duplex_giga,
+ .set_rate = sh_eth_set_rate_giga,
+
+ .ecsr_value = ECSR_ICD | ECSR_MPD,
+ .ecsipr_value = ECSIPR_LCHNGIP | ECSIPR_ICDIP | ECSIPR_MPDIP,
+ .eesipr_value = DMAC_M_RFRMER | DMAC_M_ECI | 0x003fffff,
+
+ .tx_check = EESR_TC1 | EESR_FTC,
+ .eesr_err_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_RABT | \
+ EESR_RDE | EESR_RFRMER | EESR_TFE | EESR_TDE | \
+ EESR_ECI,
+ .tx_error_check = EESR_TWB1 | EESR_TWB | EESR_TABT | EESR_TDE | \
+ EESR_TFE,
+ .fdr_value = 0x0000072f,
+ .rmcr_value = 0x00000001,
+
+ .apr = 1,
+ .mpr = 1,
+ .tpauser = 1,
+ .bculr = 1,
+ .hw_swap = 1,
+ .rpadir = 1,
+ .rpadir_value = 2 << 16,
+ .no_trimd = 1,
+ .no_ade = 1,
+};
+
+static struct sh_eth_cpu_data *sh_eth_get_cpu_data(struct sh_eth_private *mdp)
+{
+ if (sh_eth_is_gether(mdp))
+ return &sh_eth_my_cpu_data_giga;
+ else
+ return &sh_eth_my_cpu_data;
+}
+
#elif defined(CONFIG_CPU_SUBTYPE_SH7763)
#define SH_ETH_HAS_TSU 1
static void sh_eth_chip_reset(struct net_device *ndev)
@@ -1515,7 +1645,11 @@ static int sh_eth_drv_probe(struct platform_device *pdev)
mdp->reg_offset = sh_eth_get_register_offset(pd->register_type);
/* set cpu data */
+#if defined(SH_ETH_HAS_BOTH_MODULES)
+ mdp->cd = sh_eth_get_cpu_data(mdp);
+#else
mdp->cd = &sh_eth_my_cpu_data;
+#endif
sh_eth_set_default_cpu_data(mdp->cd);
/* set function */
--
1.7.1
^ permalink raw reply related
* [PATCH] drivers/net: Call netif_carrier_off at the end of the probe
From: Ivan Vecera @ 2011-02-15 12:08 UTC (permalink / raw)
To: netdev; +Cc: romieu, davem, aabdulla
Without calling of netif_carrier_off at the end of the probe the operstate
is unknown when the device is initially opened. By default the carrier is
on so when the device is opened and netif_carrier_on is called the link
watch event is not fired and operstate remains zero (unknown).
This patch fixes this behavior in forcedeth and r8169.
Signed-off-by: Ivan Vecera <ivecera@redhat.com>
---
drivers/net/forcedeth.c | 2 ++
drivers/net/r8169.c | 2 ++
2 files changed, 4 insertions(+), 0 deletions(-)
diff --git a/drivers/net/forcedeth.c b/drivers/net/forcedeth.c
index af09296..9c0b1ba 100644
--- a/drivers/net/forcedeth.c
+++ b/drivers/net/forcedeth.c
@@ -5645,6 +5645,8 @@ static int __devinit nv_probe(struct pci_dev *pci_dev, const struct pci_device_i
goto out_error;
}
+ netif_carrier_off(dev);
+
dev_info(&pci_dev->dev, "ifname %s, PHY OUI 0x%x @ %d, addr %pM\n",
dev->name, np->phy_oui, np->phyaddr, dev->dev_addr);
diff --git a/drivers/net/r8169.c b/drivers/net/r8169.c
index 59ccf0c..469ab0b 100644
--- a/drivers/net/r8169.c
+++ b/drivers/net/r8169.c
@@ -3190,6 +3190,8 @@ rtl8169_init_one(struct pci_dev *pdev, const struct pci_device_id *ent)
if (pci_dev_run_wake(pdev))
pm_runtime_put_noidle(&pdev->dev);
+ netif_carrier_off(dev);
+
out:
return rc;
--
1.7.3.4
^ permalink raw reply related
* Re: [PATCH] virtio: use __GFP_NOWARN for try_fill_recv in virtnet_poll
From: Michal Hocko @ 2011-02-15 12:39 UTC (permalink / raw)
To: Rusty Russell; +Cc: Michael S. Tsirkin, virtualization, netdev, linux-kernel
In-Reply-To: <20110215093527.GB8341@tiehlicka.suse.cz>
On Tue 15-02-11 10:35:27, Michal Hocko wrote:
[...]
> [22798.508903] The following is only an harmless informational message.
> [22798.508909] Unless you get a _continuous_flood_ of these messages it means
> [22798.508911] everything is working fine. Allocations from irqs cannot be
> [22798.508913] perfectly reliable and the kernel is designed to handle that.
I have just realized that the above text is SLES specific so only the
line below with stack trace and memory info is printed. Sorry for confusion
> [22798.508917] loop3: page allocation failure. order:0, mode:0x20, alloc_flags:0x30 pflags:0x80208040
--
Michal Hocko
SUSE Labs
SUSE LINUX s.r.o.
Lihovarska 1060/12
190 00 Praha 9
Czech Republic
^ permalink raw reply
* Re: [PATCH] virtio: use __GFP_NOWARN for try_fill_recv in virtnet_poll
From: Michal Hocko @ 2011-02-15 12:42 UTC (permalink / raw)
To: Rusty Russell; +Cc: Michael S. Tsirkin, virtualization, netdev, linux-kernel
In-Reply-To: <201102152139.03451.rusty@rustcorp.com.au>
On Tue 15-02-11 21:39:03, Rusty Russell wrote:
> On Tue, 15 Feb 2011 08:55:50 pm Michal Hocko wrote:
> > On Tue 15-02-11 20:41:29, Rusty Russell wrote:
> > > On Tue, 15 Feb 2011 08:05:27 pm Michal Hocko wrote:
> > > > Hi,
> > > > we have started seeing a lot of allocator messages complaining about
> > > > failed allocations from virtnet_poll in soft IRQ. Could you consider the
> > > > following patch, please?
> > >
> > > Do we really want to silence this? Isn't warning about it kind of the
> > > point? Your network is probably sucking if this happens...
> >
> > What can user do about it? Is the low level memory allocator message
> > very much usefull for him? Maybe we can add a printk_once in the fail
> > path with some more useful and virtio specific message.
>
> That's an argument against ever printing any message.
Well, honestly, I do not see much point for this message but it is there
for ages so it maybe it is valueable for somebody...
>
> What we need to know is why does this happen with virtio_net and not other
> cards?
The machine just happened to be short on memory due to a strong memory
pressure.
> If it happens to them too, and they silently fall back, all good.
>
> I want to make sure we're not papering over a real problem...
>
> Thanks,
> Rusty.
--
Michal Hocko
SUSE Labs
SUSE LINUX s.r.o.
Lihovarska 1060/12
190 00 Praha 9
Czech Republic
^ permalink raw reply
* [PATCH] TX timestamp IPv6 support
From: Anders Berggren @ 2011-02-15 13:56 UTC (permalink / raw)
To: netdev; +Cc: John Ronciak
This patch enables UDP IPv6 TX timestamping (using SO_TIMESTAMPING, enabled by CONFIG_NETWORK_PHY_TIMESTAMPING) as Marcus D. Leech suggested in http://kerneltrap.org/mailarchive/linux-netdev/2009/11/10/6260604 and http://kerneltrap.org/mailarchive/linux-netdev/2009/11/11/6260643
It's mostly copied from net/ipv4/udp.c. I guess it would be better to run sock_tx_timestamp in ipv6/udp.c and pass it to ipv6/ip6_output.c's ip6_append_data somehow, but I didn't find a suitable struct to extend for this purpose.
Anders Berggren
Halon Security
diff --git a/net/ipv6/ip6_output.c b/net/ipv6/ip6_output.c
index 94b5bf1..74d9343 100644
--- a/net/ipv6/ip6_output.c
+++ b/net/ipv6/ip6_output.c
@@ -1115,6 +1115,7 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
int err;
int offset = 0;
int csummode = CHECKSUM_NONE;
+ __u8 tx_flags = 0;
if (flags&MSG_PROBE)
return 0;
@@ -1199,6 +1200,13 @@ int ip6_append_data(struct sock *sk, int getfrag(void *from, char *to,
}
}
+ /* For UDP, check if TX timestamp is enabled */
+ if (sk->sk_type == SOCK_DGRAM) {
+ err = sock_tx_timestamp(sk, &tx_flags);
+ if (err)
+ goto error;
+ }
+
/*
* Let's try using as much space as possible.
* Use MTU if total length of the message fits into the MTU.
@@ -1303,6 +1311,10 @@ alloc_new_skb:
sk->sk_allocation);
if (unlikely(skb == NULL))
err = -ENOBUFS;
+ else
+ /* only the initial fragment is
+ time stamped */
+ tx_flags = 0;
}
if (skb == NULL)
goto error;
@@ -1314,6 +1326,9 @@ alloc_new_skb:
/* reserve for fragmentation */
skb_reserve(skb, hh_len+sizeof(struct frag_hdr));
+ if (sk->sk_type == SOCK_DGRAM)
+ skb_shinfo(skb)->tx_flags = tx_flags;
+
/*
* Find where to start putting bytes
*/
^ permalink raw reply related
* 3x59x WOL and CONFIG_SUSPEND
From: Markku Pesonen @ 2011-02-15 13:55 UTC (permalink / raw)
To: netdev; +Cc: Steffen Klassert, Rafael J. Wysocki
Hi,
Since commit 074037ec79bea73edf1b1ec72fef1010e83e3cc5
(PM / Wakeup: Introduce wakeup source objects and event statistics (v3)),
Wake-On-Lan on my 3c905C has not worked unless I enable CONFIG_SUSPEND.
The driver says "0000:00:0b.0: WOL not supported."
Enabling CONFIG_SUSPEND makes Wake-On-Lan work on 2.6.37 while 2.6.36
works just fine without it. Is this a regression or intended behavior?
^ permalink raw reply
* [PATCH] Add basic support for smsc9311 in smsc911x Driver
From: Fernando @ 2011-02-15 14:57 UTC (permalink / raw)
To: netdev
The smsc9311 chip is an switch chip with 3 ports that have almost the same
register structure of the LAN9115. There are some differences in IRQ regs,
but that doesn't seem to be a problem right now.
This patch was tested on a Torpedo (OMAP35x) based board and is based on
v2.6.38-rc4.
Fernando
>From e987729802dd3980041fd7e48e68f3a9f53424bd Mon Sep 17 00:00:00 2001
From: Fernando Governatore <fernando@syspac.com.br>
Date: Tue, 15 Feb 2011 12:10:22 -0200
Subject: [PATCH] Add basic support for smsc9311 in smsc911x Driver
The smsc9311 chip is an switch chip with three ports.
Here is assumed that only the first one is connected to
the host.
Makes the driver aware of the chip revision id.
If no external phy is being used, mask out all the PHY
IDs that are not present by default.
The default switch configuration is not changed.
---
drivers/net/smc911x.h | 2 ++
drivers/net/smsc911x.c | 15 ++++++++++++---
2 files changed, 14 insertions(+), 3 deletions(-)
diff --git a/drivers/net/smc911x.h b/drivers/net/smc911x.h
index 3269292..5e336d2 100644
--- a/drivers/net/smc911x.h
+++ b/drivers/net/smc911x.h
@@ -687,6 +687,7 @@ smc_pxa_dma_outsl(struct smc911x_local *lp, u_long physaddr,
#define CHIP_9215 0x115A
#define CHIP_9217 0x117A
#define CHIP_9218 0x118A
+#define CHIP_9311 0x9311
struct chip_id {
u16 id;
@@ -702,6 +703,7 @@ static const struct chip_id chip_ids[] = {
{ CHIP_9215, "LAN9215" },
{ CHIP_9217, "LAN9217" },
{ CHIP_9218, "LAN9218" },
+ { CHIP_9311, "LAN9311" },
{ 0, NULL },
};
diff --git a/drivers/net/smsc911x.c b/drivers/net/smsc911x.c
index 64bfdae..483fdbd 100644
--- a/drivers/net/smsc911x.c
+++ b/drivers/net/smsc911x.c
@@ -856,6 +856,7 @@ static int __devinit smsc911x_mii_init(struct platform_device *pdev,
case 0x01150000:
case 0x117A0000:
case 0x115A0000:
+ case 0x93110000:
/* External PHY supported, try to autodetect */
smsc911x_phy_initialise_external(pdata);
break;
@@ -867,8 +868,15 @@ static int __devinit smsc911x_mii_init(struct platform_device *pdev,
}
if (!pdata->using_extphy) {
- /* Mask all PHYs except ID 1 (internal) */
- pdata->mii_bus->phy_mask = ~(1 << 1);
+ /* Mask all PHYs except internal IDs */
+ switch(pdata->idrev & 0xFFFF0000){
+ case 0x93110000:
+ pdata->mii_bus->phy_mask = ~(1 << 0) & ~(1 << 1) & ~(1 << 2);
+ break;
+ default:
+ pdata->mii_bus->phy_mask = ~(1 << 1);
+ break;
+ }
}
if (mdiobus_register(pdata->mii_bus)) {
@@ -1870,7 +1878,8 @@ static int __devinit smsc911x_init(struct net_device *dev)
case 0x92110000:
case 0x92200000:
case 0x92210000:
- /* LAN9210/LAN9211/LAN9220/LAN9221 */
+ case 0x93110000:
+ /* LAN9210/LAN9211/LAN9220/LAN9221/LAN9311 */
pdata->generation = 4;
break;
--
1.7.1
^ permalink raw reply related
* Re: [PATCH] drivers/net: Call netif_carrier_off at the end of the probe
From: Francois Romieu @ 2011-02-15 15:22 UTC (permalink / raw)
To: Ivan Vecera; +Cc: netdev, davem, aabdulla, Ben Hutchings
In-Reply-To: <1297771719-14202-1-git-send-email-ivecera@redhat.com>
Ivan Vecera <ivecera@redhat.com> :
> Without calling of netif_carrier_off at the end of the probe the operstate
> is unknown when the device is initially opened. By default the carrier is
> on so when the device is opened and netif_carrier_on is called the link
> watch event is not fired and operstate remains zero (unknown).
Stated this way it sounds like a core dev layer issue.
I am not completely sure after reading some history. Namely:
- (37e8273cd30592d3a82bcb70cbb1bdc4eaeb6b71 ?)
- c276e098d3ee33059b4a1c747354226cec58487c
- 22604c866889c4b2e12b73cbf1683bda1b72a313
- b47300168e770b60ab96c8924854c3b0eb4260eb
I am confused.
--
Ueimor
^ permalink raw reply
* Re: [PATCH] drivers/net: Call netif_carrier_off at the end of the probe
From: Ben Hutchings @ 2011-02-15 15:58 UTC (permalink / raw)
To: Francois Romieu; +Cc: Ivan Vecera, netdev, davem, aabdulla, Ben Hutchings
In-Reply-To: <20110215152246.GA11719@electric-eye.fr.zoreil.com>
On Tue, 2011-02-15 at 16:22 +0100, Francois Romieu wrote:
> Ivan Vecera <ivecera@redhat.com> :
> > Without calling of netif_carrier_off at the end of the probe the operstate
> > is unknown when the device is initially opened. By default the carrier is
> > on so when the device is opened and netif_carrier_on is called the link
> > watch event is not fired and operstate remains zero (unknown).
>
> Stated this way it sounds like a core dev layer issue.
Due to hardware limitations, some network drivers cannot report the
carrier state and they never call netif_carrier_{on,off}(). Therefore
the initial operstate of 'unknown' is correct.
> I am not completely sure after reading some history. Namely:
> - (37e8273cd30592d3a82bcb70cbb1bdc4eaeb6b71 ?)
> - c276e098d3ee33059b4a1c747354226cec58487c
> - 22604c866889c4b2e12b73cbf1683bda1b72a313
> - b47300168e770b60ab96c8924854c3b0eb4260eb
>
> I am confused.
Drivers that can report carrier state should do so initially some time
between registering a device and bringing it up (either in the bus probe
function or the ndo_open function). It generally seems to be safe to
assume that the link is down initially, and then to rely on
notifications from the hardware. However, that does depend on the
behaviour of the hardware.
Ben.
--
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply
* [PATCH] bnx2x: Support for managing RX indirection table
From: Tom Herbert @ 2011-02-15 16:24 UTC (permalink / raw)
To: davem, eilong, netdev
Support fetching and retrieving RX indirection table via ethtool.
Signed-off-by: Tom Herbert <therbert@google.com>
---
drivers/net/bnx2x/bnx2x.h | 2 +
drivers/net/bnx2x/bnx2x_ethtool.c | 58 +++++++++++++++++++++++++++++++++++++
drivers/net/bnx2x/bnx2x_main.c | 23 +++++++++++----
3 files changed, 77 insertions(+), 6 deletions(-)
diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h
index 236d79a..bf16119 100644
--- a/drivers/net/bnx2x/bnx2x.h
+++ b/drivers/net/bnx2x/bnx2x.h
@@ -1076,6 +1076,7 @@ struct bnx2x {
int num_queues;
int disable_tpa;
int int_mode;
+ u32 rx_indir_table[128];
struct tstorm_eth_mac_filter_config mac_filters;
#define BNX2X_ACCEPT_NONE 0x0000
@@ -1799,5 +1800,6 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
BNX2X_EXTERN int load_count[2][3]; /* per path: 0-common, 1-port0, 2-port1 */
extern void bnx2x_set_ethtool_ops(struct net_device *netdev);
+extern void bnx2x_push_indir_table(struct bnx2x *bp);
#endif /* bnx2x.h */
diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c
index 816fef6..a99fee4 100644
--- a/drivers/net/bnx2x/bnx2x_ethtool.c
+++ b/drivers/net/bnx2x/bnx2x_ethtool.c
@@ -2134,6 +2134,61 @@ static int bnx2x_phys_id(struct net_device *dev, u32 data)
return 0;
}
+static int
+bnx2x_get_rxnfc(struct net_device *dev,
+ struct ethtool_rxnfc *info, void *rules __always_unused)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+
+ switch (info->cmd) {
+ case ETHTOOL_GRXRINGS:
+ info->data = bp->num_queues - NONE_ETH_CONTEXT_USE;
+ return 0;
+
+ default:
+ return -EOPNOTSUPP;
+ }
+}
+
+static int bnx2x_get_rxfh_indir(struct net_device *dev,
+ struct ethtool_rxfh_indir *indir)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+ size_t copy_size =
+ min_t(size_t, indir->size, TSTORM_INDIRECTION_TABLE_SIZE);
+
+ if (bp->multi_mode == ETH_RSS_MODE_DISABLED)
+ return -ENOENT;
+
+ indir->size = TSTORM_INDIRECTION_TABLE_SIZE;
+ memcpy(indir->ring_index, bp->rx_indir_table,
+ copy_size * sizeof(bp->rx_indir_table[0]));
+ return 0;
+}
+
+static int bnx2x_set_rxfh_indir(struct net_device *dev,
+ const struct ethtool_rxfh_indir *indir)
+{
+ struct bnx2x *bp = netdev_priv(dev);
+ size_t i;
+
+ if (bp->multi_mode == ETH_RSS_MODE_DISABLED)
+ return -ENOENT;
+
+ /* Validate size and indices */
+ if (indir->size != TSTORM_INDIRECTION_TABLE_SIZE)
+ return -EINVAL;
+ for (i = 0; i < TSTORM_INDIRECTION_TABLE_SIZE; i++)
+ if (indir->ring_index[i] >=
+ bp->num_queues - NONE_ETH_CONTEXT_USE)
+ return -EINVAL;
+
+ memcpy(bp->rx_indir_table, indir->ring_index,
+ sizeof(bp->rx_indir_table));
+ bnx2x_push_indir_table(bp);
+ return 0;
+}
+
static const struct ethtool_ops bnx2x_ethtool_ops = {
.get_settings = bnx2x_get_settings,
.set_settings = bnx2x_set_settings,
@@ -2170,6 +2225,9 @@ static const struct ethtool_ops bnx2x_ethtool_ops = {
.get_strings = bnx2x_get_strings,
.phys_id = bnx2x_phys_id,
.get_ethtool_stats = bnx2x_get_ethtool_stats,
+ .get_rxnfc = bnx2x_get_rxnfc,
+ .get_rxfh_indir = bnx2x_get_rxfh_indir,
+ .set_rxfh_indir = bnx2x_set_rxfh_indir,
};
void bnx2x_set_ethtool_ops(struct net_device *netdev)
diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c
index c238c4d..b1a84d4 100644
--- a/drivers/net/bnx2x/bnx2x_main.c
+++ b/drivers/net/bnx2x/bnx2x_main.c
@@ -4254,7 +4254,7 @@ static void bnx2x_init_eq_ring(struct bnx2x *bp)
min_t(int, MAX_SP_DESC_CNT - MAX_SPQ_PENDING, NUM_EQ_DESC) - 1);
}
-static void bnx2x_init_ind_table(struct bnx2x *bp)
+void bnx2x_push_indir_table(struct bnx2x *bp)
{
int func = BP_FUNC(bp);
int i;
@@ -4262,13 +4262,24 @@ static void bnx2x_init_ind_table(struct bnx2x *bp)
if (bp->multi_mode == ETH_RSS_MODE_DISABLED)
return;
- DP(NETIF_MSG_IFUP,
- "Initializing indirection table multi_mode %d\n", bp->multi_mode);
for (i = 0; i < TSTORM_INDIRECTION_TABLE_SIZE; i++)
REG_WR8(bp, BAR_TSTRORM_INTMEM +
TSTORM_INDIRECTION_TABLE_OFFSET(func) + i,
- bp->fp->cl_id + (i % (bp->num_queues -
- NONE_ETH_CONTEXT_USE)));
+ bp->fp->cl_id + bp->rx_indir_table[i]);
+}
+
+static void bnx2x_init_indir_table(struct bnx2x *bp)
+{
+ int i;
+
+ BUG_ON(ARRAY_SIZE(bp->rx_indir_table) <
+ TSTORM_INDIRECTION_TABLE_SIZE);
+
+ for (i = 0; i < TSTORM_INDIRECTION_TABLE_SIZE; i++)
+ bp->rx_indir_table[i] =
+ (i % (bp->num_queues - NONE_ETH_CONTEXT_USE));
+
+ bnx2x_push_indir_table(bp);
}
void bnx2x_set_storm_rx_mode(struct bnx2x *bp)
@@ -4496,7 +4507,7 @@ void bnx2x_nic_init(struct bnx2x *bp, u32 load_code)
bnx2x_init_eq_ring(bp);
bnx2x_init_internal(bp, load_code);
bnx2x_pf_init(bp);
- bnx2x_init_ind_table(bp);
+ bnx2x_init_indir_table(bp);
bnx2x_stats_init(bp);
/* At this point, we are ready for interrupts */
--
1.7.3.1
^ permalink raw reply related
* Re: [PATCH] bnx2x: Support for managing RX indirection table
From: Eric Dumazet @ 2011-02-15 16:35 UTC (permalink / raw)
To: Tom Herbert; +Cc: davem, eilong, netdev
In-Reply-To: <alpine.DEB.2.00.1102150815060.27695@pokey.mtv.corp.google.com>
Le mardi 15 février 2011 à 08:24 -0800, Tom Herbert a écrit :
> Support fetching and retrieving RX indirection table via ethtool.
>
> Signed-off-by: Tom Herbert <therbert@google.com>
> ---
> drivers/net/bnx2x/bnx2x.h | 2 +
> drivers/net/bnx2x/bnx2x_ethtool.c | 58 +++++++++++++++++++++++++++++++++++++
> drivers/net/bnx2x/bnx2x_main.c | 23 +++++++++++----
> 3 files changed, 77 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h
> index 236d79a..bf16119 100644
> --- a/drivers/net/bnx2x/bnx2x.h
> +++ b/drivers/net/bnx2x/bnx2x.h
> @@ -1076,6 +1076,7 @@ struct bnx2x {
> int num_queues;
> int disable_tpa;
> int int_mode;
> + u32 rx_indir_table[128];
>
> struct tstorm_eth_mac_filter_config mac_filters;
> #define BNX2X_ACCEPT_NONE 0x0000
> @@ -1799,5 +1800,6 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
> BNX2X_EXTERN int load_count[2][3]; /* per path: 0-common, 1-port0, 2-port1 */
>
> extern void bnx2x_set_ethtool_ops(struct net_device *netdev);
> +extern void bnx2x_push_indir_table(struct bnx2x *bp);
>
> #endif /* bnx2x.h */
> diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c
> index 816fef6..a99fee4 100644
> --- a/drivers/net/bnx2x/bnx2x_ethtool.c
> +++ b/drivers/net/bnx2x/bnx2x_ethtool.c
> @@ -2134,6 +2134,61 @@ static int bnx2x_phys_id(struct net_device *dev, u32 data)
> return 0;
> }
>
> +static int
> +bnx2x_get_rxnfc(struct net_device *dev,
> + struct ethtool_rxnfc *info, void *rules __always_unused)
> +{
> + struct bnx2x *bp = netdev_priv(dev);
> +
> + switch (info->cmd) {
> + case ETHTOOL_GRXRINGS:
> + info->data = bp->num_queues - NONE_ETH_CONTEXT_USE;
> + return 0;
> +
> + default:
> + return -EOPNOTSUPP;
> + }
> +}
> +
> +static int bnx2x_get_rxfh_indir(struct net_device *dev,
> + struct ethtool_rxfh_indir *indir)
> +{
> + struct bnx2x *bp = netdev_priv(dev);
> + size_t copy_size =
> + min_t(size_t, indir->size, TSTORM_INDIRECTION_TABLE_SIZE);
> +
> + if (bp->multi_mode == ETH_RSS_MODE_DISABLED)
> + return -ENOENT;
> +
> + indir->size = TSTORM_INDIRECTION_TABLE_SIZE;
> + memcpy(indir->ring_index, bp->rx_indir_table,
> + copy_size * sizeof(bp->rx_indir_table[0]));
> + return 0;
> +}
> +
> +static int bnx2x_set_rxfh_indir(struct net_device *dev,
> + const struct ethtool_rxfh_indir *indir)
> +{
> + struct bnx2x *bp = netdev_priv(dev);
> + size_t i;
> +
> + if (bp->multi_mode == ETH_RSS_MODE_DISABLED)
> + return -ENOENT;
> +
> + /* Validate size and indices */
> + if (indir->size != TSTORM_INDIRECTION_TABLE_SIZE)
> + return -EINVAL;
> + for (i = 0; i < TSTORM_INDIRECTION_TABLE_SIZE; i++)
> + if (indir->ring_index[i] >=
> + bp->num_queues - NONE_ETH_CONTEXT_USE)
BNX2X_NUM_ETH_QUEUES(bp) instead of
(bp->num_queues - NONE_ETH_CONTEXT_USE)
> + return -EINVAL;
> +
> + memcpy(bp->rx_indir_table, indir->ring_index,
> + sizeof(bp->rx_indir_table));
> + bnx2x_push_indir_table(bp);
> + return 0;
> +}
> +
> static const struct ethtool_ops bnx2x_ethtool_ops = {
> .get_settings = bnx2x_get_settings,
> .set_settings = bnx2x_set_settings,
> @@ -2170,6 +2225,9 @@ static const struct ethtool_ops bnx2x_ethtool_ops = {
> .get_strings = bnx2x_get_strings,
> .phys_id = bnx2x_phys_id,
> .get_ethtool_stats = bnx2x_get_ethtool_stats,
> + .get_rxnfc = bnx2x_get_rxnfc,
> + .get_rxfh_indir = bnx2x_get_rxfh_indir,
> + .set_rxfh_indir = bnx2x_set_rxfh_indir,
> };
>
> void bnx2x_set_ethtool_ops(struct net_device *netdev)
> diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c
> index c238c4d..b1a84d4 100644
> --- a/drivers/net/bnx2x/bnx2x_main.c
> +++ b/drivers/net/bnx2x/bnx2x_main.c
> @@ -4254,7 +4254,7 @@ static void bnx2x_init_eq_ring(struct bnx2x *bp)
> min_t(int, MAX_SP_DESC_CNT - MAX_SPQ_PENDING, NUM_EQ_DESC) - 1);
> }
>
> -static void bnx2x_init_ind_table(struct bnx2x *bp)
> +void bnx2x_push_indir_table(struct bnx2x *bp)
> {
> int func = BP_FUNC(bp);
> int i;
> @@ -4262,13 +4262,24 @@ static void bnx2x_init_ind_table(struct bnx2x *bp)
> if (bp->multi_mode == ETH_RSS_MODE_DISABLED)
> return;
>
> - DP(NETIF_MSG_IFUP,
> - "Initializing indirection table multi_mode %d\n", bp->multi_mode);
> for (i = 0; i < TSTORM_INDIRECTION_TABLE_SIZE; i++)
> REG_WR8(bp, BAR_TSTRORM_INTMEM +
> TSTORM_INDIRECTION_TABLE_OFFSET(func) + i,
> - bp->fp->cl_id + (i % (bp->num_queues -
> - NONE_ETH_CONTEXT_USE)));
ditto
> + bp->fp->cl_id + bp->rx_indir_table[i]);
> +}
> +
> +static void bnx2x_init_indir_table(struct bnx2x *bp)
> +{
> + int i;
> +
> + BUG_ON(ARRAY_SIZE(bp->rx_indir_table) <
> + TSTORM_INDIRECTION_TABLE_SIZE);
> +
> + for (i = 0; i < TSTORM_INDIRECTION_TABLE_SIZE; i++)
> + bp->rx_indir_table[i] =
> + (i % (bp->num_queues - NONE_ETH_CONTEXT_USE));
and here
> +
> + bnx2x_push_indir_table(bp);
> }
>
> void bnx2x_set_storm_rx_mode(struct bnx2x *bp)
> @@ -4496,7 +4507,7 @@ void bnx2x_nic_init(struct bnx2x *bp, u32 load_code)
> bnx2x_init_eq_ring(bp);
> bnx2x_init_internal(bp, load_code);
> bnx2x_pf_init(bp);
> - bnx2x_init_ind_table(bp);
> + bnx2x_init_indir_table(bp);
> bnx2x_stats_init(bp);
>
> /* At this point, we are ready for interrupts */
^ permalink raw reply
* Re: [Bugme-new] [Bug 27212] New: Warning kmemcheck: Caught 64-bit read from uninitialized memory in netlink_broadcast_filtered
From: Christoph Lameter @ 2011-02-15 16:40 UTC (permalink / raw)
To: Pekka Enberg
Cc: Eric Dumazet, Andrew Morton, netdev, bugzilla-daemon,
bugme-daemon, casteyde.christian, Changli Gao, Vegard Nossum,
David Miller, linux-kernel, David Rientjes
In-Reply-To: <AANLkTinKTdeO5mnE38n==aZMz5P1XKKM+kykhoBu0=9k@mail.gmail.com>
On Tue, 15 Feb 2011, Pekka Enberg wrote:
> Looks good to me. Christoph, David, any objections to the patch?
My eyes hurt. Is there some way you could use tabs or spaces instead of
these weird symbols?
If the kmemcheck people are fine with checking data beyond the last byte
of the object then its fine with me.
Acked-by: Christoph Lameter <cl@linux.com>
^ permalink raw reply
* Re: [PATCH] bnx2x: Support for managing RX indirection table
From: Ben Hutchings @ 2011-02-15 16:48 UTC (permalink / raw)
To: Tom Herbert; +Cc: davem, eilong, netdev
In-Reply-To: <alpine.DEB.2.00.1102150815060.27695@pokey.mtv.corp.google.com>
On Tue, 2011-02-15 at 08:24 -0800, Tom Herbert wrote:
> Support fetching and retrieving RX indirection table via ethtool.
>
> Signed-off-by: Tom Herbert <therbert@google.com>
> ---
> drivers/net/bnx2x/bnx2x.h | 2 +
> drivers/net/bnx2x/bnx2x_ethtool.c | 58 +++++++++++++++++++++++++++++++++++++
> drivers/net/bnx2x/bnx2x_main.c | 23 +++++++++++----
> 3 files changed, 77 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h
> index 236d79a..bf16119 100644
> --- a/drivers/net/bnx2x/bnx2x.h
> +++ b/drivers/net/bnx2x/bnx2x.h
> @@ -1076,6 +1076,7 @@ struct bnx2x {
> int num_queues;
> int disable_tpa;
> int int_mode;
> + u32 rx_indir_table[128];
Shouldn't the dimension be TSTORM_INDIRECTION_TABLE_SIZE?
[...]
> +static int bnx2x_set_rxfh_indir(struct net_device *dev,
> + const struct ethtool_rxfh_indir *indir)
> +{
> + struct bnx2x *bp = netdev_priv(dev);
> + size_t i;
> +
> + if (bp->multi_mode == ETH_RSS_MODE_DISABLED)
> + return -ENOENT;
[...]
I think the error code for this should be -EOPNOTSUPP. Similarly in
bnx2x_get_rxfh_indir().
Ben.
--
Ben Hutchings, Senior Software Engineer, Solarflare Communications
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply
* Re: [PATCH V10 12/15] ptp: Added a brand new class driver for ptp clocks.
From: Richard Cochran @ 2011-02-15 17:29 UTC (permalink / raw)
To: John Stultz
Cc: linux-kernel, linux-api, netdev, Alan Cox, Arnd Bergmann,
Christoph Lameter, David Miller, Krzysztof Halasa, Peter Zijlstra,
Rodolfo Giometti, Thomas Gleixner, Benjamin Herrenschmidt,
H. Peter Anvin, Ingo Molnar, Mike Frysinger, Paul Mackerras,
Russell King
In-Reply-To: <20110211081524.GA12270@riccoc20.at.omicron.at>
On Fri, Feb 11, 2011 at 09:15:24AM +0100, Richard Cochran wrote:
> On Tue, Feb 01, 2011 at 06:00:31PM -0800, John Stultz wrote:
> > So what is serializing access to the timestamp_event_queue here? I don't
> > see any usage of tsevq_mux by the callers. Am I missing it? It looks
> > like its called from interrupt context, so do you really need a spinlock
> > and not a mutex here?
>
> The external timestamp FIFO is written only from interrupt context.
Oops, I lied. After reworking the phyter driver, I find that I want to
enqueue time stamps from non-interrupt contexts, too.
So, you are right. This will need a spin lock...
Thanks,
Richard
^ permalink raw reply
* Re: [PATCH] bnx2x: Support for managing RX indirection table
From: Vlad Zolotarov @ 2011-02-15 17:31 UTC (permalink / raw)
To: Tom Herbert; +Cc: netdev@vger.kernel.org
In-Reply-To: <alpine.DEB.2.00.1102150815060.27695@pokey.mtv.corp.google.com>
On Tuesday 15 February 2011 18:24:40 Tom Herbert wrote:
> Support fetching and retrieving RX indirection table via ethtool.
>
> Signed-off-by: Tom Herbert <therbert@google.com>
> ---
> drivers/net/bnx2x/bnx2x.h | 2 +
> drivers/net/bnx2x/bnx2x_ethtool.c | 58 +++++++++++++++++++++++++++++++++++++
> drivers/net/bnx2x/bnx2x_main.c | 23 +++++++++++----
> 3 files changed, 77 insertions(+), 6 deletions(-)
>
> diff --git a/drivers/net/bnx2x/bnx2x.h b/drivers/net/bnx2x/bnx2x.h
> index 236d79a..bf16119 100644
> --- a/drivers/net/bnx2x/bnx2x.h
> +++ b/drivers/net/bnx2x/bnx2x.h
> @@ -1076,6 +1076,7 @@ struct bnx2x {
> int num_queues;
> int disable_tpa;
> int int_mode;
> + u32 rx_indir_table[128];
>
> struct tstorm_eth_mac_filter_config mac_filters;
> #define BNX2X_ACCEPT_NONE 0x0000
> @@ -1799,5 +1800,6 @@ static inline u32 reg_poll(struct bnx2x *bp, u32 reg, u32 expected, int ms,
> BNX2X_EXTERN int load_count[2][3]; /* per path: 0-common, 1-port0, 2-port1 */
>
> extern void bnx2x_set_ethtool_ops(struct net_device *netdev);
> +extern void bnx2x_push_indir_table(struct bnx2x *bp);
Why to use "extern" for the prototype here and "static" for the implementation
below? Pls., declare it in .h (without an "extern") and use it as u do in
bnx2x_ethtool.c and bnx2x_main.c as u do.
thanks,
vlad
>
> #endif /* bnx2x.h */
> diff --git a/drivers/net/bnx2x/bnx2x_ethtool.c b/drivers/net/bnx2x/bnx2x_ethtool.c
> index 816fef6..a99fee4 100644
> --- a/drivers/net/bnx2x/bnx2x_ethtool.c
> +++ b/drivers/net/bnx2x/bnx2x_ethtool.c
> @@ -2134,6 +2134,61 @@ static int bnx2x_phys_id(struct net_device *dev, u32 data)
> return 0;
> }
>
> +static int
> +bnx2x_get_rxnfc(struct net_device *dev,
> + struct ethtool_rxnfc *info, void *rules __always_unused)
> +{
> + struct bnx2x *bp = netdev_priv(dev);
> +
> + switch (info->cmd) {
> + case ETHTOOL_GRXRINGS:
> + info->data = bp->num_queues - NONE_ETH_CONTEXT_USE;
> + return 0;
> +
> + default:
> + return -EOPNOTSUPP;
> + }
> +}
> +
> +static int bnx2x_get_rxfh_indir(struct net_device *dev,
> + struct ethtool_rxfh_indir *indir)
> +{
> + struct bnx2x *bp = netdev_priv(dev);
> + size_t copy_size =
> + min_t(size_t, indir->size, TSTORM_INDIRECTION_TABLE_SIZE);
> +
> + if (bp->multi_mode == ETH_RSS_MODE_DISABLED)
> + return -ENOENT;
> +
> + indir->size = TSTORM_INDIRECTION_TABLE_SIZE;
> + memcpy(indir->ring_index, bp->rx_indir_table,
> + copy_size * sizeof(bp->rx_indir_table[0]));
> + return 0;
> +}
> +
> +static int bnx2x_set_rxfh_indir(struct net_device *dev,
> + const struct ethtool_rxfh_indir *indir)
> +{
> + struct bnx2x *bp = netdev_priv(dev);
> + size_t i;
> +
> + if (bp->multi_mode == ETH_RSS_MODE_DISABLED)
> + return -ENOENT;
> +
> + /* Validate size and indices */
> + if (indir->size != TSTORM_INDIRECTION_TABLE_SIZE)
> + return -EINVAL;
> + for (i = 0; i < TSTORM_INDIRECTION_TABLE_SIZE; i++)
> + if (indir->ring_index[i] >=
> + bp->num_queues - NONE_ETH_CONTEXT_USE)
> + return -EINVAL;
> +
> + memcpy(bp->rx_indir_table, indir->ring_index,
> + sizeof(bp->rx_indir_table));
> + bnx2x_push_indir_table(bp);
> + return 0;
> +}
> +
> static const struct ethtool_ops bnx2x_ethtool_ops = {
> .get_settings = bnx2x_get_settings,
> .set_settings = bnx2x_set_settings,
> @@ -2170,6 +2225,9 @@ static const struct ethtool_ops bnx2x_ethtool_ops = {
> .get_strings = bnx2x_get_strings,
> .phys_id = bnx2x_phys_id,
> .get_ethtool_stats = bnx2x_get_ethtool_stats,
> + .get_rxnfc = bnx2x_get_rxnfc,
> + .get_rxfh_indir = bnx2x_get_rxfh_indir,
> + .set_rxfh_indir = bnx2x_set_rxfh_indir,
> };
>
> void bnx2x_set_ethtool_ops(struct net_device *netdev)
> diff --git a/drivers/net/bnx2x/bnx2x_main.c b/drivers/net/bnx2x/bnx2x_main.c
> index c238c4d..b1a84d4 100644
> --- a/drivers/net/bnx2x/bnx2x_main.c
> +++ b/drivers/net/bnx2x/bnx2x_main.c
> @@ -4254,7 +4254,7 @@ static void bnx2x_init_eq_ring(struct bnx2x *bp)
> min_t(int, MAX_SP_DESC_CNT - MAX_SPQ_PENDING, NUM_EQ_DESC) - 1);
> }
>
> -static void bnx2x_init_ind_table(struct bnx2x *bp)
> +void bnx2x_push_indir_table(struct bnx2x *bp)
> {
> int func = BP_FUNC(bp);
> int i;
> @@ -4262,13 +4262,24 @@ static void bnx2x_init_ind_table(struct bnx2x *bp)
> if (bp->multi_mode == ETH_RSS_MODE_DISABLED)
> return;
>
> - DP(NETIF_MSG_IFUP,
> - "Initializing indirection table multi_mode %d\n", bp->multi_mode);
> for (i = 0; i < TSTORM_INDIRECTION_TABLE_SIZE; i++)
> REG_WR8(bp, BAR_TSTRORM_INTMEM +
> TSTORM_INDIRECTION_TABLE_OFFSET(func) + i,
> - bp->fp->cl_id + (i % (bp->num_queues -
> - NONE_ETH_CONTEXT_USE)));
> + bp->fp->cl_id + bp->rx_indir_table[i]);
> +}
> +
> +static void bnx2x_init_indir_table(struct bnx2x *bp)
> +{
> + int i;
> +
> + BUG_ON(ARRAY_SIZE(bp->rx_indir_table) <
> + TSTORM_INDIRECTION_TABLE_SIZE);
> +
> + for (i = 0; i < TSTORM_INDIRECTION_TABLE_SIZE; i++)
> + bp->rx_indir_table[i] =
> + (i % (bp->num_queues - NONE_ETH_CONTEXT_USE));
> +
> + bnx2x_push_indir_table(bp);
> }
>
> void bnx2x_set_storm_rx_mode(struct bnx2x *bp)
> @@ -4496,7 +4507,7 @@ void bnx2x_nic_init(struct bnx2x *bp, u32 load_code)
> bnx2x_init_eq_ring(bp);
> bnx2x_init_internal(bp, load_code);
> bnx2x_pf_init(bp);
> - bnx2x_init_ind_table(bp);
> + bnx2x_init_indir_table(bp);
> bnx2x_stats_init(bp);
>
> /* At this point, we are ready for interrupts */
>
^ permalink raw reply
* Re: [PATCH] bnx2x: Support for managing RX indirection table
From: Vlad Zolotarov @ 2011-02-15 17:39 UTC (permalink / raw)
To: Tom Herbert; +Cc: netdev@vger.kernel.org
In-Reply-To: <alpine.DEB.2.00.1102150815060.27695@pokey.mtv.corp.google.com>
> void bnx2x_set_storm_rx_mode(struct bnx2x *bp)
> @@ -4496,7 +4507,7 @@ void bnx2x_nic_init(struct bnx2x *bp, u32 load_code)
> bnx2x_init_eq_ring(bp);
> bnx2x_init_internal(bp, load_code);
> bnx2x_pf_init(bp);
> - bnx2x_init_ind_table(bp);
> + bnx2x_init_indir_table(bp);
Tom, one more thing: could u, pls., cancel this rename? ;)
thanks,
vlad
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox