* Re: [PATCH net-next-2.6 2/2] 3c59x: Use fine-grained locks for MII and windowed register access
From: Steffen Klassert @ 2010-06-24 14:00 UTC (permalink / raw)
To: Ben Hutchings; +Cc: David Miller, netdev, Chase Douglas, Arne Nordmark
In-Reply-To: <1277384239.26161.162.camel@localhost>
On Thu, Jun 24, 2010 at 01:57:19PM +0100, Ben Hutchings wrote:
> >
> > This adds a lot of calls to spin_lock_irqsave/spin_unlock_irqrestore to many
> > places where this is not necessary at all. For example during device probe and
> > device open, window_read/window_write are called multiple times, each time
> > disabling the interrupts. I'd suggest to have unlocked, locked and irqsave
> > versions of window_read/window_write and use them in appropriate places.
>
> So what? These are not speed-critical. The fast-path functions do
> acquire the lock just once.
>
The point is that we should not disable the interrupts if we don't need to
do so. It is not speed critical for the 3c59x driver but disabling the
interrupts should be avoided whenever possible. For example during device
probe and device open we can't race against an interrupt handler because
the device is not yet running.
An example from vortex_probe1() is:
for (i = 0; i < 6; i++)
window_write8(vp, dev->dev_addr[i], 2, i);
which expands to someting like:
for (i = 0; i < 6; i++) {
unsigned long flags;
spin_lock_irqsave(&vp->window_lock, flags);
window_set(vp, window);
iowrite8(dev->dev_addr[i], vp->ioaddr + i);
spin_unlock_irqrestore(&vp->window_lock, flags);
return ret;
}
which is quite odd in a codepath that could simply do:
for (i = 0; i < 6; i++) {
window_set(vp, window);
iowrite8(dev->dev_addr[i], vp->ioaddr + i);
}
>
> This locked section is now very short - 5 or 6 register read/writes and
> no delays. We might even be able to get away without locking here as
> the only software state this accesses is dev->if_port and I don't think
> it can race with anything except SIOCGIFMAP (which seems harmless).
>
Best would be, if we don't need to disable the interrupts on this cpu
at all. But then we probaply need to disable the interupt line with
disable_irq. That's why I suggested to move the timer to thread context.
Steffen
^ permalink raw reply
* [PATCH] vxge: fix memory leak in vxge_alloc_msix() error path
From: Michal Schmidt @ 2010-06-24 14:13 UTC (permalink / raw)
To: Ramkrishna Vepa; +Cc: netdev
When pci_enable_msix() returned ret<0, entries and vxge_entries were leaked.
While at it, use the centralized exit idiom in the function.
Not tested. It compiles OK.
Signed-off-by: Michal Schmidt <mschmidt@redhat.com>
---
drivers/net/vxge/vxge-main.c | 29 ++++++++++++++++++++---------
1 files changed, 20 insertions(+), 9 deletions(-)
diff --git a/drivers/net/vxge/vxge-main.c b/drivers/net/vxge/vxge-main.c
index 45c5dc2..8b9e73b 100644
--- a/drivers/net/vxge/vxge-main.c
+++ b/drivers/net/vxge/vxge-main.c
@@ -2262,7 +2262,8 @@ start:
vxge_debug_init(VXGE_ERR,
"%s: memory allocation failed",
VXGE_DRIVER_NAME);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto alloc_entries_failed;
}
vdev->vxge_entries =
@@ -2271,8 +2272,8 @@ start:
if (!vdev->vxge_entries) {
vxge_debug_init(VXGE_ERR, "%s: memory allocation failed",
VXGE_DRIVER_NAME);
- kfree(vdev->entries);
- return -ENOMEM;
+ ret = -ENOMEM;
+ goto alloc_vxge_entries_failed;
}
for (i = 0, j = 0; i < vdev->no_of_vpath; i++) {
@@ -2303,22 +2304,32 @@ start:
vxge_debug_init(VXGE_ERR,
"%s: MSI-X enable failed for %d vectors, ret: %d",
VXGE_DRIVER_NAME, vdev->intr_cnt, ret);
+ if ((max_config_vpath != VXGE_USE_DEFAULT) || (ret < 3)) {
+ ret = -ENODEV;
+ goto enable_msix_failed;
+ }
+
kfree(vdev->entries);
kfree(vdev->vxge_entries);
vdev->entries = NULL;
vdev->vxge_entries = NULL;
-
- if ((max_config_vpath != VXGE_USE_DEFAULT) || (ret < 3))
- return -ENODEV;
/* Try with less no of vector by reducing no of vpaths count */
temp = (ret - 1)/2;
vxge_close_vpaths(vdev, temp);
vdev->no_of_vpath = temp;
goto start;
- } else if (ret < 0)
- return -ENODEV;
-
+ } else if (ret < 0) {
+ ret = -ENODEV;
+ goto enable_msix_failed;
+ }
return 0;
+
+enable_msix_failed:
+ kfree(vdev->vxge_entries);
+alloc_vxge_entries_failed:
+ kfree(vdev->entries);
+alloc_entries_failed:
+ return ret;
}
static int vxge_enable_msix(struct vxgedev *vdev)
--
1.7.1
^ permalink raw reply related
* Re: [PATCH net-next-2.6 3/4] macvlan: 64 bit rx counters
From: Patrick McHardy @ 2010-06-24 14:55 UTC (permalink / raw)
To: Eric Dumazet; +Cc: David Miller, netdev
In-Reply-To: <1277376861.2816.284.camel@edumazet-laptop>
Eric Dumazet wrote:
> Use u64_stats_sync infrastructure to implement 64bit stats.
>
>
Looks good to me, thanks, I actually wanted to do this myself yesterday :)
Acked-by: Patrick McHardy <kaber@trash.net>
^ permalink raw reply
* Re: [PATCH net-next-2.6 4/4] vlan: 64 bit rx counters
From: Patrick McHardy @ 2010-06-24 14:57 UTC (permalink / raw)
To: Eric Dumazet; +Cc: David Miller, netdev
In-Reply-To: <1277376906.2816.287.camel@edumazet-laptop>
Eric Dumazet wrote:
> Use u64_stats_sync infrastructure to implement 64bit rx stats.
>
> (tx stats are addressed later)
Acked-by: Patrick McHardy <kaber@trash.net>
^ permalink raw reply
* Re: [PATCH net-next-2.6 5/5] sfc: Record hardware RX hash on each skb where possible
From: Ben Hutchings @ 2010-06-24 15:18 UTC (permalink / raw)
To: David Miller; +Cc: netdev, linux-net-drivers
In-Reply-To: <1277328688.2101.12.camel@achroite.uk.solarflarecom.com>
David,
Unfortunately, this version of the patch can hit a hardware bug that
results in bogus hashes. Let me know whether you've applied it, and
I'll send an incremental or a replacement patch.
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 net-next-2.6] netfilter: allow nf_tproxy_core module to be removed
From: Patrick McHardy @ 2010-06-24 15:29 UTC (permalink / raw)
To: David Miller; +Cc: fw, jpirko, netdev, Balazs Scheidler, KOVACS Krisztian
In-Reply-To: <20100623.115558.189705237.davem@davemloft.net>
David Miller wrote:
> From: Florian Westphal <fw@strlen.de>
> Date: Wed, 23 Jun 2010 20:46:11 +0200
>
>
>> tproxy assigns skb->destructor, what prevents module unload while such skbs may
>> still be around?
>>
>
> The only reference to nf_tproxy_core.ko is for the symbol, "nf_tproxy_assign_sock".
> xt_TPROXY.c, which references this symbol, thus creates a symbol dependency on this
> module, so xt_TPROXY.o needs to unload before nf_tproxy_core.ko can unload, and
> xt_TPROXY.o has it's own manner for handling module references properly.
>
I don't see anything waiting for skbs in flight using the tproxy
destructor in either xt_TPROXY or nf_tproxy_core though, so I think
Florian is correct.
^ permalink raw reply
* [RFC net-next-2.6] snmp: ipstats_mib becomes u64 for all arches
From: Eric Dumazet @ 2010-06-24 16:47 UTC (permalink / raw)
To: David Miller; +Cc: netdev
David,
I will respin this patch after net-next-2.6 tree stabilizes a bit.
(It needs u64_stats_fetch_begin_bh() and u64_stats_fetch_retry_bh(), and
probably the SNMP fix I sent earlier, currently in net-2.6 only)
Thanks
[RFC net-next-2.6] snmp: ipstats_mib becomes u64 for all arches
/proc/net/snmp and /proc/net/netstat expose SNMP counters.
Width of these counters is either 32 or 64 bits, depending on the size
of "unsigned long" in kernel.
This means user program parsing these files must already be prepared to
deal with 64bit values, regardless of user program being 32 or 64 bit.
This patch introduces 64bit snmp values for IPSTAT mib, where some
counters can wrap pretty fast if they are 32bit wide.
This uses u64_stats_sync infrastructure.
Signed-off-by: Eric Dumazet <eric.dumazet@gmail.com>
---
include/net/ip.h | 20 ++++++--
include/net/ipv6.h | 12 ++---
include/net/snmp.h | 98 ++++++++++++++++++++++++++++++++++++++----
net/ipv4/af_inet.c | 33 ++++++++++++++
net/ipv4/proc.c | 12 ++---
net/ipv6/addrconf.c | 18 +++++++
net/ipv6/proc.c | 13 ++++-
7 files changed, 176 insertions(+), 30 deletions(-)
diff --git a/include/net/ip.h b/include/net/ip.h
index 3b524df..890f972 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -165,12 +165,12 @@ struct ipv4_config {
};
extern struct ipv4_config ipv4_config;
-#define IP_INC_STATS(net, field) SNMP_INC_STATS((net)->mib.ip_statistics, field)
-#define IP_INC_STATS_BH(net, field) SNMP_INC_STATS_BH((net)->mib.ip_statistics, field)
-#define IP_ADD_STATS(net, field, val) SNMP_ADD_STATS((net)->mib.ip_statistics, field, val)
-#define IP_ADD_STATS_BH(net, field, val) SNMP_ADD_STATS_BH((net)->mib.ip_statistics, field, val)
-#define IP_UPD_PO_STATS(net, field, val) SNMP_UPD_PO_STATS((net)->mib.ip_statistics, field, val)
-#define IP_UPD_PO_STATS_BH(net, field, val) SNMP_UPD_PO_STATS_BH((net)->mib.ip_statistics, field, val)
+#define IP_INC_STATS(net, field) SNMP_INC_STATS64((net)->mib.ip_statistics, field)
+#define IP_INC_STATS_BH(net, field) SNMP_INC_STATS64_BH((net)->mib.ip_statistics, field)
+#define IP_ADD_STATS(net, field, val) SNMP_ADD_STATS64((net)->mib.ip_statistics, field, val)
+#define IP_ADD_STATS_BH(net, field, val) SNMP_ADD_STATS64_BH((net)->mib.ip_statistics, field, val)
+#define IP_UPD_PO_STATS(net, field, val) SNMP_UPD_PO_STATS64((net)->mib.ip_statistics, field, val)
+#define IP_UPD_PO_STATS_BH(net, field, val) SNMP_UPD_PO_STATS64_BH((net)->mib.ip_statistics, field, val)
#define NET_INC_STATS(net, field) SNMP_INC_STATS((net)->mib.net_statistics, field)
#define NET_INC_STATS_BH(net, field) SNMP_INC_STATS_BH((net)->mib.net_statistics, field)
#define NET_INC_STATS_USER(net, field) SNMP_INC_STATS_USER((net)->mib.net_statistics, field)
@@ -178,6 +178,14 @@ extern struct ipv4_config ipv4_config;
#define NET_ADD_STATS_USER(net, field, adnd) SNMP_ADD_STATS_USER((net)->mib.net_statistics, field, adnd)
extern unsigned long snmp_fold_field(void __percpu *mib[], int offt);
+#if BITS_PER_LONG==32
+extern u64 snmp_fold_field64(void __percpu *mib[], int offt, size_t sync_off);
+#else
+static inline u64 snmp_fold_field64(void __percpu *mib[], int offt, size_t syncp_off)
+{
+ return snmp_fold_field(mib, offt);
+}
+#endif
extern int snmp_mib_init(void __percpu *ptr[2], size_t mibsize, size_t align);
extern void snmp_mib_free(void __percpu *ptr[2]);
diff --git a/include/net/ipv6.h b/include/net/ipv6.h
index f5808d5..1f84124 100644
--- a/include/net/ipv6.h
+++ b/include/net/ipv6.h
@@ -136,17 +136,17 @@ extern struct ctl_path net_ipv6_ctl_path[];
/* MIBs */
#define IP6_INC_STATS(net, idev,field) \
- _DEVINC(net, ipv6, , idev, field)
+ _DEVINC(net, ipv6, 64, idev, field)
#define IP6_INC_STATS_BH(net, idev,field) \
- _DEVINC(net, ipv6, _BH, idev, field)
+ _DEVINC(net, ipv6, 64_BH, idev, field)
#define IP6_ADD_STATS(net, idev,field,val) \
- _DEVADD(net, ipv6, , idev, field, val)
+ _DEVADD(net, ipv6, 64, idev, field, val)
#define IP6_ADD_STATS_BH(net, idev,field,val) \
- _DEVADD(net, ipv6, _BH, idev, field, val)
+ _DEVADD(net, ipv6, 64_BH, idev, field, val)
#define IP6_UPD_PO_STATS(net, idev,field,val) \
- _DEVUPD(net, ipv6, , idev, field, val)
+ _DEVUPD(net, ipv6, 64, idev, field, val)
#define IP6_UPD_PO_STATS_BH(net, idev,field,val) \
- _DEVUPD(net, ipv6, _BH, idev, field, val)
+ _DEVUPD(net, ipv6, 64_BH, idev, field, val)
#define ICMP6_INC_STATS(net, idev, field) \
_DEVINC(net, icmpv6, , idev, field)
#define ICMP6_INC_STATS_BH(net, idev, field) \
diff --git a/include/net/snmp.h b/include/net/snmp.h
index 92456f1..af7e9dc 100644
--- a/include/net/snmp.h
+++ b/include/net/snmp.h
@@ -47,15 +47,15 @@ struct snmp_mib {
}
/*
- * We use all unsigned longs. Linux will soon be so reliable that even
- * these will rapidly get too small 8-). Seriously consider the IpInReceives
- * count on the 20Gb/s + networks people expect in a few years time!
+ * We use unsigned longs for most mibs but u64 for ipstats.
*/
+#include <linux/u64_stats_sync.h>
/* IPstats */
#define IPSTATS_MIB_MAX __IPSTATS_MIB_MAX
struct ipstats_mib {
- unsigned long mibs[IPSTATS_MIB_MAX];
+ u64 mibs[IPSTATS_MIB_MAX];
+ struct u64_stats_sync syncp;
};
/* ICMP */
@@ -122,19 +122,31 @@ struct linux_xfrm_mib {
#define SNMP_STAT_USRPTR(name) (name[1])
#define SNMP_INC_STATS_BH(mib, field) \
- __this_cpu_inc(mib[0]->mibs[field])
+ do { \
+ BUILD_BUG_ON(sizeof(mib[0]->mibs[field]) > sizeof(long)); \
+ __this_cpu_inc(mib[0]->mibs[field]); \
+ } while (0)
#define SNMP_INC_STATS_USER(mib, field) \
- this_cpu_inc(mib[1]->mibs[field])
+ do { \
+ BUILD_BUG_ON(sizeof(mib[1]->mibs[field]) > sizeof(long)); \
+ this_cpu_inc(mib[1]->mibs[field]); \
+ } while (0)
#define SNMP_INC_STATS(mib, field) \
- this_cpu_inc(mib[!in_softirq()]->mibs[field])
+ do { \
+ BUILD_BUG_ON(sizeof(mib[0]->mibs[field]) > sizeof(long)); \
+ this_cpu_inc(mib[!in_softirq()]->mibs[field]); \
+ } while (0)
#define SNMP_DEC_STATS(mib, field) \
- this_cpu_dec(mib[!in_softirq()]->mibs[field])
+ do { \
+ BUILD_BUG_ON(sizeof(mib[0]->mibs[field]) > sizeof(long)); \
+ this_cpu_dec(mib[!in_softirq()]->mibs[field]); \
+ } while (0)
#define SNMP_ADD_STATS_BH(mib, field, addend) \
__this_cpu_add(mib[0]->mibs[field], addend)
#define SNMP_ADD_STATS_USER(mib, field, addend) \
this_cpu_add(mib[1]->mibs[field], addend)
#define SNMP_ADD_STATS(mib, field, addend) \
- this_cpu_add(mib[0]->mibs[field], addend)
+ this_cpu_add(mib[!in_softirq()]->mibs[field], addend)
/*
* Use "__typeof__(*mib[0]) *ptr" instead of "__typeof__(mib[0]) ptr"
* to make @ptr a non-percpu pointer.
@@ -144,6 +156,7 @@ struct linux_xfrm_mib {
__typeof__(*mib[0]) *ptr; \
preempt_disable(); \
ptr = this_cpu_ptr((mib)[!in_softirq()]); \
+ BUILD_BUG_ON(sizeof(mib[0]->mibs[0]) > sizeof(long)); \
ptr->mibs[basefield##PKTS]++; \
ptr->mibs[basefield##OCTETS] += addend;\
preempt_enable(); \
@@ -152,7 +165,74 @@ struct linux_xfrm_mib {
do { \
__typeof__(*mib[0]) *ptr = \
__this_cpu_ptr((mib)[!in_softirq()]); \
+ BUILD_BUG_ON(sizeof(mib[0]->mibs[0]) > sizeof(long)); \
ptr->mibs[basefield##PKTS]++; \
ptr->mibs[basefield##OCTETS] += addend;\
} while (0)
+
+
+#if BITS_PER_LONG==32
+
+#define SNMP_ADD_STATS64_BH(mib, field, addend) \
+ do { \
+ __typeof__(*mib[0]) *ptr = __this_cpu_ptr((mib)[0]); \
+ u64_stats_update_begin(&ptr->syncp); \
+ ptr->mibs[field] += addend; \
+ u64_stats_update_end(&ptr->syncp); \
+ } while (0)
+#define SNMP_ADD_STATS64_USER(mib, field, addend) \
+ do { \
+ __typeof__(*mib[0]) *ptr; \
+ preempt_disable(); \
+ ptr = __this_cpu_ptr((mib)[1]); \
+ u64_stats_update_begin(&ptr->syncp); \
+ ptr->mibs[field] += addend; \
+ u64_stats_update_end(&ptr->syncp); \
+ preempt_enable(); \
+ } while (0)
+#define SNMP_ADD_STATS64(mib, field, addend) \
+ do { \
+ __typeof__(*mib[0]) *ptr; \
+ preempt_disable(); \
+ ptr = __this_cpu_ptr((mib)[!in_softirq()]); \
+ u64_stats_update_begin(&ptr->syncp); \
+ ptr->mibs[field] += addend; \
+ u64_stats_update_end(&ptr->syncp); \
+ preempt_enable(); \
+ } while (0)
+#define SNMP_INC_STATS64_BH(mib, field) SNMP_ADD_STATS64_BH(mib, field, 1)
+#define SNMP_INC_STATS64_USER(mib, field) SNMP_ADD_STATS64_USER(mib, field, 1)
+#define SNMP_INC_STATS64(mib, field) SNMP_ADD_STATS64(mib, field, 1)
+#define SNMP_UPD_PO_STATS64(mib, basefield, addend) \
+ do { \
+ __typeof__(*mib[0]) *ptr; \
+ preempt_disable(); \
+ ptr = __this_cpu_ptr((mib)[!in_softirq()]); \
+ u64_stats_update_begin(&ptr->syncp); \
+ ptr->mibs[basefield##PKTS]++; \
+ ptr->mibs[basefield##OCTETS] += addend; \
+ u64_stats_update_end(&ptr->syncp); \
+ preempt_enable(); \
+ } while (0)
+#define SNMP_UPD_PO_STATS64_BH(mib, basefield, addend) \
+ do { \
+ __typeof__(*mib[0]) *ptr; \
+ ptr = __this_cpu_ptr((mib)[!in_softirq()]); \
+ u64_stats_update_begin(&ptr->syncp); \
+ ptr->mibs[basefield##PKTS]++; \
+ ptr->mibs[basefield##OCTETS] += addend; \
+ u64_stats_update_end(&ptr->syncp); \
+ } while (0)
+#else
+#define SNMP_INC_STATS64_BH(mib, field) SNMP_INC_STATS_BH(mib, field)
+#define SNMP_INC_STATS64_USER(mib, field) SNMP_INC_STATS_USER(mib, field)
+#define SNMP_INC_STATS64(mib, field) SNMP_INC_STATS(mib, field)
+#define SNMP_DEC_STATS64(mib, field) SNMP_DEC_STATS(mib, field)
+#define SNMP_ADD_STATS64_BH(mib, field, addend) SNMP_ADD_STATS_BH(mib, field, addend)
+#define SNMP_ADD_STATS64_USER(mib, field, addend) SNMP_ADD_STATS_USER(mib, field, addend)
+#define SNMP_ADD_STATS64(mib, field, addend) SNMP_ADD_STATS(mib, field, addend)
+#define SNMP_UPD_PO_STATS64(mib, basefield, addend) SNMP_UPD_PO_STATS(mib, basefield, addend)
+#define SNMP_UPD_PO_STATS64_BH(mib, basefield, addend) SNMP_UPD_PO_STATS_BH(mib, basefield, addend)
+#endif
+
#endif
diff --git a/net/ipv4/af_inet.c b/net/ipv4/af_inet.c
index 640db9b..aeb178e 100644
--- a/net/ipv4/af_inet.c
+++ b/net/ipv4/af_inet.c
@@ -1427,6 +1427,39 @@ unsigned long snmp_fold_field(void __percpu *mib[], int offt)
}
EXPORT_SYMBOL_GPL(snmp_fold_field);
+#if BITS_PER_LONG==32
+
+u64 snmp_fold_field64(void __percpu *mib[], int offt, size_t syncp_offset)
+{
+ u64 res = 0;
+ int i;
+
+ for_each_possible_cpu(i) {
+ struct u64_stats_sync *syncp;
+ u64 v0, v1;
+ unsigned int start;
+
+ /* first mib used by softirq context */
+ syncp = (struct u64_stats_sync *)(per_cpu_ptr(mib[0], i) + syncp_offset);
+ do {
+ start = u64_stats_fetch_begin_bh(syncp);
+ v0 = *(((u64 *) per_cpu_ptr(mib[0], i)) + offt);
+ } while (u64_stats_fetch_retry_bh(syncp, start));
+
+ /* second mib used in USER context */
+ syncp = (struct u64_stats_sync *)(per_cpu_ptr(mib[1], i) + syncp_offset);
+ do {
+ start = u64_stats_fetch_begin(syncp);
+ v1 = *(((u64 *) per_cpu_ptr(mib[1], i)) + offt);
+ } while (u64_stats_fetch_retry(syncp, start));
+
+ res += v0 + v1;
+ }
+ return res;
+}
+EXPORT_SYMBOL_GPL(snmp_fold_field64);
+#endif
+
int snmp_mib_init(void __percpu *ptr[2], size_t mibsize, size_t align)
{
BUG_ON(ptr == NULL);
diff --git a/net/ipv4/proc.c b/net/ipv4/proc.c
index e320ca6..d41cf26 100644
--- a/net/ipv4/proc.c
+++ b/net/ipv4/proc.c
@@ -344,9 +344,9 @@ static int snmp_seq_show(struct seq_file *seq, void *v)
sysctl_ip_default_ttl);
for (i = 0; snmp4_ipstats_list[i].name != NULL; i++)
- seq_printf(seq, " %lu",
- snmp_fold_field((void __percpu **)net->mib.ip_statistics,
- snmp4_ipstats_list[i].entry));
+ seq_printf(seq, " %llu",
+ snmp_fold_field64((void __percpu **)net->mib.ip_statistics,
+ snmp4_ipstats_list[i].entry, offsetof(struct ipstats_mib, syncp)));
icmp_put(seq); /* RFC 2011 compatibility */
icmpmsg_put(seq);
@@ -432,9 +432,9 @@ static int netstat_seq_show(struct seq_file *seq, void *v)
seq_puts(seq, "\nIpExt:");
for (i = 0; snmp4_ipextstats_list[i].name != NULL; i++)
- seq_printf(seq, " %lu",
- snmp_fold_field((void __percpu **)net->mib.ip_statistics,
- snmp4_ipextstats_list[i].entry));
+ seq_printf(seq, " %llu",
+ snmp_fold_field64((void __percpu **)net->mib.ip_statistics,
+ snmp4_ipextstats_list[i].entry, offsetof(struct ipstats_mib, syncp)));
seq_putc(seq, '\n');
return 0;
diff --git a/net/ipv6/addrconf.c b/net/ipv6/addrconf.c
index c20a7c2..56165ae 100644
--- a/net/ipv6/addrconf.c
+++ b/net/ipv6/addrconf.c
@@ -3858,12 +3858,28 @@ static inline void __snmp6_fill_stats(u64 *stats, void __percpu **mib,
memset(&stats[items], 0, pad);
}
+static inline void __snmp6_fill_stats64(u64 *stats, void __percpu **mib,
+ int items, int bytes, size_t syncpoff)
+{
+ int i;
+ int pad = bytes - sizeof(u64) * items;
+ BUG_ON(pad < 0);
+
+ /* Use put_unaligned() because stats may not be aligned for u64. */
+ put_unaligned(items, &stats[0]);
+ for (i = 1; i < items; i++)
+ put_unaligned(snmp_fold_field64(mib, i, syncpoff), &stats[i]);
+
+ memset(&stats[items], 0, pad);
+}
+
static void snmp6_fill_stats(u64 *stats, struct inet6_dev *idev, int attrtype,
int bytes)
{
switch (attrtype) {
case IFLA_INET6_STATS:
- __snmp6_fill_stats(stats, (void __percpu **)idev->stats.ipv6, IPSTATS_MIB_MAX, bytes);
+ __snmp6_fill_stats64(stats, (void __percpu **)idev->stats.ipv6,
+ IPSTATS_MIB_MAX, bytes, offsetof(struct ipstats_mib, syncp));
break;
case IFLA_INET6_ICMP6STATS:
__snmp6_fill_stats(stats, (void __percpu **)idev->stats.icmpv6, ICMP6_MIB_MAX, bytes);
diff --git a/net/ipv6/proc.c b/net/ipv6/proc.c
index 566798d..acc1960 100644
--- a/net/ipv6/proc.c
+++ b/net/ipv6/proc.c
@@ -179,12 +179,21 @@ static void snmp6_seq_show_item(struct seq_file *seq, void __percpu **mib,
snmp_fold_field(mib, itemlist[i].entry));
}
+static void snmp6_seq_show_item64(struct seq_file *seq, void __percpu **mib,
+ const struct snmp_mib *itemlist, size_t syncpoff)
+{
+ int i;
+ for (i=0; itemlist[i].name; i++)
+ seq_printf(seq, "%-32s\t%llu\n", itemlist[i].name,
+ snmp_fold_field64(mib, itemlist[i].entry, syncpoff));
+}
+
static int snmp6_seq_show(struct seq_file *seq, void *v)
{
struct net *net = (struct net *)seq->private;
- snmp6_seq_show_item(seq, (void __percpu **)net->mib.ipv6_statistics,
- snmp6_ipstats_list);
+ snmp6_seq_show_item64(seq, (void __percpu **)net->mib.ipv6_statistics,
+ snmp6_ipstats_list, offsetof(struct ipstats_mib, syncp));
snmp6_seq_show_item(seq, (void __percpu **)net->mib.icmpv6_statistics,
snmp6_icmp6_list);
snmp6_seq_show_icmpv6msg(seq,
^ permalink raw reply related
* Re: [PATCH 0/3] b43: logging cleanups
From: John W. Linville @ 2010-06-24 18:53 UTC (permalink / raw)
To: Joe Perches
Cc: Stefano Brivio, linux-wireless, netdev, linux-kernel,
Larry.Finger, mb, zajec5
In-Reply-To: <cover.1276988387.git.joe@perches.com>
On Sat, Jun 19, 2010 at 04:30:08PM -0700, Joe Perches wrote:
> Just some small cleanups
>
> Joe Perches (3):
> drivers/net/wireless/b43: Use local ratelimit_state
> drivers/net/wireless/b43: Logging cleanups
> drivers/net/wireless/b43: Rename b43_debug to b43_debugging
Any of the b43 guys want to express an opinion on these?
--
John W. Linville Someday the world will need a hero, and you
linville@tuxdriver.com might be all we have. Be ready.
^ permalink raw reply
* Re: [PATCH] vlan_dev: VLAN 0 should be treated as "no vlan tag" (802.1p packet)
From: Pedro Garcia Pelaez @ 2010-06-24 18:28 UTC (permalink / raw)
To: Pedro Garcia; +Cc: netdev, Patrick McHardy, Ben Hutchings, Eric Dumazet
In-Reply-To: <311b59aee7d648c6124a84b5ca06ac60@dondevamos.com>
On Wed, 16 Jun 2010 10:49:27 +0200, Pedro Garcia
<pedro.netdev@dondevamos.com> wrote:
> On Mon, 14 Jun 2010 21:12:52 +0200, Eric Dumazet
<eric.dumazet@gmail.com>
> wrote:
>> Le lundi 14 juin 2010 à 19:11 +0200, Patrick McHardy a écrit :
>>> Ben Hutchings wrote:
>>> > On Mon, 2010-06-14 at 18:49 +0200, Pedro Garcia wrote:
>>> >
>>> >> On Sun, 13 Jun 2010 22:56:30 +0100, Ben Hutchings
>>> >> <bhutchings@solarflare.com> wrote:
>>> >>
>>> >>> I have no particular opinion on this change, but you need to read
>>> >>> and
>>> >>> follow Documentation/SubmittingPatches.
>>> >>>
>>> >>> Ben.
>>> >>>
>>> >> Sorry, first kernel patch, and I did not know about it. I resubmit
>>> >> with
>>> >> the correct style / format:
>>> >>
>>> > [...]
>>> >
>>> > Sorry, no you haven't.
>>> >
>>> > - Networking changes go through David Miller's net-next-2.6 tree so
>>> > you
>>> > need to use that as the baseline, not 2.6.26
>>> > - Patches should be applicable with -p1, not -p0 (so if you use
diff,
>>> > you should run it from one directory level up)
>>> > - The patch was word-wrapped
>>>
>>> Additionally:
>>>
>>> - please use the proper comment style, meaning each line begins
>>> with a '*'
>>>
>>> - the pr_debug statements may be useful for debugging, but are
>>> a bit excessive for the final version
>>>
>>> - + /* 2010-06-13: Pedro Garcia
>>>
>>> We have changelogs for this, simply explaining what the code
>>> does is enough.
>>>
>>> - Please CC the maintainer (which is me)
>>> --
>>
>> Pedro, we have two kind of vlan setups :
>>
>> accelerated and non accelerated ones.
>>
>> Your patch address non accelated ones only, since you only touch
>> vlan_skb_recv()
>>
>> Accelerated vlan can follow these paths :
>>
>> 1) NAPI devices
>>
>> vlan_gro_receive() -> vlan_gro_common()
>>
>> 2) non NAPI devices
>>
>> __vlan_hwaccel_rx()
>>
>> So you might also patch __vlan_hwaccel_rx() and vlan_gro_common()
>>
>> Please merge following bits to your patch submission :
>>
>> http://kerneltrap.org/mailarchive/linux-netdev/2010/5/23/6277868
>>
>>
>> Good luck for your first patch !
>
> Here it is again. I added the modifications in
> http://kerneltrap.org/mailarchive/linux-netdev/2010/5/23/6277868 for HW
> accelerated incoming packets (it did not apply cleanly on the last
version
> of
> the kernel, so I applied manually). Now, if the VLAN 0 is not explicitly
> created by the user, VLAN 0 packets will be treated as no VLAN (802.1p
> packets), instead of dropping them.
>
> The patch is now for two files: vlan_core (accel) and vlan_dev (non
accel)
>
> I can not test on HW accelerated devices, so if someone can check it I
> will appreciate (even though in the thread above it looked like yes).
For
> non accel I tessted in 2.6.26. Now the patch is for
> net-next-2.6, and it compiles OK, but I a have to setup a test
environment
> to check it is still OK (should, but better to test).
>
I tested the pacth under net-next-2.6, and it OOPSed the kernel (worked
under 2.6.26 but not under 2.6.35). I have found why and solved it, but
now, to my surprise, it only works when I leave the interface in
promiscuous mode.
After a lot of debugging, looks like the skb does not even arrive to
__netif_receive_skb, unless in promiscuous mode. Under what circunstances
could this happen?
Pedro
^ permalink raw reply
* [PATCH 2/2] netdev: mdio-octeon: Fix section mismatch errors.
From: David Daney @ 2010-06-24 19:14 UTC (permalink / raw)
To: netdev; +Cc: linux-mips, David Daney
In-Reply-To: <1277406888-26309-1-git-send-email-ddaney@caviumnetworks.com>
We started getting:
WARNING: vmlinux.o(.data+0x20bd0): Section mismatch in reference from
the variable octeon_mdiobus_driver to the function
.init.text:octeon_mdiobus_probe()
This fixes it.
Signed-off-by: David Daney <ddaney@caviumnetworks.com>
---
drivers/net/phy/mdio-octeon.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/phy/mdio-octeon.c b/drivers/net/phy/mdio-octeon.c
index f443d43..bd12ba9 100644
--- a/drivers/net/phy/mdio-octeon.c
+++ b/drivers/net/phy/mdio-octeon.c
@@ -85,7 +85,7 @@ static int octeon_mdiobus_write(struct mii_bus *bus, int phy_id,
return 0;
}
-static int __init octeon_mdiobus_probe(struct platform_device *pdev)
+static int __devinit octeon_mdiobus_probe(struct platform_device *pdev)
{
struct octeon_mdiobus *bus;
union cvmx_smix_en smi_en;
@@ -143,7 +143,7 @@ err:
return err;
}
-static int __exit octeon_mdiobus_remove(struct platform_device *pdev)
+static int __devexit octeon_mdiobus_remove(struct platform_device *pdev)
{
struct octeon_mdiobus *bus;
union cvmx_smix_en smi_en;
@@ -163,7 +163,7 @@ static struct platform_driver octeon_mdiobus_driver = {
.owner = THIS_MODULE,
},
.probe = octeon_mdiobus_probe,
- .remove = __exit_p(octeon_mdiobus_remove),
+ .remove = __devexit_p(octeon_mdiobus_remove),
};
void octeon_mdiobus_force_mod_depencency(void)
--
1.6.6.1
^ permalink raw reply related
* [PATCH 1/2] netdev: octeon_mgmt: Fix section mismatch errors.
From: David Daney @ 2010-06-24 19:14 UTC (permalink / raw)
To: netdev; +Cc: linux-mips, David Daney
In-Reply-To: <1277406888-26309-1-git-send-email-ddaney@caviumnetworks.com>
We started getting:
WARNING: drivers/net/built-in.o(.data+0x10f0): Section mismatch in
reference from the variable octeon_mgmt_driver to the function
.init.text:octeon_mgmt_probe()
This fixes it.
Signed-off-by: David Daney <ddaney@caviumnetworks.com>
---
drivers/net/octeon/octeon_mgmt.c | 6 +++---
1 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/drivers/net/octeon/octeon_mgmt.c b/drivers/net/octeon/octeon_mgmt.c
index 000e792..f4a0f08 100644
--- a/drivers/net/octeon/octeon_mgmt.c
+++ b/drivers/net/octeon/octeon_mgmt.c
@@ -1067,7 +1067,7 @@ static const struct net_device_ops octeon_mgmt_ops = {
#endif
};
-static int __init octeon_mgmt_probe(struct platform_device *pdev)
+static int __devinit octeon_mgmt_probe(struct platform_device *pdev)
{
struct resource *res_irq;
struct net_device *netdev;
@@ -1124,7 +1124,7 @@ err:
return -ENOENT;
}
-static int __exit octeon_mgmt_remove(struct platform_device *pdev)
+static int __devexit octeon_mgmt_remove(struct platform_device *pdev)
{
struct net_device *netdev = dev_get_drvdata(&pdev->dev);
@@ -1139,7 +1139,7 @@ static struct platform_driver octeon_mgmt_driver = {
.owner = THIS_MODULE,
},
.probe = octeon_mgmt_probe,
- .remove = __exit_p(octeon_mgmt_remove),
+ .remove = __devexit_p(octeon_mgmt_remove),
};
extern void octeon_mdiobus_force_mod_depencency(void);
--
1.6.6.1
^ permalink raw reply related
* [PATCH 0/2] Fix some section mismatch errors for Octeon network drivers
From: David Daney @ 2010-06-24 19:14 UTC (permalink / raw)
To: netdev; +Cc: linux-mips, David Daney
It seems the kernel build system is becoming more rigorous in its
checking of section mismatches. Please consider these two patches to
correct the problems.
The warnings were not seen under 2.6.34, so one could argue that these
are fixing a regression (although admittedly it a minor one).
David Daney (2):
netdev: octeon_mgmt: Fix section mismatch errors.
netdev: mdio-octeon: Fix section mismatch errors.
drivers/net/octeon/octeon_mgmt.c | 6 +++---
drivers/net/phy/mdio-octeon.c | 6 +++---
2 files changed, 6 insertions(+), 6 deletions(-)
^ permalink raw reply
* Re: [RFC PATCH v2 1/5] irq: add tracepoint to softirq_raise
From: Steven Rostedt @ 2010-06-24 19:15 UTC (permalink / raw)
To: Koki Sanagi
Cc: netdev, davem, scott.a.mcmillan, kaneshige.kenji, izumi.taku,
linux-kernel
In-Reply-To: <4C23145B.30805@jp.fujitsu.com>
Hi Koki,
Your subject says 1/5 but I do not see any other patches.
On Thu, 2010-06-24 at 17:16 +0900, Koki Sanagi wrote:
> This patch adds a tracepoint to raising of softirq.
> This is useful if you want to detect which hard interrupt raise softirq
> and lets you know a time between raising softirq and performing softirq.
> Combinating with other tracepoint, it lets us know a process of packets
> (See patch 0/5).
>
> <idle>-0 [001] 241229.957184: softirq_raise: vec=3 [action=NET_RX]
> <idle>-0 [000] 241229.993399: softirq_raise: vec=1 [action=TIMER]
> <idle>-0 [000] 241229.993400: softirq_raise: vec=9 [action=RCU]
>
> This is a same patch Lai Jiangshan submitted.
> http://marc.info/?l=linux-kernel&m=126026122728732&w=2
>
> Signed-off-by: Koki Sanagi <sanagi.koki@jp.fujitsu.com>
> ---
> include/linux/interrupt.h | 8 +++++++-
> include/trace/events/irq.h | 34 +++++++++++++++++++++++++++++++---
> 2 files changed, 38 insertions(+), 4 deletions(-)
>
> diff --git a/include/linux/interrupt.h b/include/linux/interrupt.h
> index c233113..1cb5726 100644
> --- a/include/linux/interrupt.h
> +++ b/include/linux/interrupt.h
> @@ -18,6 +18,7 @@
> #include <asm/atomic.h>
> #include <asm/ptrace.h>
> #include <asm/system.h>
> +#include <trace/events/irq.h>
>
> /*
> * These correspond to the IORESOURCE_IRQ_* defines in
> @@ -402,7 +403,12 @@ asmlinkage void do_softirq(void);
> asmlinkage void __do_softirq(void);
> extern void open_softirq(int nr, void (*action)(struct softirq_action *));
> extern void softirq_init(void);
> -#define __raise_softirq_irqoff(nr) do { or_softirq_pending(1UL << (nr)); } while (0)
> +static inline void __raise_softirq_irqoff(unsigned int nr)
> +{
> + trace_softirq_raise(nr);
> + or_softirq_pending(1UL << nr);
> +}
> +
> extern void raise_softirq_irqoff(unsigned int nr);
> extern void raise_softirq(unsigned int nr);
> extern void wakeup_softirqd(void);
> diff --git a/include/trace/events/irq.h b/include/trace/events/irq.h
> index 0e4cfb6..7cb7435 100644
> --- a/include/trace/events/irq.h
> +++ b/include/trace/events/irq.h
> @@ -5,7 +5,9 @@
> #define _TRACE_IRQ_H
>
> #include <linux/tracepoint.h>
> -#include <linux/interrupt.h>
> +
> +struct irqaction;
> +struct softirq_action;
>
> #define softirq_name(sirq) { sirq##_SOFTIRQ, #sirq }
> #define show_softirq_name(val) \
> @@ -82,6 +84,32 @@ TRACE_EVENT(irq_handler_exit,
> __entry->irq, __entry->ret ? "handled" : "unhandled")
> );
>
> +/**
> + * softirq_raise - called immediately when a softirq is raised
> + * @nr: softirq vector number
> + *
> + * Tracepoint for tracing when softirq action is raised.
> + * Also, when used in combination with the softirq_entry tracepoint
> + * we can determine the softirq raise latency.
> + */
> +TRACE_EVENT(softirq_raise,
> +
> + TP_PROTO(unsigned int nr),
> +
> + TP_ARGS(nr),
> +
> + TP_STRUCT__entry(
> + __field( unsigned int, vec )
> + ),
> +
> + TP_fast_assign(
> + __entry->vec = nr;
> + ),
> +
> + TP_printk("vec=%d [action=%s]", __entry->vec,
> + show_softirq_name(__entry->vec))
Hmm, is there a way to reuse a DECLARE_EVENT_CLASS here?
> +);
> +
> DECLARE_EVENT_CLASS(softirq,
>
> TP_PROTO(struct softirq_action *h, struct softirq_action *vec),
> @@ -89,11 +117,11 @@ DECLARE_EVENT_CLASS(softirq,
> TP_ARGS(h, vec),
>
> TP_STRUCT__entry(
> - __field( int, vec )
> + __field( unsigned int, vec )
> ),
>
> TP_fast_assign(
> - __entry->vec = (int)(h - vec);
> + __entry->vec = (unsigned int)(h - vec);
Just curious, did you see the original as a bug?
-- Steve
> ),
>
> TP_printk("vec=%d [action=%s]", __entry->vec,
^ permalink raw reply
* Re: [PATCH 0/3] b43: logging cleanups
From: Larry Finger @ 2010-06-24 19:20 UTC (permalink / raw)
To: John W. Linville
Cc: Joe Perches, Stefano Brivio,
linux-wireless-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, mb-fseUSCV1ubazQB+pC5nmwQ,
zajec5-Re5JQEeQqe8AvxtiuMwx3w
In-Reply-To: <20100624185339.GC2368-2XuSBdqkA4R54TAoqtyWWQ@public.gmane.org>
On 06/24/2010 01:53 PM, John W. Linville wrote:
> On Sat, Jun 19, 2010 at 04:30:08PM -0700, Joe Perches wrote:
>> Just some small cleanups
>>
>> Joe Perches (3):
>> drivers/net/wireless/b43: Use local ratelimit_state
>> drivers/net/wireless/b43: Logging cleanups
>> drivers/net/wireless/b43: Rename b43_debug to b43_debugging
>
> Any of the b43 guys want to express an opinion on these?
The local ratelimit patch is OK. My personal opinion is that the others
are just churning the source for no real reason, but I have no major
objections.
Larry
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH 0/3] b43: logging cleanups
From: Joe Perches @ 2010-06-24 19:40 UTC (permalink / raw)
To: John W. Linville
Cc: Stefano Brivio, linux-wireless, netdev, linux-kernel,
Larry.Finger, mb, zajec5
In-Reply-To: <20100624185339.GC2368@tuxdriver.com>
On Thu, 2010-06-24 at 14:53 -0400, John W. Linville wrote:
> On Sat, Jun 19, 2010 at 04:30:08PM -0700, Joe Perches wrote:
> > Just some small cleanups
> > Joe Perches (3):
> > drivers/net/wireless/b43: Use local ratelimit_state
> > drivers/net/wireless/b43: Logging cleanups
> > drivers/net/wireless/b43: Rename b43_debug to b43_debugging
> Any of the b43 guys want to express an opinion on these?
Stefano, are you active here?
Your last ack for b43 was Feb 2008.
There have been 400+ commits to b43 without your ack.
Should your name be moved from MAINTAINERS to CREDITS?
$ ./scripts/get_maintainer.pl --rolestats -f drivers/net/wireless/b43/
Stefano Brivio <stefano.brivio@polimi.it> (maintainer:B43 WIRELESS DRIVER)
"John W. Linville" <linville@tuxdriver.com> (maintainer:NETWORKING [WIREL...,commit_signer:204/240=85%)
"Rafał Miłecki" <zajec5@gmail.com> (commit_signer:83/240=35%)
"Gábor Stefanik" <netrolller.3d@gmail.com> (commit_signer:44/240=18%)
Michael Buesch <mb@bu3sch.de> (commit_signer:39/240=16%)
Larry Finger <Larry.Finger@lwfinger.net> (commit_signer:13/240=5%)
linux-wireless@vger.kernel.org (open list:B43 WIRELESS DRIVER)
netdev@vger.kernel.org (open list:NETWORKING DRIVERS)
linux-kernel@vger.kernel.org (open list)
^ permalink raw reply
* Re: [PATCH 0/3] b43: logging cleanups
From: Larry Finger @ 2010-06-24 19:56 UTC (permalink / raw)
To: Joe Perches
Cc: John W. Linville, Stefano Brivio, linux-wireless, netdev,
linux-kernel, mb, zajec5
In-Reply-To: <1277408432.1654.80.camel@Joe-Laptop.home>
On 06/24/2010 02:40 PM, Joe Perches wrote:
> On Thu, 2010-06-24 at 14:53 -0400, John W. Linville wrote:
>> On Sat, Jun 19, 2010 at 04:30:08PM -0700, Joe Perches wrote:
>>> Just some small cleanups
>>> Joe Perches (3):
>>> drivers/net/wireless/b43: Use local ratelimit_state
>>> drivers/net/wireless/b43: Logging cleanups
>>> drivers/net/wireless/b43: Rename b43_debug to b43_debugging
>> Any of the b43 guys want to express an opinion on these?
>
> Stefano, are you active here?
> Your last ack for b43 was Feb 2008.
> There have been 400+ commits to b43 without your ack.
>
> Should your name be moved from MAINTAINERS to CREDITS?
>
> $ ./scripts/get_maintainer.pl --rolestats -f drivers/net/wireless/b43/
> Stefano Brivio <stefano.brivio@polimi.it> (maintainer:B43 WIRELESS DRIVER)
> "John W. Linville" <linville@tuxdriver.com> (maintainer:NETWORKING [WIREL...,commit_signer:204/240=85%)
> "Rafał Miłecki" <zajec5@gmail.com> (commit_signer:83/240=35%)
> "Gábor Stefanik" <netrolller.3d@gmail.com> (commit_signer:44/240=18%)
> Michael Buesch <mb@bu3sch.de> (commit_signer:39/240=16%)
> Larry Finger <Larry.Finger@lwfinger.net> (commit_signer:13/240=5%)
> linux-wireless@vger.kernel.org (open list:B43 WIRELESS DRIVER)
> netdev@vger.kernel.org (open list:NETWORKING DRIVERS)
> linux-kernel@vger.kernel.org (open list)
The primary arbitrator for patches to the subtle parts of b43 is Michael
Buesch; however, he is no longer an official MAINTAINER. I can ACK some
things; however, any changes that are associated with my reverse
engineering of the Broadcom drivers are off limits.
Larry
^ permalink raw reply
* [net-next-2.6 PATCH 0/10] enic: updates to version 1.4.1.1
From: Vasanthy Kolluri @ 2010-06-24 20:49 UTC (permalink / raw)
To: davem; +Cc: netdev, scofeldm, vkolluri, roprabhu
The following patch series implements enic driver updates:
01/10 - Feature Add: Replace LRO with GRO
02/10 - Bug Fix: Change hardware ingress vlan rewrite mode
03/10 - Use a lighter reset operation for enic devices
04/10 - Clean up: Add wrapper routines for firmware devcmd calls
05/10 - Use (netdev|dev|pr)_<level> macro helpers for logging
06/10 - Add new firmware devcmds
07/10 - Use receive queue buffer blocks of 32/64 entries
08/10 - Feature Add: Add loopback capability to enic devices
09/10 - Bug Fix: Handle surprise hardware removals
10/10 - Clean ups
Signed-off-by: Scott Feldman <scofeldm@cisco.com>
Signed-off-by: Vasanthy Kolluri <vkolluri@cisco.com>
Signed-off-by: Roopa Prabhu <roprabhu@cisco.com>
^ permalink raw reply
* [net-next-2.6 PATCH 01/10] enic: Feature Add: Replace LRO with GRO
From: Vasanthy Kolluri @ 2010-06-24 20:49 UTC (permalink / raw)
To: davem; +Cc: netdev, scofeldm, vkolluri, roprabhu
In-Reply-To: <20100624204723.22595.42990.stgit@savbu-pc100.cisco.com>
From: Vasanthy Kolluri <vkolluri@cisco.com>
enic now uses the GRO mechanism instead of LRO to pass skbs to upper
layers.
Signed-off-by: Scott Feldman <scofeldm@cisco.com>
Signed-off-by: Vasanthy Kolluri <vkolluri@cisco.com>
Signed-off-by: Roopa Prabhu <roprabhu@cisco.com>
---
drivers/net/Kconfig | 1 -
drivers/net/enic/enic.h | 9 +----
drivers/net/enic/enic_main.c | 79 ++++--------------------------------------
3 files changed, 9 insertions(+), 80 deletions(-)
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index fe113d0..a0182a2 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -2615,7 +2615,6 @@ config EHEA
config ENIC
tristate "Cisco VIC Ethernet NIC Support"
depends on PCI && INET
- select INET_LRO
help
This enables the support for the Cisco VIC Ethernet card.
diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h
index 45e86d1..81c2ade 100644
--- a/drivers/net/enic/enic.h
+++ b/drivers/net/enic/enic.h
@@ -20,8 +20,6 @@
#ifndef _ENIC_H_
#define _ENIC_H_
-#include <linux/inet_lro.h>
-
#include "vnic_enet.h"
#include "vnic_dev.h"
#include "vnic_wq.h"
@@ -34,13 +32,10 @@
#define DRV_NAME "enic"
#define DRV_DESCRIPTION "Cisco VIC Ethernet NIC Driver"
-#define DRV_VERSION "1.3.1.1-pp"
+#define DRV_VERSION "1.4.1.1"
#define DRV_COPYRIGHT "Copyright 2008-2009 Cisco Systems, Inc"
#define PFX DRV_NAME ": "
-#define ENIC_LRO_MAX_DESC 8
-#define ENIC_LRO_MAX_AGGR 64
-
#define ENIC_BARS_MAX 6
#define ENIC_WQ_MAX 8
@@ -124,8 +119,6 @@ struct enic {
u64 rq_truncated_pkts;
u64 rq_bad_fcs;
struct napi_struct napi;
- struct net_lro_mgr lro_mgr;
- struct net_lro_desc lro_desc[ENIC_LRO_MAX_DESC];
/* interrupt resource cache line section */
____cacheline_aligned struct vnic_intr intr[ENIC_INTR_MAX];
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index bc7d6b9..c2b848f 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -1287,51 +1287,6 @@ static int enic_set_rq_alloc_buf(struct enic *enic)
return 0;
}
-static int enic_get_skb_header(struct sk_buff *skb, void **iphdr,
- void **tcph, u64 *hdr_flags, void *priv)
-{
- struct cq_enet_rq_desc *cq_desc = priv;
- unsigned int ip_len;
- struct iphdr *iph;
-
- u8 type, color, eop, sop, ingress_port, vlan_stripped;
- u8 fcoe, fcoe_sof, fcoe_fc_crc_ok, fcoe_enc_error, fcoe_eof;
- u8 tcp_udp_csum_ok, udp, tcp, ipv4_csum_ok;
- u8 ipv6, ipv4, ipv4_fragment, fcs_ok, rss_type, csum_not_calc;
- u8 packet_error;
- u16 q_number, completed_index, bytes_written, vlan, checksum;
- u32 rss_hash;
-
- cq_enet_rq_desc_dec(cq_desc,
- &type, &color, &q_number, &completed_index,
- &ingress_port, &fcoe, &eop, &sop, &rss_type,
- &csum_not_calc, &rss_hash, &bytes_written,
- &packet_error, &vlan_stripped, &vlan, &checksum,
- &fcoe_sof, &fcoe_fc_crc_ok, &fcoe_enc_error,
- &fcoe_eof, &tcp_udp_csum_ok, &udp, &tcp,
- &ipv4_csum_ok, &ipv6, &ipv4, &ipv4_fragment,
- &fcs_ok);
-
- if (!(ipv4 && tcp && !ipv4_fragment))
- return -1;
-
- skb_reset_network_header(skb);
- iph = ip_hdr(skb);
-
- ip_len = ip_hdrlen(skb);
- skb_set_transport_header(skb, ip_len);
-
- /* check if ip header and tcp header are complete */
- if (ntohs(iph->tot_len) < ip_len + tcp_hdrlen(skb))
- return -1;
-
- *hdr_flags = LRO_IPV4 | LRO_TCP;
- *tcph = tcp_hdr(skb);
- *iphdr = iph;
-
- return 0;
-}
-
static void enic_rq_indicate_buf(struct vnic_rq *rq,
struct cq_desc *cq_desc, struct vnic_rq_buf *buf,
int skipped, void *opaque)
@@ -1397,18 +1352,17 @@ static void enic_rq_indicate_buf(struct vnic_rq *rq,
if (enic->vlan_group && vlan_stripped) {
- if ((netdev->features & NETIF_F_LRO) && ipv4)
- lro_vlan_hwaccel_receive_skb(&enic->lro_mgr,
- skb, enic->vlan_group,
- vlan, cq_desc);
+ if (netdev->features & NETIF_F_GRO)
+ vlan_gro_receive(&enic->napi, enic->vlan_group,
+ vlan, skb);
else
vlan_hwaccel_receive_skb(skb,
enic->vlan_group, vlan);
} else {
- if ((netdev->features & NETIF_F_LRO) && ipv4)
- lro_receive_skb(&enic->lro_mgr, skb, cq_desc);
+ if (netdev->features & NETIF_F_GRO)
+ napi_gro_receive(&enic->napi, skb);
else
netif_receive_skb(skb);
@@ -1438,7 +1392,6 @@ static int enic_rq_service(struct vnic_dev *vdev, struct cq_desc *cq_desc,
static int enic_poll(struct napi_struct *napi, int budget)
{
struct enic *enic = container_of(napi, struct enic, napi);
- struct net_device *netdev = enic->netdev;
unsigned int rq_work_to_do = budget;
unsigned int wq_work_to_do = -1; /* no limit */
unsigned int work_done, rq_work_done, wq_work_done;
@@ -1478,12 +1431,9 @@ static int enic_poll(struct napi_struct *napi, int budget)
if (rq_work_done < rq_work_to_do) {
/* Some work done, but not enough to stay in polling,
- * flush all LROs and exit polling
+ * exit polling
*/
- if (netdev->features & NETIF_F_LRO)
- lro_flush_all(&enic->lro_mgr);
-
napi_complete(napi);
vnic_intr_unmask(&enic->intr[ENIC_INTX_WQ_RQ]);
}
@@ -1494,7 +1444,6 @@ static int enic_poll(struct napi_struct *napi, int budget)
static int enic_poll_msix(struct napi_struct *napi, int budget)
{
struct enic *enic = container_of(napi, struct enic, napi);
- struct net_device *netdev = enic->netdev;
unsigned int work_to_do = budget;
unsigned int work_done;
int err;
@@ -1528,12 +1477,9 @@ static int enic_poll_msix(struct napi_struct *napi, int budget)
if (work_done < work_to_do) {
/* Some work done, but not enough to stay in polling,
- * flush all LROs and exit polling
+ * exit polling
*/
- if (netdev->features & NETIF_F_LRO)
- lro_flush_all(&enic->lro_mgr);
-
napi_complete(napi);
vnic_intr_unmask(&enic->intr[ENIC_MSIX_RQ]);
}
@@ -2378,21 +2324,12 @@ static int __devinit enic_probe(struct pci_dev *pdev,
netdev->features |= NETIF_F_TSO |
NETIF_F_TSO6 | NETIF_F_TSO_ECN;
if (ENIC_SETTING(enic, LRO))
- netdev->features |= NETIF_F_LRO;
+ netdev->features |= NETIF_F_GRO;
if (using_dac)
netdev->features |= NETIF_F_HIGHDMA;
enic->csum_rx_enabled = ENIC_SETTING(enic, RXCSUM);
- enic->lro_mgr.max_aggr = ENIC_LRO_MAX_AGGR;
- enic->lro_mgr.max_desc = ENIC_LRO_MAX_DESC;
- enic->lro_mgr.lro_arr = enic->lro_desc;
- enic->lro_mgr.get_skb_header = enic_get_skb_header;
- enic->lro_mgr.features = LRO_F_NAPI | LRO_F_EXTRACT_VLAN_ID;
- enic->lro_mgr.dev = netdev;
- enic->lro_mgr.ip_summed = CHECKSUM_COMPLETE;
- enic->lro_mgr.ip_summed_aggr = CHECKSUM_UNNECESSARY;
-
err = register_netdev(netdev);
if (err) {
printk(KERN_ERR PFX
^ permalink raw reply related
* [net-next-2.6 PATCH 02/10] enic: Bug Fix: Change hardware ingress vlan rewrite mode
From: Vasanthy Kolluri @ 2010-06-24 20:49 UTC (permalink / raw)
To: davem; +Cc: netdev, scofeldm, vkolluri, roprabhu
In-Reply-To: <20100624204723.22595.42990.stgit@savbu-pc100.cisco.com>
From: Vasanthy Kolluri <vkolluri@cisco.com>
The current ingress vlan rewrite mode setting lets the hardware strip off
the tag control information of a packet received on native vlan. As a
result, the priority bits are also lost. The fix is to change the ingress
vlan rewrite mode setting such that the complete tag control information is
retained for packets that belong to native vlan.
Signed-off-by: Scott Feldman <scofeldm@cisco.com>
Signed-off-by: Vasanthy Kolluri <vkolluri@cisco.com>
Signed-off-by: Roopa Prabhu <roprabhu@cisco.com>
---
drivers/net/enic/cq_enet_desc.h | 16 ++++++++++++++--
drivers/net/enic/enic_main.c | 31 ++++++++++++++++++++++++++-----
drivers/net/enic/vnic_dev.c | 14 ++++++++++++++
drivers/net/enic/vnic_dev.h | 2 ++
drivers/net/enic/vnic_devcmd.h | 12 ++++++++++++
5 files changed, 68 insertions(+), 7 deletions(-)
diff --git a/drivers/net/enic/cq_enet_desc.h b/drivers/net/enic/cq_enet_desc.h
index 337d194..f2d98bb 100644
--- a/drivers/net/enic/cq_enet_desc.h
+++ b/drivers/net/enic/cq_enet_desc.h
@@ -73,6 +73,15 @@ struct cq_enet_rq_desc {
#define CQ_ENET_RQ_DESC_FLAGS_TRUNCATED (0x1 << 14)
#define CQ_ENET_RQ_DESC_FLAGS_VLAN_STRIPPED (0x1 << 15)
+#define CQ_ENET_RQ_DESC_VLAN_TCI_VLAN_BITS 12
+#define CQ_ENET_RQ_DESC_VLAN_TCI_VLAN_MASK \
+ ((1 << CQ_ENET_RQ_DESC_VLAN_TCI_VLAN_BITS) - 1)
+#define CQ_ENET_RQ_DESC_VLAN_TCI_CFI_MASK (0x1 << 12)
+#define CQ_ENET_RQ_DESC_VLAN_TCI_USER_PRIO_BITS 3
+#define CQ_ENET_RQ_DESC_VLAN_TCI_USER_PRIO_MASK \
+ ((1 << CQ_ENET_RQ_DESC_VLAN_TCI_USER_PRIO_BITS) - 1)
+#define CQ_ENET_RQ_DESC_VLAN_TCI_USER_PRIO_SHIFT 13
+
#define CQ_ENET_RQ_DESC_FCOE_SOF_BITS 4
#define CQ_ENET_RQ_DESC_FCOE_SOF_MASK \
((1 << CQ_ENET_RQ_DESC_FCOE_SOF_BITS) - 1)
@@ -96,7 +105,7 @@ static inline void cq_enet_rq_desc_dec(struct cq_enet_rq_desc *desc,
u8 *type, u8 *color, u16 *q_number, u16 *completed_index,
u8 *ingress_port, u8 *fcoe, u8 *eop, u8 *sop, u8 *rss_type,
u8 *csum_not_calc, u32 *rss_hash, u16 *bytes_written, u8 *packet_error,
- u8 *vlan_stripped, u16 *vlan, u16 *checksum, u8 *fcoe_sof,
+ u8 *vlan_stripped, u16 *vlan_tci, u16 *checksum, u8 *fcoe_sof,
u8 *fcoe_fc_crc_ok, u8 *fcoe_enc_error, u8 *fcoe_eof,
u8 *tcp_udp_csum_ok, u8 *udp, u8 *tcp, u8 *ipv4_csum_ok,
u8 *ipv6, u8 *ipv4, u8 *ipv4_fragment, u8 *fcs_ok)
@@ -136,7 +145,10 @@ static inline void cq_enet_rq_desc_dec(struct cq_enet_rq_desc *desc,
*vlan_stripped = (bytes_written_flags &
CQ_ENET_RQ_DESC_FLAGS_VLAN_STRIPPED) ? 1 : 0;
- *vlan = le16_to_cpu(desc->vlan);
+ /*
+ * Tag Control Information(16) = user_priority(3) + cfi(1) + vlan(12)
+ */
+ *vlan_tci = le16_to_cpu(desc->vlan);
if (*fcoe) {
*fcoe_sof = (u8)(le16_to_cpu(desc->checksum_fcoe) &
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index c2b848f..7f98af1 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -1300,7 +1300,7 @@ static void enic_rq_indicate_buf(struct vnic_rq *rq,
u8 tcp_udp_csum_ok, udp, tcp, ipv4_csum_ok;
u8 ipv6, ipv4, ipv4_fragment, fcs_ok, rss_type, csum_not_calc;
u8 packet_error;
- u16 q_number, completed_index, bytes_written, vlan, checksum;
+ u16 q_number, completed_index, bytes_written, vlan_tci, checksum;
u32 rss_hash;
if (skipped)
@@ -1315,7 +1315,7 @@ static void enic_rq_indicate_buf(struct vnic_rq *rq,
&type, &color, &q_number, &completed_index,
&ingress_port, &fcoe, &eop, &sop, &rss_type,
&csum_not_calc, &rss_hash, &bytes_written,
- &packet_error, &vlan_stripped, &vlan, &checksum,
+ &packet_error, &vlan_stripped, &vlan_tci, &checksum,
&fcoe_sof, &fcoe_fc_crc_ok, &fcoe_enc_error,
&fcoe_eof, &tcp_udp_csum_ok, &udp, &tcp,
&ipv4_csum_ok, &ipv6, &ipv4, &ipv4_fragment,
@@ -1350,14 +1350,15 @@ static void enic_rq_indicate_buf(struct vnic_rq *rq,
skb->dev = netdev;
- if (enic->vlan_group && vlan_stripped) {
+ if (enic->vlan_group && vlan_stripped &&
+ (vlan_tci & CQ_ENET_RQ_DESC_VLAN_TCI_VLAN_MASK)) {
if (netdev->features & NETIF_F_GRO)
vlan_gro_receive(&enic->napi, enic->vlan_group,
- vlan, skb);
+ vlan_tci, skb);
else
vlan_hwaccel_receive_skb(skb,
- enic->vlan_group, vlan);
+ enic->vlan_group, vlan_tci);
} else {
@@ -1879,6 +1880,18 @@ static int enic_set_niccfg(struct enic *enic)
ig_vlan_strip_en);
}
+int enic_dev_set_ig_vlan_rewrite_mode(struct enic *enic)
+{
+ int err;
+
+ spin_lock(&enic->devcmd_lock);
+ err = vnic_dev_set_ig_vlan_rewrite_mode(enic->vdev,
+ IG_VLAN_REWRITE_MODE_PRIORITY_TAG_DEFAULT_VLAN);
+ spin_unlock(&enic->devcmd_lock);
+
+ return err;
+}
+
static void enic_reset(struct work_struct *work)
{
struct enic *enic = container_of(work, struct enic, reset);
@@ -1898,6 +1911,7 @@ static void enic_reset(struct work_struct *work)
enic_reset_mcaddrs(enic);
enic_init_vnic_resources(enic);
enic_set_niccfg(enic);
+ enic_dev_set_ig_vlan_rewrite_mode(enic);
enic_open(enic->netdev);
rtnl_unlock();
@@ -2110,6 +2124,13 @@ int enic_dev_init(struct enic *enic)
goto err_out_free_vnic_resources;
}
+ err = enic_dev_set_ig_vlan_rewrite_mode(enic);
+ if (err) {
+ printk(KERN_ERR PFX
+ "Failed to set ingress vlan rewrite mode, aborting.\n");
+ goto err_out_free_vnic_resources;
+ }
+
switch (vnic_dev_get_intr_mode(enic->vdev)) {
default:
netif_napi_add(netdev, &enic->napi, enic_poll, 64);
diff --git a/drivers/net/enic/vnic_dev.c b/drivers/net/enic/vnic_dev.c
index e0d3328..e3742fa 100644
--- a/drivers/net/enic/vnic_dev.c
+++ b/drivers/net/enic/vnic_dev.c
@@ -564,6 +564,20 @@ int vnic_dev_del_addr(struct vnic_dev *vdev, u8 *addr)
return err;
}
+int vnic_dev_set_ig_vlan_rewrite_mode(struct vnic_dev *vdev,
+ u8 ig_vlan_rewrite_mode)
+{
+ u64 a0 = ig_vlan_rewrite_mode, a1 = 0;
+ int wait = 1000;
+ int err;
+
+ err = vnic_dev_cmd(vdev, CMD_IG_VLAN_REWRITE_MODE, &a0, &a1, wait);
+ if (err == ERR_ECMDUNKNOWN)
+ return 0;
+
+ return err;
+}
+
int vnic_dev_raise_intr(struct vnic_dev *vdev, u16 intr)
{
u64 a0 = intr, a1 = 0;
diff --git a/drivers/net/enic/vnic_dev.h b/drivers/net/enic/vnic_dev.h
index caccce3..780c3cd 100644
--- a/drivers/net/enic/vnic_dev.h
+++ b/drivers/net/enic/vnic_dev.h
@@ -133,6 +133,8 @@ void vnic_dev_set_intr_mode(struct vnic_dev *vdev,
enum vnic_dev_intr_mode intr_mode);
enum vnic_dev_intr_mode vnic_dev_get_intr_mode(struct vnic_dev *vdev);
void vnic_dev_unregister(struct vnic_dev *vdev);
+int vnic_dev_set_ig_vlan_rewrite_mode(struct vnic_dev *vdev,
+ u8 ig_vlan_rewrite_mode);
struct vnic_dev *vnic_dev_register(struct vnic_dev *vdev,
void *priv, struct pci_dev *pdev, struct vnic_dev_bar *bar,
unsigned int num_bars);
diff --git a/drivers/net/enic/vnic_devcmd.h b/drivers/net/enic/vnic_devcmd.h
index d78bbcc..c5ff4ff 100644
--- a/drivers/net/enic/vnic_devcmd.h
+++ b/drivers/net/enic/vnic_devcmd.h
@@ -211,6 +211,12 @@ enum vnic_devcmd_cmd {
* in: (u16)a0=interrupt number to assert
*/
CMD_IAR = _CMDCNW(_CMD_DIR_WRITE, _CMD_VTYPE_ALL, 38),
+
+ /*
+ * Set hw ingress packet vlan rewrite mode:
+ * in: (u32)a0=new vlan rewrite mode
+ * out: (u32)a0=old vlan rewrite mode */
+ CMD_IG_VLAN_REWRITE_MODE = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_ENET, 41),
};
/* flags for CMD_OPEN */
@@ -226,6 +232,12 @@ enum vnic_devcmd_cmd {
#define CMD_PFILTER_PROMISCUOUS 0x08
#define CMD_PFILTER_ALL_MULTICAST 0x10
+/* rewrite modes for CMD_IG_VLAN_REWRITE_MODE */
+#define IG_VLAN_REWRITE_MODE_DEFAULT_TRUNK 0
+#define IG_VLAN_REWRITE_MODE_UNTAG_DEFAULT_VLAN 1
+#define IG_VLAN_REWRITE_MODE_PRIORITY_TAG_DEFAULT_VLAN 2
+#define IG_VLAN_REWRITE_MODE_PASS_THRU 3
+
enum vnic_devcmd_status {
STAT_NONE = 0,
STAT_BUSY = 1 << 0, /* cmd in progress */
^ permalink raw reply related
* [net-next-2.6 PATCH 03/10] enic: Use a lighter reset operation for enic devices
From: Vasanthy Kolluri @ 2010-06-24 20:50 UTC (permalink / raw)
To: davem; +Cc: netdev, scofeldm, vkolluri, roprabhu
In-Reply-To: <20100624204723.22595.42990.stgit@savbu-pc100.cisco.com>
From: Vasanthy Kolluri <vkolluri@cisco.com>
The port profile information for a dynamic enic device is set by the upper
layers, that are oblivious to the device reset operation. We do not want a
reset operation erase the network state of a dynamic enic device as there
is no way to set up the port profile information again. Hence a lighter
reset operation called hang reset is used. Hang reset, unlike soft reset
does not reset the network state and resets the host side state only.
Signed-off-by: Scott Feldman <scofeldm@cisco.com>
Signed-off-by: Vasanthy Kolluri <vkolluri@cisco.com>
Signed-off-by: Roopa Prabhu <roprabhu@cisco.com>
---
drivers/net/enic/enic_main.c | 16 ++++++++--------
drivers/net/enic/vnic_dev.c | 38 ++++++++++++++++++++++++++++++++++++++
drivers/net/enic/vnic_dev.h | 2 ++
drivers/net/enic/vnic_devcmd.h | 7 +++++++
4 files changed, 55 insertions(+), 8 deletions(-)
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index 7f98af1..d7434b7 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -812,9 +812,10 @@ static struct net_device_stats *enic_get_stats(struct net_device *netdev)
return net_stats;
}
-static void enic_reset_mcaddrs(struct enic *enic)
+static void enic_reset_multicast_list(struct enic *enic)
{
enic->mc_count = 0;
+ enic->flags = 0;
}
static int enic_set_mac_addr(struct net_device *netdev, char *addr)
@@ -1847,15 +1848,15 @@ static int enic_dev_open(struct enic *enic)
return err;
}
-static int enic_dev_soft_reset(struct enic *enic)
+static int enic_dev_hang_reset(struct enic *enic)
{
int err;
- err = enic_dev_wait(enic->vdev, vnic_dev_soft_reset,
- vnic_dev_soft_reset_done, 0);
+ err = enic_dev_wait(enic->vdev, vnic_dev_hang_reset,
+ vnic_dev_hang_reset_done, 0);
if (err)
printk(KERN_ERR PFX
- "vNIC soft reset failed, err %d.\n", err);
+ "vNIC hang reset failed, err %d.\n", err);
return err;
}
@@ -1906,9 +1907,8 @@ static void enic_reset(struct work_struct *work)
spin_unlock(&enic->devcmd_lock);
enic_stop(enic->netdev);
- enic_dev_soft_reset(enic);
- vnic_dev_init(enic->vdev, 0);
- enic_reset_mcaddrs(enic);
+ enic_dev_hang_reset(enic);
+ enic_reset_multicast_list(enic);
enic_init_vnic_resources(enic);
enic_set_niccfg(enic);
enic_dev_set_ig_vlan_rewrite_mode(enic);
diff --git a/drivers/net/enic/vnic_dev.c b/drivers/net/enic/vnic_dev.c
index e3742fa..c93012f 100644
--- a/drivers/net/enic/vnic_dev.c
+++ b/drivers/net/enic/vnic_dev.c
@@ -486,6 +486,44 @@ int vnic_dev_soft_reset_done(struct vnic_dev *vdev, int *done)
return 0;
}
+int vnic_dev_hang_reset(struct vnic_dev *vdev, int arg)
+{
+ u64 a0 = (u32)arg, a1 = 0;
+ int wait = 1000;
+ int err;
+
+ err = vnic_dev_cmd(vdev, CMD_HANG_RESET, &a0, &a1, wait);
+ if (err == ERR_ECMDUNKNOWN) {
+ err = vnic_dev_soft_reset(vdev, arg);
+ if (err)
+ return err;
+
+ return vnic_dev_init(vdev, 0);
+ }
+
+ return err;
+}
+
+int vnic_dev_hang_reset_done(struct vnic_dev *vdev, int *done)
+{
+ u64 a0 = 0, a1 = 0;
+ int wait = 1000;
+ int err;
+
+ *done = 0;
+
+ err = vnic_dev_cmd(vdev, CMD_HANG_RESET_STATUS, &a0, &a1, wait);
+ if (err) {
+ if (err == ERR_ECMDUNKNOWN)
+ return vnic_dev_soft_reset_done(vdev, done);
+ return err;
+ }
+
+ *done = (a0 == 0);
+
+ return 0;
+}
+
int vnic_dev_hang_notify(struct vnic_dev *vdev)
{
u64 a0, a1;
diff --git a/drivers/net/enic/vnic_dev.h b/drivers/net/enic/vnic_dev.h
index 780c3cd..4980615 100644
--- a/drivers/net/enic/vnic_dev.h
+++ b/drivers/net/enic/vnic_dev.h
@@ -129,6 +129,8 @@ int vnic_dev_init_prov(struct vnic_dev *vdev, u8 *buf, u32 len);
int vnic_dev_deinit(struct vnic_dev *vdev);
int vnic_dev_soft_reset(struct vnic_dev *vdev, int arg);
int vnic_dev_soft_reset_done(struct vnic_dev *vdev, int *done);
+int vnic_dev_hang_reset(struct vnic_dev *vdev, int arg);
+int vnic_dev_hang_reset_done(struct vnic_dev *vdev, int *done);
void vnic_dev_set_intr_mode(struct vnic_dev *vdev,
enum vnic_dev_intr_mode intr_mode);
enum vnic_dev_intr_mode vnic_dev_get_intr_mode(struct vnic_dev *vdev);
diff --git a/drivers/net/enic/vnic_devcmd.h b/drivers/net/enic/vnic_devcmd.h
index c5ff4ff..1c4fb35 100644
--- a/drivers/net/enic/vnic_devcmd.h
+++ b/drivers/net/enic/vnic_devcmd.h
@@ -212,6 +212,13 @@ enum vnic_devcmd_cmd {
*/
CMD_IAR = _CMDCNW(_CMD_DIR_WRITE, _CMD_VTYPE_ALL, 38),
+ /* initiate hangreset, like softreset after hang detected */
+ CMD_HANG_RESET = _CMDC(_CMD_DIR_NONE, _CMD_VTYPE_ALL, 39),
+
+ /* hangreset status:
+ * out: a0=0 reset complete, a0=1 reset in progress */
+ CMD_HANG_RESET_STATUS = _CMDC(_CMD_DIR_READ, _CMD_VTYPE_ALL, 40),
+
/*
* Set hw ingress packet vlan rewrite mode:
* in: (u32)a0=new vlan rewrite mode
^ permalink raw reply related
* [net-next-2.6 PATCH 04/10] enic: Clean up: Add wrapper routines for firmware devcmd calls
From: Vasanthy Kolluri @ 2010-06-24 20:50 UTC (permalink / raw)
To: davem; +Cc: netdev, scofeldm, vkolluri, roprabhu
In-Reply-To: <20100624204723.22595.42990.stgit@savbu-pc100.cisco.com>
From: Vasanthy Kolluri <vkolluri@cisco.com>
Add wrapper routines that issue devcmds to firmware and ensure that a
devcmd lock is held for each devcmd call.
Signed-off-by: Scott Feldman <scofeldm@cisco.com>
Signed-off-by: Vasanthy Kolluri <vkolluri@cisco.com>
Signed-off-by: Roopa Prabhu <roprabhu@cisco.com>
---
drivers/net/enic/enic_main.c | 226 ++++++++++++++++++++++++++++++++----------
drivers/net/enic/enic_res.c | 23 +---
drivers/net/enic/enic_res.h | 6 -
drivers/net/enic/vnic_dev.c | 23 +++-
drivers/net/enic/vnic_dev.h | 7 +
5 files changed, 201 insertions(+), 84 deletions(-)
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index d7434b7..9e05805 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -145,15 +145,25 @@ static int enic_get_settings(struct net_device *netdev,
return 0;
}
+static int enic_dev_fw_info(struct enic *enic,
+ struct vnic_devcmd_fw_info **fw_info)
+{
+ int err;
+
+ spin_lock(&enic->devcmd_lock);
+ err = vnic_dev_fw_info(enic->vdev, fw_info);
+ spin_unlock(&enic->devcmd_lock);
+
+ return err;
+}
+
static void enic_get_drvinfo(struct net_device *netdev,
struct ethtool_drvinfo *drvinfo)
{
struct enic *enic = netdev_priv(netdev);
struct vnic_devcmd_fw_info *fw_info;
- spin_lock(&enic->devcmd_lock);
- vnic_dev_fw_info(enic->vdev, &fw_info);
- spin_unlock(&enic->devcmd_lock);
+ enic_dev_fw_info(enic, &fw_info);
strncpy(drvinfo->driver, DRV_NAME, sizeof(drvinfo->driver));
strncpy(drvinfo->version, DRV_VERSION, sizeof(drvinfo->version));
@@ -191,6 +201,17 @@ static int enic_get_sset_count(struct net_device *netdev, int sset)
}
}
+static int enic_dev_stats_dump(struct enic *enic, struct vnic_stats **vstats)
+{
+ int err;
+
+ spin_lock(&enic->devcmd_lock);
+ err = vnic_dev_stats_dump(enic->vdev, vstats);
+ spin_unlock(&enic->devcmd_lock);
+
+ return err;
+}
+
static void enic_get_ethtool_stats(struct net_device *netdev,
struct ethtool_stats *stats, u64 *data)
{
@@ -198,9 +219,7 @@ static void enic_get_ethtool_stats(struct net_device *netdev,
struct vnic_stats *vstats;
unsigned int i;
- spin_lock(&enic->devcmd_lock);
- vnic_dev_stats_dump(enic->vdev, &vstats);
- spin_unlock(&enic->devcmd_lock);
+ enic_dev_stats_dump(enic, &vstats);
for (i = 0; i < enic_n_tx_stats; i++)
*(data++) = ((u64 *)&vstats->tx)[enic_tx_stats[i].offset];
@@ -411,17 +430,14 @@ static void enic_log_q_error(struct enic *enic)
}
}
-static void enic_link_check(struct enic *enic)
+static void enic_msglvl_check(struct enic *enic)
{
- int link_status = vnic_dev_link_status(enic->vdev);
- int carrier_ok = netif_carrier_ok(enic->netdev);
+ u32 msg_enable = vnic_dev_msg_lvl(enic->vdev);
- if (link_status && !carrier_ok) {
- printk(KERN_INFO PFX "%s: Link UP\n", enic->netdev->name);
- netif_carrier_on(enic->netdev);
- } else if (!link_status && carrier_ok) {
- printk(KERN_INFO PFX "%s: Link DOWN\n", enic->netdev->name);
- netif_carrier_off(enic->netdev);
+ if (msg_enable != enic->msg_enable) {
+ printk(KERN_INFO PFX "%s: msg lvl changed from 0x%x to 0x%x\n",
+ enic->netdev->name, enic->msg_enable, msg_enable);
+ enic->msg_enable = msg_enable;
}
}
@@ -439,14 +455,17 @@ static void enic_mtu_check(struct enic *enic)
}
}
-static void enic_msglvl_check(struct enic *enic)
+static void enic_link_check(struct enic *enic)
{
- u32 msg_enable = vnic_dev_msg_lvl(enic->vdev);
+ int link_status = vnic_dev_link_status(enic->vdev);
+ int carrier_ok = netif_carrier_ok(enic->netdev);
- if (msg_enable != enic->msg_enable) {
- printk(KERN_INFO PFX "%s: msg lvl changed from 0x%x to 0x%x\n",
- enic->netdev->name, enic->msg_enable, msg_enable);
- enic->msg_enable = msg_enable;
+ if (link_status && !carrier_ok) {
+ printk(KERN_INFO PFX "%s: Link UP\n", enic->netdev->name);
+ netif_carrier_on(enic->netdev);
+ } else if (!link_status && carrier_ok) {
+ printk(KERN_INFO PFX "%s: Link DOWN\n", enic->netdev->name);
+ netif_carrier_off(enic->netdev);
}
}
@@ -792,9 +811,7 @@ static struct net_device_stats *enic_get_stats(struct net_device *netdev)
struct net_device_stats *net_stats = &netdev->stats;
struct vnic_stats *stats;
- spin_lock(&enic->devcmd_lock);
- vnic_dev_stats_dump(enic->vdev, &stats);
- spin_unlock(&enic->devcmd_lock);
+ enic_dev_stats_dump(enic, &stats);
net_stats->tx_packets = stats->tx.tx_frames_ok;
net_stats->tx_bytes = stats->tx.tx_bytes_ok;
@@ -892,6 +909,41 @@ static int enic_set_mac_address(struct net_device *netdev, void *p)
return -EOPNOTSUPP;
}
+static int enic_dev_packet_filter(struct enic *enic, int directed,
+ int multicast, int broadcast, int promisc, int allmulti)
+{
+ int err;
+
+ spin_lock(&enic->devcmd_lock);
+ err = vnic_dev_packet_filter(enic->vdev, directed,
+ multicast, broadcast, promisc, allmulti);
+ spin_unlock(&enic->devcmd_lock);
+
+ return err;
+}
+
+static int enic_dev_add_multicast_addr(struct enic *enic, u8 *addr)
+{
+ int err;
+
+ spin_lock(&enic->devcmd_lock);
+ err = vnic_dev_add_addr(enic->vdev, addr);
+ spin_unlock(&enic->devcmd_lock);
+
+ return err;
+}
+
+static int enic_dev_del_multicast_addr(struct enic *enic, u8 *addr)
+{
+ int err;
+
+ spin_lock(&enic->devcmd_lock);
+ err = vnic_dev_del_addr(enic->vdev, addr);
+ spin_unlock(&enic->devcmd_lock);
+
+ return err;
+}
+
/* netif_tx_lock held, BHs disabled */
static void enic_set_multicast_list(struct net_device *netdev)
{
@@ -911,11 +963,9 @@ static void enic_set_multicast_list(struct net_device *netdev)
if (mc_count > ENIC_MULTICAST_PERFECT_FILTERS)
mc_count = ENIC_MULTICAST_PERFECT_FILTERS;
- spin_lock(&enic->devcmd_lock);
-
if (enic->flags != flags) {
enic->flags = flags;
- vnic_dev_packet_filter(enic->vdev, directed,
+ enic_dev_packet_filter(enic, directed,
multicast, broadcast, promisc, allmulti);
}
@@ -938,7 +988,7 @@ static void enic_set_multicast_list(struct net_device *netdev)
mc_addr[j]) == 0)
break;
if (j == mc_count)
- enic_del_multicast_addr(enic, enic->mc_addr[i]);
+ enic_dev_del_multicast_addr(enic, enic->mc_addr[i]);
}
for (i = 0; i < mc_count; i++) {
@@ -947,7 +997,7 @@ static void enic_set_multicast_list(struct net_device *netdev)
enic->mc_addr[j]) == 0)
break;
if (j == enic->mc_count)
- enic_add_multicast_addr(enic, mc_addr[i]);
+ enic_dev_add_multicast_addr(enic, mc_addr[i]);
}
/* Save the list to compare against next time
@@ -957,8 +1007,6 @@ static void enic_set_multicast_list(struct net_device *netdev)
memcpy(enic->mc_addr[i], mc_addr[i], ETH_ALEN);
enic->mc_count = mc_count;
-
- spin_unlock(&enic->devcmd_lock);
}
/* rtnl lock is held */
@@ -1264,12 +1312,24 @@ static int enic_rq_alloc_buf_a1(struct vnic_rq *rq)
return 0;
}
+static int enic_dev_hw_version(struct enic *enic,
+ enum vnic_dev_hw_version *hw_ver)
+{
+ int err;
+
+ spin_lock(&enic->devcmd_lock);
+ err = vnic_dev_hw_version(enic->vdev, hw_ver);
+ spin_unlock(&enic->devcmd_lock);
+
+ return err;
+}
+
static int enic_set_rq_alloc_buf(struct enic *enic)
{
enum vnic_dev_hw_version hw_ver;
int err;
- err = vnic_dev_hw_version(enic->vdev, &hw_ver);
+ err = enic_dev_hw_version(enic, &hw_ver);
if (err)
return err;
@@ -1603,7 +1663,7 @@ static void enic_synchronize_irqs(struct enic *enic)
}
}
-static int enic_notify_set(struct enic *enic)
+static int enic_dev_notify_set(struct enic *enic)
{
int err;
@@ -1624,6 +1684,39 @@ static int enic_notify_set(struct enic *enic)
return err;
}
+static int enic_dev_notify_unset(struct enic *enic)
+{
+ int err;
+
+ spin_lock(&enic->devcmd_lock);
+ err = vnic_dev_notify_unset(enic->vdev);
+ spin_unlock(&enic->devcmd_lock);
+
+ return err;
+}
+
+static int enic_dev_enable(struct enic *enic)
+{
+ int err;
+
+ spin_lock(&enic->devcmd_lock);
+ err = vnic_dev_enable(enic->vdev);
+ spin_unlock(&enic->devcmd_lock);
+
+ return err;
+}
+
+static int enic_dev_disable(struct enic *enic)
+{
+ int err;
+
+ spin_lock(&enic->devcmd_lock);
+ err = vnic_dev_disable(enic->vdev);
+ spin_unlock(&enic->devcmd_lock);
+
+ return err;
+}
+
static void enic_notify_timer_start(struct enic *enic)
{
switch (vnic_dev_get_intr_mode(enic->vdev)) {
@@ -1650,7 +1743,7 @@ static int enic_open(struct net_device *netdev)
return err;
}
- err = enic_notify_set(enic);
+ err = enic_dev_notify_set(enic);
if (err) {
printk(KERN_ERR PFX
"%s: Failed to alloc notify buffer, aborting.\n",
@@ -1680,9 +1773,7 @@ static int enic_open(struct net_device *netdev)
netif_wake_queue(netdev);
napi_enable(&enic->napi);
- spin_lock(&enic->devcmd_lock);
- vnic_dev_enable(enic->vdev);
- spin_unlock(&enic->devcmd_lock);
+ enic_dev_enable(enic);
for (i = 0; i < enic->intr_count; i++)
vnic_intr_unmask(&enic->intr[i]);
@@ -1692,9 +1783,7 @@ static int enic_open(struct net_device *netdev)
return 0;
err_out_notify_unset:
- spin_lock(&enic->devcmd_lock);
- vnic_dev_notify_unset(enic->vdev);
- spin_unlock(&enic->devcmd_lock);
+ enic_dev_notify_unset(enic);
err_out_free_intr:
enic_free_intr(enic);
@@ -1715,9 +1804,7 @@ static int enic_stop(struct net_device *netdev)
del_timer_sync(&enic->notify_timer);
- spin_lock(&enic->devcmd_lock);
- vnic_dev_disable(enic->vdev);
- spin_unlock(&enic->devcmd_lock);
+ enic_dev_disable(enic);
napi_disable(&enic->napi);
netif_carrier_off(netdev);
netif_tx_disable(netdev);
@@ -1735,9 +1822,7 @@ static int enic_stop(struct net_device *netdev)
return err;
}
- spin_lock(&enic->devcmd_lock);
- vnic_dev_notify_unset(enic->vdev);
- spin_unlock(&enic->devcmd_lock);
+ enic_dev_notify_unset(enic);
enic_free_intr(enic);
for (i = 0; i < enic->wq_count; i++)
@@ -1870,15 +1955,31 @@ static int enic_set_niccfg(struct enic *enic)
const u8 rss_enable = 0;
const u8 tso_ipid_split_en = 0;
const u8 ig_vlan_strip_en = 1;
+ int err;
/* Enable VLAN tag stripping. RSS not enabled (yet).
*/
- return enic_set_nic_cfg(enic,
+ spin_lock(&enic->devcmd_lock);
+ err = enic_set_nic_cfg(enic,
rss_default_cpu, rss_hash_type,
rss_hash_bits, rss_base_cpu,
rss_enable, tso_ipid_split_en,
ig_vlan_strip_en);
+ spin_unlock(&enic->devcmd_lock);
+
+ return err;
+}
+
+static int enic_dev_hang_notify(struct enic *enic)
+{
+ int err;
+
+ spin_lock(&enic->devcmd_lock);
+ err = vnic_dev_hang_notify(enic->vdev);
+ spin_unlock(&enic->devcmd_lock);
+
+ return err;
}
int enic_dev_set_ig_vlan_rewrite_mode(struct enic *enic)
@@ -1902,10 +2003,7 @@ static void enic_reset(struct work_struct *work)
rtnl_lock();
- spin_lock(&enic->devcmd_lock);
- vnic_dev_hang_notify(enic->vdev);
- spin_unlock(&enic->devcmd_lock);
-
+ enic_dev_hang_notify(enic);
enic_stop(enic->netdev);
enic_dev_hang_reset(enic);
enic_reset_multicast_list(enic);
@@ -2047,8 +2145,8 @@ static const struct net_device_ops enic_netdev_ops = {
.ndo_start_xmit = enic_hard_start_xmit,
.ndo_get_stats = enic_get_stats,
.ndo_validate_addr = eth_validate_addr,
- .ndo_set_multicast_list = enic_set_multicast_list,
.ndo_set_mac_address = enic_set_mac_address,
+ .ndo_set_multicast_list = enic_set_multicast_list,
.ndo_change_mtu = enic_change_mtu,
.ndo_vlan_rx_register = enic_vlan_rx_register,
.ndo_vlan_rx_add_vid = enic_vlan_rx_add_vid,
@@ -2066,6 +2164,17 @@ void enic_dev_deinit(struct enic *enic)
enic_clear_intr_mode(enic);
}
+static int enic_dev_stats_clear(struct enic *enic)
+{
+ int err;
+
+ spin_lock(&enic->devcmd_lock);
+ err = vnic_dev_stats_clear(enic->vdev);
+ spin_unlock(&enic->devcmd_lock);
+
+ return err;
+}
+
int enic_dev_init(struct enic *enic)
{
struct net_device *netdev = enic->netdev;
@@ -2110,6 +2219,10 @@ int enic_dev_init(struct enic *enic)
enic_init_vnic_resources(enic);
+ /* Clear LIF stats
+ */
+ enic_dev_stats_clear(enic);
+
err = enic_set_rq_alloc_buf(enic);
if (err) {
printk(KERN_ERR PFX
@@ -2293,6 +2406,11 @@ static int __devinit enic_probe(struct pci_dev *pdev,
}
}
+ /* Setup devcmd lock
+ */
+
+ spin_lock_init(&enic->devcmd_lock);
+
err = enic_dev_init(enic);
if (err) {
printk(KERN_ERR PFX
@@ -2300,7 +2418,7 @@ static int __devinit enic_probe(struct pci_dev *pdev,
goto err_out_dev_close;
}
- /* Setup notification timer, HW reset task, and locks
+ /* Setup notification timer, HW reset task, and wq locks
*/
init_timer(&enic->notify_timer);
@@ -2312,8 +2430,6 @@ static int __devinit enic_probe(struct pci_dev *pdev,
for (i = 0; i < enic->wq_count; i++)
spin_lock_init(&enic->wq_lock[i]);
- spin_lock_init(&enic->devcmd_lock);
-
/* Register net device
*/
diff --git a/drivers/net/enic/enic_res.c b/drivers/net/enic/enic_res.c
index 9b18840..04cfc4e 100644
--- a/drivers/net/enic/enic_res.c
+++ b/drivers/net/enic/enic_res.c
@@ -103,17 +103,7 @@ int enic_get_vnic_config(struct enic *enic)
return 0;
}
-void enic_add_multicast_addr(struct enic *enic, u8 *addr)
-{
- vnic_dev_add_addr(enic->vdev, addr);
-}
-
-void enic_del_multicast_addr(struct enic *enic, u8 *addr)
-{
- vnic_dev_del_addr(enic->vdev, addr);
-}
-
-void enic_add_vlan(struct enic *enic, u16 vlanid)
+int enic_add_vlan(struct enic *enic, u16 vlanid)
{
u64 a0 = vlanid, a1 = 0;
int wait = 1000;
@@ -122,9 +112,11 @@ void enic_add_vlan(struct enic *enic, u16 vlanid)
err = vnic_dev_cmd(enic->vdev, CMD_VLAN_ADD, &a0, &a1, wait);
if (err)
printk(KERN_ERR PFX "Can't add vlan id, %d\n", err);
+
+ return err;
}
-void enic_del_vlan(struct enic *enic, u16 vlanid)
+int enic_del_vlan(struct enic *enic, u16 vlanid)
{
u64 a0 = vlanid, a1 = 0;
int wait = 1000;
@@ -133,6 +125,8 @@ void enic_del_vlan(struct enic *enic, u16 vlanid)
err = vnic_dev_cmd(enic->vdev, CMD_VLAN_DEL, &a0, &a1, wait);
if (err)
printk(KERN_ERR PFX "Can't delete vlan id, %d\n", err);
+
+ return err;
}
int enic_set_nic_cfg(struct enic *enic, u8 rss_default_cpu, u8 rss_hash_type,
@@ -304,11 +298,6 @@ void enic_init_vnic_resources(struct enic *enic)
enic->config.intr_timer_type,
mask_on_assertion);
}
-
- /* Clear LIF stats
- */
-
- vnic_dev_stats_clear(enic->vdev);
}
int enic_alloc_vnic_resources(struct enic *enic)
diff --git a/drivers/net/enic/enic_res.h b/drivers/net/enic/enic_res.h
index 494664f..3f6e039 100644
--- a/drivers/net/enic/enic_res.h
+++ b/drivers/net/enic/enic_res.h
@@ -131,10 +131,8 @@ static inline void enic_queue_rq_desc(struct vnic_rq *rq,
struct enic;
int enic_get_vnic_config(struct enic *);
-void enic_add_multicast_addr(struct enic *enic, u8 *addr);
-void enic_del_multicast_addr(struct enic *enic, u8 *addr);
-void enic_add_vlan(struct enic *enic, u16 vlanid);
-void enic_del_vlan(struct enic *enic, u16 vlanid);
+int enic_add_vlan(struct enic *enic, u16 vlanid);
+int enic_del_vlan(struct enic *enic, u16 vlanid);
int enic_set_nic_cfg(struct enic *enic, u8 rss_default_cpu, u8 rss_hash_type,
u8 rss_hash_bits, u8 rss_base_cpu, u8 rss_enable, u8 tso_ipid_split_en,
u8 ig_vlan_strip_en);
diff --git a/drivers/net/enic/vnic_dev.c b/drivers/net/enic/vnic_dev.c
index c93012f..bebadb3 100644
--- a/drivers/net/enic/vnic_dev.c
+++ b/drivers/net/enic/vnic_dev.c
@@ -550,7 +550,7 @@ int vnic_dev_mac_addr(struct vnic_dev *vdev, u8 *mac_addr)
return 0;
}
-void vnic_dev_packet_filter(struct vnic_dev *vdev, int directed, int multicast,
+int vnic_dev_packet_filter(struct vnic_dev *vdev, int directed, int multicast,
int broadcast, int promisc, int allmulti)
{
u64 a0, a1 = 0;
@@ -566,6 +566,8 @@ void vnic_dev_packet_filter(struct vnic_dev *vdev, int directed, int multicast,
err = vnic_dev_cmd(vdev, CMD_PACKET_FILTER, &a0, &a1, wait);
if (err)
printk(KERN_ERR "Can't set packet filter\n");
+
+ return err;
}
int vnic_dev_add_addr(struct vnic_dev *vdev, u8 *addr)
@@ -670,22 +672,25 @@ int vnic_dev_notify_set(struct vnic_dev *vdev, u16 intr)
return vnic_dev_notify_setcmd(vdev, notify_addr, notify_pa, intr);
}
-void vnic_dev_notify_unsetcmd(struct vnic_dev *vdev)
+int vnic_dev_notify_unsetcmd(struct vnic_dev *vdev)
{
u64 a0, a1;
int wait = 1000;
+ int err;
a0 = 0; /* paddr = 0 to unset notify buffer */
a1 = 0x0000ffff00000000ULL; /* intr num = -1 to unreg for intr */
a1 += sizeof(struct vnic_devcmd_notify);
- vnic_dev_cmd(vdev, CMD_NOTIFY, &a0, &a1, wait);
+ err = vnic_dev_cmd(vdev, CMD_NOTIFY, &a0, &a1, wait);
vdev->notify = NULL;
vdev->notify_pa = 0;
vdev->notify_sz = 0;
+
+ return err;
}
-void vnic_dev_notify_unset(struct vnic_dev *vdev)
+int vnic_dev_notify_unset(struct vnic_dev *vdev)
{
if (vdev->notify) {
pci_free_consistent(vdev->pdev,
@@ -694,7 +699,7 @@ void vnic_dev_notify_unset(struct vnic_dev *vdev)
vdev->notify_pa);
}
- vnic_dev_notify_unsetcmd(vdev);
+ return vnic_dev_notify_unsetcmd(vdev);
}
static int vnic_dev_notify_ready(struct vnic_dev *vdev)
@@ -839,6 +844,14 @@ u32 vnic_dev_notify_status(struct vnic_dev *vdev)
return vdev->notify_copy.status;
}
+u32 vnic_dev_uif(struct vnic_dev *vdev)
+{
+ if (!vnic_dev_notify_ready(vdev))
+ return 0;
+
+ return vdev->notify_copy.uif;
+}
+
void vnic_dev_set_intr_mode(struct vnic_dev *vdev,
enum vnic_dev_intr_mode intr_mode)
{
diff --git a/drivers/net/enic/vnic_dev.h b/drivers/net/enic/vnic_dev.h
index 4980615..3a29681 100644
--- a/drivers/net/enic/vnic_dev.h
+++ b/drivers/net/enic/vnic_dev.h
@@ -101,7 +101,7 @@ int vnic_dev_spec(struct vnic_dev *vdev, unsigned int offset, unsigned int size,
int vnic_dev_stats_clear(struct vnic_dev *vdev);
int vnic_dev_stats_dump(struct vnic_dev *vdev, struct vnic_stats **stats);
int vnic_dev_hang_notify(struct vnic_dev *vdev);
-void vnic_dev_packet_filter(struct vnic_dev *vdev, int directed, int multicast,
+int vnic_dev_packet_filter(struct vnic_dev *vdev, int directed, int multicast,
int broadcast, int promisc, int allmulti);
int vnic_dev_add_addr(struct vnic_dev *vdev, u8 *addr);
int vnic_dev_del_addr(struct vnic_dev *vdev, u8 *addr);
@@ -110,14 +110,15 @@ int vnic_dev_raise_intr(struct vnic_dev *vdev, u16 intr);
int vnic_dev_notify_setcmd(struct vnic_dev *vdev,
void *notify_addr, dma_addr_t notify_pa, u16 intr);
int vnic_dev_notify_set(struct vnic_dev *vdev, u16 intr);
-void vnic_dev_notify_unsetcmd(struct vnic_dev *vdev);
-void vnic_dev_notify_unset(struct vnic_dev *vdev);
+int vnic_dev_notify_unsetcmd(struct vnic_dev *vdev);
+int vnic_dev_notify_unset(struct vnic_dev *vdev);
int vnic_dev_link_status(struct vnic_dev *vdev);
u32 vnic_dev_port_speed(struct vnic_dev *vdev);
u32 vnic_dev_msg_lvl(struct vnic_dev *vdev);
u32 vnic_dev_mtu(struct vnic_dev *vdev);
u32 vnic_dev_link_down_cnt(struct vnic_dev *vdev);
u32 vnic_dev_notify_status(struct vnic_dev *vdev);
+u32 vnic_dev_uif(struct vnic_dev *vdev);
int vnic_dev_close(struct vnic_dev *vdev);
int vnic_dev_enable(struct vnic_dev *vdev);
int vnic_dev_disable(struct vnic_dev *vdev);
^ permalink raw reply related
* [net-next-2.6 PATCH 05/10] enic: Use (netdev|dev|pr)_<level> macro helpers for logging
From: Vasanthy Kolluri @ 2010-06-24 20:50 UTC (permalink / raw)
To: davem; +Cc: netdev, scofeldm, vkolluri, roprabhu
In-Reply-To: <20100624204723.22595.42990.stgit@savbu-pc100.cisco.com>
From: Vasanthy Kolluri <vkolluri@cisco.com>
Replace all printk routines with the (netdev|dev|pr)_<level> macros that
provide verbose logs.
Signed-off-by: Joe Perches <joe@perches.com>
Signed-off-by: Scott Feldman <scofeldm@cisco.com>
Signed-off-by: Vasanthy Kolluri <vkolluri@cisco.com>
Signed-off-by: Roopa Prabhu <roprabhu@cisco.com>
---
drivers/net/enic/enic.h | 6 ++
drivers/net/enic/enic_main.c | 125 ++++++++++++++++++------------------------
drivers/net/enic/enic_res.c | 27 +++++----
drivers/net/enic/vnic_cq.c | 2 -
drivers/net/enic/vnic_dev.c | 29 ++++------
drivers/net/enic/vnic_dev.h | 3 +
drivers/net/enic/vnic_intr.c | 3 -
drivers/net/enic/vnic_rq.c | 6 +-
drivers/net/enic/vnic_wq.c | 6 +-
9 files changed, 98 insertions(+), 109 deletions(-)
diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h
index 81c2ade..3588ef5 100644
--- a/drivers/net/enic/enic.h
+++ b/drivers/net/enic/enic.h
@@ -34,7 +34,6 @@
#define DRV_DESCRIPTION "Cisco VIC Ethernet NIC Driver"
#define DRV_VERSION "1.4.1.1"
#define DRV_COPYRIGHT "Copyright 2008-2009 Cisco Systems, Inc"
-#define PFX DRV_NAME ": "
#define ENIC_BARS_MAX 6
@@ -130,4 +129,9 @@ struct enic {
unsigned int cq_count;
};
+static inline struct device *enic_get_dev(struct enic *enic)
+{
+ return &(enic->pdev->dev);
+}
+
#endif /* _ENIC_H_ */
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index 9e05805..413e362 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -418,15 +418,15 @@ static void enic_log_q_error(struct enic *enic)
for (i = 0; i < enic->wq_count; i++) {
error_status = vnic_wq_error_status(&enic->wq[i]);
if (error_status)
- printk(KERN_ERR PFX "%s: WQ[%d] error_status %d\n",
- enic->netdev->name, i, error_status);
+ netdev_err(enic->netdev, "WQ[%d] error_status %d\n",
+ i, error_status);
}
for (i = 0; i < enic->rq_count; i++) {
error_status = vnic_rq_error_status(&enic->rq[i]);
if (error_status)
- printk(KERN_ERR PFX "%s: RQ[%d] error_status %d\n",
- enic->netdev->name, i, error_status);
+ netdev_err(enic->netdev, "RQ[%d] error_status %d\n",
+ i, error_status);
}
}
@@ -435,8 +435,8 @@ static void enic_msglvl_check(struct enic *enic)
u32 msg_enable = vnic_dev_msg_lvl(enic->vdev);
if (msg_enable != enic->msg_enable) {
- printk(KERN_INFO PFX "%s: msg lvl changed from 0x%x to 0x%x\n",
- enic->netdev->name, enic->msg_enable, msg_enable);
+ netdev_info(enic->netdev, "msg lvl changed from 0x%x to 0x%x\n",
+ enic->msg_enable, msg_enable);
enic->msg_enable = msg_enable;
}
}
@@ -444,14 +444,15 @@ static void enic_msglvl_check(struct enic *enic)
static void enic_mtu_check(struct enic *enic)
{
u32 mtu = vnic_dev_mtu(enic->vdev);
+ struct net_device *netdev = enic->netdev;
if (mtu && mtu != enic->port_mtu) {
enic->port_mtu = mtu;
- if (mtu < enic->netdev->mtu)
- printk(KERN_WARNING PFX
- "%s: interface MTU (%d) set higher "
+ if (mtu < netdev->mtu)
+ netdev_warn(netdev,
+ "interface MTU (%d) set higher "
"than switch port MTU (%d)\n",
- enic->netdev->name, enic->netdev->mtu, mtu);
+ netdev->mtu, mtu);
}
}
@@ -461,10 +462,10 @@ static void enic_link_check(struct enic *enic)
int carrier_ok = netif_carrier_ok(enic->netdev);
if (link_status && !carrier_ok) {
- printk(KERN_INFO PFX "%s: Link UP\n", enic->netdev->name);
+ netdev_info(enic->netdev, "Link UP\n");
netif_carrier_on(enic->netdev);
} else if (!link_status && carrier_ok) {
- printk(KERN_INFO PFX "%s: Link DOWN\n", enic->netdev->name);
+ netdev_info(enic->netdev, "Link DOWN\n");
netif_carrier_off(enic->netdev);
}
}
@@ -788,8 +789,7 @@ static netdev_tx_t enic_hard_start_xmit(struct sk_buff *skb,
skb_shinfo(skb)->nr_frags + ENIC_DESC_MAX_SPLITS) {
netif_stop_queue(netdev);
/* This is a hard error, log it */
- printk(KERN_ERR PFX "%s: BUG! Tx ring full when "
- "queue awake!\n", netdev->name);
+ netdev_err(netdev, "BUG! Tx ring full when queue awake!\n");
spin_unlock_irqrestore(&enic->wq_lock[0], flags);
return NETDEV_TX_BUSY;
}
@@ -1738,16 +1738,14 @@ static int enic_open(struct net_device *netdev)
err = enic_request_intr(enic);
if (err) {
- printk(KERN_ERR PFX "%s: Unable to request irq.\n",
- netdev->name);
+ netdev_err(netdev, "Unable to request irq.\n");
return err;
}
err = enic_dev_notify_set(enic);
if (err) {
- printk(KERN_ERR PFX
- "%s: Failed to alloc notify buffer, aborting.\n",
- netdev->name);
+ netdev_err(netdev,
+ "Failed to alloc notify buffer, aborting.\n");
goto err_out_free_intr;
}
@@ -1755,9 +1753,7 @@ static int enic_open(struct net_device *netdev)
vnic_rq_fill(&enic->rq[i], enic->rq_alloc_buf);
/* Need at least one buffer on ring to get going */
if (vnic_rq_desc_used(&enic->rq[i]) == 0) {
- printk(KERN_ERR PFX
- "%s: Unable to alloc receive buffers.\n",
- netdev->name);
+ netdev_err(netdev, "Unable to alloc receive buffers\n");
err = -ENOMEM;
goto err_out_notify_unset;
}
@@ -1851,10 +1847,9 @@ static int enic_change_mtu(struct net_device *netdev, int new_mtu)
netdev->mtu = new_mtu;
if (netdev->mtu > enic->port_mtu)
- printk(KERN_WARNING PFX
- "%s: interface MTU (%d) set higher "
- "than port MTU (%d)\n",
- netdev->name, netdev->mtu, enic->port_mtu);
+ netdev_warn(netdev,
+ "interface MTU (%d) set higher than port MTU (%d)\n",
+ netdev->mtu, enic->port_mtu);
if (running)
enic_open(netdev);
@@ -1927,8 +1922,8 @@ static int enic_dev_open(struct enic *enic)
err = enic_dev_wait(enic->vdev, vnic_dev_open,
vnic_dev_open_done, 0);
if (err)
- printk(KERN_ERR PFX
- "vNIC device open failed, err %d.\n", err);
+ dev_err(enic_get_dev(enic), "vNIC device open failed, err %d\n",
+ err);
return err;
}
@@ -1940,8 +1935,8 @@ static int enic_dev_hang_reset(struct enic *enic)
err = enic_dev_wait(enic->vdev, vnic_dev_hang_reset,
vnic_dev_hang_reset_done, 0);
if (err)
- printk(KERN_ERR PFX
- "vNIC hang reset failed, err %d.\n", err);
+ netdev_err(enic->netdev, "vNIC hang reset failed, err %d\n",
+ err);
return err;
}
@@ -2177,6 +2172,7 @@ static int enic_dev_stats_clear(struct enic *enic)
int enic_dev_init(struct enic *enic)
{
+ struct device *dev = enic_get_dev(enic);
struct net_device *netdev = enic->netdev;
int err;
@@ -2185,8 +2181,7 @@ int enic_dev_init(struct enic *enic)
err = enic_get_vnic_config(enic);
if (err) {
- printk(KERN_ERR PFX
- "Get vNIC configuration failed, aborting.\n");
+ dev_err(dev, "Get vNIC configuration failed, aborting\n");
return err;
}
@@ -2201,9 +2196,8 @@ int enic_dev_init(struct enic *enic)
err = enic_set_intr_mode(enic);
if (err) {
- printk(KERN_ERR PFX
- "Failed to set intr mode based on resource "
- "counts and system capabilities, aborting.\n");
+ dev_err(dev, "Failed to set intr mode based on resource "
+ "counts and system capabilities, aborting\n");
return err;
}
@@ -2212,8 +2206,7 @@ int enic_dev_init(struct enic *enic)
err = enic_alloc_vnic_resources(enic);
if (err) {
- printk(KERN_ERR PFX
- "Failed to alloc vNIC resources, aborting.\n");
+ dev_err(dev, "Failed to alloc vNIC resources, aborting\n");
goto err_out_free_vnic_resources;
}
@@ -2225,21 +2218,19 @@ int enic_dev_init(struct enic *enic)
err = enic_set_rq_alloc_buf(enic);
if (err) {
- printk(KERN_ERR PFX
- "Failed to set RQ buffer allocator, aborting.\n");
+ dev_err(dev, "Failed to set RQ buffer allocator, aborting\n");
goto err_out_free_vnic_resources;
}
err = enic_set_niccfg(enic);
if (err) {
- printk(KERN_ERR PFX
- "Failed to config nic, aborting.\n");
+ dev_err(dev, "Failed to config nic, aborting\n");
goto err_out_free_vnic_resources;
}
err = enic_dev_set_ig_vlan_rewrite_mode(enic);
if (err) {
- printk(KERN_ERR PFX
+ netdev_err(netdev,
"Failed to set ingress vlan rewrite mode, aborting.\n");
goto err_out_free_vnic_resources;
}
@@ -2274,6 +2265,7 @@ static void enic_iounmap(struct enic *enic)
static int __devinit enic_probe(struct pci_dev *pdev,
const struct pci_device_id *ent)
{
+ struct device *dev = &pdev->dev;
struct net_device *netdev;
struct enic *enic;
int using_dac = 0;
@@ -2286,7 +2278,7 @@ static int __devinit enic_probe(struct pci_dev *pdev,
netdev = alloc_etherdev(sizeof(struct enic));
if (!netdev) {
- printk(KERN_ERR PFX "Etherdev alloc failed, aborting.\n");
+ pr_err("Etherdev alloc failed, aborting\n");
return -ENOMEM;
}
@@ -2303,15 +2295,13 @@ static int __devinit enic_probe(struct pci_dev *pdev,
err = pci_enable_device(pdev);
if (err) {
- printk(KERN_ERR PFX
- "Cannot enable PCI device, aborting.\n");
+ dev_err(dev, "Cannot enable PCI device, aborting\n");
goto err_out_free_netdev;
}
err = pci_request_regions(pdev, DRV_NAME);
if (err) {
- printk(KERN_ERR PFX
- "Cannot request PCI regions, aborting.\n");
+ dev_err(dev, "Cannot request PCI regions, aborting\n");
goto err_out_disable_device;
}
@@ -2326,23 +2316,20 @@ static int __devinit enic_probe(struct pci_dev *pdev,
if (err) {
err = pci_set_dma_mask(pdev, DMA_BIT_MASK(32));
if (err) {
- printk(KERN_ERR PFX
- "No usable DMA configuration, aborting.\n");
+ dev_err(dev, "No usable DMA configuration, aborting\n");
goto err_out_release_regions;
}
err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(32));
if (err) {
- printk(KERN_ERR PFX
- "Unable to obtain 32-bit DMA "
- "for consistent allocations, aborting.\n");
+ dev_err(dev, "Unable to obtain %u-bit DMA "
+ "for consistent allocations, aborting\n", 32);
goto err_out_release_regions;
}
} else {
err = pci_set_consistent_dma_mask(pdev, DMA_BIT_MASK(40));
if (err) {
- printk(KERN_ERR PFX
- "Unable to obtain 40-bit DMA "
- "for consistent allocations, aborting.\n");
+ dev_err(dev, "Unable to obtain %u-bit DMA "
+ "for consistent allocations, aborting\n", 40);
goto err_out_release_regions;
}
using_dac = 1;
@@ -2357,8 +2344,7 @@ static int __devinit enic_probe(struct pci_dev *pdev,
enic->bar[i].len = pci_resource_len(pdev, i);
enic->bar[i].vaddr = pci_iomap(pdev, i, enic->bar[i].len);
if (!enic->bar[i].vaddr) {
- printk(KERN_ERR PFX
- "Cannot memory-map BAR %d, aborting.\n", i);
+ dev_err(dev, "Cannot memory-map BAR %d, aborting\n", i);
err = -ENODEV;
goto err_out_iounmap;
}
@@ -2371,8 +2357,7 @@ static int __devinit enic_probe(struct pci_dev *pdev,
enic->vdev = vnic_dev_register(NULL, enic, pdev, enic->bar,
ARRAY_SIZE(enic->bar));
if (!enic->vdev) {
- printk(KERN_ERR PFX
- "vNIC registration failed, aborting.\n");
+ dev_err(dev, "vNIC registration failed, aborting\n");
err = -ENODEV;
goto err_out_iounmap;
}
@@ -2382,8 +2367,7 @@ static int __devinit enic_probe(struct pci_dev *pdev,
err = enic_dev_open(enic);
if (err) {
- printk(KERN_ERR PFX
- "vNIC dev open failed, aborting.\n");
+ dev_err(dev, "vNIC dev open failed, aborting\n");
goto err_out_vnic_unregister;
}
@@ -2397,11 +2381,15 @@ static int __devinit enic_probe(struct pci_dev *pdev,
netif_carrier_off(netdev);
+ /* Do not call dev_init for a dynamic vnic.
+ * For a dynamic vnic, init_prov_info will be
+ * called later by an upper layer.
+ */
+
if (!enic_is_dynamic(enic)) {
err = vnic_dev_init(enic->vdev, 0);
if (err) {
- printk(KERN_ERR PFX
- "vNIC dev init failed, aborting.\n");
+ dev_err(dev, "vNIC dev init failed, aborting\n");
goto err_out_dev_close;
}
}
@@ -2413,8 +2401,7 @@ static int __devinit enic_probe(struct pci_dev *pdev,
err = enic_dev_init(enic);
if (err) {
- printk(KERN_ERR PFX
- "Device initialization failed, aborting.\n");
+ dev_err(dev, "Device initialization failed, aborting\n");
goto err_out_dev_close;
}
@@ -2438,8 +2425,7 @@ static int __devinit enic_probe(struct pci_dev *pdev,
err = enic_set_mac_addr(netdev, enic->mac_addr);
if (err) {
- printk(KERN_ERR PFX
- "Invalid MAC address, aborting.\n");
+ dev_err(dev, "Invalid MAC address, aborting\n");
goto err_out_dev_deinit;
}
@@ -2469,8 +2455,7 @@ static int __devinit enic_probe(struct pci_dev *pdev,
err = register_netdev(netdev);
if (err) {
- printk(KERN_ERR PFX
- "Cannot register net device, aborting.\n");
+ dev_err(dev, "Cannot register net device, aborting\n");
goto err_out_dev_deinit;
}
@@ -2524,7 +2509,7 @@ static struct pci_driver enic_driver = {
static int __init enic_init_module(void)
{
- printk(KERN_INFO PFX "%s, ver %s\n", DRV_DESCRIPTION, DRV_VERSION);
+ pr_info("%s, ver %s\n", DRV_DESCRIPTION, DRV_VERSION);
return pci_register_driver(&enic_driver);
}
diff --git a/drivers/net/enic/enic_res.c b/drivers/net/enic/enic_res.c
index 04cfc4e..478928b 100644
--- a/drivers/net/enic/enic_res.c
+++ b/drivers/net/enic/enic_res.c
@@ -46,7 +46,8 @@ int enic_get_vnic_config(struct enic *enic)
err = vnic_dev_mac_addr(enic->vdev, enic->mac_addr);
if (err) {
- printk(KERN_ERR PFX "Error getting MAC addr, %d\n", err);
+ dev_err(enic_get_dev(enic),
+ "Error getting MAC addr, %d\n", err);
return err;
}
@@ -56,7 +57,7 @@ int enic_get_vnic_config(struct enic *enic)
offsetof(struct vnic_enet_config, m), \
sizeof(c->m), &c->m); \
if (err) { \
- printk(KERN_ERR PFX \
+ dev_err(enic_get_dev(enic), \
"Error getting %s, %d\n", #m, err); \
return err; \
} \
@@ -92,10 +93,10 @@ int enic_get_vnic_config(struct enic *enic)
INTR_COALESCE_HW_TO_USEC(VNIC_INTR_TIMER_MAX),
c->intr_timer_usec);
- printk(KERN_INFO PFX "vNIC MAC addr %pM wq/rq %d/%d\n",
+ dev_info(enic_get_dev(enic), "vNIC MAC addr %pM wq/rq %d/%d\n",
enic->mac_addr, c->wq_desc_count, c->rq_desc_count);
- printk(KERN_INFO PFX "vNIC mtu %d csum tx/rx %d/%d tso/lro %d/%d "
- "intr timer %d usec\n",
+ dev_info(enic_get_dev(enic), "vNIC mtu %d csum tx/rx %d/%d "
+ "tso/lro %d/%d intr timer %d usec\n",
c->mtu, ENIC_SETTING(enic, TXCSUM),
ENIC_SETTING(enic, RXCSUM), ENIC_SETTING(enic, TSO),
ENIC_SETTING(enic, LRO), c->intr_timer_usec);
@@ -111,7 +112,7 @@ int enic_add_vlan(struct enic *enic, u16 vlanid)
err = vnic_dev_cmd(enic->vdev, CMD_VLAN_ADD, &a0, &a1, wait);
if (err)
- printk(KERN_ERR PFX "Can't add vlan id, %d\n", err);
+ dev_err(enic_get_dev(enic), "Can't add vlan id, %d\n", err);
return err;
}
@@ -124,7 +125,7 @@ int enic_del_vlan(struct enic *enic, u16 vlanid)
err = vnic_dev_cmd(enic->vdev, CMD_VLAN_DEL, &a0, &a1, wait);
if (err)
- printk(KERN_ERR PFX "Can't delete vlan id, %d\n", err);
+ dev_err(enic_get_dev(enic), "Can't delete vlan id, %d\n", err);
return err;
}
@@ -192,8 +193,8 @@ void enic_get_res_counts(struct enic *enic)
vnic_dev_get_res_count(enic->vdev, RES_TYPE_INTR_CTRL),
ENIC_INTR_MAX);
- printk(KERN_INFO PFX "vNIC resources avail: "
- "wq %d rq %d cq %d intr %d\n",
+ dev_info(enic_get_dev(enic),
+ "vNIC resources avail: wq %d rq %d cq %d intr %d\n",
enic->wq_count, enic->rq_count,
enic->cq_count, enic->intr_count);
}
@@ -308,15 +309,14 @@ int enic_alloc_vnic_resources(struct enic *enic)
intr_mode = vnic_dev_get_intr_mode(enic->vdev);
- printk(KERN_INFO PFX "vNIC resources used: "
+ dev_info(enic_get_dev(enic), "vNIC resources used: "
"wq %d rq %d cq %d intr %d intr mode %s\n",
enic->wq_count, enic->rq_count,
enic->cq_count, enic->intr_count,
intr_mode == VNIC_DEV_INTR_MODE_INTX ? "legacy PCI INTx" :
intr_mode == VNIC_DEV_INTR_MODE_MSI ? "MSI" :
intr_mode == VNIC_DEV_INTR_MODE_MSIX ? "MSI-X" :
- "unknown"
- );
+ "unknown");
/* Allocate queue resources
*/
@@ -362,7 +362,8 @@ int enic_alloc_vnic_resources(struct enic *enic)
enic->legacy_pba = vnic_dev_get_res(enic->vdev,
RES_TYPE_INTR_PBA_LEGACY, 0);
if (!enic->legacy_pba && intr_mode == VNIC_DEV_INTR_MODE_INTX) {
- printk(KERN_ERR PFX "Failed to hook legacy pba resource\n");
+ dev_err(enic_get_dev(enic),
+ "Failed to hook legacy pba resource\n");
err = -ENODEV;
goto err_out_cleanup;
}
diff --git a/drivers/net/enic/vnic_cq.c b/drivers/net/enic/vnic_cq.c
index 020ae6c..326ea40 100644
--- a/drivers/net/enic/vnic_cq.c
+++ b/drivers/net/enic/vnic_cq.c
@@ -42,7 +42,7 @@ int vnic_cq_alloc(struct vnic_dev *vdev, struct vnic_cq *cq, unsigned int index,
cq->ctrl = vnic_dev_get_res(vdev, RES_TYPE_CQ, index);
if (!cq->ctrl) {
- printk(KERN_ERR "Failed to hook CQ[%d] resource\n", index);
+ pr_err("Failed to hook CQ[%d] resource\n", index);
return -EINVAL;
}
diff --git a/drivers/net/enic/vnic_dev.c b/drivers/net/enic/vnic_dev.c
index bebadb3..042f4b8 100644
--- a/drivers/net/enic/vnic_dev.c
+++ b/drivers/net/enic/vnic_dev.c
@@ -78,19 +78,19 @@ static int vnic_dev_discover_res(struct vnic_dev *vdev,
return -EINVAL;
if (bar->len < VNIC_MAX_RES_HDR_SIZE) {
- printk(KERN_ERR "vNIC BAR0 res hdr length error\n");
+ pr_err("vNIC BAR0 res hdr length error\n");
return -EINVAL;
}
rh = bar->vaddr;
if (!rh) {
- printk(KERN_ERR "vNIC BAR0 res hdr not mem-mapped\n");
+ pr_err("vNIC BAR0 res hdr not mem-mapped\n");
return -EINVAL;
}
if (ioread32(&rh->magic) != VNIC_RES_MAGIC ||
ioread32(&rh->version) != VNIC_RES_VERSION) {
- printk(KERN_ERR "vNIC BAR0 res magic/version error "
+ pr_err("vNIC BAR0 res magic/version error "
"exp (%lx/%lx) curr (%x/%x)\n",
VNIC_RES_MAGIC, VNIC_RES_VERSION,
ioread32(&rh->magic), ioread32(&rh->version));
@@ -122,7 +122,7 @@ static int vnic_dev_discover_res(struct vnic_dev *vdev,
/* each count is stride bytes long */
len = count * VNIC_RES_STRIDE;
if (len + bar_offset > bar[bar_num].len) {
- printk(KERN_ERR "vNIC BAR0 resource %d "
+ pr_err("vNIC BAR0 resource %d "
"out-of-bounds, offset 0x%x + "
"size 0x%x > bar len 0x%lx\n",
type, bar_offset,
@@ -229,8 +229,7 @@ int vnic_dev_alloc_desc_ring(struct vnic_dev *vdev, struct vnic_dev_ring *ring,
&ring->base_addr_unaligned);
if (!ring->descs_unaligned) {
- printk(KERN_ERR
- "Failed to allocate ring (size=%d), aborting\n",
+ pr_err("Failed to allocate ring (size=%d), aborting\n",
(int)ring->size);
return -ENOMEM;
}
@@ -268,7 +267,7 @@ int vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
status = ioread32(&devcmd->status);
if (status & STAT_BUSY) {
- printk(KERN_ERR "Busy devcmd %d\n", _CMD_N(cmd));
+ pr_err("Busy devcmd %d\n", _CMD_N(cmd));
return -EBUSY;
}
@@ -294,7 +293,7 @@ int vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
err = (int)readq(&devcmd->args[0]);
if (err != ERR_ECMDUNKNOWN ||
cmd != CMD_CAPABILITY)
- printk(KERN_ERR "Error %d devcmd %d\n",
+ pr_err("Error %d devcmd %d\n",
err, _CMD_N(cmd));
return err;
}
@@ -309,7 +308,7 @@ int vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
}
}
- printk(KERN_ERR "Timedout devcmd %d\n", _CMD_N(cmd));
+ pr_err("Timedout devcmd %d\n", _CMD_N(cmd));
return -ETIMEDOUT;
}
@@ -565,7 +564,7 @@ int vnic_dev_packet_filter(struct vnic_dev *vdev, int directed, int multicast,
err = vnic_dev_cmd(vdev, CMD_PACKET_FILTER, &a0, &a1, wait);
if (err)
- printk(KERN_ERR "Can't set packet filter\n");
+ pr_err("Can't set packet filter\n");
return err;
}
@@ -582,7 +581,7 @@ int vnic_dev_add_addr(struct vnic_dev *vdev, u8 *addr)
err = vnic_dev_cmd(vdev, CMD_ADDR_ADD, &a0, &a1, wait);
if (err)
- printk(KERN_ERR "Can't add addr [%pM], %d\n", addr, err);
+ pr_err("Can't add addr [%pM], %d\n", addr, err);
return err;
}
@@ -599,7 +598,7 @@ int vnic_dev_del_addr(struct vnic_dev *vdev, u8 *addr)
err = vnic_dev_cmd(vdev, CMD_ADDR_DEL, &a0, &a1, wait);
if (err)
- printk(KERN_ERR "Can't del addr [%pM], %d\n", addr, err);
+ pr_err("Can't del addr [%pM], %d\n", addr, err);
return err;
}
@@ -626,8 +625,7 @@ int vnic_dev_raise_intr(struct vnic_dev *vdev, u16 intr)
err = vnic_dev_cmd(vdev, CMD_IAR, &a0, &a1, wait);
if (err)
- printk(KERN_ERR "Failed to raise INTR[%d], err %d\n",
- intr, err);
+ pr_err("Failed to raise INTR[%d], err %d\n", intr, err);
return err;
}
@@ -658,8 +656,7 @@ int vnic_dev_notify_set(struct vnic_dev *vdev, u16 intr)
dma_addr_t notify_pa;
if (vdev->notify || vdev->notify_pa) {
- printk(KERN_ERR "notify block %p still allocated",
- vdev->notify);
+ pr_err("notify block %p still allocated", vdev->notify);
return -EINVAL;
}
diff --git a/drivers/net/enic/vnic_dev.h b/drivers/net/enic/vnic_dev.h
index 3a29681..11659c6 100644
--- a/drivers/net/enic/vnic_dev.h
+++ b/drivers/net/enic/vnic_dev.h
@@ -41,6 +41,9 @@ static inline void writeq(u64 val, void __iomem *reg)
}
#endif
+#undef pr_fmt
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
enum vnic_dev_hw_version {
VNIC_DEV_HW_VER_UNKNOWN,
VNIC_DEV_HW_VER_A1,
diff --git a/drivers/net/enic/vnic_intr.c b/drivers/net/enic/vnic_intr.c
index 3934309..416eae7 100644
--- a/drivers/net/enic/vnic_intr.c
+++ b/drivers/net/enic/vnic_intr.c
@@ -39,8 +39,7 @@ int vnic_intr_alloc(struct vnic_dev *vdev, struct vnic_intr *intr,
intr->ctrl = vnic_dev_get_res(vdev, RES_TYPE_INTR_CTRL, index);
if (!intr->ctrl) {
- printk(KERN_ERR "Failed to hook INTR[%d].ctrl resource\n",
- index);
+ pr_err("Failed to hook INTR[%d].ctrl resource\n", index);
return -EINVAL;
}
diff --git a/drivers/net/enic/vnic_rq.c b/drivers/net/enic/vnic_rq.c
index cc580cf..6d84ca8 100644
--- a/drivers/net/enic/vnic_rq.c
+++ b/drivers/net/enic/vnic_rq.c
@@ -39,7 +39,7 @@ static int vnic_rq_alloc_bufs(struct vnic_rq *rq)
for (i = 0; i < blks; i++) {
rq->bufs[i] = kzalloc(VNIC_RQ_BUF_BLK_SZ, GFP_ATOMIC);
if (!rq->bufs[i]) {
- printk(KERN_ERR "Failed to alloc rq_bufs\n");
+ pr_err("Failed to alloc rq_bufs\n");
return -ENOMEM;
}
}
@@ -94,7 +94,7 @@ int vnic_rq_alloc(struct vnic_dev *vdev, struct vnic_rq *rq, unsigned int index,
rq->ctrl = vnic_dev_get_res(vdev, RES_TYPE_RQ, index);
if (!rq->ctrl) {
- printk(KERN_ERR "Failed to hook RQ[%d] resource\n", index);
+ pr_err("Failed to hook RQ[%d] resource\n", index);
return -EINVAL;
}
@@ -174,7 +174,7 @@ int vnic_rq_disable(struct vnic_rq *rq)
udelay(10);
}
- printk(KERN_ERR "Failed to disable RQ[%d]\n", rq->index);
+ pr_err("Failed to disable RQ[%d]\n", rq->index);
return -ETIMEDOUT;
}
diff --git a/drivers/net/enic/vnic_wq.c b/drivers/net/enic/vnic_wq.c
index 1378afb..ed090a3 100644
--- a/drivers/net/enic/vnic_wq.c
+++ b/drivers/net/enic/vnic_wq.c
@@ -39,7 +39,7 @@ static int vnic_wq_alloc_bufs(struct vnic_wq *wq)
for (i = 0; i < blks; i++) {
wq->bufs[i] = kzalloc(VNIC_WQ_BUF_BLK_SZ, GFP_ATOMIC);
if (!wq->bufs[i]) {
- printk(KERN_ERR "Failed to alloc wq_bufs\n");
+ pr_err("Failed to alloc wq_bufs\n");
return -ENOMEM;
}
}
@@ -94,7 +94,7 @@ int vnic_wq_alloc(struct vnic_dev *vdev, struct vnic_wq *wq, unsigned int index,
wq->ctrl = vnic_dev_get_res(vdev, RES_TYPE_WQ, index);
if (!wq->ctrl) {
- printk(KERN_ERR "Failed to hook WQ[%d] resource\n", index);
+ pr_err("Failed to hook WQ[%d] resource\n", index);
return -EINVAL;
}
@@ -167,7 +167,7 @@ int vnic_wq_disable(struct vnic_wq *wq)
udelay(10);
}
- printk(KERN_ERR "Failed to disable WQ[%d]\n", wq->index);
+ pr_err("Failed to disable WQ[%d]\n", wq->index);
return -ETIMEDOUT;
}
^ permalink raw reply related
* [net-next-2.6 PATCH 06/10] enic: Add new firmware devcmds
From: Vasanthy Kolluri @ 2010-06-24 20:51 UTC (permalink / raw)
To: davem; +Cc: netdev, scofeldm, vkolluri, roprabhu
In-Reply-To: <20100624204723.22595.42990.stgit@savbu-pc100.cisco.com>
From: Vasanthy Kolluri <vkolluri@cisco.com>
Add new firmware devcmds - CMD_PROXY_BY_BDF, CMD_PACKET_FILTER_ALL,
CMD_ENABLE_WAIT.
Signed-off-by: Scott Feldman <scofeldm@cisco.com>
Signed-off-by: Vasanthy Kolluri <vkolluri@cisco.com>
Signed-off-by: Roopa Prabhu <roprabhu@cisco.com>
---
drivers/net/enic/vnic_dev.c | 136 +++++++++++++++++++++++++++++++++++++---
drivers/net/enic/vnic_dev.h | 5 +
drivers/net/enic/vnic_devcmd.h | 14 ++++
3 files changed, 146 insertions(+), 9 deletions(-)
diff --git a/drivers/net/enic/vnic_dev.c b/drivers/net/enic/vnic_dev.c
index 042f4b8..180912f 100644
--- a/drivers/net/enic/vnic_dev.c
+++ b/drivers/net/enic/vnic_dev.c
@@ -30,6 +30,11 @@
#include "vnic_dev.h"
#include "vnic_stats.h"
+enum vnic_proxy_type {
+ PROXY_NONE,
+ PROXY_BY_BDF,
+};
+
struct vnic_res {
void __iomem *vaddr;
dma_addr_t bus_addr;
@@ -55,6 +60,9 @@ struct vnic_dev {
struct vnic_devcmd_fw_info *fw_info;
dma_addr_t fw_info_pa;
u32 cap_flags;
+ enum vnic_proxy_type proxy;
+ u32 proxy_index;
+ u64 args[VNIC_DEVCMD_NARGS];
};
#define VNIC_MAX_RES_HDR_SIZE \
@@ -257,10 +265,11 @@ void vnic_dev_free_desc_ring(struct vnic_dev *vdev, struct vnic_dev_ring *ring)
}
}
-int vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
- u64 *a0, u64 *a1, int wait)
+static int _vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
+ int wait)
{
struct vnic_devcmd __iomem *devcmd = vdev->devcmd;
+ unsigned int i;
int delay;
u32 status;
int err;
@@ -272,8 +281,8 @@ int vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
}
if (_CMD_DIR(cmd) & _CMD_DIR_WRITE) {
- writeq(*a0, &devcmd->args[0]);
- writeq(*a1, &devcmd->args[1]);
+ for (i = 0; i < VNIC_DEVCMD_NARGS; i++)
+ writeq(vdev->args[i], &devcmd->args[i]);
wmb();
}
@@ -287,6 +296,7 @@ int vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
udelay(100);
status = ioread32(&devcmd->status);
+
if (!(status & STAT_BUSY)) {
if (status & STAT_ERROR) {
@@ -300,8 +310,8 @@ int vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
if (_CMD_DIR(cmd) & _CMD_DIR_READ) {
rmb();
- *a0 = readq(&devcmd->args[0]);
- *a1 = readq(&devcmd->args[1]);
+ for (i = 0; i < VNIC_DEVCMD_NARGS; i++)
+ vdev->args[i] = readq(&devcmd->args[i]);
}
return 0;
@@ -312,6 +322,80 @@ int vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
return -ETIMEDOUT;
}
+static int vnic_dev_cmd_proxy_by_bdf(struct vnic_dev *vdev,
+ enum vnic_devcmd_cmd cmd, u64 *a0, u64 *a1, int wait)
+{
+ u32 status;
+ int err;
+
+ memset(vdev->args, 0, sizeof(vdev->args));
+
+ vdev->args[0] = vdev->proxy_index; /* bdf */
+ vdev->args[1] = cmd;
+ vdev->args[2] = *a0;
+ vdev->args[3] = *a1;
+
+ err = _vnic_dev_cmd(vdev, CMD_PROXY_BY_BDF, wait);
+ if (err)
+ return err;
+
+ status = (u32)vdev->args[0];
+ if (status & STAT_ERROR) {
+ err = (int)vdev->args[1];
+ if (err != ERR_ECMDUNKNOWN ||
+ cmd != CMD_CAPABILITY)
+ pr_err("Error %d proxy devcmd %d\n", err, _CMD_N(cmd));
+ return err;
+ }
+
+ *a0 = vdev->args[1];
+ *a1 = vdev->args[2];
+
+ return 0;
+}
+
+static int vnic_dev_cmd_no_proxy(struct vnic_dev *vdev,
+ enum vnic_devcmd_cmd cmd, u64 *a0, u64 *a1, int wait)
+{
+ int err;
+
+ vdev->args[0] = *a0;
+ vdev->args[1] = *a1;
+
+ err = _vnic_dev_cmd(vdev, cmd, wait);
+
+ *a0 = vdev->args[0];
+ *a1 = vdev->args[1];
+
+ return err;
+}
+
+void vnic_dev_cmd_proxy_by_bdf_start(struct vnic_dev *vdev, u16 bdf)
+{
+ vdev->proxy = PROXY_BY_BDF;
+ vdev->proxy_index = bdf;
+}
+
+void vnic_dev_cmd_proxy_end(struct vnic_dev *vdev)
+{
+ vdev->proxy = PROXY_NONE;
+ vdev->proxy_index = 0;
+}
+
+int vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
+ u64 *a0, u64 *a1, int wait)
+{
+ memset(vdev->args, 0, sizeof(vdev->args));
+
+ switch (vdev->proxy) {
+ case PROXY_BY_BDF:
+ return vnic_dev_cmd_proxy_by_bdf(vdev, cmd, a0, a1, wait);
+ case PROXY_NONE:
+ default:
+ return vnic_dev_cmd_no_proxy(vdev, cmd, a0, a1, wait);
+ }
+}
+
static int vnic_dev_capable(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd)
{
u64 a0 = (u32)cmd, a1 = 0;
@@ -430,6 +514,19 @@ int vnic_dev_enable(struct vnic_dev *vdev)
return vnic_dev_cmd(vdev, CMD_ENABLE, &a0, &a1, wait);
}
+int vnic_dev_enable_wait(struct vnic_dev *vdev)
+{
+ u64 a0 = 0, a1 = 0;
+ int wait = 1000;
+ int err;
+
+ err = vnic_dev_cmd(vdev, CMD_ENABLE_WAIT, &a0, &a1, wait);
+ if (err == ERR_ECMDUNKNOWN)
+ return vnic_dev_cmd(vdev, CMD_ENABLE, &a0, &a1, wait);
+
+ return err;
+}
+
int vnic_dev_disable(struct vnic_dev *vdev)
{
u64 a0 = 0, a1 = 0;
@@ -569,6 +666,26 @@ int vnic_dev_packet_filter(struct vnic_dev *vdev, int directed, int multicast,
return err;
}
+int vnic_dev_packet_filter_all(struct vnic_dev *vdev, int directed,
+ int multicast, int broadcast, int promisc, int allmulti)
+{
+ u64 a0, a1 = 0;
+ int wait = 1000;
+ int err;
+
+ a0 = (directed ? CMD_PFILTER_DIRECTED : 0) |
+ (multicast ? CMD_PFILTER_MULTICAST : 0) |
+ (broadcast ? CMD_PFILTER_BROADCAST : 0) |
+ (promisc ? CMD_PFILTER_PROMISCUOUS : 0) |
+ (allmulti ? CMD_PFILTER_ALL_MULTICAST : 0);
+
+ err = vnic_dev_cmd(vdev, CMD_PACKET_FILTER_ALL, &a0, &a1, wait);
+ if (err)
+ pr_err("Can't set packet filter\n");
+
+ return err;
+}
+
int vnic_dev_add_addr(struct vnic_dev *vdev, u8 *addr)
{
u64 a0 = 0, a1 = 0;
@@ -731,8 +848,9 @@ int vnic_dev_init(struct vnic_dev *vdev, int arg)
else {
vnic_dev_cmd(vdev, CMD_INIT_v1, &a0, &a1, wait);
if (a0 & CMD_INITF_DEFAULT_MAC) {
- // Emulate these for old CMD_INIT_v1 which
- // didn't pass a0 so no CMD_INITF_*.
+ /* Emulate these for old CMD_INIT_v1 which
+ * didn't pass a0 so no CMD_INITF_*.
+ */
vnic_dev_cmd(vdev, CMD_MAC_ADDR, &a0, &a1, wait);
vnic_dev_cmd(vdev, CMD_ADDR_ADD, &a0, &a1, wait);
}
@@ -754,7 +872,7 @@ int vnic_dev_init_done(struct vnic_dev *vdev, int *done, int *err)
*done = (a0 == 0);
- *err = (a0 == 0) ? a1 : 0;
+ *err = (a0 == 0) ? (int)a1:0;
return 0;
}
diff --git a/drivers/net/enic/vnic_dev.h b/drivers/net/enic/vnic_dev.h
index 11659c6..cfdaa69 100644
--- a/drivers/net/enic/vnic_dev.h
+++ b/drivers/net/enic/vnic_dev.h
@@ -95,6 +95,8 @@ void vnic_dev_free_desc_ring(struct vnic_dev *vdev,
struct vnic_dev_ring *ring);
int vnic_dev_cmd(struct vnic_dev *vdev, enum vnic_devcmd_cmd cmd,
u64 *a0, u64 *a1, int wait);
+void vnic_dev_cmd_proxy_by_bdf_start(struct vnic_dev *vdev, u16 bdf);
+void vnic_dev_cmd_proxy_end(struct vnic_dev *vdev);
int vnic_dev_fw_info(struct vnic_dev *vdev,
struct vnic_devcmd_fw_info **fw_info);
int vnic_dev_hw_version(struct vnic_dev *vdev,
@@ -106,6 +108,8 @@ int vnic_dev_stats_dump(struct vnic_dev *vdev, struct vnic_stats **stats);
int vnic_dev_hang_notify(struct vnic_dev *vdev);
int vnic_dev_packet_filter(struct vnic_dev *vdev, int directed, int multicast,
int broadcast, int promisc, int allmulti);
+int vnic_dev_packet_filter_all(struct vnic_dev *vdev, int directed,
+ int multicast, int broadcast, int promisc, int allmulti);
int vnic_dev_add_addr(struct vnic_dev *vdev, u8 *addr);
int vnic_dev_del_addr(struct vnic_dev *vdev, u8 *addr);
int vnic_dev_mac_addr(struct vnic_dev *vdev, u8 *mac_addr);
@@ -124,6 +128,7 @@ u32 vnic_dev_notify_status(struct vnic_dev *vdev);
u32 vnic_dev_uif(struct vnic_dev *vdev);
int vnic_dev_close(struct vnic_dev *vdev);
int vnic_dev_enable(struct vnic_dev *vdev);
+int vnic_dev_enable_wait(struct vnic_dev *vdev);
int vnic_dev_disable(struct vnic_dev *vdev);
int vnic_dev_open(struct vnic_dev *vdev, int arg);
int vnic_dev_open_done(struct vnic_dev *vdev, int *done);
diff --git a/drivers/net/enic/vnic_devcmd.h b/drivers/net/enic/vnic_devcmd.h
index 1c4fb35..e6c80c7 100644
--- a/drivers/net/enic/vnic_devcmd.h
+++ b/drivers/net/enic/vnic_devcmd.h
@@ -98,6 +98,9 @@ enum vnic_devcmd_cmd {
/* set Rx packet filter: (u32)a0=filters (see CMD_PFILTER_*) */
CMD_PACKET_FILTER = _CMDCNW(_CMD_DIR_WRITE, _CMD_VTYPE_ENET, 7),
+ /* set Rx packet filter for all: (u32)a0=filters (see CMD_PFILTER_*) */
+ CMD_PACKET_FILTER_ALL = _CMDCNW(_CMD_DIR_WRITE, _CMD_VTYPE_ALL, 7),
+
/* hang detection notification */
CMD_HANG_NOTIFY = _CMDC(_CMD_DIR_NONE, _CMD_VTYPE_ALL, 8),
@@ -171,6 +174,9 @@ enum vnic_devcmd_cmd {
/* enable virtual link */
CMD_ENABLE = _CMDCNW(_CMD_DIR_WRITE, _CMD_VTYPE_ALL, 28),
+ /* enable virtual link, waiting variant. */
+ CMD_ENABLE_WAIT = _CMDC(_CMD_DIR_WRITE, _CMD_VTYPE_ALL, 28),
+
/* disable virtual link */
CMD_DISABLE = _CMDC(_CMD_DIR_NONE, _CMD_VTYPE_ALL, 29),
@@ -224,6 +230,14 @@ enum vnic_devcmd_cmd {
* in: (u32)a0=new vlan rewrite mode
* out: (u32)a0=old vlan rewrite mode */
CMD_IG_VLAN_REWRITE_MODE = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_ENET, 41),
+
+ /*
+ * in: (u16)a0=bdf of target vnic
+ * (u32)a1=cmd to proxy
+ * a2-a15=args to cmd in a1
+ * out: (u32)a0=status of proxied cmd
+ * a1-a15=out args of proxied cmd */
+ CMD_PROXY_BY_BDF = _CMDC(_CMD_DIR_RW, _CMD_VTYPE_ALL, 42),
};
/* flags for CMD_OPEN */
^ permalink raw reply related
* [net-next-2.6 PATCH 07/10] enic: Use receive queue buffer blocks of 32/64 entries
From: Vasanthy Kolluri @ 2010-06-24 20:51 UTC (permalink / raw)
To: davem; +Cc: netdev, scofeldm, vkolluri, roprabhu
In-Reply-To: <20100624204723.22595.42990.stgit@savbu-pc100.cisco.com>
From: Vasanthy Kolluri <vkolluri@cisco.com>
Change the receive queue buffer allocations into blocks of 32 entries when
ring size is less than 64, otherwise use 64 entries per block.
Signed-off-by: Scott Feldman <scofeldm@cisco.com>
Signed-off-by: Vasanthy Kolluri <vkolluri@cisco.com>
Signed-off-by: Roopa Prabhu <roprabhu@cisco.com>
---
drivers/net/enic/vnic_rq.c | 20 +++++++++++---------
drivers/net/enic/vnic_rq.h | 14 +++++++++-----
drivers/net/enic/vnic_wq.c | 15 ++++++++-------
drivers/net/enic/vnic_wq.h | 14 +++++++++-----
4 files changed, 37 insertions(+), 26 deletions(-)
diff --git a/drivers/net/enic/vnic_rq.c b/drivers/net/enic/vnic_rq.c
index 6d84ca8..45cfc79 100644
--- a/drivers/net/enic/vnic_rq.c
+++ b/drivers/net/enic/vnic_rq.c
@@ -37,7 +37,7 @@ static int vnic_rq_alloc_bufs(struct vnic_rq *rq)
vdev = rq->vdev;
for (i = 0; i < blks; i++) {
- rq->bufs[i] = kzalloc(VNIC_RQ_BUF_BLK_SZ, GFP_ATOMIC);
+ rq->bufs[i] = kzalloc(VNIC_RQ_BUF_BLK_SZ(count), GFP_ATOMIC);
if (!rq->bufs[i]) {
pr_err("Failed to alloc rq_bufs\n");
return -ENOMEM;
@@ -46,14 +46,14 @@ static int vnic_rq_alloc_bufs(struct vnic_rq *rq)
for (i = 0; i < blks; i++) {
buf = rq->bufs[i];
- for (j = 0; j < VNIC_RQ_BUF_BLK_ENTRIES; j++) {
- buf->index = i * VNIC_RQ_BUF_BLK_ENTRIES + j;
+ for (j = 0; j < VNIC_RQ_BUF_BLK_ENTRIES(count); j++) {
+ buf->index = i * VNIC_RQ_BUF_BLK_ENTRIES(count) + j;
buf->desc = (u8 *)rq->ring.descs +
rq->ring.desc_size * buf->index;
if (buf->index + 1 == count) {
buf->next = rq->bufs[0];
break;
- } else if (j + 1 == VNIC_RQ_BUF_BLK_ENTRIES) {
+ } else if (j + 1 == VNIC_RQ_BUF_BLK_ENTRIES(count)) {
buf->next = rq->bufs[i + 1];
} else {
buf->next = buf + 1;
@@ -119,10 +119,11 @@ void vnic_rq_init_start(struct vnic_rq *rq, unsigned int cq_index,
unsigned int error_interrupt_offset)
{
u64 paddr;
+ unsigned int count = rq->ring.desc_count;
paddr = (u64)rq->ring.base_addr | VNIC_PADDR_TARGET;
writeq(paddr, &rq->ctrl->ring_base);
- iowrite32(rq->ring.desc_count, &rq->ctrl->ring_size);
+ iowrite32(count, &rq->ctrl->ring_size);
iowrite32(cq_index, &rq->ctrl->cq_index);
iowrite32(error_interrupt_enable, &rq->ctrl->error_interrupt_enable);
iowrite32(error_interrupt_offset, &rq->ctrl->error_interrupt_offset);
@@ -132,8 +133,8 @@ void vnic_rq_init_start(struct vnic_rq *rq, unsigned int cq_index,
iowrite32(posted_index, &rq->ctrl->posted_index);
rq->to_use = rq->to_clean =
- &rq->bufs[fetch_index / VNIC_RQ_BUF_BLK_ENTRIES]
- [fetch_index % VNIC_RQ_BUF_BLK_ENTRIES];
+ &rq->bufs[fetch_index / VNIC_RQ_BUF_BLK_ENTRIES(count)]
+ [fetch_index % VNIC_RQ_BUF_BLK_ENTRIES(count)];
}
void vnic_rq_init(struct vnic_rq *rq, unsigned int cq_index,
@@ -184,6 +185,7 @@ void vnic_rq_clean(struct vnic_rq *rq,
{
struct vnic_rq_buf *buf;
u32 fetch_index;
+ unsigned int count = rq->ring.desc_count;
BUG_ON(ioread32(&rq->ctrl->enable));
@@ -200,8 +202,8 @@ void vnic_rq_clean(struct vnic_rq *rq,
/* Use current fetch_index as the ring starting point */
fetch_index = ioread32(&rq->ctrl->fetch_index);
rq->to_use = rq->to_clean =
- &rq->bufs[fetch_index / VNIC_RQ_BUF_BLK_ENTRIES]
- [fetch_index % VNIC_RQ_BUF_BLK_ENTRIES];
+ &rq->bufs[fetch_index / VNIC_RQ_BUF_BLK_ENTRIES(count)]
+ [fetch_index % VNIC_RQ_BUF_BLK_ENTRIES(count)];
iowrite32(fetch_index, &rq->ctrl->posted_index);
vnic_dev_clear_desc_ring(&rq->ring);
diff --git a/drivers/net/enic/vnic_rq.h b/drivers/net/enic/vnic_rq.h
index 35e736c..8f0fb78 100644
--- a/drivers/net/enic/vnic_rq.h
+++ b/drivers/net/enic/vnic_rq.h
@@ -52,12 +52,16 @@ struct vnic_rq_ctrl {
u32 pad10;
};
-/* Break the vnic_rq_buf allocations into blocks of 64 entries */
-#define VNIC_RQ_BUF_BLK_ENTRIES 64
-#define VNIC_RQ_BUF_BLK_SZ \
- (VNIC_RQ_BUF_BLK_ENTRIES * sizeof(struct vnic_rq_buf))
+/* Break the vnic_rq_buf allocations into blocks of 32/64 entries */
+#define VNIC_RQ_BUF_MIN_BLK_ENTRIES 32
+#define VNIC_RQ_BUF_DFLT_BLK_ENTRIES 64
+#define VNIC_RQ_BUF_BLK_ENTRIES(entries) \
+ ((unsigned int)((entries < VNIC_RQ_BUF_DFLT_BLK_ENTRIES) ? \
+ VNIC_RQ_BUF_MIN_BLK_ENTRIES : VNIC_RQ_BUF_DFLT_BLK_ENTRIES))
+#define VNIC_RQ_BUF_BLK_SZ(entries) \
+ (VNIC_RQ_BUF_BLK_ENTRIES(entries) * sizeof(struct vnic_rq_buf))
#define VNIC_RQ_BUF_BLKS_NEEDED(entries) \
- DIV_ROUND_UP(entries, VNIC_RQ_BUF_BLK_ENTRIES)
+ DIV_ROUND_UP(entries, VNIC_RQ_BUF_BLK_ENTRIES(entries))
#define VNIC_RQ_BUF_BLKS_MAX VNIC_RQ_BUF_BLKS_NEEDED(4096)
struct vnic_rq_buf {
diff --git a/drivers/net/enic/vnic_wq.c b/drivers/net/enic/vnic_wq.c
index ed090a3..6c4d4f7 100644
--- a/drivers/net/enic/vnic_wq.c
+++ b/drivers/net/enic/vnic_wq.c
@@ -37,7 +37,7 @@ static int vnic_wq_alloc_bufs(struct vnic_wq *wq)
vdev = wq->vdev;
for (i = 0; i < blks; i++) {
- wq->bufs[i] = kzalloc(VNIC_WQ_BUF_BLK_SZ, GFP_ATOMIC);
+ wq->bufs[i] = kzalloc(VNIC_WQ_BUF_BLK_SZ(count), GFP_ATOMIC);
if (!wq->bufs[i]) {
pr_err("Failed to alloc wq_bufs\n");
return -ENOMEM;
@@ -46,14 +46,14 @@ static int vnic_wq_alloc_bufs(struct vnic_wq *wq)
for (i = 0; i < blks; i++) {
buf = wq->bufs[i];
- for (j = 0; j < VNIC_WQ_BUF_BLK_ENTRIES; j++) {
- buf->index = i * VNIC_WQ_BUF_BLK_ENTRIES + j;
+ for (j = 0; j < VNIC_WQ_BUF_BLK_ENTRIES(count); j++) {
+ buf->index = i * VNIC_WQ_BUF_BLK_ENTRIES(count) + j;
buf->desc = (u8 *)wq->ring.descs +
wq->ring.desc_size * buf->index;
if (buf->index + 1 == count) {
buf->next = wq->bufs[0];
break;
- } else if (j + 1 == VNIC_WQ_BUF_BLK_ENTRIES) {
+ } else if (j + 1 == VNIC_WQ_BUF_BLK_ENTRIES(count)) {
buf->next = wq->bufs[i + 1];
} else {
buf->next = buf + 1;
@@ -119,10 +119,11 @@ void vnic_wq_init_start(struct vnic_wq *wq, unsigned int cq_index,
unsigned int error_interrupt_offset)
{
u64 paddr;
+ unsigned int count = wq->ring.desc_count;
paddr = (u64)wq->ring.base_addr | VNIC_PADDR_TARGET;
writeq(paddr, &wq->ctrl->ring_base);
- iowrite32(wq->ring.desc_count, &wq->ctrl->ring_size);
+ iowrite32(count, &wq->ctrl->ring_size);
iowrite32(fetch_index, &wq->ctrl->fetch_index);
iowrite32(posted_index, &wq->ctrl->posted_index);
iowrite32(cq_index, &wq->ctrl->cq_index);
@@ -131,8 +132,8 @@ void vnic_wq_init_start(struct vnic_wq *wq, unsigned int cq_index,
iowrite32(0, &wq->ctrl->error_status);
wq->to_use = wq->to_clean =
- &wq->bufs[fetch_index / VNIC_WQ_BUF_BLK_ENTRIES]
- [fetch_index % VNIC_WQ_BUF_BLK_ENTRIES];
+ &wq->bufs[fetch_index / VNIC_WQ_BUF_BLK_ENTRIES(count)]
+ [fetch_index % VNIC_WQ_BUF_BLK_ENTRIES(count)];
}
void vnic_wq_init(struct vnic_wq *wq, unsigned int cq_index,
diff --git a/drivers/net/enic/vnic_wq.h b/drivers/net/enic/vnic_wq.h
index 9c34d41..1c82139 100644
--- a/drivers/net/enic/vnic_wq.h
+++ b/drivers/net/enic/vnic_wq.h
@@ -60,12 +60,16 @@ struct vnic_wq_buf {
void *desc;
};
-/* Break the vnic_wq_buf allocations into blocks of 64 entries */
-#define VNIC_WQ_BUF_BLK_ENTRIES 64
-#define VNIC_WQ_BUF_BLK_SZ \
- (VNIC_WQ_BUF_BLK_ENTRIES * sizeof(struct vnic_wq_buf))
+/* Break the vnic_wq_buf allocations into blocks of 32/64 entries */
+#define VNIC_WQ_BUF_MIN_BLK_ENTRIES 32
+#define VNIC_WQ_BUF_DFLT_BLK_ENTRIES 64
+#define VNIC_WQ_BUF_BLK_ENTRIES(entries) \
+ ((unsigned int)((entries < VNIC_WQ_BUF_DFLT_BLK_ENTRIES) ? \
+ VNIC_WQ_BUF_MIN_BLK_ENTRIES : VNIC_WQ_BUF_DFLT_BLK_ENTRIES))
+#define VNIC_WQ_BUF_BLK_SZ(entries) \
+ (VNIC_WQ_BUF_BLK_ENTRIES(entries) * sizeof(struct vnic_wq_buf))
#define VNIC_WQ_BUF_BLKS_NEEDED(entries) \
- DIV_ROUND_UP(entries, VNIC_WQ_BUF_BLK_ENTRIES)
+ DIV_ROUND_UP(entries, VNIC_WQ_BUF_BLK_ENTRIES(entries))
#define VNIC_WQ_BUF_BLKS_MAX VNIC_WQ_BUF_BLKS_NEEDED(4096)
struct vnic_wq {
^ permalink raw reply related
* [net-next-2.6 PATCH 08/10] enic: Feature Add: Add loopback capability to enic devices
From: Vasanthy Kolluri @ 2010-06-24 20:51 UTC (permalink / raw)
To: davem; +Cc: netdev, scofeldm, vkolluri, roprabhu
In-Reply-To: <20100624204723.22595.42990.stgit@savbu-pc100.cisco.com>
From: Vasanthy Kolluri <vkolluri@cisco.com>
Hardware has the loopback capability to queue the packets transmitted from
a device to the receive queue of the same device. enic now supports the
loopback capability.
Signed-off-by: Scott Feldman <scofeldm@cisco.com>
Signed-off-by: Vasanthy Kolluri <vkolluri@cisco.com>
Signed-off-by: Roopa Prabhu <roprabhu@cisco.com>
---
drivers/net/enic/enic.h | 2 ++
drivers/net/enic/enic_main.c | 42 +++++++++++++++++++++++++++---------------
drivers/net/enic/enic_res.c | 1 +
drivers/net/enic/enic_res.h | 25 +++++++++++++------------
drivers/net/enic/vnic_enet.h | 2 ++
5 files changed, 45 insertions(+), 27 deletions(-)
diff --git a/drivers/net/enic/enic.h b/drivers/net/enic/enic.h
index 3588ef5..7280314 100644
--- a/drivers/net/enic/enic.h
+++ b/drivers/net/enic/enic.h
@@ -110,6 +110,8 @@ struct enic {
spinlock_t wq_lock[ENIC_WQ_MAX];
unsigned int wq_count;
struct vlan_group *vlan_group;
+ u16 loop_enable;
+ u16 loop_tag;
/* receive queue cache line section */
____cacheline_aligned struct vnic_rq rq[ENIC_RQ_MAX];
diff --git a/drivers/net/enic/enic_main.c b/drivers/net/enic/enic_main.c
index 413e362..eda5530 100644
--- a/drivers/net/enic/enic_main.c
+++ b/drivers/net/enic/enic_main.c
@@ -594,7 +594,7 @@ static irqreturn_t enic_isr_msix_notify(int irq, void *data)
static inline void enic_queue_wq_skb_cont(struct enic *enic,
struct vnic_wq *wq, struct sk_buff *skb,
- unsigned int len_left)
+ unsigned int len_left, int loopback)
{
skb_frag_t *frag;
@@ -606,13 +606,14 @@ static inline void enic_queue_wq_skb_cont(struct enic *enic,
frag->page_offset, frag->size,
PCI_DMA_TODEVICE),
frag->size,
- (len_left == 0)); /* EOP? */
+ (len_left == 0), /* EOP? */
+ loopback);
}
}
static inline void enic_queue_wq_skb_vlan(struct enic *enic,
struct vnic_wq *wq, struct sk_buff *skb,
- int vlan_tag_insert, unsigned int vlan_tag)
+ int vlan_tag_insert, unsigned int vlan_tag, int loopback)
{
unsigned int head_len = skb_headlen(skb);
unsigned int len_left = skb->len - head_len;
@@ -628,15 +629,15 @@ static inline void enic_queue_wq_skb_vlan(struct enic *enic,
head_len, PCI_DMA_TODEVICE),
head_len,
vlan_tag_insert, vlan_tag,
- eop);
+ eop, loopback);
if (!eop)
- enic_queue_wq_skb_cont(enic, wq, skb, len_left);
+ enic_queue_wq_skb_cont(enic, wq, skb, len_left, loopback);
}
static inline void enic_queue_wq_skb_csum_l4(struct enic *enic,
struct vnic_wq *wq, struct sk_buff *skb,
- int vlan_tag_insert, unsigned int vlan_tag)
+ int vlan_tag_insert, unsigned int vlan_tag, int loopback)
{
unsigned int head_len = skb_headlen(skb);
unsigned int len_left = skb->len - head_len;
@@ -656,15 +657,15 @@ static inline void enic_queue_wq_skb_csum_l4(struct enic *enic,
csum_offset,
hdr_len,
vlan_tag_insert, vlan_tag,
- eop);
+ eop, loopback);
if (!eop)
- enic_queue_wq_skb_cont(enic, wq, skb, len_left);
+ enic_queue_wq_skb_cont(enic, wq, skb, len_left, loopback);
}
static inline void enic_queue_wq_skb_tso(struct enic *enic,
struct vnic_wq *wq, struct sk_buff *skb, unsigned int mss,
- int vlan_tag_insert, unsigned int vlan_tag)
+ int vlan_tag_insert, unsigned int vlan_tag, int loopback)
{
unsigned int frag_len_left = skb_headlen(skb);
unsigned int len_left = skb->len - frag_len_left;
@@ -701,7 +702,7 @@ static inline void enic_queue_wq_skb_tso(struct enic *enic,
len,
mss, hdr_len,
vlan_tag_insert, vlan_tag,
- eop && (len == frag_len_left));
+ eop && (len == frag_len_left), loopback);
frag_len_left -= len;
offset += len;
}
@@ -727,7 +728,8 @@ static inline void enic_queue_wq_skb_tso(struct enic *enic,
dma_addr,
len,
(len_left == 0) &&
- (len == frag_len_left)); /* EOP? */
+ (len == frag_len_left), /* EOP? */
+ loopback);
frag_len_left -= len;
offset += len;
}
@@ -740,22 +742,26 @@ static inline void enic_queue_wq_skb(struct enic *enic,
unsigned int mss = skb_shinfo(skb)->gso_size;
unsigned int vlan_tag = 0;
int vlan_tag_insert = 0;
+ int loopback = 0;
if (enic->vlan_group && vlan_tx_tag_present(skb)) {
/* VLAN tag from trunking driver */
vlan_tag_insert = 1;
vlan_tag = vlan_tx_tag_get(skb);
+ } else if (enic->loop_enable) {
+ vlan_tag = enic->loop_tag;
+ loopback = 1;
}
if (mss)
enic_queue_wq_skb_tso(enic, wq, skb, mss,
- vlan_tag_insert, vlan_tag);
+ vlan_tag_insert, vlan_tag, loopback);
else if (skb->ip_summed == CHECKSUM_PARTIAL)
enic_queue_wq_skb_csum_l4(enic, wq, skb,
- vlan_tag_insert, vlan_tag);
+ vlan_tag_insert, vlan_tag, loopback);
else
enic_queue_wq_skb_vlan(enic, wq, skb,
- vlan_tag_insert, vlan_tag);
+ vlan_tag_insert, vlan_tag, loopback);
}
/* netif_tx_lock held, process context with BHs disabled, or BH */
@@ -1275,7 +1281,7 @@ static int enic_rq_alloc_buf(struct vnic_rq *rq)
struct enic *enic = vnic_dev_priv(rq->vdev);
struct net_device *netdev = enic->netdev;
struct sk_buff *skb;
- unsigned int len = netdev->mtu + ETH_HLEN;
+ unsigned int len = netdev->mtu + VLAN_ETH_HLEN;
unsigned int os_buf_index = 0;
dma_addr_t dma_addr;
@@ -2441,6 +2447,12 @@ static int __devinit enic_probe(struct pci_dev *pdev,
netdev->ethtool_ops = &enic_ethtool_ops;
netdev->features |= NETIF_F_HW_VLAN_TX | NETIF_F_HW_VLAN_RX;
+ if (ENIC_SETTING(enic, LOOP)) {
+ netdev->features &= ~NETIF_F_HW_VLAN_TX;
+ enic->loop_enable = 1;
+ enic->loop_tag = enic->config.loop_tag;
+ dev_info(dev, "loopback tag=0x%04x\n", enic->loop_tag);
+ }
if (ENIC_SETTING(enic, TXCSUM))
netdev->features |= NETIF_F_SG | NETIF_F_HW_CSUM;
if (ENIC_SETTING(enic, TSO))
diff --git a/drivers/net/enic/enic_res.c b/drivers/net/enic/enic_res.c
index 478928b..2cc7e27 100644
--- a/drivers/net/enic/enic_res.c
+++ b/drivers/net/enic/enic_res.c
@@ -70,6 +70,7 @@ int enic_get_vnic_config(struct enic *enic)
GET_CONFIG(intr_timer_type);
GET_CONFIG(intr_mode);
GET_CONFIG(intr_timer_usec);
+ GET_CONFIG(loop_tag);
c->wq_desc_count =
min_t(u32, ENIC_MAX_WQ_DESCS,
diff --git a/drivers/net/enic/enic_res.h b/drivers/net/enic/enic_res.h
index 3f6e039..8b25a07 100644
--- a/drivers/net/enic/enic_res.h
+++ b/drivers/net/enic/enic_res.h
@@ -43,7 +43,7 @@ static inline void enic_queue_wq_desc_ex(struct vnic_wq *wq,
void *os_buf, dma_addr_t dma_addr, unsigned int len,
unsigned int mss_or_csum_offset, unsigned int hdr_len,
int vlan_tag_insert, unsigned int vlan_tag,
- int offload_mode, int cq_entry, int sop, int eop)
+ int offload_mode, int cq_entry, int sop, int eop, int loopback)
{
struct wq_enet_desc *desc = vnic_wq_next_desc(wq);
@@ -56,61 +56,62 @@ static inline void enic_queue_wq_desc_ex(struct vnic_wq *wq,
0, /* fcoe_encap */
(u8)vlan_tag_insert,
(u16)vlan_tag,
- 0 /* loopback */);
+ (u8)loopback);
vnic_wq_post(wq, os_buf, dma_addr, len, sop, eop);
}
static inline void enic_queue_wq_desc_cont(struct vnic_wq *wq,
- void *os_buf, dma_addr_t dma_addr, unsigned int len, int eop)
+ void *os_buf, dma_addr_t dma_addr, unsigned int len,
+ int eop, int loopback)
{
enic_queue_wq_desc_ex(wq, os_buf, dma_addr, len,
0, 0, 0, 0, 0,
- eop, 0 /* !SOP */, eop);
+ eop, 0 /* !SOP */, eop, loopback);
}
static inline void enic_queue_wq_desc(struct vnic_wq *wq, void *os_buf,
dma_addr_t dma_addr, unsigned int len, int vlan_tag_insert,
- unsigned int vlan_tag, int eop)
+ unsigned int vlan_tag, int eop, int loopback)
{
enic_queue_wq_desc_ex(wq, os_buf, dma_addr, len,
0, 0, vlan_tag_insert, vlan_tag,
WQ_ENET_OFFLOAD_MODE_CSUM,
- eop, 1 /* SOP */, eop);
+ eop, 1 /* SOP */, eop, loopback);
}
static inline void enic_queue_wq_desc_csum(struct vnic_wq *wq,
void *os_buf, dma_addr_t dma_addr, unsigned int len,
int ip_csum, int tcpudp_csum, int vlan_tag_insert,
- unsigned int vlan_tag, int eop)
+ unsigned int vlan_tag, int eop, int loopback)
{
enic_queue_wq_desc_ex(wq, os_buf, dma_addr, len,
(ip_csum ? 1 : 0) + (tcpudp_csum ? 2 : 0),
0, vlan_tag_insert, vlan_tag,
WQ_ENET_OFFLOAD_MODE_CSUM,
- eop, 1 /* SOP */, eop);
+ eop, 1 /* SOP */, eop, loopback);
}
static inline void enic_queue_wq_desc_csum_l4(struct vnic_wq *wq,
void *os_buf, dma_addr_t dma_addr, unsigned int len,
unsigned int csum_offset, unsigned int hdr_len,
- int vlan_tag_insert, unsigned int vlan_tag, int eop)
+ int vlan_tag_insert, unsigned int vlan_tag, int eop, int loopback)
{
enic_queue_wq_desc_ex(wq, os_buf, dma_addr, len,
csum_offset, hdr_len, vlan_tag_insert, vlan_tag,
WQ_ENET_OFFLOAD_MODE_CSUM_L4,
- eop, 1 /* SOP */, eop);
+ eop, 1 /* SOP */, eop, loopback);
}
static inline void enic_queue_wq_desc_tso(struct vnic_wq *wq,
void *os_buf, dma_addr_t dma_addr, unsigned int len,
unsigned int mss, unsigned int hdr_len, int vlan_tag_insert,
- unsigned int vlan_tag, int eop)
+ unsigned int vlan_tag, int eop, int loopback)
{
enic_queue_wq_desc_ex(wq, os_buf, dma_addr, len,
mss, hdr_len, vlan_tag_insert, vlan_tag,
WQ_ENET_OFFLOAD_MODE_TSO,
- eop, 1 /* SOP */, eop);
+ eop, 1 /* SOP */, eop, loopback);
}
static inline void enic_queue_rq_desc(struct vnic_rq *rq,
diff --git a/drivers/net/enic/vnic_enet.h b/drivers/net/enic/vnic_enet.h
index 8eeb675..42baaa1 100644
--- a/drivers/net/enic/vnic_enet.h
+++ b/drivers/net/enic/vnic_enet.h
@@ -35,6 +35,7 @@ struct vnic_enet_config {
u8 intr_mode;
char devname[16];
u32 intr_timer_usec;
+ u16 loop_tag;
};
#define VENETF_TSO 0x1 /* TSO enabled */
@@ -48,5 +49,6 @@ struct vnic_enet_config {
#define VENETF_RSSHASH_TCPIPV6 0x100 /* Hash on TCP + IPv6 fields */
#define VENETF_RSSHASH_IPV6_EX 0x200 /* Hash on IPv6 extended fields */
#define VENETF_RSSHASH_TCPIPV6_EX 0x400 /* Hash on TCP + IPv6 ext. fields */
+#define VENETF_LOOP 0x800 /* Loopback enabled */
#endif /* _VNIC_ENIC_H_ */
^ permalink raw reply related
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