* [PATCH] arm: sa1100: move irda header to linux/platform_data
From: Dmitry Eremin-Solenikov @ 2014-12-23 22:14 UTC (permalink / raw)
To: Russell King, Samuel Ortiz; +Cc: linux-arm-kernel, netdev
In the end asm/mach/irda.h header is not used by anybody except sa1100.
Move the header to the platform data includes dir and rename it to
irda-sa11x0.h.
Signed-off-by: Dmitry Eremin-Solenikov <dbaryshkov@gmail.com>
---
arch/arm/mach-sa1100/assabet.c | 2 +-
arch/arm/mach-sa1100/collie.c | 2 +-
arch/arm/mach-sa1100/h3100.c | 2 +-
arch/arm/mach-sa1100/h3600.c | 2 +-
drivers/net/irda/sa1100_ir.c | 2 +-
.../asm/mach/irda.h => include/linux/platform_data/irda-sa11x0.h | 0
6 files changed, 5 insertions(+), 5 deletions(-)
rename arch/arm/include/asm/mach/irda.h => include/linux/platform_data/irda-sa11x0.h (100%)
diff --git a/arch/arm/mach-sa1100/assabet.c b/arch/arm/mach-sa1100/assabet.c
index 7dd894e..d28ecb9 100644
--- a/arch/arm/mach-sa1100/assabet.c
+++ b/arch/arm/mach-sa1100/assabet.c
@@ -37,7 +37,7 @@
#include <asm/mach/arch.h>
#include <asm/mach/flash.h>
-#include <asm/mach/irda.h>
+#include <linux/platform_data/irda-sa11x0.h>
#include <asm/mach/map.h>
#include <mach/assabet.h>
#include <linux/platform_data/mfd-mcp-sa11x0.h>
diff --git a/arch/arm/mach-sa1100/collie.c b/arch/arm/mach-sa1100/collie.c
index 108939f..0a816e2 100644
--- a/arch/arm/mach-sa1100/collie.c
+++ b/arch/arm/mach-sa1100/collie.c
@@ -43,7 +43,7 @@
#include <asm/mach/arch.h>
#include <asm/mach/flash.h>
#include <asm/mach/map.h>
-#include <asm/mach/irda.h>
+#include <linux/platform_data/irda-sa11x0.h>
#include <asm/hardware/scoop.h>
#include <asm/mach/sharpsl_param.h>
diff --git a/arch/arm/mach-sa1100/h3100.c b/arch/arm/mach-sa1100/h3100.c
index 3c43219..c6b4120 100644
--- a/arch/arm/mach-sa1100/h3100.c
+++ b/arch/arm/mach-sa1100/h3100.c
@@ -18,7 +18,7 @@
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
-#include <asm/mach/irda.h>
+#include <linux/platform_data/irda-sa11x0.h>
#include <mach/h3xxx.h>
#include <mach/irqs.h>
diff --git a/arch/arm/mach-sa1100/h3600.c b/arch/arm/mach-sa1100/h3600.c
index 5be54c2..118338e 100644
--- a/arch/arm/mach-sa1100/h3600.c
+++ b/arch/arm/mach-sa1100/h3600.c
@@ -18,7 +18,7 @@
#include <asm/mach-types.h>
#include <asm/mach/arch.h>
-#include <asm/mach/irda.h>
+#include <linux/platform_data/irda-sa11x0.h>
#include <mach/h3xxx.h>
#include <mach/irqs.h>
diff --git a/drivers/net/irda/sa1100_ir.c b/drivers/net/irda/sa1100_ir.c
index 42fde9e..dd14722 100644
--- a/drivers/net/irda/sa1100_ir.c
+++ b/drivers/net/irda/sa1100_ir.c
@@ -38,7 +38,7 @@
#include <net/irda/irda_device.h>
#include <mach/hardware.h>
-#include <asm/mach/irda.h>
+#include <linux/platform_data/irda-sa11x0.h>
static int power_level = 3;
static int tx_lpm;
diff --git a/arch/arm/include/asm/mach/irda.h b/include/linux/platform_data/irda-sa11x0.h
similarity index 100%
rename from arch/arm/include/asm/mach/irda.h
rename to include/linux/platform_data/irda-sa11x0.h
--
2.1.3
^ permalink raw reply related
* Re: [PATCH net] net: Generalize ndo_gso_check to ndo_features_check
From: Tom Herbert @ 2014-12-23 21:54 UTC (permalink / raw)
To: Sathya Perla
Cc: Jesse Gross, David Miller, Linux Netdev List, Joe Stringer,
Eric Dumazet
In-Reply-To: <CF9D1877D81D214CB0CA0669EFAE020C68D41FA3@CMEXMB1.ad.emulex.com>
On Mon, Dec 22, 2014 at 10:24 PM, Sathya Perla <Sathya.Perla@emulex.com> wrote:
>> -----Original Message-----
>> From: netdev-owner@vger.kernel.org [mailto:netdev-
>> owner@vger.kernel.org] On Behalf Of Tom Herbert
>>
>> On Mon, Dec 22, 2014 at 8:03 AM, Jesse Gross <jesse@nicira.com> wrote:
>> > GSO isn't the only offload feature with restrictions that
>> > potentially can't be expressed with the current features mechanism.
>> > Checksum is another although it's a general issue that could in
>> > theory apply to anything. Even if it may be possible to
>> > implement these restrictions in other ways, it can result in
>> > duplicate code or inefficient per-packet behavior.
>> >
>> > This generalizes ndo_gso_check so that drivers can remove any
>> > features that don't make sense for a given packet, similar to
>> > netif_skb_features(). It also converts existing driver
>> > restrictions to the new format, completing the work that was
>> > done to support tunnel protocols since the issues apply to
>> > checksums as well.
>> >
>> It's a nice feature, but I really hope that this is not used for
>> checksums. We already have a sufficiently general interface for that
>> and checksum is already computed in drivers to work around HW bugs.
>>
> The ndo_featureas_check() interface that includes a means to report
> inability to compute inner checksums on some tunnel types, seems like
> a useful feature. The Skyhawk-R NIC can support inner csum offload for
> either vxlan or nv-gre, but not both simultaneously. So, this ndo_
> is useful in reporting this situation.
> This would also obviate the need to have extra code in the drivers to
> compute csums in the above scenario.
>
You could use it for that, but many drivers already call
skb_checksum_help and I really doubt it makes sense to change all of
those. Besides that, I don't think we should be "encouraging" vendors
to continue developing NICs that do protocol specific checksums. The
general interface (NETIF_HW_CSUM) is incredibly simple and obviates a
whole bunch of complexity in drivers to figure out whether it can
checksum a packet.
Tom
> thanks,
> -Sathya
^ permalink raw reply
* Re: [PATCH net-next 08/11] net: ixgbe: convert to timecounter adjtime.
From: Richard Cochran @ 2014-12-23 21:42 UTC (permalink / raw)
To: Jeff Kirsher
Cc: netdev, linux-kernel, Amir Vadai, Ariel Elior, Carolyn Wyborny,
David Miller, Frank Li, John Stultz, Matthew Vick,
Miroslav Lichvar, Mugunthan V N, Or Gerlitz, Thomas Gleixner,
Tom Lendacky
In-Reply-To: <1419368839.2470.32.camel@jtkirshe-mobl>
On Tue, Dec 23, 2014 at 01:07:19PM -0800, Jeff Kirsher wrote:
> Just for sanity sake, I will have Phillip test the changes, but there is
> no need to hold this up from being committed in the mean time.
FYI, here is a test that may show the improved behavior when comparing
before/after.
1. Start ptp4l, let it run long enough to find the frequency offset.
2. Stop ptp4l with ^C.
3. Wait a bit, to let the clock drift away.
4. Restart ptp4l, it will now start with the frequency offset learned
in step 1.
5. Notice the the offsets in states s0 -> s1 -> s2.
There will likely be less offset error with the patches applied.
Thanks,
Richard
^ permalink raw reply
* Re: [PATCH net-next 08/11] net: ixgbe: convert to timecounter adjtime.
From: Jeff Kirsher @ 2014-12-23 21:07 UTC (permalink / raw)
To: Richard Cochran
Cc: netdev, linux-kernel, Amir Vadai, Ariel Elior, Carolyn Wyborny,
David Miller, Frank Li, John Stultz, Matthew Vick,
Miroslav Lichvar, Mugunthan V N, Or Gerlitz, Thomas Gleixner,
Tom Lendacky
In-Reply-To: <5d83679d541974c164cfc415c0bb171e2b363f16.1418504889.git.richardcochran@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 593 bytes --]
On Sun, 2014-12-21 at 19:47 +0100, Richard Cochran wrote:
> This patch changes the driver to use the new and improved method
> for adjusting the offset of a timecounter.
>
> Compile tested only.
>
> Signed-off-by: Richard Cochran <richardcochran@gmail.com>
Acked-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
Just for sanity sake, I will have Phillip test the changes, but there is
no need to hold this up from being committed in the mean time.
> ---
> drivers/net/ethernet/intel/ixgbe/ixgbe_ptp.c | 11 +----------
> 1 file changed, 1 insertion(+), 10 deletions(-)
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply
* Re: [PATCH net-next 07/11] net: igb: convert to timecounter adjtime.
From: Jeff Kirsher @ 2014-12-23 21:04 UTC (permalink / raw)
To: Richard Cochran
Cc: netdev, linux-kernel, Amir Vadai, Ariel Elior, Carolyn Wyborny,
David Miller, Frank Li, John Stultz, Matthew Vick,
Miroslav Lichvar, Mugunthan V N, Or Gerlitz, Thomas Gleixner,
Tom Lendacky
In-Reply-To: <bb15b44a539ec6da39812229b5fb0718bd6859f0.1418504889.git.richardcochran@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 418 bytes --]
On Sun, 2014-12-21 at 19:47 +0100, Richard Cochran wrote:
> This patch changes the driver to use the new and improved method
> for adjusting the offset of a timecounter.
>
> Signed-off-by: Richard Cochran <richardcochran@gmail.com>
Acked-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> ---
> drivers/net/ethernet/intel/igb/igb_ptp.c | 7 +------
> 1 file changed, 1 insertion(+), 6 deletions(-)
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply
* Re: [PATCH net-next 06/11] net: e1000e: convert to timecounter adjtime.
From: Jeff Kirsher @ 2014-12-23 21:04 UTC (permalink / raw)
To: Richard Cochran
Cc: netdev, linux-kernel, Amir Vadai, Ariel Elior, Carolyn Wyborny,
David Miller, Frank Li, John Stultz, Matthew Vick,
Miroslav Lichvar, Mugunthan V N, Or Gerlitz, Thomas Gleixner,
Tom Lendacky
In-Reply-To: <7455b879a8aab91f11c3082c2c8c1dc3ef71b96e.1418504889.git.richardcochran@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 415 bytes --]
On Sun, 2014-12-21 at 19:47 +0100, Richard Cochran wrote:
> This patch changes the driver to use the new and improved method
> for adjusting the offset of a timecounter.
>
> Signed-off-by: Richard Cochran <richardcochran@gmail.com>
Acked-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
> ---
> drivers/net/ethernet/intel/e1000e/ptp.c | 5 +----
> 1 file changed, 1 insertion(+), 4 deletions(-)
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply
* Re: [PATCH net-next 01/11] time: move the timecounter/cyclecounter code into its own file.
From: Jeff Kirsher @ 2014-12-23 21:03 UTC (permalink / raw)
To: Richard Cochran
Cc: netdev, linux-kernel, Amir Vadai, Ariel Elior, Carolyn Wyborny,
David Miller, Frank Li, John Stultz, Matthew Vick,
Miroslav Lichvar, Mugunthan V N, Or Gerlitz, Thomas Gleixner,
Tom Lendacky
In-Reply-To: <3698bac182b6c5aba4dd541afabc1a5d61db1d00.1418504887.git.richardcochran@gmail.com>
[-- Attachment #1: Type: text/plain, Size: 1600 bytes --]
On Sun, 2014-12-21 at 19:46 +0100, Richard Cochran wrote:
> The timecounter code has almost nothing to do with the clocksource
> code. Let it live in its own file. This will help isolate the
> timecounter users from the clocksource users in the source tree.
>
> Signed-off-by: Richard Cochran <richardcochran@gmail.com>
Acked-by: Jeff Kirsher <jeffrey.t.kirsher@intel.com>
For the Intel driver changes...
> ---
> drivers/net/ethernet/amd/xgbe/xgbe.h | 2 +-
> drivers/net/ethernet/broadcom/bnx2x/bnx2x.h | 2 +-
> drivers/net/ethernet/freescale/fec.h | 1 +
> drivers/net/ethernet/intel/e1000e/e1000.h | 2 +-
> drivers/net/ethernet/intel/igb/igb.h | 2 +-
> drivers/net/ethernet/intel/ixgbe/ixgbe.h | 2 +-
> drivers/net/ethernet/ti/cpts.h | 1 +
> include/clocksource/arm_arch_timer.h | 2 +-
> include/linux/clocksource.h | 102
> ----------------------
> include/linux/mlx4/device.h | 2 +-
> include/linux/timecounter.h | 122
> +++++++++++++++++++++++++++
> include/linux/types.h | 3 +
> kernel/time/Makefile | 2 +-
> kernel/time/clocksource.c | 76 -----------------
> kernel/time/timecounter.c | 95
> +++++++++++++++++++++
> sound/pci/hda/hda_priv.h | 2 +-
> 16 files changed, 231 insertions(+), 187 deletions(-)
> create mode 100644 include/linux/timecounter.h
> create mode 100644 kernel/time/timecounter.c
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply
* [PATCH] netlink/genetlink: pass network namespace to bind/unbind
From: Johannes Berg @ 2014-12-23 20:00 UTC (permalink / raw)
To: netdev; +Cc: Johannes Berg
From: Johannes Berg <johannes.berg@intel.com>
Netlink families can exist in multiple namespaces, and for the most
part multicast subscriptions are per network namespace. Thus it only
makes sense to have bind/unbind notifications per network namespace.
To achieve this, pass the network namespace of a given client socket
to the bind/unbind functions.
Also do this in generic netlink, and there also make sure that any
bind for multicast groups that only exist in init_net is rejected.
This isn't really a problem if it is accepted since a client in a
different namespace will never receive any notifications from such
a group, but it can confuse the family if not rejected (it's also
possible to silently (without telling the family) accept it, but it
would also have to be ignored on unbind so families that take any
kind of action on bind/unbind won't do unnecessary work for invalid
clients like that.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
include/linux/netlink.h | 4 ++--
include/net/genetlink.h | 4 ++--
kernel/audit.c | 2 +-
net/netfilter/nfnetlink.c | 2 +-
net/netlink/af_netlink.c | 21 +++++++++++----------
net/netlink/af_netlink.h | 8 ++++----
net/netlink/genetlink.c | 12 +++++++-----
7 files changed, 28 insertions(+), 25 deletions(-)
diff --git a/include/linux/netlink.h b/include/linux/netlink.h
index 9e572daa15d5..02fc86d2348e 100644
--- a/include/linux/netlink.h
+++ b/include/linux/netlink.h
@@ -46,8 +46,8 @@ struct netlink_kernel_cfg {
unsigned int flags;
void (*input)(struct sk_buff *skb);
struct mutex *cb_mutex;
- int (*bind)(int group);
- void (*unbind)(int group);
+ int (*bind)(struct net *net, int group);
+ void (*unbind)(struct net *net, int group);
bool (*compare)(struct net *net, struct sock *sk);
};
diff --git a/include/net/genetlink.h b/include/net/genetlink.h
index 3ed31e5a445b..84125088c309 100644
--- a/include/net/genetlink.h
+++ b/include/net/genetlink.h
@@ -56,8 +56,8 @@ struct genl_family {
void (*post_doit)(const struct genl_ops *ops,
struct sk_buff *skb,
struct genl_info *info);
- int (*mcast_bind)(int group);
- void (*mcast_unbind)(int group);
+ int (*mcast_bind)(struct net *net, int group);
+ void (*mcast_unbind)(struct net *net, int group);
struct nlattr ** attrbuf; /* private */
const struct genl_ops * ops; /* private */
const struct genl_multicast_group *mcgrps; /* private */
diff --git a/kernel/audit.c b/kernel/audit.c
index 1f37f15117e5..0264ab84c446 100644
--- a/kernel/audit.c
+++ b/kernel/audit.c
@@ -1100,7 +1100,7 @@ static void audit_receive(struct sk_buff *skb)
}
/* Run custom bind function on netlink socket group connect or bind requests. */
-static int audit_bind(int group)
+static int audit_bind(struct net *net, int group)
{
if (!capable(CAP_AUDIT_READ))
return -EPERM;
diff --git a/net/netfilter/nfnetlink.c b/net/netfilter/nfnetlink.c
index 13c2e17bbe27..cde4a6702fa3 100644
--- a/net/netfilter/nfnetlink.c
+++ b/net/netfilter/nfnetlink.c
@@ -463,7 +463,7 @@ static void nfnetlink_rcv(struct sk_buff *skb)
}
#ifdef CONFIG_MODULES
-static int nfnetlink_bind(int group)
+static int nfnetlink_bind(struct net *net, int group)
{
const struct nfnetlink_subsystem *ss;
int type;
diff --git a/net/netlink/af_netlink.c b/net/netlink/af_netlink.c
index 07a903de4439..5fe199abfa41 100644
--- a/net/netlink/af_netlink.c
+++ b/net/netlink/af_netlink.c
@@ -1161,8 +1161,8 @@ static int netlink_create(struct net *net, struct socket *sock, int protocol,
struct module *module = NULL;
struct mutex *cb_mutex;
struct netlink_sock *nlk;
- int (*bind)(int group);
- void (*unbind)(int group);
+ int (*bind)(struct net *net, int group);
+ void (*unbind)(struct net *net, int group);
int err = 0;
sock->state = SS_UNCONNECTED;
@@ -1271,7 +1271,7 @@ static int netlink_release(struct socket *sock)
for (i = 0; i < nlk->ngroups; i++)
if (test_bit(i, nlk->groups))
- nlk->netlink_unbind(i + 1);
+ nlk->netlink_unbind(sock_net(sk), i + 1);
}
kfree(nlk->groups);
nlk->groups = NULL;
@@ -1438,8 +1438,9 @@ static int netlink_realloc_groups(struct sock *sk)
}
static void netlink_undo_bind(int group, long unsigned int groups,
- struct netlink_sock *nlk)
+ struct sock *sk)
{
+ struct netlink_sock *nlk = nlk_sk(sk);
int undo;
if (!nlk->netlink_unbind)
@@ -1447,7 +1448,7 @@ static void netlink_undo_bind(int group, long unsigned int groups,
for (undo = 0; undo < group; undo++)
if (test_bit(undo, &groups))
- nlk->netlink_unbind(undo);
+ nlk->netlink_unbind(sock_net(sk), undo);
}
static int netlink_bind(struct socket *sock, struct sockaddr *addr,
@@ -1485,10 +1486,10 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr,
for (group = 0; group < nlk->ngroups; group++) {
if (!test_bit(group, &groups))
continue;
- err = nlk->netlink_bind(group);
+ err = nlk->netlink_bind(net, group);
if (!err)
continue;
- netlink_undo_bind(group, groups, nlk);
+ netlink_undo_bind(group, groups, sk);
return err;
}
}
@@ -1498,7 +1499,7 @@ static int netlink_bind(struct socket *sock, struct sockaddr *addr,
netlink_insert(sk, net, nladdr->nl_pid) :
netlink_autobind(sock);
if (err) {
- netlink_undo_bind(nlk->ngroups, groups, nlk);
+ netlink_undo_bind(nlk->ngroups, groups, sk);
return err;
}
}
@@ -2149,7 +2150,7 @@ static int netlink_setsockopt(struct socket *sock, int level, int optname,
if (!val || val - 1 >= nlk->ngroups)
return -EINVAL;
if (optname == NETLINK_ADD_MEMBERSHIP && nlk->netlink_bind) {
- err = nlk->netlink_bind(val);
+ err = nlk->netlink_bind(sock_net(sk), val);
if (err)
return err;
}
@@ -2158,7 +2159,7 @@ static int netlink_setsockopt(struct socket *sock, int level, int optname,
optname == NETLINK_ADD_MEMBERSHIP);
netlink_table_ungrab();
if (optname == NETLINK_DROP_MEMBERSHIP && nlk->netlink_unbind)
- nlk->netlink_unbind(val);
+ nlk->netlink_unbind(sock_net(sk), val);
err = 0;
break;
diff --git a/net/netlink/af_netlink.h b/net/netlink/af_netlink.h
index b20a1731759b..f123a88496f8 100644
--- a/net/netlink/af_netlink.h
+++ b/net/netlink/af_netlink.h
@@ -39,8 +39,8 @@ struct netlink_sock {
struct mutex *cb_mutex;
struct mutex cb_def_mutex;
void (*netlink_rcv)(struct sk_buff *skb);
- int (*netlink_bind)(int group);
- void (*netlink_unbind)(int group);
+ int (*netlink_bind)(struct net *net, int group);
+ void (*netlink_unbind)(struct net *net, int group);
struct module *module;
#ifdef CONFIG_NETLINK_MMAP
struct mutex pg_vec_lock;
@@ -65,8 +65,8 @@ struct netlink_table {
unsigned int groups;
struct mutex *cb_mutex;
struct module *module;
- int (*bind)(int group);
- void (*unbind)(int group);
+ int (*bind)(struct net *net, int group);
+ void (*unbind)(struct net *net, int group);
bool (*compare)(struct net *net, struct sock *sock);
int registered;
};
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index 05bf40bbd189..91566ed36c43 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -983,7 +983,7 @@ static struct genl_multicast_group genl_ctrl_groups[] = {
{ .name = "notify", },
};
-static int genl_bind(int group)
+static int genl_bind(struct net *net, int group)
{
int i, err;
bool found = false;
@@ -997,8 +997,10 @@ static int genl_bind(int group)
group < f->mcgrp_offset + f->n_mcgrps) {
int fam_grp = group - f->mcgrp_offset;
- if (f->mcast_bind)
- err = f->mcast_bind(fam_grp);
+ if (!f->netnsok && net != &init_net)
+ err = -ENOENT;
+ else if (f->mcast_bind)
+ err = f->mcast_bind(net, fam_grp);
else
err = 0;
found = true;
@@ -1014,7 +1016,7 @@ static int genl_bind(int group)
return err;
}
-static void genl_unbind(int group)
+static void genl_unbind(struct net *net, int group)
{
int i;
bool found = false;
@@ -1029,7 +1031,7 @@ static void genl_unbind(int group)
int fam_grp = group - f->mcgrp_offset;
if (f->mcast_unbind)
- f->mcast_unbind(fam_grp);
+ f->mcast_unbind(net, fam_grp);
found = true;
break;
}
--
2.1.1
^ permalink raw reply related
* Re: [PATCH net] neigh: remove next ptr from struct neigh_table
From: Cong Wang @ 2014-12-23 19:57 UTC (permalink / raw)
To: Nicolas Dichtel; +Cc: David Miller, Linux Kernel Network Developers
In-Reply-To: <1419353437-4213-1-git-send-email-nicolas.dichtel@6wind.com>
On Tue, Dec 23, 2014 at 8:50 AM, Nicolas Dichtel
<nicolas.dichtel@6wind.com> wrote:
> After commit
> d7480fd3b173 ("neigh: remove dynamic neigh table registration support"),
> this field is not used anymore.
>
> CC: Cong Wang <xiyou.wangcong@gmail.com>
> Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
Acked-by: Cong Wang <xiyou.wangcong@gmail.com>
Thanks for fixing this leftover!
^ permalink raw reply
* [PATCH v2] genetlink: pass multicast bind/unbind to families
From: Johannes Berg @ 2014-12-23 19:54 UTC (permalink / raw)
To: netdev; +Cc: Johannes Berg
From: Johannes Berg <johannes.berg@intel.com>
In order to make the newly fixed multicast bind/unbind
functionality in generic netlink, pass them down to the
appropriate family.
Signed-off-by: Johannes Berg <johannes.berg@intel.com>
---
include/net/genetlink.h | 5 +++++
net/netlink/genetlink.c | 59 +++++++++++++++++++++++++++++++++++++++++++++++++
2 files changed, 64 insertions(+)
diff --git a/include/net/genetlink.h b/include/net/genetlink.h
index 38620da4aa7a..3ed31e5a445b 100644
--- a/include/net/genetlink.h
+++ b/include/net/genetlink.h
@@ -31,6 +31,9 @@ struct genl_info;
* do additional, common, filtering and return an error
* @post_doit: called after an operation's doit callback, it may
* undo operations done by pre_doit, for example release locks
+ * @mcast_bind: a socket bound to the given multicast group (which
+ * is given as the offset into the groups array)
+ * @mcast_unbind: a socket was unbound from the given multicast group
* @attrbuf: buffer to store parsed attributes
* @family_list: family list
* @mcgrps: multicast groups used by this family (private)
@@ -53,6 +56,8 @@ struct genl_family {
void (*post_doit)(const struct genl_ops *ops,
struct sk_buff *skb,
struct genl_info *info);
+ int (*mcast_bind)(int group);
+ void (*mcast_unbind)(int group);
struct nlattr ** attrbuf; /* private */
const struct genl_ops * ops; /* private */
const struct genl_multicast_group *mcgrps; /* private */
diff --git a/net/netlink/genetlink.c b/net/netlink/genetlink.c
index 76393f2f4b22..05bf40bbd189 100644
--- a/net/netlink/genetlink.c
+++ b/net/netlink/genetlink.c
@@ -983,11 +983,70 @@ static struct genl_multicast_group genl_ctrl_groups[] = {
{ .name = "notify", },
};
+static int genl_bind(int group)
+{
+ int i, err;
+ bool found = false;
+
+ down_read(&cb_lock);
+ for (i = 0; i < GENL_FAM_TAB_SIZE; i++) {
+ struct genl_family *f;
+
+ list_for_each_entry(f, genl_family_chain(i), family_list) {
+ if (group >= f->mcgrp_offset &&
+ group < f->mcgrp_offset + f->n_mcgrps) {
+ int fam_grp = group - f->mcgrp_offset;
+
+ if (f->mcast_bind)
+ err = f->mcast_bind(fam_grp);
+ else
+ err = 0;
+ found = true;
+ break;
+ }
+ }
+ }
+ up_read(&cb_lock);
+
+ if (WARN_ON(!found))
+ err = 0;
+
+ return err;
+}
+
+static void genl_unbind(int group)
+{
+ int i;
+ bool found = false;
+
+ down_read(&cb_lock);
+ for (i = 0; i < GENL_FAM_TAB_SIZE; i++) {
+ struct genl_family *f;
+
+ list_for_each_entry(f, genl_family_chain(i), family_list) {
+ if (group >= f->mcgrp_offset &&
+ group < f->mcgrp_offset + f->n_mcgrps) {
+ int fam_grp = group - f->mcgrp_offset;
+
+ if (f->mcast_unbind)
+ f->mcast_unbind(fam_grp);
+ found = true;
+ break;
+ }
+ }
+ }
+ up_read(&cb_lock);
+
+ WARN_ON(!found);
+}
+
static int __net_init genl_pernet_init(struct net *net)
{
struct netlink_kernel_cfg cfg = {
.input = genl_rcv,
.flags = NL_CFG_F_NONROOT_RECV,
+ .bind = genl_bind,
+ .unbind = genl_unbind,
};
/* we'll bump the group number right afterwards */
--
2.1.1
^ permalink raw reply related
* Re: [PATCH net] net: Reset secmark when scrubbing packet
From: Flavio Leitner @ 2014-12-23 19:28 UTC (permalink / raw)
To: Thomas Graf; +Cc: davem, netdev
In-Reply-To: <efb09aca5173a9a18f15066c33a4998ed70bd34a.1419293504.git.tgraf@suug.ch>
On Tuesday, December 23, 2014 01:13:18 AM Thomas Graf wrote:
>
> skb_scrub_packet() is called when a packet switches between a context
> such as between underlay and overlay, between namespaces, or between
> L3 subnets.
>
> While we already scrub the packet mark, connection tracking entry,
> and cached destination, the security mark/context is left intact.
>
> It seems wrong to inherit the security context of a packet when going
> from overlay to underlay or across forwarding paths.
>
> Signed-off-by: Thomas Graf <tgraf@suug.ch>
> ---
> net/core/skbuff.c | 1 +
> 1 file changed, 1 insertion(+)
Acked-by: Flavio Leitner <fbl@sysclose.org>
^ permalink raw reply
* [PATCH] net: incorrect use of init_completion fixup
From: Nicholas Mc Guire @ 2014-12-23 17:47 UTC (permalink / raw)
To: Rasesh Mody; +Cc: netdev, linux-kernel, Nicholas Mc Guire
The second init_completion call should be a reinit_completion here.
patch is against 3.18.0 linux-next
Signed-off-by: Nicholas Mc Guire <der.herr@hofr.at>
---
drivers/net/ethernet/brocade/bna/bnad_debugfs.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/brocade/bna/bnad_debugfs.c b/drivers/net/ethernet/brocade/bna/bnad_debugfs.c
index 7d6aa8c..619083a 100644
--- a/drivers/net/ethernet/brocade/bna/bnad_debugfs.c
+++ b/drivers/net/ethernet/brocade/bna/bnad_debugfs.c
@@ -172,7 +172,7 @@ bnad_get_debug_drvinfo(struct bnad *bnad, void *buffer, u32 len)
/* Retrieve flash partition info */
fcomp.comp_status = 0;
- init_completion(&fcomp.comp);
+ reinit_completion(&fcomp.comp);
spin_lock_irqsave(&bnad->bna_lock, flags);
ret = bfa_nw_flash_get_attr(&bnad->bna.flash, &drvinfo->flash_attr,
bnad_cb_completion, &fcomp);
--
1.7.10.4
^ permalink raw reply related
* [PATCH net] neigh: remove next ptr from struct neigh_table
From: Nicolas Dichtel @ 2014-12-23 16:50 UTC (permalink / raw)
To: davem; +Cc: netdev, Nicolas Dichtel, Cong Wang
After commit
d7480fd3b173 ("neigh: remove dynamic neigh table registration support"),
this field is not used anymore.
CC: Cong Wang <xiyou.wangcong@gmail.com>
Signed-off-by: Nicolas Dichtel <nicolas.dichtel@6wind.com>
---
include/net/neighbour.h | 1 -
1 file changed, 1 deletion(-)
diff --git a/include/net/neighbour.h b/include/net/neighbour.h
index eb070b3674a1..76f708486aae 100644
--- a/include/net/neighbour.h
+++ b/include/net/neighbour.h
@@ -190,7 +190,6 @@ struct neigh_hash_table {
struct neigh_table {
- struct neigh_table *next;
int family;
int entry_size;
int key_len;
--
2.1.0
^ permalink raw reply related
* Re: [PATCH] bonding: change error message to debug message in __bond_release_one()
From: Andy Gospodarek @ 2014-12-23 16:02 UTC (permalink / raw)
To: Wengang Wang; +Cc: netdev, dingtianhong
In-Reply-To: <1419297876-1412-1-git-send-email-wen.gang.wang@oracle.com>
On Tue, Dec 23, 2014 at 09:24:36AM +0800, Wengang Wang wrote:
> In __bond_release_one(), when the interface is not a slave or not a slave of
> "this" master, it log error message.
>
> The message actually should be a debug message matching what bond_enslave()
> does.
>
> Signed-off-by: Wengang Wang <wen.gang.wang@oracle.com>
Signed-off-by: Andy Gospodarek <gospo@cumulusnetworks.com>
> ---
> drivers/net/bonding/bond_main.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/drivers/net/bonding/bond_main.c b/drivers/net/bonding/bond_main.c
> index 184c434..0dceba1 100644
> --- a/drivers/net/bonding/bond_main.c
> +++ b/drivers/net/bonding/bond_main.c
> @@ -1648,7 +1648,7 @@ static int __bond_release_one(struct net_device *bond_dev,
> /* slave is not a slave or master is not master of this slave */
> if (!(slave_dev->flags & IFF_SLAVE) ||
> !netdev_has_upper_dev(slave_dev, bond_dev)) {
> - netdev_err(bond_dev, "cannot release %s\n",
> + netdev_dbg(bond_dev, "cannot release %s\n",
> slave_dev->name);
> return -EINVAL;
> }
> --
> 1.8.3.1
>
^ permalink raw reply
* [PATCH] can: kvaser_usb: Add support for the Usbcan-II family
From: Ahmed S. Darwish @ 2014-12-23 15:53 UTC (permalink / raw)
To: Olivier Sobrie, Oliver Hartkopp, Wolfgang Grandegger,
Marc Kleine-Budde
Cc: David S. Miller, Paul Gortmaker, Linux-CAN, netdev, LKML
In-Reply-To: <20141223154654.GB6460@vivalin-002>
From: Ahmed S. Darwish <ahmed.darwish@valeo.com>
CAN to USB interfaces sold by the Swedish manufacturer Kvaser are
divided into two major families: 'Leaf', and 'UsbcanII'. From an
Operating System perspective, the firmware of both families behave
in a not too drastically different fashion.
This patch adds support for the UsbcanII family of devices to the
current Kvaser Leaf-only driver.
CAN frames sending, receiving, and error handling paths has been
tested using the dual-channel "Kvaser USBcan II HS/LS" dongle. It
should also work nicely with other products in the same category.
Signed-off-by: Ahmed S. Darwish <ahmed.darwish@valeo.com>
---
drivers/net/can/usb/kvaser_usb.c | 630 +++++++++++++++++++++++++++++++--------
1 file changed, 505 insertions(+), 125 deletions(-)
(Generated over 3.19.0-rc1 + generic bugfix at
can-kvaser_usb-Don-t-free-packets-when-tight-on-URBs.patch)
diff --git a/drivers/net/can/usb/kvaser_usb.c b/drivers/net/can/usb/kvaser_usb.c
index 34c35d8..e7076da 100644
--- a/drivers/net/can/usb/kvaser_usb.c
+++ b/drivers/net/can/usb/kvaser_usb.c
@@ -6,12 +6,15 @@
* Parts of this driver are based on the following:
* - Kvaser linux leaf driver (version 4.78)
* - CAN driver for esd CAN-USB/2
+ * - Kvaser linux usbcanII driver (version 5.3)
*
* Copyright (C) 2002-2006 KVASER AB, Sweden. All rights reserved.
* Copyright (C) 2010 Matthias Fuchs <matthias.fuchs@esd.eu>, esd gmbh
* Copyright (C) 2012 Olivier Sobrie <olivier@sobrie.be>
+ * Copyright (C) 2014 Valeo Corporation
*/
+#include <linux/kernel.h>
#include <linux/completion.h>
#include <linux/module.h>
#include <linux/netdevice.h>
@@ -21,6 +24,18 @@
#include <linux/can/dev.h>
#include <linux/can/error.h>
+#define MAX(a, b) ((a) > (b) ? (a) : (b))
+
+/*
+ * Kvaser USB CAN dongles are divided into two major families:
+ * - Leaf: Based on Renesas M32C, running firmware labeled as 'filo'
+ * - UsbcanII: Based on Renesas M16C, running firmware labeled as 'helios'
+ */
+enum kvaser_usb_family {
+ KVASER_LEAF,
+ KVASER_USBCAN,
+};
+
#define MAX_TX_URBS 16
#define MAX_RX_URBS 4
#define START_TIMEOUT 1000 /* msecs */
@@ -29,9 +44,12 @@
#define USB_RECV_TIMEOUT 1000 /* msecs */
#define RX_BUFFER_SIZE 3072
#define CAN_USB_CLOCK 8000000
-#define MAX_NET_DEVICES 3
+#define LEAF_MAX_NET_DEVICES 3
+#define USBCAN_MAX_NET_DEVICES 2
+#define MAX_NET_DEVICES MAX(LEAF_MAX_NET_DEVICES, \
+ USBCAN_MAX_NET_DEVICES)
-/* Kvaser USB devices */
+/* Leaf USB devices */
#define KVASER_VENDOR_ID 0x0bfd
#define USB_LEAF_DEVEL_PRODUCT_ID 10
#define USB_LEAF_LITE_PRODUCT_ID 11
@@ -55,6 +73,16 @@
#define USB_CAN_R_PRODUCT_ID 39
#define USB_LEAF_LITE_V2_PRODUCT_ID 288
#define USB_MINI_PCIE_HS_PRODUCT_ID 289
+#define LEAF_PRODUCT_ID(id) (id >= USB_LEAF_DEVEL_PRODUCT_ID && \
+ id <= USB_MINI_PCIE_HS_PRODUCT_ID)
+
+/* USBCANII devices */
+#define USB_USBCAN_REVB_PRODUCT_ID 2
+#define USB_VCI2_PRODUCT_ID 3
+#define USB_USBCAN2_PRODUCT_ID 4
+#define USB_MEMORATOR_PRODUCT_ID 5
+#define USBCAN_PRODUCT_ID(id) (id >= USB_USBCAN_REVB_PRODUCT_ID && \
+ id <= USB_MEMORATOR_PRODUCT_ID)
/* USB devices features */
#define KVASER_HAS_SILENT_MODE BIT(0)
@@ -73,7 +101,7 @@
#define MSG_FLAG_TX_ACK BIT(6)
#define MSG_FLAG_TX_REQUEST BIT(7)
-/* Can states */
+/* Can states (M16C CxSTRH register) */
#define M16C_STATE_BUS_RESET BIT(0)
#define M16C_STATE_BUS_ERROR BIT(4)
#define M16C_STATE_BUS_PASSIVE BIT(5)
@@ -98,7 +126,13 @@
#define CMD_START_CHIP_REPLY 27
#define CMD_STOP_CHIP 28
#define CMD_STOP_CHIP_REPLY 29
-#define CMD_GET_CARD_INFO2 32
+#define CMD_READ_CLOCK 30
+#define CMD_READ_CLOCK_REPLY 31
+
+#define LEAF_CMD_GET_CARD_INFO2 32
+#define USBCAN_CMD_RESET_CLOCK 32
+#define USBCAN_CMD_CLOCK_OVERFLOW_EVENT 33
+
#define CMD_GET_CARD_INFO 34
#define CMD_GET_CARD_INFO_REPLY 35
#define CMD_GET_SOFTWARE_INFO 38
@@ -108,8 +142,9 @@
#define CMD_RESET_ERROR_COUNTER 49
#define CMD_TX_ACKNOWLEDGE 50
#define CMD_CAN_ERROR_EVENT 51
-#define CMD_USB_THROTTLE 77
-#define CMD_LOG_MESSAGE 106
+
+#define LEAF_CMD_USB_THROTTLE 77
+#define LEAF_CMD_LOG_MESSAGE 106
/* error factors */
#define M16C_EF_ACKE BIT(0)
@@ -121,6 +156,13 @@
#define M16C_EF_RCVE BIT(6)
#define M16C_EF_TRE BIT(7)
+/* Only Leaf-based devices can report M16C error factors,
+ * thus define our own error status flags for USBCAN */
+#define USBCAN_ERROR_STATE_NONE 0
+#define USBCAN_ERROR_STATE_TX_ERROR BIT(0)
+#define USBCAN_ERROR_STATE_RX_ERROR BIT(1)
+#define USBCAN_ERROR_STATE_BUSERROR BIT(2)
+
/* bittiming parameters */
#define KVASER_USB_TSEG1_MIN 1
#define KVASER_USB_TSEG1_MAX 16
@@ -137,7 +179,7 @@
#define KVASER_CTRL_MODE_SELFRECEPTION 3
#define KVASER_CTRL_MODE_OFF 4
-/* log message */
+/* Extended CAN identifier flag */
#define KVASER_EXTENDED_FRAME BIT(31)
struct kvaser_msg_simple {
@@ -148,30 +190,55 @@ struct kvaser_msg_simple {
struct kvaser_msg_cardinfo {
u8 tid;
u8 nchannels;
- __le32 serial_number;
- __le32 padding;
+ union {
+ struct {
+ __le32 serial_number;
+ __le32 padding;
+ } __packed leaf0;
+ struct {
+ __le32 serial_number_low;
+ __le32 serial_number_high;
+ } __packed usbcan0;
+ } __packed;
__le32 clock_resolution;
__le32 mfgdate;
u8 ean[8];
u8 hw_revision;
- u8 usb_hs_mode;
- __le16 padding2;
+ union {
+ struct {
+ u8 usb_hs_mode;
+ } __packed leaf1;
+ struct {
+ u8 padding;
+ } __packed usbcan1;
+ } __packed;
+ __le16 padding;
} __packed;
struct kvaser_msg_cardinfo2 {
u8 tid;
- u8 channel;
+ u8 reserved;
u8 pcb_id[24];
__le32 oem_unlock_code;
} __packed;
-struct kvaser_msg_softinfo {
+struct leaf_msg_softinfo {
u8 tid;
- u8 channel;
+ u8 padding0;
__le32 sw_options;
__le32 fw_version;
__le16 max_outstanding_tx;
- __le16 padding[9];
+ __le16 padding1[9];
+} __packed;
+
+struct usbcan_msg_softinfo {
+ u8 tid;
+ u8 fw_name[5];
+ __le16 max_outstanding_tx;
+ u8 padding[6];
+ __le32 fw_version;
+ __le16 checksum;
+ __le16 sw_options;
} __packed;
struct kvaser_msg_busparams {
@@ -188,36 +255,86 @@ struct kvaser_msg_tx_can {
u8 channel;
u8 tid;
u8 msg[14];
- u8 padding;
- u8 flags;
+ union {
+ struct {
+ u8 padding;
+ u8 flags;
+ } __packed leaf;
+ struct {
+ u8 flags;
+ u8 padding;
+ } __packed usbcan;
+ } __packed;
+} __packed;
+
+struct kvaser_msg_rx_can_header {
+ u8 channel;
+ u8 flag;
} __packed;
-struct kvaser_msg_rx_can {
+struct leaf_msg_rx_can {
u8 channel;
u8 flag;
+
__le16 time[3];
u8 msg[14];
} __packed;
-struct kvaser_msg_chip_state_event {
+struct usbcan_msg_rx_can {
+ u8 channel;
+ u8 flag;
+
+ u8 msg[14];
+ __le16 time;
+} __packed;
+
+struct leaf_msg_chip_state_event {
u8 tid;
u8 channel;
+
__le16 time[3];
u8 tx_errors_count;
u8 rx_errors_count;
+
u8 status;
u8 padding[3];
} __packed;
-struct kvaser_msg_tx_acknowledge {
+struct usbcan_msg_chip_state_event {
+ u8 tid;
+ u8 channel;
+
+ u8 tx_errors_count;
+ u8 rx_errors_count;
+ __le16 time;
+
+ u8 status;
+ u8 padding[3];
+} __packed;
+
+struct kvaser_msg_tx_acknowledge_header {
+ u8 channel;
+ u8 tid;
+};
+
+struct leaf_msg_tx_acknowledge {
u8 channel;
u8 tid;
+
__le16 time[3];
u8 flags;
u8 time_offset;
} __packed;
-struct kvaser_msg_error_event {
+struct usbcan_msg_tx_acknowledge {
+ u8 channel;
+ u8 tid;
+
+ __le16 time;
+ __le16 padding;
+} __packed;
+
+struct leaf_msg_error_event {
u8 tid;
u8 flags;
__le16 time[3];
@@ -229,6 +346,18 @@ struct kvaser_msg_error_event {
u8 error_factor;
} __packed;
+struct usbcan_msg_error_event {
+ u8 tid;
+ u8 padding;
+ u8 tx_errors_count_ch0;
+ u8 rx_errors_count_ch0;
+ u8 tx_errors_count_ch1;
+ u8 rx_errors_count_ch1;
+ u8 status_ch0;
+ u8 status_ch1;
+ __le16 time;
+} __packed;
+
struct kvaser_msg_ctrl_mode {
u8 tid;
u8 channel;
@@ -243,7 +372,7 @@ struct kvaser_msg_flush_queue {
u8 padding[3];
} __packed;
-struct kvaser_msg_log_message {
+struct leaf_msg_log_message {
u8 channel;
u8 flags;
__le16 time[3];
@@ -260,19 +389,49 @@ struct kvaser_msg {
struct kvaser_msg_simple simple;
struct kvaser_msg_cardinfo cardinfo;
struct kvaser_msg_cardinfo2 cardinfo2;
- struct kvaser_msg_softinfo softinfo;
struct kvaser_msg_busparams busparams;
+
+ struct kvaser_msg_rx_can_header rx_can_header;
+ struct kvaser_msg_tx_acknowledge_header tx_acknowledge_header;
+
+ union {
+ struct leaf_msg_softinfo softinfo;
+ struct leaf_msg_rx_can rx_can;
+ struct leaf_msg_chip_state_event chip_state_event;
+ struct leaf_msg_tx_acknowledge tx_acknowledge;
+ struct leaf_msg_error_event error_event;
+ struct leaf_msg_log_message log_message;
+ } __packed leaf;
+
+ union {
+ struct usbcan_msg_softinfo softinfo;
+ struct usbcan_msg_rx_can rx_can;
+ struct usbcan_msg_chip_state_event chip_state_event;
+ struct usbcan_msg_tx_acknowledge tx_acknowledge;
+ struct usbcan_msg_error_event error_event;
+ } __packed usbcan;
+
struct kvaser_msg_tx_can tx_can;
- struct kvaser_msg_rx_can rx_can;
- struct kvaser_msg_chip_state_event chip_state_event;
- struct kvaser_msg_tx_acknowledge tx_acknowledge;
- struct kvaser_msg_error_event error_event;
struct kvaser_msg_ctrl_mode ctrl_mode;
struct kvaser_msg_flush_queue flush_queue;
- struct kvaser_msg_log_message log_message;
} u;
} __packed;
+/* Leaf/USBCAN-agnostic summary of an error event.
+ * No M16C error factors for USBCAN-based devices. */
+struct kvaser_error_summary {
+ u8 channel, status, txerr, rxerr;
+ union {
+ struct {
+ u8 error_factor;
+ } leaf;
+ struct {
+ u8 other_ch_status;
+ u8 error_state;
+ } usbcan;
+ };
+};
+
struct kvaser_usb_tx_urb_context {
struct kvaser_usb_net_priv *priv;
u32 echo_index;
@@ -288,6 +447,8 @@ struct kvaser_usb {
u32 fw_version;
unsigned int nchannels;
+ enum kvaser_usb_family family;
+ unsigned int max_channels;
bool rxinitdone;
void *rxbuf[MAX_RX_URBS];
@@ -311,6 +472,7 @@ struct kvaser_usb_net_priv {
};
static const struct usb_device_id kvaser_usb_table[] = {
+ /* Leaf family IDs */
{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_DEVEL_PRODUCT_ID) },
{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_PRODUCT_ID) },
{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_PRO_PRODUCT_ID),
@@ -360,6 +522,17 @@ static const struct usb_device_id kvaser_usb_table[] = {
.driver_info = KVASER_HAS_TXRX_ERRORS },
{ USB_DEVICE(KVASER_VENDOR_ID, USB_LEAF_LITE_V2_PRODUCT_ID) },
{ USB_DEVICE(KVASER_VENDOR_ID, USB_MINI_PCIE_HS_PRODUCT_ID) },
+
+ /* USBCANII family IDs */
+ { USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN2_PRODUCT_ID),
+ .driver_info = KVASER_HAS_TXRX_ERRORS },
+ { USB_DEVICE(KVASER_VENDOR_ID, USB_USBCAN_REVB_PRODUCT_ID),
+ .driver_info = KVASER_HAS_TXRX_ERRORS },
+ { USB_DEVICE(KVASER_VENDOR_ID, USB_MEMORATOR_PRODUCT_ID),
+ .driver_info = KVASER_HAS_TXRX_ERRORS },
+ { USB_DEVICE(KVASER_VENDOR_ID, USB_VCI2_PRODUCT_ID),
+ .driver_info = KVASER_HAS_TXRX_ERRORS },
+
{ }
};
MODULE_DEVICE_TABLE(usb, kvaser_usb_table);
@@ -463,7 +636,18 @@ static int kvaser_usb_get_software_info(struct kvaser_usb *dev)
if (err)
return err;
- dev->fw_version = le32_to_cpu(msg.u.softinfo.fw_version);
+ switch (dev->family) {
+ case KVASER_LEAF:
+ dev->fw_version = le32_to_cpu(msg.u.leaf.softinfo.fw_version);
+ break;
+ case KVASER_USBCAN:
+ dev->fw_version = le32_to_cpu(msg.u.usbcan.softinfo.fw_version);
+ break;
+ default:
+ dev_err(dev->udev->dev.parent,
+ "Invalid device family (%d)\n", dev->family);
+ return -EINVAL;
+ }
return 0;
}
@@ -482,7 +666,7 @@ static int kvaser_usb_get_card_info(struct kvaser_usb *dev)
return err;
dev->nchannels = msg.u.cardinfo.nchannels;
- if (dev->nchannels > MAX_NET_DEVICES)
+ if (dev->nchannels > dev->max_channels)
return -EINVAL;
return 0;
@@ -496,8 +680,10 @@ static void kvaser_usb_tx_acknowledge(const struct kvaser_usb *dev,
struct kvaser_usb_net_priv *priv;
struct sk_buff *skb;
struct can_frame *cf;
- u8 channel = msg->u.tx_acknowledge.channel;
- u8 tid = msg->u.tx_acknowledge.tid;
+ u8 channel, tid;
+
+ channel = msg->u.tx_acknowledge_header.channel;
+ tid = msg->u.tx_acknowledge_header.tid;
if (channel >= dev->nchannels) {
dev_err(dev->udev->dev.parent,
@@ -615,37 +801,83 @@ static void kvaser_usb_unlink_tx_urbs(struct kvaser_usb_net_priv *priv)
priv->tx_contexts[i].echo_index = MAX_TX_URBS;
}
-static void kvaser_usb_rx_error(const struct kvaser_usb *dev,
- const struct kvaser_msg *msg)
+static void kvaser_report_error_event(const struct kvaser_usb *dev,
+ struct kvaser_error_summary *es);
+
+/*
+ * Report error to userspace iff the controller's errors counter has
+ * increased, or we're the only channel seeing the bus error state.
+ *
+ * As reported by USBCAN sheets, "the CAN controller has difficulties
+ * to tell whether an error frame arrived on channel 1 or on channel 2."
+ * Thus, error counters are compared with their earlier values to
+ * determine which channel was responsible for the error event.
+ */
+static void usbcan_report_error_if_applicable(const struct kvaser_usb *dev,
+ struct kvaser_error_summary *es)
{
- struct can_frame *cf;
- struct sk_buff *skb;
- struct net_device_stats *stats;
struct kvaser_usb_net_priv *priv;
- unsigned int new_state;
- u8 channel, status, txerr, rxerr, error_factor;
+ int old_tx_err_count, old_rx_err_count, channel, report_error;
+
+ channel = es->channel;
+ if (channel >= dev->nchannels) {
+ dev_err(dev->udev->dev.parent,
+ "Invalid channel number (%d)\n", channel);
+ return;
+ }
+
+ priv = dev->nets[channel];
+ old_tx_err_count = priv->bec.txerr;
+ old_rx_err_count = priv->bec.rxerr;
+
+ report_error = 0;
+ if (es->txerr > old_tx_err_count) {
+ es->usbcan.error_state |= USBCAN_ERROR_STATE_TX_ERROR;
+ report_error = 1;
+ }
+ if (es->rxerr > old_rx_err_count) {
+ es->usbcan.error_state |= USBCAN_ERROR_STATE_RX_ERROR;
+ report_error = 1;
+ }
+ if ((es->status & M16C_STATE_BUS_ERROR) &&
+ !(es->usbcan.other_ch_status & M16C_STATE_BUS_ERROR)) {
+ es->usbcan.error_state |= USBCAN_ERROR_STATE_BUSERROR;
+ report_error = 1;
+ }
+
+ if (report_error)
+ kvaser_report_error_event(dev, es);
+}
+
+/*
+ * Extract error summary from a Leaf-based device error message
+ */
+static void leaf_extract_error_from_msg(const struct kvaser_usb *dev,
+ const struct kvaser_msg *msg)
+{
+ struct kvaser_error_summary es = { 0, };
switch (msg->id) {
case CMD_CAN_ERROR_EVENT:
- channel = msg->u.error_event.channel;
- status = msg->u.error_event.status;
- txerr = msg->u.error_event.tx_errors_count;
- rxerr = msg->u.error_event.rx_errors_count;
- error_factor = msg->u.error_event.error_factor;
+ es.channel = msg->u.leaf.error_event.channel;
+ es.status = msg->u.leaf.error_event.status;
+ es.txerr = msg->u.leaf.error_event.tx_errors_count;
+ es.rxerr = msg->u.leaf.error_event.rx_errors_count;
+ es.leaf.error_factor = msg->u.leaf.error_event.error_factor;
break;
- case CMD_LOG_MESSAGE:
- channel = msg->u.log_message.channel;
- status = msg->u.log_message.data[0];
- txerr = msg->u.log_message.data[2];
- rxerr = msg->u.log_message.data[3];
- error_factor = msg->u.log_message.data[1];
+ case LEAF_CMD_LOG_MESSAGE:
+ es.channel = msg->u.leaf.log_message.channel;
+ es.status = msg->u.leaf.log_message.data[0];
+ es.txerr = msg->u.leaf.log_message.data[2];
+ es.rxerr = msg->u.leaf.log_message.data[3];
+ es.leaf.error_factor = msg->u.leaf.log_message.data[1];
break;
case CMD_CHIP_STATE_EVENT:
- channel = msg->u.chip_state_event.channel;
- status = msg->u.chip_state_event.status;
- txerr = msg->u.chip_state_event.tx_errors_count;
- rxerr = msg->u.chip_state_event.rx_errors_count;
- error_factor = 0;
+ es.channel = msg->u.leaf.chip_state_event.channel;
+ es.status = msg->u.leaf.chip_state_event.status;
+ es.txerr = msg->u.leaf.chip_state_event.tx_errors_count;
+ es.rxerr = msg->u.leaf.chip_state_event.rx_errors_count;
+ es.leaf.error_factor = 0;
break;
default:
dev_err(dev->udev->dev.parent, "Invalid msg id (%d)\n",
@@ -653,16 +885,92 @@ static void kvaser_usb_rx_error(const struct kvaser_usb *dev,
return;
}
- if (channel >= dev->nchannels) {
+ kvaser_report_error_event(dev, &es);
+}
+
+/*
+ * Extract summary from a USBCANII-based device error message.
+ */
+static void usbcan_extract_error_from_msg(const struct kvaser_usb *dev,
+ const struct kvaser_msg *msg)
+{
+ struct kvaser_error_summary es = { 0, };
+
+ switch (msg->id) {
+
+ /* Sometimes errors are sent as unsolicited chip state events */
+ case CMD_CHIP_STATE_EVENT:
+ es.channel = msg->u.usbcan.chip_state_event.channel;
+ es.status = msg->u.usbcan.chip_state_event.status;
+ es.txerr = msg->u.usbcan.chip_state_event.tx_errors_count;
+ es.rxerr = msg->u.usbcan.chip_state_event.rx_errors_count;
+ usbcan_report_error_if_applicable(dev, &es);
+ break;
+
+ case CMD_CAN_ERROR_EVENT:
+ es.channel = 0;
+ es.status = msg->u.usbcan.error_event.status_ch0;
+ es.txerr = msg->u.usbcan.error_event.tx_errors_count_ch0;
+ es.rxerr = msg->u.usbcan.error_event.rx_errors_count_ch0;
+ es.usbcan.other_ch_status =
+ msg->u.usbcan.error_event.status_ch1;
+ usbcan_report_error_if_applicable(dev, &es);
+
+ /* For error events, the USBCAN firmware does not support
+ * more than 2 channels: ch0, and ch1. */
+ if (dev->nchannels > 1) {
+ es.channel = 1;
+ es.status = msg->u.usbcan.error_event.status_ch1;
+ es.txerr = msg->u.usbcan.error_event.tx_errors_count_ch1;
+ es.rxerr = msg->u.usbcan.error_event.rx_errors_count_ch1;
+ es.usbcan.other_ch_status =
+ msg->u.usbcan.error_event.status_ch0;
+ usbcan_report_error_if_applicable(dev, &es);
+ }
+ break;
+
+ default:
+ dev_err(dev->udev->dev.parent, "Invalid msg id (%d)\n",
+ msg->id);
+ }
+}
+
+static void kvaser_usb_rx_error(const struct kvaser_usb *dev,
+ const struct kvaser_msg *msg)
+{
+ switch (dev->family) {
+ case KVASER_LEAF:
+ leaf_extract_error_from_msg(dev, msg);
+ break;
+ case KVASER_USBCAN:
+ usbcan_extract_error_from_msg(dev, msg);
+ break;
+ default:
dev_err(dev->udev->dev.parent,
- "Invalid channel number (%d)\n", channel);
+ "Invalid device family (%d)\n", dev->family);
return;
}
+}
- priv = dev->nets[channel];
+static void kvaser_report_error_event(const struct kvaser_usb *dev,
+ struct kvaser_error_summary *es)
+{
+ struct can_frame *cf;
+ struct sk_buff *skb;
+ struct net_device_stats *stats;
+ struct kvaser_usb_net_priv *priv;
+ unsigned int new_state;
+
+ if (es->channel >= dev->nchannels) {
+ dev_err(dev->udev->dev.parent,
+ "Invalid channel number (%d)\n", es->channel);
+ return;
+ }
+
+ priv = dev->nets[es->channel];
stats = &priv->netdev->stats;
- if (status & M16C_STATE_BUS_RESET) {
+ if (es->status & M16C_STATE_BUS_RESET) {
kvaser_usb_unlink_tx_urbs(priv);
return;
}
@@ -675,9 +983,9 @@ static void kvaser_usb_rx_error(const struct kvaser_usb *dev,
new_state = priv->can.state;
- netdev_dbg(priv->netdev, "Error status: 0x%02x\n", status);
+ netdev_dbg(priv->netdev, "Error status: 0x%02x\n", es->status);
- if (status & M16C_STATE_BUS_OFF) {
+ if (es->status & M16C_STATE_BUS_OFF) {
cf->can_id |= CAN_ERR_BUSOFF;
priv->can.can_stats.bus_off++;
@@ -687,12 +995,12 @@ static void kvaser_usb_rx_error(const struct kvaser_usb *dev,
netif_carrier_off(priv->netdev);
new_state = CAN_STATE_BUS_OFF;
- } else if (status & M16C_STATE_BUS_PASSIVE) {
+ } else if (es->status & M16C_STATE_BUS_PASSIVE) {
if (priv->can.state != CAN_STATE_ERROR_PASSIVE) {
cf->can_id |= CAN_ERR_CRTL;
- if (txerr || rxerr)
- cf->data[1] = (txerr > rxerr)
+ if (es->txerr || es->rxerr)
+ cf->data[1] = (es->txerr > es->rxerr)
? CAN_ERR_CRTL_TX_PASSIVE
: CAN_ERR_CRTL_RX_PASSIVE;
else
@@ -703,13 +1011,11 @@ static void kvaser_usb_rx_error(const struct kvaser_usb *dev,
}
new_state = CAN_STATE_ERROR_PASSIVE;
- }
-
- if (status == M16C_STATE_BUS_ERROR) {
+ } else if (es->status & M16C_STATE_BUS_ERROR) {
if ((priv->can.state < CAN_STATE_ERROR_WARNING) &&
- ((txerr >= 96) || (rxerr >= 96))) {
+ ((es->txerr >= 96) || (es->rxerr >= 96))) {
cf->can_id |= CAN_ERR_CRTL;
- cf->data[1] = (txerr > rxerr)
+ cf->data[1] = (es->txerr > es->rxerr)
? CAN_ERR_CRTL_TX_WARNING
: CAN_ERR_CRTL_RX_WARNING;
@@ -723,7 +1029,7 @@ static void kvaser_usb_rx_error(const struct kvaser_usb *dev,
}
}
- if (!status) {
+ if (!es->status) {
cf->can_id |= CAN_ERR_PROT;
cf->data[2] = CAN_ERR_PROT_ACTIVE;
@@ -739,34 +1045,52 @@ static void kvaser_usb_rx_error(const struct kvaser_usb *dev,
priv->can.can_stats.restarts++;
}
- if (error_factor) {
- priv->can.can_stats.bus_error++;
- stats->rx_errors++;
-
- cf->can_id |= CAN_ERR_BUSERROR | CAN_ERR_PROT;
-
- if (error_factor & M16C_EF_ACKE)
- cf->data[3] |= (CAN_ERR_PROT_LOC_ACK);
- if (error_factor & M16C_EF_CRCE)
- cf->data[3] |= (CAN_ERR_PROT_LOC_CRC_SEQ |
- CAN_ERR_PROT_LOC_CRC_DEL);
- if (error_factor & M16C_EF_FORME)
- cf->data[2] |= CAN_ERR_PROT_FORM;
- if (error_factor & M16C_EF_STFE)
- cf->data[2] |= CAN_ERR_PROT_STUFF;
- if (error_factor & M16C_EF_BITE0)
- cf->data[2] |= CAN_ERR_PROT_BIT0;
- if (error_factor & M16C_EF_BITE1)
- cf->data[2] |= CAN_ERR_PROT_BIT1;
- if (error_factor & M16C_EF_TRE)
- cf->data[2] |= CAN_ERR_PROT_TX;
+ switch (dev->family) {
+ case KVASER_LEAF:
+ if (es->leaf.error_factor) {
+ priv->can.can_stats.bus_error++;
+ stats->rx_errors++;
+
+ cf->can_id |= CAN_ERR_BUSERROR | CAN_ERR_PROT;
+
+ if (es->leaf.error_factor & M16C_EF_ACKE)
+ cf->data[3] |= (CAN_ERR_PROT_LOC_ACK);
+ if (es->leaf.error_factor & M16C_EF_CRCE)
+ cf->data[3] |= (CAN_ERR_PROT_LOC_CRC_SEQ |
+ CAN_ERR_PROT_LOC_CRC_DEL);
+ if (es->leaf.error_factor & M16C_EF_FORME)
+ cf->data[2] |= CAN_ERR_PROT_FORM;
+ if (es->leaf.error_factor & M16C_EF_STFE)
+ cf->data[2] |= CAN_ERR_PROT_STUFF;
+ if (es->leaf.error_factor & M16C_EF_BITE0)
+ cf->data[2] |= CAN_ERR_PROT_BIT0;
+ if (es->leaf.error_factor & M16C_EF_BITE1)
+ cf->data[2] |= CAN_ERR_PROT_BIT1;
+ if (es->leaf.error_factor & M16C_EF_TRE)
+ cf->data[2] |= CAN_ERR_PROT_TX;
+ }
+ break;
+ case KVASER_USBCAN:
+ if (es->usbcan.error_state & USBCAN_ERROR_STATE_TX_ERROR)
+ stats->tx_errors++;
+ if (es->usbcan.error_state & USBCAN_ERROR_STATE_RX_ERROR)
+ stats->rx_errors++;
+ if (es->usbcan.error_state & USBCAN_ERROR_STATE_BUSERROR) {
+ priv->can.can_stats.bus_error++;
+ cf->can_id |= CAN_ERR_BUSERROR;
+ }
+ break;
+ default:
+ dev_err(dev->udev->dev.parent,
+ "Invalid device family (%d)\n", dev->family);
+ goto err;
}
- cf->data[6] = txerr;
- cf->data[7] = rxerr;
+ cf->data[6] = es->txerr;
+ cf->data[7] = es->rxerr;
- priv->bec.txerr = txerr;
- priv->bec.rxerr = rxerr;
+ priv->bec.txerr = es->txerr;
+ priv->bec.rxerr = es->rxerr;
priv->can.state = new_state;
@@ -774,6 +1098,11 @@ static void kvaser_usb_rx_error(const struct kvaser_usb *dev,
stats->rx_packets++;
stats->rx_bytes += cf->can_dlc;
+
+ return;
+
+err:
+ dev_kfree_skb(skb);
}
static void kvaser_usb_rx_can_err(const struct kvaser_usb_net_priv *priv,
@@ -783,16 +1112,16 @@ static void kvaser_usb_rx_can_err(const struct kvaser_usb_net_priv *priv,
struct sk_buff *skb;
struct net_device_stats *stats = &priv->netdev->stats;
- if (msg->u.rx_can.flag & (MSG_FLAG_ERROR_FRAME |
+ if (msg->u.rx_can_header.flag & (MSG_FLAG_ERROR_FRAME |
MSG_FLAG_NERR)) {
netdev_err(priv->netdev, "Unknow error (flags: 0x%02x)\n",
- msg->u.rx_can.flag);
+ msg->u.rx_can_header.flag);
stats->rx_errors++;
return;
}
- if (msg->u.rx_can.flag & MSG_FLAG_OVERRUN) {
+ if (msg->u.rx_can_header.flag & MSG_FLAG_OVERRUN) {
skb = alloc_can_err_skb(priv->netdev, &cf);
if (!skb) {
stats->rx_dropped++;
@@ -819,7 +1148,8 @@ static void kvaser_usb_rx_can_msg(const struct kvaser_usb *dev,
struct can_frame *cf;
struct sk_buff *skb;
struct net_device_stats *stats;
- u8 channel = msg->u.rx_can.channel;
+ u8 channel = msg->u.rx_can_header.channel;
+ const u8 *rx_msg;
if (channel >= dev->nchannels) {
dev_err(dev->udev->dev.parent,
@@ -830,19 +1160,32 @@ static void kvaser_usb_rx_can_msg(const struct kvaser_usb *dev,
priv = dev->nets[channel];
stats = &priv->netdev->stats;
- if ((msg->u.rx_can.flag & MSG_FLAG_ERROR_FRAME) &&
- (msg->id == CMD_LOG_MESSAGE)) {
+ if ((msg->u.rx_can_header.flag & MSG_FLAG_ERROR_FRAME) &&
+ (dev->family == KVASER_LEAF && msg->id == LEAF_CMD_LOG_MESSAGE)) {
kvaser_usb_rx_error(dev, msg);
return;
- } else if (msg->u.rx_can.flag & (MSG_FLAG_ERROR_FRAME |
- MSG_FLAG_NERR |
- MSG_FLAG_OVERRUN)) {
+ } else if (msg->u.rx_can_header.flag & (MSG_FLAG_ERROR_FRAME |
+ MSG_FLAG_NERR |
+ MSG_FLAG_OVERRUN)) {
kvaser_usb_rx_can_err(priv, msg);
return;
- } else if (msg->u.rx_can.flag & ~MSG_FLAG_REMOTE_FRAME) {
+ } else if (msg->u.rx_can_header.flag & ~MSG_FLAG_REMOTE_FRAME) {
netdev_warn(priv->netdev,
"Unhandled frame (flags: 0x%02x)",
- msg->u.rx_can.flag);
+ msg->u.rx_can_header.flag);
+ return;
+ }
+
+ switch (dev->family) {
+ case KVASER_LEAF:
+ rx_msg = msg->u.leaf.rx_can.msg;
+ break;
+ case KVASER_USBCAN:
+ rx_msg = msg->u.usbcan.rx_can.msg;
+ break;
+ default:
+ dev_err(dev->udev->dev.parent,
+ "Invalid device family (%d)\n", dev->family);
return;
}
@@ -852,38 +1195,37 @@ static void kvaser_usb_rx_can_msg(const struct kvaser_usb *dev,
return;
}
- if (msg->id == CMD_LOG_MESSAGE) {
- cf->can_id = le32_to_cpu(msg->u.log_message.id);
+ if (dev->family == KVASER_LEAF && msg->id == LEAF_CMD_LOG_MESSAGE) {
+ cf->can_id = le32_to_cpu(msg->u.leaf.log_message.id);
if (cf->can_id & KVASER_EXTENDED_FRAME)
cf->can_id &= CAN_EFF_MASK | CAN_EFF_FLAG;
else
cf->can_id &= CAN_SFF_MASK;
- cf->can_dlc = get_can_dlc(msg->u.log_message.dlc);
+ cf->can_dlc = get_can_dlc(msg->u.leaf.log_message.dlc);
- if (msg->u.log_message.flags & MSG_FLAG_REMOTE_FRAME)
+ if (msg->u.leaf.log_message.flags & MSG_FLAG_REMOTE_FRAME)
cf->can_id |= CAN_RTR_FLAG;
else
- memcpy(cf->data, &msg->u.log_message.data,
+ memcpy(cf->data, &msg->u.leaf.log_message.data,
cf->can_dlc);
} else {
- cf->can_id = ((msg->u.rx_can.msg[0] & 0x1f) << 6) |
- (msg->u.rx_can.msg[1] & 0x3f);
+ cf->can_id = ((rx_msg[0] & 0x1f) << 6) | (rx_msg[1] & 0x3f);
if (msg->id == CMD_RX_EXT_MESSAGE) {
cf->can_id <<= 18;
- cf->can_id |= ((msg->u.rx_can.msg[2] & 0x0f) << 14) |
- ((msg->u.rx_can.msg[3] & 0xff) << 6) |
- (msg->u.rx_can.msg[4] & 0x3f);
+ cf->can_id |= ((rx_msg[2] & 0x0f) << 14) |
+ ((rx_msg[3] & 0xff) << 6) |
+ (rx_msg[4] & 0x3f);
cf->can_id |= CAN_EFF_FLAG;
}
- cf->can_dlc = get_can_dlc(msg->u.rx_can.msg[5]);
+ cf->can_dlc = get_can_dlc(rx_msg[5]);
- if (msg->u.rx_can.flag & MSG_FLAG_REMOTE_FRAME)
+ if (msg->u.rx_can_header.flag & MSG_FLAG_REMOTE_FRAME)
cf->can_id |= CAN_RTR_FLAG;
else
- memcpy(cf->data, &msg->u.rx_can.msg[6],
+ memcpy(cf->data, &rx_msg[6],
cf->can_dlc);
}
@@ -947,7 +1289,12 @@ static void kvaser_usb_handle_message(const struct kvaser_usb *dev,
case CMD_RX_STD_MESSAGE:
case CMD_RX_EXT_MESSAGE:
- case CMD_LOG_MESSAGE:
+ kvaser_usb_rx_can_msg(dev, msg);
+ break;
+
+ case LEAF_CMD_LOG_MESSAGE:
+ if (dev->family != KVASER_LEAF)
+ goto warn;
kvaser_usb_rx_can_msg(dev, msg);
break;
@@ -960,8 +1307,14 @@ static void kvaser_usb_handle_message(const struct kvaser_usb *dev,
kvaser_usb_tx_acknowledge(dev, msg);
break;
+ /* Ignored messages */
+ case USBCAN_CMD_CLOCK_OVERFLOW_EVENT:
+ if (dev->family != KVASER_USBCAN)
+ goto warn;
+ break;
+
default:
- dev_warn(dev->udev->dev.parent,
+warn: dev_warn(dev->udev->dev.parent,
"Unhandled message (%d)\n", msg->id);
break;
}
@@ -1181,7 +1534,7 @@ static void kvaser_usb_unlink_all_urbs(struct kvaser_usb *dev)
dev->rxbuf[i],
dev->rxbuf_dma[i]);
- for (i = 0; i < MAX_NET_DEVICES; i++) {
+ for (i = 0; i < dev->max_channels; i++) {
struct kvaser_usb_net_priv *priv = dev->nets[i];
if (priv)
@@ -1286,6 +1639,7 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb,
struct kvaser_msg *msg;
int i, err;
int ret = NETDEV_TX_OK;
+ uint8_t *msg_tx_can_flags;
bool kfree_skb_on_error = true;
if (can_dropped_invalid_skb(netdev, skb))
@@ -1306,9 +1660,23 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb,
msg = buf;
msg->len = MSG_HEADER_LEN + sizeof(struct kvaser_msg_tx_can);
- msg->u.tx_can.flags = 0;
msg->u.tx_can.channel = priv->channel;
+ switch (dev->family) {
+ case KVASER_LEAF:
+ msg_tx_can_flags = &msg->u.tx_can.leaf.flags;
+ break;
+ case KVASER_USBCAN:
+ msg_tx_can_flags = &msg->u.tx_can.usbcan.flags;
+ break;
+ default:
+ dev_err(dev->udev->dev.parent,
+ "Invalid device family (%d)\n", dev->family);
+ goto releasebuf;
+ }
+
+ *msg_tx_can_flags = 0;
+
if (cf->can_id & CAN_EFF_FLAG) {
msg->id = CMD_TX_EXT_MESSAGE;
msg->u.tx_can.msg[0] = (cf->can_id >> 24) & 0x1f;
@@ -1326,7 +1694,7 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb,
memcpy(&msg->u.tx_can.msg[6], cf->data, cf->can_dlc);
if (cf->can_id & CAN_RTR_FLAG)
- msg->u.tx_can.flags |= MSG_FLAG_REMOTE_FRAME;
+ *msg_tx_can_flags |= MSG_FLAG_REMOTE_FRAME;
for (i = 0; i < ARRAY_SIZE(priv->tx_contexts); i++) {
if (priv->tx_contexts[i].echo_index == MAX_TX_URBS) {
@@ -1596,6 +1964,18 @@ static int kvaser_usb_probe(struct usb_interface *intf,
if (!dev)
return -ENOMEM;
+ if (LEAF_PRODUCT_ID(id->idProduct)) {
+ dev->family = KVASER_LEAF;
+ dev->max_channels = LEAF_MAX_NET_DEVICES;
+ } else if (USBCAN_PRODUCT_ID(id->idProduct)) {
+ dev->family = KVASER_USBCAN;
+ dev->max_channels = USBCAN_MAX_NET_DEVICES;
+ } else {
+ dev_err(&intf->dev, "Product ID (%d) does not belong to any "
+ "known Kvaser USB family", id->idProduct);
+ return -ENODEV;
+ }
+
err = kvaser_usb_get_endpoints(intf, &dev->bulk_in, &dev->bulk_out);
if (err) {
dev_err(&intf->dev, "Cannot get usb endpoint(s)");
@@ -1608,7 +1988,7 @@ static int kvaser_usb_probe(struct usb_interface *intf,
usb_set_intfdata(intf, dev);
- for (i = 0; i < MAX_NET_DEVICES; i++)
+ for (i = 0; i < dev->max_channels; i++)
kvaser_usb_send_simple_msg(dev, CMD_RESET_CHIP, i);
err = kvaser_usb_get_software_info(dev);
^ permalink raw reply related
* [PATCH] can: kvaser_usb: Don't free packets when tight on URBs
From: Ahmed S. Darwish @ 2014-12-23 15:46 UTC (permalink / raw)
To: Olivier Sobrie, Oliver Hartkopp, Wolfgang Grandegger,
Marc Kleine-Budde
Cc: David S. Miller, Paul Gortmaker, Linux-CAN, netdev, LKML
From: Ahmed S. Darwish <ahmed.darwish@valeo.com>
Flooding the Kvaser CAN to USB dongle with multiple reads and
writes in high frequency caused seemingly-random panics in the
kernel.
On further inspection, it seems the driver erroneously freed the
to-be-transmitted packet upon getting tight on URBs and returning
NETDEV_TX_BUSY, leading to invalid memory writes and double frees
at a later point in time.
Signed-off-by: Ahmed S. Darwish <ahmed.darwish@valeo.com>
---
drivers/net/can/usb/kvaser_usb.c | 8 +++++---
1 file changed, 5 insertions(+), 3 deletions(-)
(Generated over 3.19.0-rc1)
diff --git a/drivers/net/can/usb/kvaser_usb.c b/drivers/net/can/usb/kvaser_usb.c
index 541fb7a..34c35d8 100644
--- a/drivers/net/can/usb/kvaser_usb.c
+++ b/drivers/net/can/usb/kvaser_usb.c
@@ -1286,6 +1286,7 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb,
struct kvaser_msg *msg;
int i, err;
int ret = NETDEV_TX_OK;
+ bool kfree_skb_on_error = true;
if (can_dropped_invalid_skb(netdev, skb))
return NETDEV_TX_OK;
@@ -1336,6 +1337,7 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb,
if (!context) {
netdev_warn(netdev, "cannot find free context\n");
+ kfree_skb_on_error = false;
ret = NETDEV_TX_BUSY;
goto releasebuf;
}
@@ -1364,8 +1366,7 @@ static netdev_tx_t kvaser_usb_start_xmit(struct sk_buff *skb,
if (unlikely(err)) {
can_free_echo_skb(netdev, context->echo_index);
- skb = NULL; /* set to NULL to avoid double free in
- * dev_kfree_skb(skb) */
+ kfree_skb_on_error = false;
atomic_dec(&priv->active_tx_urbs);
usb_unanchor_urb(urb);
@@ -1389,7 +1390,8 @@ releasebuf:
nobufmem:
usb_free_urb(urb);
nourbmem:
- dev_kfree_skb(skb);
+ if (kfree_skb_on_error)
+ dev_kfree_skb(skb);
return ret;
}
^ permalink raw reply related
* Re: [PATCH v3] 3c59x: Fix memory leaks in vortex_open
From: Neil Horman @ 2014-12-23 15:43 UTC (permalink / raw)
To: Jia-Ju Bai
Cc: davem, ebiederm, dingtianhong, paul.gortmaker,
justinvanwijngaarden, netdev
In-Reply-To: <54998371.7060109@163.com>
On Tue, Dec 23, 2014 at 11:00:01PM +0800, Jia-Ju Bai wrote:
> Thanks for the reply!
>
> >This doesn't make sense. We free all the skbs in vortex_open if we don't
> >allocate all of them (the if (i != RX_RING_SIZE) check), the only place we miss
> >is if vortex_up fails, and you didn't remove the if (!retval) goto out check, so
> >this code won't get run appropriately.
>
> In the code, when vortex_up is failed and does not returns 0,
> "if (!retval)" is failed and "goto out" is not executed, so error handling
> code
> below is executed, including my added code.
> Is it right?
>
Yup, you're right, I missed the sense of the check.
> >
> >That said, it does seem we need to clean up if vortex_up fails, but it would
> >seem to me to be easier to just call vortex_close if it does, since that will do
> >all of the approriate cleanup.
> >
> >Neil
> >
>
> In the code, vortex_close does too many releasing operations, such as free
> vp->tx_skbuff, but vortex_open only allocates memory for vp->rx_skbuff
> before
> vortex_up is called.
> So I think it is enough to just free the memory of vp->rx_skbuff when
> vortex_up
> is failed.
>
No, I don't think so. vortex_close predicates each free with a NULL check, so
if its not been allocated, it shouldn't be freed. vortex_close also puts the
adapter back into a known state (undoing all the setup that vortex_open does).
I really think its better to go with the proper close path than just unwinding
the allocation
Neil
>
^ permalink raw reply
* Re: [PATCH v3 1/3] igb: Add igb_disable_sriov in error handling
From: Jia-Ju Bai @ 2014-12-23 15:06 UTC (permalink / raw)
To: Jeff Kirsher
Cc: linux.nics, Sergei Shtylyov, e1000-devel, netdev, bruce.w.allan,
jesse.brandeburg, davem
In-Reply-To: <1419343393.2470.14.camel@jtkirshe-mobl>
On 12/23/2014 10:03 PM, Jeff Kirsher wrote:
>
> No it is not. If you were sending a patch (which has already been
> accepted upstream) to the stable trees, then you would specify what
> stable kernels the patch applies to. In your case, I would not consider
> your patches critical for the stable trees.
>
> So when sending patches, you inform the maintainer (i.e. me) what tree
> you want your patch applied by stating either "net" or "net-next" in the
> title. For example, this patch would be titled:
>
> [net v3 1/3] igb: Add igb_disable_sriov in error handling
>
> Which lets me know you want your patch applied to the "net" tree. If it
> were not a fix, then it would go into the "net-next" tree by using the
> title:
>
> [net-next v3 1/3] igb: Add igb_disable_sriov in error handling
>
>
Thanks!
------------------------------------------------------------------------------
Dive into the World of Parallel Programming! The Go Parallel Website,
sponsored by Intel and developed in partnership with Slashdot Media, is your
hub for all things parallel software development, from weekly thought
leadership blogs to news, videos, case studies, tutorials and more. Take a
look and join the conversation now. http://goparallel.sourceforge.net
_______________________________________________
E1000-devel mailing list
E1000-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/e1000-devel
To learn more about Intel® Ethernet, visit http://communities.intel.com/community/wired
^ permalink raw reply
* Re: [PATCH v3] 3c59x: Fix memory leaks in vortex_open
From: Jia-Ju Bai @ 2014-12-23 15:00 UTC (permalink / raw)
To: Neil Horman
Cc: davem, ebiederm, dingtianhong, paul.gortmaker,
justinvanwijngaarden, netdev
In-Reply-To: <20141223142439.GD31876@hmsreliant.think-freely.org>
Thanks for the reply!
> This doesn't make sense. We free all the skbs in vortex_open if we don't
> allocate all of them (the if (i != RX_RING_SIZE) check), the only place we miss
> is if vortex_up fails, and you didn't remove the if (!retval) goto out check, so
> this code won't get run appropriately.
In the code, when vortex_up is failed and does not returns 0,
"if (!retval)" is failed and "goto out" is not executed, so error
handling code
below is executed, including my added code.
Is it right?
>
> That said, it does seem we need to clean up if vortex_up fails, but it would
> seem to me to be easier to just call vortex_close if it does, since that will do
> all of the approriate cleanup.
>
> Neil
>
In the code, vortex_close does too many releasing operations, such as free
vp->tx_skbuff, but vortex_open only allocates memory for vp->rx_skbuff
before
vortex_up is called.
So I think it is enough to just free the memory of vp->rx_skbuff when
vortex_up
is failed.
^ permalink raw reply
* Re: [PATCH v3] 3c59x: Fix memory leaks in vortex_open
From: Neil Horman @ 2014-12-23 14:24 UTC (permalink / raw)
To: Jia-Ju Bai
Cc: davem, ebiederm, dingtianhong, paul.gortmaker,
justinvanwijngaarden, netdev
In-Reply-To: <1419303290-27565-1-git-send-email-baijiaju1990@163.com>
On Tue, Dec 23, 2014 at 10:54:50AM +0800, Jia-Ju Bai wrote:
> For linux-3.18.0
> The driver calls __netdev_alloc_skb in vortex_open but lacks dev_kfree_skb
> when vortex_up is failed, so memory leaks may occur in this situation.
> This patch fixes this problem.
>
> Signed-off-by: Jia-Ju Bai <baijiaju1990@163.com>
> ---
> drivers/net/ethernet/3com/3c59x.c | 10 ++++++++++
> 1 file changed, 10 insertions(+)
>
> diff --git a/drivers/net/ethernet/3com/3c59x.c b/drivers/net/ethernet/3com/3c59x.c
> index 41095eb..d0c5bee 100644
> --- a/drivers/net/ethernet/3com/3c59x.c
> +++ b/drivers/net/ethernet/3com/3c59x.c
> @@ -1782,6 +1782,16 @@ vortex_open(struct net_device *dev)
> if (!retval)
> goto out;
>
> + if (vp->full_bus_master_rx) {
> + for (i = 0; i < RX_RING_SIZE; i++) {
> + if (vp->rx_skbuff[i]) {
> + dev_kfree_skb(vp->rx_skbuff[i]);
> + vp->rx_skbuff[i] = NULL;
> + }
> + }
> + retval = -ENOMEM;
> + }
> +
> err_free_irq:
> free_irq(dev->irq, dev);
> err:
> --
> 1.7.9.5
>
>
>
This doesn't make sense. We free all the skbs in vortex_open if we don't
allocate all of them (the if (i != RX_RING_SIZE) check), the only place we miss
is if vortex_up fails, and you didn't remove the if (!retval) goto out check, so
this code won't get run appropriately.
That said, it does seem we need to clean up if vortex_up fails, but it would
seem to me to be easier to just call vortex_close if it does, since that will do
all of the approriate cleanup.
Neil
^ permalink raw reply
* Re: [PATCH 2/3] net/fsl: remove irq assignment from xgmac_mdio
From: Sergei Shtylyov @ 2014-12-23 14:11 UTC (permalink / raw)
To: shh.xie, netdev, davem; +Cc: Shaohui Xie
In-Reply-To: <1419328019-27254-1-git-send-email-shh.xie@gmail.com>
Hello.
On 12/23/2014 12:46 PM, shh.xie@gmail.com wrote:
> From: Shaohui Xie <Shaohui.Xie@freescale.com>
> Which is wrong and not used, so no extra space needed by
> mdio_alloc_size(), change the parameter accordingly.
> Signed-off-by: Shaohui Xie <Shaohui.Xie@freescale.com>
> ---
> drivers/net/ethernet/freescale/xgmac_mdio.c | 3 +--
> 1 file changed, 1 insertion(+), 2 deletions(-)
> diff --git a/drivers/net/ethernet/freescale/xgmac_mdio.c b/drivers/net/ethernet/freescale/xgmac_mdio.c
> index 90adba1..72e0b85 100644
> --- a/drivers/net/ethernet/freescale/xgmac_mdio.c
> +++ b/drivers/net/ethernet/freescale/xgmac_mdio.c
> @@ -187,14 +187,13 @@ static int xgmac_mdio_probe(struct platform_device *pdev)
> return ret;
> }
>
> - bus = mdiobus_alloc_size(PHY_MAX_ADDR * sizeof(int));
> + bus = mdiobus_alloc_size(0);
It's now equivalent to a mere mdiobus_alloc().
[...]
WBR, Sergei
^ permalink raw reply
* Re: [PATCH v3 1/3] igb: Add igb_disable_sriov in error handling
From: Jeff Kirsher @ 2014-12-23 14:03 UTC (permalink / raw)
To: Jia-Ju Bai
Cc: Sergei Shtylyov, davem, bruce.w.allan, jesse.brandeburg,
linux.nics, e1000-devel, netdev
In-Reply-To: <54996CAB.7080007@163.com>
[-- Attachment #1: Type: text/plain, Size: 1607 bytes --]
On Tue, 2014-12-23 at 21:22 +0800, Jia-Ju Bai wrote:
> On 12/23/2014 07:23 PM, Sergei Shtylyov wrote:
> > Hello.
> >
> > On 12/23/2014 10:17 AM, Jia-Ju Bai wrote:
> >
> >> For linux-3.18.0
> >
> > For the future: such words should be placed under --- tear line...
> >
> >> The driver lacks igb_disable_sriov in error handling,
> >> which should match igb_enable_sriov in igb_probe.
> >> This patch fixes this problem, and it has been tested in runtime.
> >
> >> Signed-off-by: Jia-Ju Bai <baijiaju1990@163.com>
> >> ---
> >
> > .... here.
> >
> >> drivers/net/ethernet/intel/igb/igb_main.c | 4 ++++
> >> 1 file changed, 4 insertions(+)
> >
> > WBR, Sergei
> >
>
> Thanks. ^_^
> I see that most patches in netdev mailing list do not mention the linux
> kernel version, so is it necessary to write the version in the patch?
>
No it is not. If you were sending a patch (which has already been
accepted upstream) to the stable trees, then you would specify what
stable kernels the patch applies to. In your case, I would not consider
your patches critical for the stable trees.
So when sending patches, you inform the maintainer (i.e. me) what tree
you want your patch applied by stating either "net" or "net-next" in the
title. For example, this patch would be titled:
[net v3 1/3] igb: Add igb_disable_sriov in error handling
Which lets me know you want your patch applied to the "net" tree. If it
were not a fix, then it would go into the "net-next" tree by using the
title:
[net-next v3 1/3] igb: Add igb_disable_sriov in error handling
[-- Attachment #2: This is a digitally signed message part --]
[-- Type: application/pgp-signature, Size: 819 bytes --]
^ permalink raw reply
* Re: [PATCH 1/1 net-next] netfilter: remove unnecessary sizeof(char)
From: Pablo Neira Ayuso @ 2014-12-23 13:33 UTC (permalink / raw)
To: Fabian Frederick
Cc: linux-kernel, davem, joe, Patrick McHardy, Jozsef Kadlecsik,
netfilter-devel, coreteam, netdev
In-Reply-To: <1419273375-24312-1-git-send-email-fabf@skynet.be>
On Mon, Dec 22, 2014 at 07:36:15PM +0100, Fabian Frederick wrote:
> sizeof(char) is always 1.
Applied, thanks.
Made a small change on it:
> Suggested-by: Joe Perches <joe@perches.com>
> Signed-off-by: Fabian Frederick <fabf@skynet.be>
> ---
> net/netfilter/nf_log.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)
>
> diff --git a/net/netfilter/nf_log.c b/net/netfilter/nf_log.c
> index 43c926c..1191f66 100644
> --- a/net/netfilter/nf_log.c
> +++ b/net/netfilter/nf_log.c
> @@ -426,7 +426,7 @@ static int netfilter_log_sysctl_init(struct net *net)
> nf_log_sysctl_fnames[i];
> nf_log_sysctl_table[i].data = NULL;
> nf_log_sysctl_table[i].maxlen =
> - NFLOGGER_NAME_LEN * sizeof(char);
> + NFLOGGER_NAME_LEN;
this now fits in one line (80-chars).
> nf_log_sysctl_table[i].mode = 0644;
> nf_log_sysctl_table[i].proc_handler =
> nf_log_proc_dostring;
> --
> 1.9.1
>
^ permalink raw reply
* Re: [PATCH v3 1/3] igb: Add igb_disable_sriov in error handling
From: Jia-Ju Bai @ 2014-12-23 13:22 UTC (permalink / raw)
To: Sergei Shtylyov
Cc: linux.nics, e1000-devel, netdev, bruce.w.allan, jesse.brandeburg,
davem
In-Reply-To: <54995097.8090105@cogentembedded.com>
On 12/23/2014 07:23 PM, Sergei Shtylyov wrote:
> Hello.
>
> On 12/23/2014 10:17 AM, Jia-Ju Bai wrote:
>
>> For linux-3.18.0
>
> For the future: such words should be placed under --- tear line...
>
>> The driver lacks igb_disable_sriov in error handling,
>> which should match igb_enable_sriov in igb_probe.
>> This patch fixes this problem, and it has been tested in runtime.
>
>> Signed-off-by: Jia-Ju Bai <baijiaju1990@163.com>
>> ---
>
> .... here.
>
>> drivers/net/ethernet/intel/igb/igb_main.c | 4 ++++
>> 1 file changed, 4 insertions(+)
>
> WBR, Sergei
>
Thanks. ^_^
I see that most patches in netdev mailing list do not mention the linux
kernel version, so is it necessary to write the version in the patch?
------------------------------------------------------------------------------
Dive into the World of Parallel Programming! The Go Parallel Website,
sponsored by Intel and developed in partnership with Slashdot Media, is your
hub for all things parallel software development, from weekly thought
leadership blogs to news, videos, case studies, tutorials and more. Take a
look and join the conversation now. http://goparallel.sourceforge.net
_______________________________________________
E1000-devel mailing list
E1000-devel@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/e1000-devel
To learn more about Intel® Ethernet, visit http://communities.intel.com/community/wired
^ permalink raw reply
* Re: [PATCH netfilter-next] xt_osf: Use continue to reduce indentation
From: Pablo Neira Ayuso @ 2014-12-23 13:22 UTC (permalink / raw)
To: Evgeniy Polyakov
Cc: Joe Perches, Patrick McHardy, Jozsef Kadlecsik, netfilter-devel,
netdev, LKML
In-Reply-To: <8632531418806285@web23h.yandex.ru>
On Wed, Dec 17, 2014 at 11:51:25AM +0300, Evgeniy Polyakov wrote:
> Hi everyone
>
> 16.12.2014, 23:17, "Joe Perches" <joe@perches.com>:
> > Invert logic in test to use continue.
> >
> > This routine already uses continue, use it a bit more to
> > minimize > 80 column long lines and unnecessary indentation.
> >
> > No change in compiled object file.
>
> Looks good. Thank you.
> Which tree should this patch go through? Please pull it in.
>
> Acked-by: Evgeniy Polyakov <zbr@ioremap.net>
Applied to nf-next, thanks.
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox