* Re: [PATCH 0/1] net/hyperv: Use wait_event on outstanding sends during device removal
From: David Miller @ 2012-06-04 15:51 UTC (permalink / raw)
To: haiyangz; +Cc: netdev, kys, olaf, linux-kernel, devel
In-Reply-To: <1338820532-2345-1-git-send-email-haiyangz@microsoft.com>
From: Haiyang Zhang <haiyangz@microsoft.com>
Date: Mon, 4 Jun 2012 07:35:31 -0700
> This patch is targeting net-next tree (when it's available for check in).
>
> Haiyang Zhang (1):
> net/hyperv: Use wait_event on outstanding sends during device removal
Why in the world are you doing this?
This patch you are already asking me to apply to the 'net' tree, and
changes already will automatically propagate from 'net' to
'net-next' the next time I merge those trees.
So you never need to submit bug fixes twice, once for 'net' and
once for 'net-next' so please do not do it.
^ permalink raw reply
* [PATCH (net.git)] net: icplus: fix interrupt mask
From: Giuseppe CAVALLARO @ 2012-06-04 15:51 UTC (permalink / raw)
To: netdev; +Cc: Giuseppe Cavallaro
This patch fixes the interrupt mask for IC101 A/G devices
and now enables the link/speed/duplex interrupts.
This is done by setting the "INTR pin used" bit and cleaning
all the other bits in the Register 17.
Reported-by: Stuart Menefy <stuart.menefy@st.com>
Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
---
drivers/net/phy/icplus.c | 7 +++++++
1 files changed, 7 insertions(+), 0 deletions(-)
diff --git a/drivers/net/phy/icplus.c b/drivers/net/phy/icplus.c
index 5ac46f5..47f8e89 100644
--- a/drivers/net/phy/icplus.c
+++ b/drivers/net/phy/icplus.c
@@ -41,6 +41,8 @@ MODULE_LICENSE("GPL");
#define IP1001_APS_ON 11 /* IP1001 APS Mode bit */
#define IP101A_G_APS_ON 2 /* IP101A/G APS Mode bit */
#define IP101A_G_IRQ_CONF_STATUS 0x11 /* Conf Info IRQ & Status Reg */
+#define IP101A_G_IRQ_PIN_USED (1<<15) /* INTR pin used */
+#define IP101A_G_IRQ_DEFAULT IP101A_G_IRQ_PIN_USED
static int ip175c_config_init(struct phy_device *phydev)
{
@@ -136,6 +138,11 @@ static int ip1001_config_init(struct phy_device *phydev)
if (c < 0)
return c;
+ /* INTR pin used: speed/link/duplex will cause an interrupt */
+ c = phy_write(phydev, IP101A_G_IRQ_CONF_STATUS, IP101A_G_IRQ_DEFAULT);
+ if (c < 0)
+ return c;
+
if (phydev->interface == PHY_INTERFACE_MODE_RGMII) {
/* Additional delay (2ns) used to adjust RX clock phase
* at RGMII interface */
--
1.7.4.4
^ permalink raw reply related
* Re: pull-request: can 2012-06-03
From: David Miller @ 2012-06-04 15:51 UTC (permalink / raw)
To: mkl; +Cc: netdev, linux-can
In-Reply-To: <4FCCD86F.40007@pengutronix.de>
From: Marc Kleine-Budde <mkl@pengutronix.de>
Date: Mon, 04 Jun 2012 17:46:55 +0200
> On 06/04/2012 05:44 PM, David Miller wrote:
>> From: Marc Kleine-Budde <mkl@pengutronix.de>
>> Date: Mon, 4 Jun 2012 00:21:56 +0200
>>
>>> git@gitorious.org:linux-can/linux-can.git master
>>
>> I can't pull from that tree.
>>
>> [davem@bql net]$ git pull git@gitorious.org:linux-can/linux-can.git master
>> The authenticity of host 'gitorious.org (87.238.52.168)' can't be established.
>> RSA key fingerprint is 7e:af:8d:ec:f0:39:5e:ba:52:16:ce:19:fa:d4:b8:7d.
>> Are you sure you want to continue connecting (yes/no)? yes
>> Warning: Permanently added 'gitorious.org,87.238.52.168' (RSA) to the list of known hosts.
>> Permission denied (publickey).
>> fatal: The remote end hung up unexpectedly
>
> Doh,
>
> git://gitorious.org/linux-can/linux-can.git master
Pulled, thanks.
^ permalink raw reply
* Re: pull-request: can-next 2012-06-04
From: Marc Kleine-Budde @ 2012-06-04 15:52 UTC (permalink / raw)
To: davem; +Cc: Linux Netdev List, linux-can@vger.kernel.org
In-Reply-To: <4FCBEAAB.90708@pengutronix.de>
[-- Attachment #1: Type: text/plain, Size: 940 bytes --]
On 06/04/2012 12:52 AM, Marc Kleine-Budde wrote:
> Hello David,
>
> here are the first patches for net-next, they add power management
> support for the flexcan driver and clarify the documentation with
> respect to error messages.
>
> regards, Marc
>
> ---
>
> The following changes since commit 31a67102f4762df5544bc2dfb34a931233d2a5b2:
>
> Fix blocking allocations called very early during bootup (2012-05-21 12:52:42 -0700)
>
> are available in the git repository at:
> git@gitorious.org:linux-can/linux-can-next.git master
That should be:
git://gitorious.org/linux-can/linux-can-next.git master
Sorry for the noise,
Marc
--
Pengutronix e.K. | Marc Kleine-Budde |
Industrial Linux Solutions | Phone: +49-231-2826-924 |
Vertretung West/Dortmund | Fax: +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686 | http://www.pengutronix.de |
[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 262 bytes --]
^ permalink raw reply
* Re: [PATCH] net: Remove casts to same type
From: Joe Perches @ 2012-06-04 15:52 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In-Reply-To: <20120604.114533.1720204611284591292.davem@davemloft.net>
On Mon, 2012-06-04 at 11:45 -0400, David Miller wrote:
> From: Joe Perches <joe@perches.com>
> > Adding casts of objects to the same type is unnecessary
> > and confusing for a human reader.
[]
> > I used the coccinelle script below to find and remove these
> > unnecessary casts. I manually removed the conversions this
> > script produces of casts with __force and __user.
> >
> > @@
> > type T;
> > T *p;
> > @@
> >
> > - (T *)p
> > + p
> Applied to net-next, thanks Joe.
Do you want the same thing for drivers/net?
It's pretty big and might be better broken into
commits by maintainer/directory.
^ permalink raw reply
* Re: [PATCH] net: Remove casts to same type
From: David Miller @ 2012-06-04 15:53 UTC (permalink / raw)
To: joe; +Cc: netdev
In-Reply-To: <1338825128.8574.15.camel@joe2Laptop>
From: Joe Perches <joe@perches.com>
Date: Mon, 04 Jun 2012 08:52:08 -0700
> On Mon, 2012-06-04 at 11:45 -0400, David Miller wrote:
>> From: Joe Perches <joe@perches.com>
>> > Adding casts of objects to the same type is unnecessary
>> > and confusing for a human reader.
> []
>> > I used the coccinelle script below to find and remove these
>> > unnecessary casts. I manually removed the conversions this
>> > script produces of casts with __force and __user.
>> >
>> > @@
>> > type T;
>> > T *p;
>> > @@
>> >
>> > - (T *)p
>> > + p
>> Applied to net-next, thanks Joe.
>
> Do you want the same thing for drivers/net?
>
> It's pretty big and might be better broken into
> commits by maintainer/directory.
I don't see any value beyond perhaps splitting it into
drivers/net/ethernet, drivers/net/wireless, and "rest".
^ permalink raw reply
* Re: [PATCH RFC] c_can_pci: generic module for c_can on PCI
From: Alan Cox @ 2012-06-04 15:56 UTC (permalink / raw)
To: Federico Vaga
Cc: Wolfgang Grandegger, Marc Kleine-Budde, Giancarlo Asnaghi,
Alan Cox, Alessandro Rubini, linux-can, netdev, linux-kernel
In-Reply-To: <1338816766-7089-2-git-send-email-federico.vaga@gmail.com>
> +enum c_can_pci_reg_align {
> + C_CAN_REG_ALIGN_16,
> + C_CAN_REG_ALIGN_32,
> +};
Anythign wrong with
bool aligned32;
> +
> +struct c_can_pci_data {
> + unsigned int reg_align; /* Set the register alignment in the memory */
Not the enum .. indeed
> +static u16 c_can_pci_read_reg_aligned_to_16bit(struct c_can_priv *priv,
> + void *reg)
I'm a bit worried this function name might be too short ;)
> + dev_info(&pdev->dev, "%s device registered (regs=%p, irq=%d)\n",
> + KBUILD_MODNAME, priv->regs, dev->irq);
dev_dbg
> + * do not call pci_disable_device on sta2x11 because it
> + * break all other Bus masters on this EP
> + */
> + if(pdev->vendor == PCI_VENDOR_ID_STMICRO &&
> + pdev->device == PCI_DEVICE_ID_STMICRO_CAN)
> + goto out;
Is that the disabling or the dropping it into D3. We have a PCI quirk
flag for the latter. See "quirk_no_ata_d3". That will also avoid any
accidents elsewhere. Right now the quirk has "ata" in the name but the
ata is just historically because we had to quirk various disk controllers.
^ permalink raw reply
* Re: [PATCH (net.git) 1/4] stmmac: remove two useless initialisation
From: Giuseppe CAVALLARO @ 2012-06-04 15:58 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In-Reply-To: <20120604.114940.813410325113851773.davem@davemloft.net>
On 6/4/2012 5:49 PM, David Miller wrote:
> From: Giuseppe CAVALLARO <peppe.cavallaro@st.com>
> Date: Mon, 4 Jun 2012 17:37:47 +0200
>
>> This patch removes two useful initialisation in the
>> stmmac_rx and stmmac_tx function.
>> In the former, count var was already reset and in the
>> stmmac_tx we only need to increment the dirty pointer
>> w/o setting the entry var.
>>
>> Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
>
> There are so many problems with this patch I do not know where
> to start.
>
> Your subject line says the initializations are "useless" yet
> your commit message says they are "useful".
Sorry, I meant "useless".
> This is a cleanup, and does not fix any bugs, and is therefore
> absolutely not appropriate for the 'net' tree.
Yes this is not a fix but a cleanup.
I've not clear where I have to post this patch.
Do you mean, w/o net.git entry in the patch subject?
Can you tell me what I have to do? So will resend all the patches again
but I'll be more careful on all.
> I'm tossing this entire series, you need to be more careful
> with your submissions.
ok, thanks a lot.
peppe
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
>
^ permalink raw reply
* Re: [PATCH (net.git) 1/4] stmmac: remove two useless initialisation
From: David Miller @ 2012-06-04 16:01 UTC (permalink / raw)
To: peppe.cavallaro; +Cc: netdev
In-Reply-To: <4FCCDB1A.1080307@st.com>
From: Giuseppe CAVALLARO <peppe.cavallaro@st.com>
Date: Mon, 04 Jun 2012 17:58:18 +0200
> I've not clear where I have to post this patch.
This is mind boggling that you can't figure this out.
If I tell you it's not appropriate for net, that means
it obviously must go to net-next
^ permalink raw reply
* Re: [PATCH (net.git)] net: icplus: fix interrupt mask
From: David Miller @ 2012-06-04 16:03 UTC (permalink / raw)
To: peppe.cavallaro; +Cc: netdev
In-Reply-To: <1338825078-31856-1-git-send-email-peppe.cavallaro@st.com>
From: Giuseppe CAVALLARO <peppe.cavallaro@st.com>
Date: Mon, 4 Jun 2012 17:51:18 +0200
> This patch fixes the interrupt mask for IC101 A/G devices
> and now enables the link/speed/duplex interrupts.
> This is done by setting the "INTR pin used" bit and cleaning
> all the other bits in the Register 17.
>
> Reported-by: Stuart Menefy <stuart.menefy@st.com>
> Signed-off-by: Giuseppe Cavallaro <peppe.cavallaro@st.com>
Applied.
^ permalink raw reply
* Re: [PATCH] net: Remove casts to same type
From: Ben Hutchings @ 2012-06-04 16:04 UTC (permalink / raw)
To: Joe Perches; +Cc: David S. Miller, netdev
In-Reply-To: <4b3738493b23bc386d3372012faa8cd3672a138d.1338780551.git.joe@perches.com>
On Sun, 2012-06-03 at 20:41 -0700, Joe Perches wrote:
> Adding casts of objects to the same type is unnecessary
> and confusing for a human reader.
>
> For example, this cast:
>
> int y;
> int *p = (int *)&y;
>
> I used the coccinelle script below to find and remove these
> unnecessary casts. I manually removed the conversions this
> script produces of casts with __force and __user.
[...]
> diff --git a/net/9p/client.c b/net/9p/client.c
> index a170893..5cbea90 100644
> --- a/net/9p/client.c
> +++ b/net/9p/client.c
> @@ -1548,7 +1548,7 @@ p9_client_read(struct p9_fid *fid, char *data, char __user *udata, u64 offset,
> kernel_buf = 1;
> indata = data;
> } else
> - indata = (char *)udata;
> + indata = udata;
> /*
> * response header len is 11
> * PDU Header(7) + IO Size (4)
[...]
This one is casting char __user * to char *. We need a cast to let
sparse know this is deliberate, though presumably we need __force as
well.
Ben.
--
Ben Hutchings, Staff Engineer, Solarflare
Not speaking for my employer; that's the marketing department's job.
They asked us to note that Solarflare product names are trademarked.
^ permalink raw reply
* [PATCH iproute2 0/3] CAN Filter/Classifier
From: Rostislav Lisovy @ 2012-06-04 16:09 UTC (permalink / raw)
To: netdev; +Cc: linux-can, lartc, pisa, sojkam1, Rostislav Lisovy
This classifier classifies CAN frames (AF_CAN) according to their
identifiers. This functionality can not be easily achieved with
existing classifiers, such as u32. This classifier can be used
with any available qdisc and it is able to classify both SFF
or EFF frames.
The filtering rules for EFF frames are stored in an array, which
is traversed during classification. A bitmap is used to store SFF
rules -- one bit for each ID.
More info about the project:
http://rtime.felk.cvut.cz/can/socketcan-qdisc-final.pdf
Rostislav Lisovy (3):
Add missing can.h
CAN Filter/Classifier -- Source code
CAN Filter/Classifier -- Documentation
include/linux/can.h | 112 ++++++++++++++++++++++
include/linux/pkt_cls.h | 10 ++
man/man8/tc-can.8 | 97 +++++++++++++++++++
tc/Makefile | 1 +
tc/f_can.c | 238 +++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 458 insertions(+)
create mode 100644 include/linux/can.h
create mode 100644 man/man8/tc-can.8
create mode 100644 tc/f_can.c
--
1.7.9.5
^ permalink raw reply
* [PATCH iproute2 1/3] Add missing can.h
From: Rostislav Lisovy @ 2012-06-04 16:09 UTC (permalink / raw)
To: netdev; +Cc: linux-can, lartc, pisa, sojkam1, Rostislav Lisovy
In-Reply-To: <1338826149-11604-1-git-send-email-lisovy@gmail.com>
This header file is slightly modified version copied from
Linux kernel v. 3.3. It contains defines necessary for working
with AF_CAN packets.
Signed-off-by: Rostislav Lisovy <lisovy@gmail.com>
---
include/linux/can.h | 112 +++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 112 insertions(+)
create mode 100644 include/linux/can.h
diff --git a/include/linux/can.h b/include/linux/can.h
new file mode 100644
index 0000000..08d1610
--- /dev/null
+++ b/include/linux/can.h
@@ -0,0 +1,112 @@
+/*
+ * linux/can.h
+ *
+ * Definitions for CAN network layer (socket addr / CAN frame / CAN filter)
+ *
+ * Authors: Oliver Hartkopp <oliver.hartkopp@volkswagen.de>
+ * Urs Thuermann <urs.thuermann@volkswagen.de>
+ * Copyright (c) 2002-2007 Volkswagen Group Electronic Research
+ * All rights reserved.
+ *
+ */
+
+#ifndef CAN_H
+#define CAN_H
+
+#include <linux/types.h>
+#include <linux/socket.h>
+
+/* controller area network (CAN) kernel definitions */
+
+/* special address description flags for the CAN_ID */
+#define CAN_EFF_FLAG 0x80000000U /* EFF/SFF is set in the MSB */
+#define CAN_RTR_FLAG 0x40000000U /* remote transmission request */
+#define CAN_ERR_FLAG 0x20000000U /* error frame */
+
+/* valid bits in CAN ID for frame formats */
+#define CAN_SFF_MASK 0x000007FFU /* standard frame format (SFF) */
+#define CAN_EFF_MASK 0x1FFFFFFFU /* extended frame format (EFF) */
+#define CAN_ERR_MASK 0x1FFFFFFFU /* omit EFF, RTR, ERR flags */
+
+/*
+ * Controller Area Network Identifier structure
+ *
+ * bit 0-28 : CAN identifier (11/29 bit)
+ * bit 29 : error frame flag (0 = data frame, 1 = error frame)
+ * bit 30 : remote transmission request flag (1 = rtr frame)
+ * bit 31 : frame format flag (0 = standard 11 bit, 1 = extended 29 bit)
+ */
+typedef __u32 canid_t;
+
+#define CAN_SFF_ID_BITS 11
+#define CAN_EFF_ID_BITS 29
+
+/*
+ * Controller Area Network Error Frame Mask structure
+ *
+ * bit 0-28 : error class mask (see include/linux/can/error.h)
+ * bit 29-31 : set to zero
+ */
+typedef __u32 can_err_mask_t;
+
+/**
+ * struct can_frame - basic CAN frame structure
+ * @can_id: the CAN ID of the frame and CAN_*_FLAG flags, see above.
+ * @can_dlc: the data length field of the CAN frame
+ * @data: the CAN frame payload.
+ */
+struct can_frame {
+ canid_t can_id; /* 32 bit CAN_ID + EFF/RTR/ERR flags */
+ __u8 can_dlc; /* data length code: 0 .. 8 */
+ __u8 data[8] __attribute__((aligned(8)));
+};
+
+/* particular protocols of the protocol family PF_CAN */
+#define CAN_RAW 1 /* RAW sockets */
+#define CAN_BCM 2 /* Broadcast Manager */
+#define CAN_TP16 3 /* VAG Transport Protocol v1.6 */
+#define CAN_TP20 4 /* VAG Transport Protocol v2.0 */
+#define CAN_MCNET 5 /* Bosch MCNet */
+#define CAN_ISOTP 6 /* ISO 15765-2 Transport Protocol */
+#define CAN_NPROTO 7
+
+#define SOL_CAN_BASE 100
+
+/**
+ * struct sockaddr_can - the sockaddr structure for CAN sockets
+ * @can_family: address family number AF_CAN.
+ * @can_ifindex: CAN network interface index.
+ * @can_addr: protocol specific address information
+ */
+struct sockaddr_can {
+ __kernel_sa_family_t can_family;
+ int can_ifindex;
+ union {
+ /* transport protocol class address information (e.g. ISOTP) */
+ struct { canid_t rx_id, tx_id; } tp;
+
+ /* reserved for future CAN protocols address information */
+ } can_addr;
+};
+
+/**
+ * struct can_filter - CAN ID based filter in can_register().
+ * @can_id: relevant bits of CAN ID which are not masked out.
+ * @can_mask: CAN mask (see description)
+ *
+ * Description:
+ * A filter matches, when
+ *
+ * <received_can_id> & mask == can_id & mask
+ *
+ * The filter can be inverted (CAN_INV_FILTER bit set in can_id) or it can
+ * filter for error frames (CAN_ERR_FLAG bit set in mask).
+ */
+struct can_filter {
+ canid_t can_id;
+ canid_t can_mask;
+};
+
+#define CAN_INV_FILTER 0x20000000U /* to be set in can_filter.can_id */
+
+#endif /* CAN_H */
--
1.7.9.5
^ permalink raw reply related
* [PATCH iproute2 2/3] CAN Filter/Classifier -- Source code
From: Rostislav Lisovy @ 2012-06-04 16:09 UTC (permalink / raw)
To: netdev; +Cc: linux-can, lartc, pisa, sojkam1, Rostislav Lisovy
In-Reply-To: <1338826149-11604-1-git-send-email-lisovy@gmail.com>
This classifier classifies CAN frames (AF_CAN) according to their
identifiers. This functionality can not be easily achieved with
existing classifiers, such as u32. This classifier can be used
with any available qdisc and it is able to classify both SFF
or EFF frames.
The filtering rules for EFF frames are stored in an array, which
is traversed during classification. A bitmap is used to store SFF
rules -- one bit for each ID.
More info about the project:
http://rtime.felk.cvut.cz/can/socketcan-qdisc-final.pdf
Signed-off-by: Rostislav Lisovy <lisovy@gmail.com>
---
include/linux/pkt_cls.h | 10 ++
tc/Makefile | 1 +
tc/f_can.c | 238 +++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 249 insertions(+)
create mode 100644 tc/f_can.c
diff --git a/include/linux/pkt_cls.h b/include/linux/pkt_cls.h
index defbde2..83f9241 100644
--- a/include/linux/pkt_cls.h
+++ b/include/linux/pkt_cls.h
@@ -375,6 +375,16 @@ enum {
#define TCA_BASIC_MAX (__TCA_BASIC_MAX - 1)
+/* CAN filter */
+
+enum {
+ TCA_CANFLTR_UNSPEC,
+ TCA_CANFLTR_CLASSID,
+ TCA_CANFLTR_RULES,
+ __TCA_CANFLTR_MAX
+};
+
+#define TCA_CANFLTR_MAX (__TCA_CANFLTR_MAX - 1)
/* Cgroup classifier */
diff --git a/tc/Makefile b/tc/Makefile
index 64d93ad..1281568 100644
--- a/tc/Makefile
+++ b/tc/Makefile
@@ -22,6 +22,7 @@ TCMODULES += f_u32.o
TCMODULES += f_route.o
TCMODULES += f_fw.o
TCMODULES += f_basic.o
+TCMODULES += f_can.o
TCMODULES += f_flow.o
TCMODULES += f_cgroup.o
TCMODULES += q_dsmark.o
diff --git a/tc/f_can.c b/tc/f_can.c
new file mode 100644
index 0000000..208625f
--- /dev/null
+++ b/tc/f_can.c
@@ -0,0 +1,238 @@
+/*
+ * f_can.c Filter for CAN packets
+ *
+ * This program is free software; you can distribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; either version
+ * 2 of the License, or (at your option) any later version.
+ *
+ * Idea: Oliver Hartkopp <oliver.hartkopp@volkswagen.de>
+ * Copyright: (c) 2011 Czech Technical University in Prague
+ * (c) 2011 Volkswagen Group Research
+ * Authors: Michal Sojka <sojkam1@fel.cvut.cz>
+ * Pavel Pisa <pisa@cmp.felk.cvut.cz>
+ * Rostislav Lisovy <lisovy@gmail.cz>
+ * Funded by: Volkswagen Group Research
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <syslog.h>
+#include <fcntl.h>
+#include <sys/socket.h>
+#include <netinet/in.h>
+#include <arpa/inet.h>
+#include <string.h>
+#include <linux/if.h>
+#include <limits.h>
+#include <inttypes.h>
+#include "utils.h"
+#include "tc_util.h"
+#include "linux/can.h"
+
+#define RULES_SIZE 128 /* Maximum number of rules sent via the
+ netlink message during creation/configuration */
+
+
+static void canfltr_explain(void)
+{
+ fprintf(stderr, "Usage: ... can [ MATCHSPEC ] [ flowid FLOWID ]\n"
+ "\n"
+ "Where: MATCHSPEC := { sffid FILTERID | effid FILTERID |\n"
+ " MATCHSPEC ... }\n"
+ " FILTERID := CANID[:MASK]\n"
+ "\n"
+ "NOTE: CLASSID, CANID, MASK is parsed as hexadecimal input.\n");
+}
+
+static int canfltr_parse_opt(struct filter_util *qu, char *handle,
+ int argc, char **argv, struct nlmsghdr *n)
+{
+ struct tcmsg *t = NLMSG_DATA(n);
+ struct rtattr *tail;
+ struct can_filter canfltr_rules[RULES_SIZE];
+ int rules_count = 0;
+ long h = 0;
+ canid_t can_id;
+ canid_t can_mask;
+
+ if (!argc)
+ return 0;
+
+ if (handle) {
+ h = strtol(handle, NULL, 0);
+ if (h == LONG_MIN || h == LONG_MAX) {
+ fprintf(stderr, "Illegal handle \"%s\", must be numeric.\n",
+ handle);
+ return -1;
+ }
+ }
+
+ t->tcm_handle = h;
+
+ tail = NLMSG_TAIL(n);
+ addattr_l(n, MAX_MSG, TCA_OPTIONS, NULL, 0);
+
+ while (argc > 0) {
+ if (matches(*argv, "sffid") == 0) {
+ /* parse SFF CAN ID optionally with mask */
+ if (rules_count >= RULES_SIZE) {
+ fprintf(stderr, "Too much rules on input. "
+ "Maximum number of rules is: %d\n",
+ RULES_SIZE);
+ return -1;
+ }
+
+ NEXT_ARG();
+
+ if (sscanf(*argv, "%"SCNx32 ":" "%"SCNx32,
+ &can_id, &can_mask) != 2) {
+ if (sscanf(*argv, "%"SCNx32, &can_id) != 1) {
+ fprintf(stderr, "Improperly formed CAN "
+ "ID & mask '%s'\n", *argv);
+ return -1;
+ } else
+ can_mask = CAN_SFF_MASK;
+ }
+
+ /* we do not support extra handling for RTR frames
+ due to the bitmap approach */
+ if (can_id & ~CAN_SFF_MASK) {
+ fprintf(stderr, "ID 0x%lx exceeded standard CAN ID range.\n",
+ (unsigned long)can_id);
+ return -1;
+ }
+
+ canfltr_rules[rules_count].can_id = can_id;
+ canfltr_rules[rules_count].can_mask =
+ (can_mask & CAN_SFF_MASK);
+ rules_count++;
+
+ } else if (matches(*argv, "effid") == 0) {
+ /* parse EFF CAN ID optionally with mask */
+ if (rules_count >= RULES_SIZE) {
+ fprintf(stderr, "Too much rules on input. "
+ "Maximum number of rules is: %d\n",
+ RULES_SIZE);
+ return -1;
+ }
+
+ NEXT_ARG();
+
+ if (sscanf(*argv, "%"SCNx32 ":" "%"SCNx32, &can_id, &can_mask) != 2) {
+ if (sscanf(*argv, "%"SCNx32, &can_id) != 1) {
+ fprintf(stderr, "Improperly formed CAN ID & mask '%s'\n", *argv);
+ return -1;
+ } else
+ can_mask = CAN_EFF_MASK;
+ }
+
+ if (can_id & ~CAN_EFF_MASK) {
+ fprintf(stderr, "ID 0x%lx exceeded extended CAN ID range.",
+ (unsigned long)can_id);
+ return -1;
+ }
+
+ canfltr_rules[rules_count].can_id =
+ can_id | CAN_EFF_FLAG;
+ canfltr_rules[rules_count].can_mask =
+ (can_mask & CAN_EFF_MASK) | CAN_EFF_FLAG;
+ rules_count++;
+
+ } else if (matches(*argv, "classid") == 0 || strcmp(*argv, "flowid") == 0) {
+ unsigned handle;
+ NEXT_ARG();
+ if (get_tc_classid(&handle, *argv)) {
+ fprintf(stderr, "Illegal \"classid\"\n");
+ return -1;
+ }
+ addattr_l(n, MAX_MSG, TCA_CANFLTR_CLASSID, &handle, 4);
+
+ } else if (strcmp(*argv, "help") == 0) {
+ canfltr_explain();
+ return -1;
+
+ } else {
+ fprintf(stderr, "What is \"%s\"?\n", *argv);
+ canfltr_explain();
+ return -1;
+ }
+ argc--; argv++;
+ }
+
+ addattr_l(n, MAX_MSG, TCA_CANFLTR_RULES, &canfltr_rules,
+ sizeof(struct can_filter) * rules_count);
+
+ tail->rta_len = (void *)NLMSG_TAIL(n) - (void *)tail;
+ return 0;
+}
+
+/* When "tc filter show dev XY" is executed, function canfltr_walk() (in
+ * kernel) is called (which calls canfltr_dump() for each instance of a
+ * filter) which sends information about each instance of a filter to
+ * userspace -- to this function which parses the message and prints it.
+ */
+static int canfltr_print_opt(struct filter_util *qu, FILE *f,
+ struct rtattr *opt, __u32 handle)
+{
+ struct rtattr *tb[TCA_CANFLTR_MAX+1];
+ struct can_filter *canfltr_rules = NULL;
+ int rules_count = 0;
+ int i;
+
+ if (opt == NULL)
+ return 0;
+
+ parse_rtattr_nested(tb, TCA_CANFLTR_MAX, opt);
+
+ if (handle)
+ fprintf(f, "handle 0x%x ", handle);
+
+
+ if (tb[TCA_BASIC_CLASSID]) {
+ SPRINT_BUF(b1); /* allocates buffer b1 */
+ fprintf(f, "flowid %s ",
+ sprint_tc_classid(*(__u32 *)RTA_DATA(tb[TCA_BASIC_CLASSID]), b1));
+ }
+
+ if (tb[TCA_CANFLTR_RULES]) {
+ if (RTA_PAYLOAD(tb[TCA_CANFLTR_RULES]) < sizeof(struct can_filter))
+ return -1;
+
+ canfltr_rules = RTA_DATA(tb[TCA_CANFLTR_RULES]);
+ rules_count = (RTA_PAYLOAD(tb[TCA_CANFLTR_RULES]) /
+ sizeof(struct can_filter));
+
+ for (i = 0; i < rules_count; i++) {
+ struct can_filter *pcfltr = &canfltr_rules[i];
+
+ if (pcfltr->can_id & CAN_EFF_FLAG) {
+ if (pcfltr->can_mask == (CAN_EFF_FLAG|CAN_EFF_MASK))
+ fprintf(f, "effid 0x%"PRIX32" ",
+ pcfltr->can_id & CAN_EFF_MASK);
+ else
+ fprintf(f, "effid 0x%"PRIX32":0x%"PRIX32" ",
+ pcfltr->can_id & CAN_EFF_MASK,
+ pcfltr->can_mask & CAN_EFF_MASK);
+ } else {
+ if (pcfltr->can_mask == CAN_SFF_MASK)
+ fprintf(f, "sffid 0x%"PRIX32" ",
+ pcfltr->can_id);
+ else
+ fprintf(f, "sffid 0x%"PRIX32":0x%"PRIX32" ",
+ pcfltr->can_id,
+ pcfltr->can_mask);
+ }
+ }
+ }
+
+ return 0;
+}
+
+struct filter_util can_filter_util = {
+ .id = "can",
+ .parse_fopt = canfltr_parse_opt,
+ .print_fopt = canfltr_print_opt,
+};
+
--
1.7.9.5
^ permalink raw reply related
* [PATCH iproute2 3/3] CAN Filter/Classifier -- Documentation
From: Rostislav Lisovy @ 2012-06-04 16:09 UTC (permalink / raw)
To: netdev; +Cc: linux-can, lartc, pisa, sojkam1, Rostislav Lisovy
In-Reply-To: <1338826149-11604-1-git-send-email-lisovy@gmail.com>
Manpage describing usage of CAN Filter.
Signed-off-by: Rostislav Lisovy <lisovy@gmail.com>
---
man/man8/tc-can.8 | 97 +++++++++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 97 insertions(+)
create mode 100644 man/man8/tc-can.8
diff --git a/man/man8/tc-can.8 b/man/man8/tc-can.8
new file mode 100644
index 0000000..54ee96a
--- /dev/null
+++ b/man/man8/tc-can.8
@@ -0,0 +1,97 @@
+.TH CAN 8 "8 May 2012" "iproute2" "Linux"
+.SH NAME
+CAN \- Controller Area Network classifier
+.SH SYNOPSIS
+.B tc filter ... dev
+DEV
+.B parent
+CLASSID
+.B [ prio
+PRIORITY
+.B ] [ protocol can ] [ handle
+HANDLE
+.B ] can [
+MATCHSPEC
+.B ] [ flowid
+FLOWID
+.B ]
+
+.B CLASSID := major:minor
+.br
+.B FLOWID := major:minor
+.br
+.B MATCHSPEC := { sffid
+FILTERID
+.B | effid
+FILTERID
+.B | MATCHSPEC ... }
+.br
+.B FILTERID := canid[:mask]
+
+.BR CLASSID ,
+.BR FLOWID ,
+.BR canid
+and
+.B mask
+are parsed as hexadecimal input.
+
+
+.SH DESCRIPTION
+The CAN classifier may be used with any available
+.B qdisc
+on Controller Area Network (CAN) frames passed through AF_CAN
+networking subsystem. The classifier classifies CAN frames according
+to their identifiers. It can be used on CAN frames with both SFF or
+EFF identifiers.
+
+It is possible to add CAN classifier to any qdisc configured on any networking
+device, however it will ignore non-CAN packets.
+
+
+.SH CLASSIFICATION
+The filtering rules for EFF frames are stored in an array, which is traversed
+during classification. This means that the worst-case time needed for
+classification of EFF frames increases with the number of configured rules.
+
+The filter implements an optimization for matching SFF frames using a bitmap
+with one bit for every ID. With this optimization, the classification time
+for SFF frames is nearly constant independently of the number of rules.
+
+.SH EXAMPLE
+This example shows how to set
+.B prio qdisc
+with
+.B CAN
+classifier.
+
+.nf
+tc qdisc add dev can0 root handle 1: prio
+
+tc filter add dev can0 parent 1:0 prio 1 handle 0xa \\
+ can sffid 0x7ff:0xf flowid 1:1
+tc filter add dev can0 parent 1:0 prio 2 handle 0xb \\
+ can sffid 0xC0:0x7ff effid 0x80:0x7ff flowid 1:2
+tc filter add dev can0 parent 1:0 prio 3 \\
+ can sffid 0x80:0x7ff flowid 1:2
+tc filter add dev can0 parent 1:0 prio 4 \\
+ can sffid 0x0:0x0 effid 0x0:0x0 flowid 1:3
+.fi
+
+
+.SH BUGS
+The maximum number or rules passed from
+.BR tc(8)
+utility to CAN classifier is fixed. The limit is set at compilation time
+(default is 128).
+
+
+.SH SEE ALSO
+.BR tc(8)
+
+
+.SH AUTHORS
+Michal Sojka <sojkam1@fel.cvut.cz>, Pavel Pisa <pisa@cmp.felk.cvut.cz>,
+Rostislav Lisovy <lisovy@gmail.cz>.
+
+This manpage maintained by Rostislav Lisovy <lisovy@gmail.com>
+
--
1.7.9.5
^ permalink raw reply related
* [PATCH 1/2] can: Add constants containing length of CAN identifiers
From: Rostislav Lisovy @ 2012-06-04 16:09 UTC (permalink / raw)
To: netdev; +Cc: linux-can, lartc, pisa, sojkam1, Rostislav Lisovy
The necessary information might be determined out of the CAN_*_MASK,
however it is undesirable to misuse masks for such purpose.
Signed-off-by: Rostislav Lisovy <lisovy@gmail.com>
---
include/linux/can.h | 3 +++
1 file changed, 3 insertions(+)
diff --git a/include/linux/can.h b/include/linux/can.h
index 9a19bcb..08d1610 100644
--- a/include/linux/can.h
+++ b/include/linux/can.h
@@ -38,6 +38,9 @@
*/
typedef __u32 canid_t;
+#define CAN_SFF_ID_BITS 11
+#define CAN_EFF_ID_BITS 29
+
/*
* Controller Area Network Error Frame Mask structure
*
--
1.7.9.5
^ permalink raw reply related
* [PATCH 2/2] net/sched: CAN Filter/Classifier
From: Rostislav Lisovy @ 2012-06-04 16:09 UTC (permalink / raw)
To: netdev; +Cc: linux-can, lartc, pisa, sojkam1, Rostislav Lisovy
In-Reply-To: <1338826176-11646-1-git-send-email-lisovy@gmail.com>
This classifier classifies CAN frames (AF_CAN) according to their
identifiers. This functionality can not be easily achieved with
existing classifiers, such as u32. This classifier can be used
with any available qdisc and it is able to classify both SFF
or EFF frames.
The filtering rules for EFF frames are stored in an array, which
is traversed during classification. A bitmap is used to store SFF
rules -- one bit for each ID.
More info about the project:
http://rtime.felk.cvut.cz/can/socketcan-qdisc-final.pdf
Signed-off-by: Rostislav Lisovy <lisovy@gmail.com>
---
net/sched/Kconfig | 10 +
net/sched/Makefile | 1 +
net/sched/cls_can.c | 572 +++++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 583 insertions(+)
create mode 100644 net/sched/cls_can.c
diff --git a/net/sched/Kconfig b/net/sched/Kconfig
index e7a8976..aeb3c29 100644
--- a/net/sched/Kconfig
+++ b/net/sched/Kconfig
@@ -323,6 +323,16 @@ config NET_CLS_BASIC
To compile this code as a module, choose M here: the
module will be called cls_basic.
+config NET_CLS_CAN
+ tristate "Controller Area Network classifier (CAN)"
+ select NET_CLS
+ ---help---
+ Say Y here if you want to be able to classify CAN frames according
+ to their CAN identifiers (can_id).
+
+ To compile this code as a module, choose M here: the
+ module will be called cls_can.
+
config NET_CLS_TCINDEX
tristate "Traffic-Control Index (TCINDEX)"
select NET_CLS
diff --git a/net/sched/Makefile b/net/sched/Makefile
index 5940a19..0217341 100644
--- a/net/sched/Makefile
+++ b/net/sched/Makefile
@@ -47,6 +47,7 @@ obj-$(CONFIG_NET_CLS_RSVP) += cls_rsvp.o
obj-$(CONFIG_NET_CLS_TCINDEX) += cls_tcindex.o
obj-$(CONFIG_NET_CLS_RSVP6) += cls_rsvp6.o
obj-$(CONFIG_NET_CLS_BASIC) += cls_basic.o
+obj-$(CONFIG_NET_CLS_CAN) += cls_can.o
obj-$(CONFIG_NET_CLS_FLOW) += cls_flow.o
obj-$(CONFIG_NET_CLS_CGROUP) += cls_cgroup.o
obj-$(CONFIG_NET_EMATCH) += ematch.o
diff --git a/net/sched/cls_can.c b/net/sched/cls_can.c
new file mode 100644
index 0000000..659be45
--- /dev/null
+++ b/net/sched/cls_can.c
@@ -0,0 +1,572 @@
+/*
+ * cls_can.c -- Controller Area Network classifier.
+ * Makes decisions according to Controller Area Network identifiers (can_id).
+ *
+ * This program is free software; you can distribute it and/or
+ * modify it under the terms of the GNU General Public License
+ * as published by the Free Software Foundation; version 2 of
+ * the License.
+ *
+ * Idea: Oliver Hartkopp <oliver.hartkopp@volkswagen.de>
+ * Copyright: (c) 2011 Czech Technical University in Prague
+ * (c) 2011 Volkswagen Group Research
+ * Authors: Michal Sojka <sojkam1@fel.cvut.cz>
+ * Pavel Pisa <pisa@cmp.felk.cvut.cz>
+ * Rostislav Lisovy <lisovy@gmail.cz>
+ * Funded by: Volkswagen Group Research
+ *
+ * Some function descriptions are heavily inspired by article "Linux Network
+ * Traffic Control -- Implementation Overview" by Werner Almesberger
+ */
+
+#include <linux/module.h>
+#include <linux/slab.h>
+#include <linux/types.h>
+#include <linux/kernel.h>
+#include <linux/string.h>
+#include <linux/errno.h>
+#include <linux/rtnetlink.h>
+#include <linux/skbuff.h>
+#include <net/netlink.h>
+#include <net/act_api.h>
+#include <net/pkt_cls.h>
+#include <linux/bitmap.h>
+#include <linux/spinlock.h>
+#include <linux/rcupdate.h>
+#include <linux/can.h>
+
+/* Definition of Netlink message parts */
+enum {
+ TCA_CANFLTR_UNSPEC,
+ TCA_CANFLTR_CLASSID,
+ TCA_CANFLTR_RULES, /* Array of can_filter structs; We are able
+ to determine the length after receiving */
+ __TCA_CANFLTR_MAX
+};
+#define TCA_CANFLTR_MAX (__TCA_CANFLTR_MAX - 1)
+
+static const struct nla_policy canfltr_policy[TCA_CANFLTR_MAX + 1] = {
+ [TCA_CANFLTR_CLASSID] = { .type = NLA_U32 }, /* Be aware of possible
+ problems with 64bit kernel and
+ 32bit userspace etc. */
+ [TCA_CANFLTR_RULES] = { .type = NLA_NESTED }
+};
+
+struct canfltr_rules {
+ struct can_filter *rules_raw; /* Raw rules copied from netlink
+ message; Used for sending information
+ to userspace (when 'tc filter show' is
+ invoked) AND when matching EFF frames*/
+ DECLARE_BITMAP(match_sff, (1 << CAN_SFF_ID_BITS)); /* For each SFF CAN
+ ID (11 bit) there is one record in this
+ bitfield */
+ int rules_count;
+ int eff_rules_count;
+ int sff_rules_count;
+
+ struct rcu_head rcu;
+};
+
+struct canfltr_head {
+ u32 hgenerator;
+ struct list_head flist;
+};
+
+struct canfltr_state {
+ u32 handle;
+ struct canfltr_rules *rules; /* All rules necessary for
+ classification */
+ struct tcf_result res; /* Class ID (flow id) the instance
+ of a filter is bound to */
+ struct list_head link;
+};
+
+/*
+ * ----------------------------------------------------------------------------
+ */
+
+static void canfltr_sff_match_add(struct canfltr_rules *rls,
+ u32 can_id, u32 can_mask)
+{
+ int i;
+
+ /* Limit can_mask and can_id to SFF range to
+ protect against write after end of array */
+ can_mask &= CAN_SFF_MASK;
+ can_id &= can_mask;
+
+ /* single frame */
+ if (can_mask == CAN_SFF_MASK) {
+ set_bit(can_id, rls->match_sff);
+ return;
+ }
+
+ /* all frames */
+ if (can_mask == 0) {
+ bitmap_fill(rls->match_sff, (1 << CAN_SFF_ID_BITS));
+ return;
+ }
+
+ /* individual frame filter */
+ /* Add record (set bit to 1) for each ID that
+ conforms particular rule */
+ for (i = 0; i < (1 << CAN_SFF_ID_BITS); i++) {
+ if ((i & can_mask) == can_id)
+ set_bit(i, rls->match_sff);
+ }
+}
+
+/**
+ * canfltr_get_id() - Extracts Can ID out of the sk_buff structure.
+ */
+static canid_t canfltr_get_id(struct sk_buff *skb)
+{
+ /* Can ID is inside of data field */
+ struct can_frame *cf = (struct can_frame *)skb->data;
+
+ return cf->can_id;
+}
+
+/**
+ * canfltr_classify() - Performs the classification.
+ *
+ * @skb: Socket buffer
+ * @tp:
+ * @res: Is used for setting Class ID as a result of classification
+ *
+ * Iterates over all instances of filter, checking for CAN ID match.
+ *
+ * Returns value relevant for policing. Used return values:
+ * TC_POLICE_OK if succesfully classified (without regard to policing rules)
+ * TC_POLICE_UNSPEC if no matching rule was found
+ */
+static int canfltr_classify(struct sk_buff *skb, const struct tcf_proto *tp,
+ struct tcf_result *res)
+{
+ struct canfltr_head *head = (struct canfltr_head *)tp->root;
+ struct canfltr_state *f;
+ struct canfltr_rules *r;
+ canid_t can_id;
+ int i;
+
+ can_id = canfltr_get_id(skb);
+
+ rcu_read_lock();
+ list_for_each_entry(f, &head->flist, link) {
+ bool match = false;
+ r = rcu_dereference(f->rules);
+
+
+ if (can_id & CAN_EFF_FLAG) {
+ can_id &= CAN_EFF_MASK;
+
+ for (i = 0; i < r->eff_rules_count; i++) {
+ if (!(((r->rules_raw[i].can_id ^ can_id) &
+ r->rules_raw[i].can_mask) & CAN_EFF_MASK)) {
+ match = true;
+ break;
+ }
+ }
+ } else { /* SFF */
+ can_id &= CAN_SFF_MASK;
+ match = test_bit(can_id, r->match_sff);
+ }
+
+ if (match) {
+ *res = f->res;
+ rcu_read_unlock();
+ return TC_POLICE_OK;
+ }
+ }
+
+ rcu_read_unlock();
+ return TC_POLICE_UNSPEC;
+}
+
+/**
+ * canfltr_get() - Looks up a filter element by its handle and returns the
+ * internal filter ID (i.e. pointer)
+ */
+static unsigned long canfltr_get(struct tcf_proto *tp, u32 handle)
+{
+ struct canfltr_head *head = (struct canfltr_head *)tp->root;
+ struct canfltr_state *f;
+
+ if (head == NULL)
+ return 0UL;
+
+ list_for_each_entry(f, &head->flist, link) {
+ if (f->handle == handle)
+ return (unsigned long) f;
+ }
+
+ return 0UL;
+}
+
+/**
+ * canfltr_put() - Is invoked when a filter element previously referenced
+ * with get() is no longer used
+ */
+static void canfltr_put(struct tcf_proto *tp, unsigned long f)
+{
+}
+
+/**
+ * canfltr_gen_handle() - Generate handle for newly created filter
+ *
+ * This code is heavily inspired by handle generator in cls_basic.c
+ */
+static unsigned int canfltr_gen_handle(struct tcf_proto *tp)
+{
+ struct canfltr_head *head = (struct canfltr_head *)tp->root;
+ unsigned int i = 0x80000000;
+
+ do {
+ if (++head->hgenerator == 0x7FFFFFFF)
+ head->hgenerator = 1;
+ } while (--i > 0 && canfltr_get(tp, head->hgenerator));
+
+ if (i == 0)
+ return 0;
+
+ return head->hgenerator;
+}
+
+static void canfltr_rules_free_rcu(struct rcu_head *rcu)
+{
+ kfree(container_of(rcu, struct canfltr_rules, rcu));
+}
+
+static int canfltr_set_parms(struct tcf_proto *tp, struct canfltr_state *f,
+ unsigned long base, struct nlattr **tb,
+ struct nlattr *est)
+{
+ struct can_filter *canfltr_nl_rules;
+ struct canfltr_rules *rules_tmp;
+ int err;
+ int i;
+
+ rules_tmp = kzalloc(sizeof(*rules_tmp), GFP_KERNEL);
+ if (!rules_tmp)
+ return -ENOBUFS;
+
+ err = -EINVAL;
+ if (tb[TCA_CANFLTR_CLASSID] == NULL)
+ goto errout;
+
+ if (tb[TCA_CANFLTR_RULES]) {
+ canfltr_nl_rules = nla_data(tb[TCA_CANFLTR_RULES]);
+ rules_tmp->sff_rules_count = 0;
+ rules_tmp->eff_rules_count = 0;
+ rules_tmp->rules_count = (nla_len(tb[TCA_CANFLTR_RULES]) /
+ sizeof(struct can_filter));
+
+ rules_tmp->rules_raw = kzalloc(sizeof(struct can_filter) *
+ rules_tmp->rules_count, GFP_KERNEL);
+ err = -ENOMEM;
+ if (rules_tmp->rules_raw == NULL)
+ goto errout;
+
+ /* We need two for() loops for copying rules into
+ two contiguous areas in rules_raw */
+
+ /* Process EFF frame rules*/
+ for (i = 0; i < rules_tmp->rules_count; i++) {
+ if ((canfltr_nl_rules[i].can_id & CAN_EFF_FLAG) &&
+ (canfltr_nl_rules[i].can_mask & CAN_EFF_FLAG)) {
+ memcpy(rules_tmp->rules_raw +
+ rules_tmp->eff_rules_count,
+ &canfltr_nl_rules[i],
+ sizeof(struct can_filter));
+ rules_tmp->eff_rules_count++;
+ } else {
+ continue;
+ }
+ }
+
+ /* Process SFF frame rules */
+ for (i = 0; i < rules_tmp->rules_count; i++) {
+ if ((canfltr_nl_rules[i].can_id & CAN_EFF_FLAG) &&
+ (canfltr_nl_rules[i].can_mask & CAN_EFF_FLAG)) {
+ continue;
+ } else {
+ memcpy(rules_tmp->rules_raw +
+ rules_tmp->eff_rules_count +
+ rules_tmp->sff_rules_count,
+ &canfltr_nl_rules[i],
+ sizeof(struct can_filter));
+ rules_tmp->sff_rules_count++;
+ canfltr_sff_match_add(rules_tmp,
+ canfltr_nl_rules[i].can_id,
+ canfltr_nl_rules[i].can_mask);
+ }
+ }
+ }
+
+
+ /* Setting parameters for newly created filter */
+ if (f->rules == NULL) {
+ rcu_assign_pointer(f->rules, rules_tmp);
+ } else { /* Changing existing filter */
+ struct canfltr_rules *rules_old;
+
+ rules_old = xchg(&f->rules, rules_tmp);
+ call_rcu(&rules_old->rcu, canfltr_rules_free_rcu);
+ }
+
+ return 0;
+
+errout:
+ kfree(rules_tmp);
+ return err;
+}
+
+/**
+ * canfltr_change() - Called for changing properties of an existing filter or
+ * after addition of a new filter to a class (by calling bind_tcf which binds
+ * an instance of a filter to the class).
+ *
+ * @tp: Structure representing instance of a filter.
+ * Part of a linked list of all filters.
+ * @base:
+ * @handle:
+ * @tca: Messages passed through the Netlink from userspace.
+ * @arg:
+ */
+static int canfltr_change(struct tcf_proto *tp, unsigned long base, u32 handle,
+ struct nlattr **tca, unsigned long *arg)
+{
+ struct canfltr_head *head = (struct canfltr_head *)tp->root;
+ struct canfltr_state *f = (struct canfltr_state *)*arg;
+ struct nlattr *tb[TCA_CANFLTR_MAX + 1];
+ int err;
+
+ if (tca[TCA_OPTIONS] == NULL)
+ return -EINVAL;
+
+ /* Parses a stream of attributes and stores a pointer to each
+ attribute in the tb array accessible via the attribute type.
+ Policy may be set to NULL if no validation is required.*/
+ err = nla_parse_nested(tb, TCA_CANFLTR_MAX, tca[TCA_OPTIONS],
+ canfltr_policy);
+ if (err < 0)
+ return err;
+ /* Change existing filter (remove all settings and add
+ them thereafter as if filter was newly created) */
+ if (f != NULL) {
+ if (handle && f->handle != handle)
+ return -EINVAL;
+
+ return canfltr_set_parms(tp, f, base, tb, tca[TCA_RATE]);
+ }
+
+ /* Create new filter */
+ err = -ENOBUFS;
+ f = kzalloc(sizeof(*f), GFP_KERNEL);
+ if (f == NULL)
+ goto errout;
+
+ if (tb[TCA_CANFLTR_CLASSID]) {
+ f->res.classid = nla_get_u32(tb[TCA_U32_CLASSID]);
+ tcf_bind_filter(tp, &f->res, base);
+ }
+
+ err = -EINVAL;
+ if (handle) /* handle passed from userspace */
+ f->handle = handle;
+ else {
+ f->handle = canfltr_gen_handle(tp);
+ if (f->handle == 0)
+ goto errout;
+ }
+
+ /* Configure filter */
+ err = canfltr_set_parms(tp, f, base, tb, tca[TCA_RATE]);
+ if (err < 0)
+ goto errout;
+
+ /* Add newly created filter to list of all filters */
+ tcf_tree_lock(tp);
+ list_add(&f->link, &head->flist);
+ tcf_tree_unlock(tp);
+ *arg = (unsigned long) f;
+
+ return 0;
+
+errout:
+ if (*arg == 0UL && f)
+ kfree(f);
+
+ return err;
+}
+
+
+static void canfltr_delete_filter(struct tcf_proto *tp,
+ struct canfltr_state *f)
+{
+ tcf_unbind_filter(tp, &f->res);
+
+ rcu_barrier();
+ kfree(f->rules->rules_raw);
+ kfree(f->rules);
+ kfree(f);
+}
+
+/**
+ * canfltr_destroy() - Remove whole filter.
+ */
+static void canfltr_destroy(struct tcf_proto *tp)
+{
+ struct canfltr_head *head = tp->root;
+ struct canfltr_state *f, *n;
+
+ list_for_each_entry_safe(f, n, &head->flist, link) {
+ list_del(&f->link);
+ canfltr_delete_filter(tp, f);
+ }
+ kfree(head);
+}
+
+/**
+ * canfltr_delete() - Delete one instance of a filter.
+ */
+static int canfltr_delete(struct tcf_proto *tp, unsigned long arg)
+{
+ struct canfltr_head *head = (struct canfltr_head *)tp->root;
+ struct canfltr_state *t;
+ struct canfltr_state *f = (struct canfltr_state *)arg;
+
+ rcu_barrier(); /* Wait for completion of call_rcu()'s */
+
+ list_for_each_entry(t, &head->flist, link)
+ if (t == f) {
+ tcf_tree_lock(tp);
+ list_del(&t->link);
+ tcf_tree_unlock(tp);
+ canfltr_delete_filter(tp, t);
+ return 0;
+ }
+
+ return -ENOENT;
+}
+
+
+/**
+ * canfltr_init() - Initialize filter
+ */
+static int canfltr_init(struct tcf_proto *tp)
+{
+ struct canfltr_head *head;
+
+ if ((tp->protocol != htons(ETH_P_ALL)) &&
+ (tp->protocol != htons(ETH_P_CAN)))
+ return -1;
+
+ /* Work only on CAN frames */
+ if (tp->protocol == htons(ETH_P_ALL))
+ tp->protocol = htons(ETH_P_CAN);
+
+ head = kzalloc(sizeof(*head), GFP_KERNEL);
+ if (head == NULL)
+ return -ENOBUFS;
+
+ INIT_LIST_HEAD(&head->flist);
+ tp->root = head;
+
+ return 0;
+}
+
+/**
+ * canfltr_walk() - Iterates over all elements of a filter and invokes a
+ * callback function for each of them. This is used to obtain diagnostic data.
+ */
+static void canfltr_walk(struct tcf_proto *tp, struct tcf_walker *arg)
+{
+ struct canfltr_head *head = (struct canfltr_head *) tp->root;
+ struct canfltr_state *f;
+
+ list_for_each_entry(f, &head->flist, link) {
+ if (arg->count < arg->skip)
+ goto skip;
+
+ if (arg->fn(tp, (unsigned long) f, arg) < 0) {
+ arg->stop = 1;
+ break;
+ }
+skip:
+ arg->count++;
+ }
+}
+
+/**
+ * canfltr_dump() - Returns diagnostic data for a filter or one of its elements.
+ */
+static int canfltr_dump(struct tcf_proto *tp, unsigned long fh,
+ struct sk_buff *skb, struct tcmsg *t)
+{
+ struct canfltr_state *f = (struct canfltr_state *) fh;
+ struct nlattr *nest;
+ struct canfltr_rules *r;
+
+ if (f == NULL)
+ return skb->len;
+
+ rcu_read_lock();
+ r = rcu_dereference(f->rules);
+ t->tcm_handle = f->handle;
+
+ nest = nla_nest_start(skb, TCA_OPTIONS);
+ if (nest == NULL)
+ goto nla_put_failure;
+
+ if (f->res.classid &&
+ nla_put_u32(skb, TCA_CANFLTR_CLASSID, f->res.classid))
+ goto nla_put_failure;
+
+ if (nla_put(skb, TCA_CANFLTR_RULES, r->rules_count *
+ sizeof(struct can_filter), r->rules_raw))
+ goto nla_put_failure;
+
+ nla_nest_end(skb, nest);
+
+ rcu_read_unlock();
+ return skb->len;
+
+nla_put_failure:
+ nla_nest_cancel(skb, nest);
+ rcu_read_unlock();
+ return -1;
+}
+
+
+static struct tcf_proto_ops cls_canfltr_ops __read_mostly = {
+ .kind = "can",
+ .classify = canfltr_classify,
+ .init = canfltr_init,
+ .destroy = canfltr_destroy,
+ .get = canfltr_get,
+ .put = canfltr_put,
+ .change = canfltr_change,
+ .delete = canfltr_delete,
+ .walk = canfltr_walk,
+ .dump = canfltr_dump,
+ .owner = THIS_MODULE,
+};
+
+static int __init init_canfltr(void)
+{
+ pr_debug("canfltr: CAN filter loaded\n");
+ return register_tcf_proto_ops(&cls_canfltr_ops);
+}
+
+static void __exit exit_canfltr(void)
+{
+ pr_debug("canfltr: CAN filter removed\n");
+ unregister_tcf_proto_ops(&cls_canfltr_ops);
+}
+
+module_init(init_canfltr);
+module_exit(exit_canfltr);
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Rostislav Lisovy <lisovy@gmail.cz>");
+MODULE_DESCRIPTION("Controller Area Network classifier");
--
1.7.9.5
^ permalink raw reply related
* RE: [PATCH 1/1] net/hyperv: Use wait_event on outstanding sends during device removal
From: Haiyang Zhang @ 2012-06-04 16:14 UTC (permalink / raw)
To: David Miller
Cc: netdev@vger.kernel.org, KY Srinivasan, olaf@aepfle.de,
linux-kernel@vger.kernel.org, devel@linuxdriverproject.org
In-Reply-To: <20120604.114803.742884170282591530.davem@davemloft.net>
> -----Original Message-----
> From: David Miller [mailto:davem@davemloft.net]
> Sent: Monday, June 04, 2012 11:48 AM
> To: Haiyang Zhang
> Cc: netdev@vger.kernel.org; KY Srinivasan; olaf@aepfle.de; linux-
> kernel@vger.kernel.org; devel@linuxdriverproject.org
> Subject: Re: [PATCH 1/1] net/hyperv: Use wait_event on outstanding sends
> during device removal
>
> From: Haiyang Zhang <haiyangz@microsoft.com>
> Date: Mon, 4 Jun 2012 07:35:32 -0700
>
> > + wait_event(net_device->wait_drain,
> > + atomic_read(&net_device->num_outstanding_sends) == 0);
>
> Please indent this properly. The goal is not to indent using only
> TAB characters, the goal is to line things up to the proper column
> using TAB and space characters as needed.
>
> You must make the first character on the second line be at the
> first column after the openning parenthesis on the previous line.
Will do.
Thanks,
- Haiyang
^ permalink raw reply
* RE: [PATCH 0/1] net/hyperv: Use wait_event on outstanding sends during device removal
From: Haiyang Zhang @ 2012-06-04 16:20 UTC (permalink / raw)
To: David Miller
Cc: netdev@vger.kernel.org, KY Srinivasan, olaf@aepfle.de,
linux-kernel@vger.kernel.org, devel@linuxdriverproject.org
In-Reply-To: <20120604.115119.568655178193939719.davem@davemloft.net>
> -----Original Message-----
> From: David Miller [mailto:davem@davemloft.net]
> Sent: Monday, June 04, 2012 11:51 AM
> To: Haiyang Zhang
> Cc: netdev@vger.kernel.org; KY Srinivasan; olaf@aepfle.de; linux-
> kernel@vger.kernel.org; devel@linuxdriverproject.org
> Subject: Re: [PATCH 0/1] net/hyperv: Use wait_event on outstanding sends
> during device removal
>
> From: Haiyang Zhang <haiyangz@microsoft.com>
> Date: Mon, 4 Jun 2012 07:35:31 -0700
>
> > This patch is targeting net-next tree (when it's available for check
> in).
> >
> > Haiyang Zhang (1):
> > net/hyperv: Use wait_event on outstanding sends during device
> removal
>
> Why in the world are you doing this?
>
> This patch you are already asking me to apply to the 'net' tree, and
> changes already will automatically propagate from 'net' to
> 'net-next' the next time I merge those trees.
>
> So you never need to submit bug fixes twice, once for 'net' and
> once for 'net-next' so please do not do it.
A while ago, I was told the 'net' tree is only for urgent fixes, and I
should specify the target tree instead of letting you guess. But, that's
fine if you will apply it (after my updating the indentation) to 'net',
then merge it into 'net-next' tree automatically.
Thanks,
- Haiyang
^ permalink raw reply
* Re: [PATCH (net.git) 1/4] stmmac: remove two useless initialisation
From: Giuseppe CAVALLARO @ 2012-06-04 16:31 UTC (permalink / raw)
To: David Miller; +Cc: netdev
In-Reply-To: <20120604.120121.1628775001889942510.davem@davemloft.net>
On 6/4/2012 6:01 PM, David Miller wrote:
> From: Giuseppe CAVALLARO <peppe.cavallaro@st.com>
> Date: Mon, 04 Jun 2012 17:58:18 +0200
>
>> I've not clear where I have to post this patch.
>
> This is mind boggling that you can't figure this out.
>
> If I tell you it's not appropriate for net, that means
> it obviously must go to net-next
I'm sending all the patches: I have verified that there are no issues
while building net.git and net-next and re-looked at all my comments and
subjects.
peppe
>
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
>
>
^ permalink raw reply
* [PATCH net-next 0/5] gianfar: coding style cleanups
From: Jan Ceuleers @ 2012-06-04 16:31 UTC (permalink / raw)
To: David S. Miller; +Cc: Jiajun Wu, Joe Perches, netdev
Various coding style cleanups, mostly whitespace and comment reformatting.
I have left a number of lines untouched where I felt that the changes I
was considering were not improving readability. But de gustibus etc.
Patch 4/5 also removes some superfluous local variable initialisations.
These are obviously correct because the variable is initialised again
right after. But you might consider this to be unnecessary code churn
because the compiler is unlikely to generate better code due to this patch.
WARNING: ENTIRELY UNTESTED. Not even compile-tested. Sorry but I haven't
figured out how to cross-compile (I tried).
This is my first patch _series_ submission; please be kind.
Jan Ceuleers (5):
gianfar: whitespace cleanup - pointers
gianfar: comment cleanup
gianfar: various coding style and whitespace cleanups
gianfar: Remove superfluous initialisations
gianfar_ethtool: coding style and whitespace cleanups
drivers/net/ethernet/freescale/gianfar.c | 491 +++++++++++-----------
drivers/net/ethernet/freescale/gianfar_ethtool.c | 420 +++++++++---------
2 files changed, 479 insertions(+), 432 deletions(-)
--
1.7.9.5
^ permalink raw reply
* [PATCH (net.git) 0/3 (v2)] stmmac fixes for net.git
From: Giuseppe CAVALLARO @ 2012-06-04 16:32 UTC (permalink / raw)
To: netdev; +Cc: Giuseppe Cavallaro
These patches fix a problem in the driver when built as dynamic
module and fix the driver's documentation.
v2: this patchset has the same patches I had sent before but
I removed a patch that did a cleanup (now moved for net-next).
Giuseppe Cavallaro (3):
stmmac: fix driver's doc when run kernel-doc script
stmmac: update driver's doc
stmmac: fix driver Kconfig when built as module
Documentation/networking/stmmac.txt | 44 +++++++++++--------
drivers/net/ethernet/stmicro/stmmac/Kconfig | 5 +-
drivers/net/ethernet/stmicro/stmmac/stmmac.h | 3 +-
drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 32 +++++++++++++-
drivers/net/ethernet/stmicro/stmmac/stmmac_pci.c | 29 +------------
.../net/ethernet/stmicro/stmmac/stmmac_platform.c | 4 +-
6 files changed, 61 insertions(+), 56 deletions(-)
--
1.7.4.4
^ permalink raw reply
* [PATCH net-next 1/5] gianfar: whitespace cleanup - pointers
From: Jan Ceuleers @ 2012-06-04 16:31 UTC (permalink / raw)
To: David S. Miller; +Cc: Jiajun Wu, Joe Perches, netdev
In-Reply-To: <1338827516-18425-1-git-send-email-jan.ceuleers@computer.org>
Signed-off-by: Jan Ceuleers <jan.ceuleers@computer.org>
---
drivers/net/ethernet/freescale/gianfar.c | 16 ++++++++--------
1 file changed, 8 insertions(+), 8 deletions(-)
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c
index 0741ade..5ca7b9e 100644
--- a/drivers/net/ethernet/freescale/gianfar.c
+++ b/drivers/net/ethernet/freescale/gianfar.c
@@ -266,8 +266,8 @@ static int gfar_alloc_skb_resources(struct net_device *ndev)
tx_queue->tx_bd_dma_base = addr;
tx_queue->dev = ndev;
/* enet DMA only understands physical addresses */
- addr += sizeof(struct txbd8) *tx_queue->tx_ring_size;
- vaddr += sizeof(struct txbd8) *tx_queue->tx_ring_size;
+ addr += sizeof(struct txbd8) * tx_queue->tx_ring_size;
+ vaddr += sizeof(struct txbd8) * tx_queue->tx_ring_size;
}
/* Start the rx descriptor ring where the tx ring leaves off */
@@ -276,8 +276,8 @@ static int gfar_alloc_skb_resources(struct net_device *ndev)
rx_queue->rx_bd_base = vaddr;
rx_queue->rx_bd_dma_base = addr;
rx_queue->dev = ndev;
- addr += sizeof (struct rxbd8) * rx_queue->rx_ring_size;
- vaddr += sizeof (struct rxbd8) * rx_queue->rx_ring_size;
+ addr += sizeof(struct rxbd8) * rx_queue->rx_ring_size;
+ vaddr += sizeof(struct rxbd8) * rx_queue->rx_ring_size;
}
/* Setup the skbuff rings */
@@ -2590,7 +2590,7 @@ static void gfar_new_rxbdp(struct gfar_priv_rx_q *rx_queue, struct rxbd8 *bdp,
gfar_init_rxbdp(rx_queue, bdp, buf);
}
-static struct sk_buff * gfar_alloc_skb(struct net_device *dev)
+static struct sk_buff *gfar_alloc_skb(struct net_device *dev)
{
struct gfar_private *priv = netdev_priv(dev);
struct sk_buff *skb = NULL;
@@ -2604,7 +2604,7 @@ static struct sk_buff * gfar_alloc_skb(struct net_device *dev)
return skb;
}
-struct sk_buff * gfar_new_skb(struct net_device *dev)
+struct sk_buff *gfar_new_skb(struct net_device *dev)
{
struct gfar_private *priv = netdev_priv(dev);
struct sk_buff *skb = NULL;
@@ -2728,8 +2728,8 @@ static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb,
}
/* gfar_clean_rx_ring() -- Processes each frame in the rx ring
- * until the budget/quota has been reached. Returns the number
- * of frames handled
+ * until the budget/quota has been reached. Returns the number
+ * of frames handled
*/
int gfar_clean_rx_ring(struct gfar_priv_rx_q *rx_queue, int rx_work_limit)
{
--
1.7.9.5
^ permalink raw reply related
* [PATCH net-next 4/5] gianfar: Remove superfluous initialisations
From: Jan Ceuleers @ 2012-06-04 16:31 UTC (permalink / raw)
To: David S. Miller; +Cc: Jiajun Wu, Joe Perches, netdev
In-Reply-To: <1338827516-18425-1-git-send-email-jan.ceuleers@computer.org>
Signed-off-by: Jan Ceuleers <jan.ceuleers@computer.org>
---
drivers/net/ethernet/freescale/gianfar.c | 30 ++++++++++++++----------------
1 file changed, 14 insertions(+), 16 deletions(-)
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c
index ed0b136..f00a095 100644
--- a/drivers/net/ethernet/freescale/gianfar.c
+++ b/drivers/net/ethernet/freescale/gianfar.c
@@ -428,7 +428,7 @@ static struct net_device_stats *gfar_get_stats(struct net_device *dev)
struct gfar_private *priv = netdev_priv(dev);
unsigned long rx_packets = 0, rx_bytes = 0, rx_dropped = 0;
unsigned long tx_packets = 0, tx_bytes = 0;
- int i = 0;
+ int i;
for (i = 0; i < priv->num_rx_queues; i++) {
rx_packets += priv->rx_queue[i]->stats.rx_packets;
@@ -470,7 +470,7 @@ static const struct net_device_ops gfar_netdev_ops = {
void lock_rx_qs(struct gfar_private *priv)
{
- int i = 0x0;
+ int i;
for (i = 0; i < priv->num_rx_queues; i++)
spin_lock(&priv->rx_queue[i]->rxlock);
@@ -478,7 +478,7 @@ void lock_rx_qs(struct gfar_private *priv)
void lock_tx_qs(struct gfar_private *priv)
{
- int i = 0x0;
+ int i;
for (i = 0; i < priv->num_tx_queues; i++)
spin_lock(&priv->tx_queue[i]->txlock);
@@ -486,7 +486,7 @@ void lock_tx_qs(struct gfar_private *priv)
void unlock_rx_qs(struct gfar_private *priv)
{
- int i = 0x0;
+ int i;
for (i = 0; i < priv->num_rx_queues; i++)
spin_unlock(&priv->rx_queue[i]->rxlock);
@@ -494,7 +494,7 @@ void unlock_rx_qs(struct gfar_private *priv)
void unlock_tx_qs(struct gfar_private *priv)
{
- int i = 0x0;
+ int i;
for (i = 0; i < priv->num_tx_queues; i++)
spin_unlock(&priv->tx_queue[i]->txlock);
@@ -516,7 +516,7 @@ static inline int gfar_uses_fcb(struct gfar_private *priv)
static void free_tx_pointers(struct gfar_private *priv)
{
- int i = 0;
+ int i;
for (i = 0; i < priv->num_tx_queues; i++)
kfree(priv->tx_queue[i]);
@@ -524,7 +524,7 @@ static void free_tx_pointers(struct gfar_private *priv)
static void free_rx_pointers(struct gfar_private *priv)
{
- int i = 0;
+ int i;
for (i = 0; i < priv->num_rx_queues; i++)
kfree(priv->rx_queue[i]);
@@ -532,7 +532,7 @@ static void free_rx_pointers(struct gfar_private *priv)
static void unmap_group_regs(struct gfar_private *priv)
{
- int i = 0;
+ int i;
for (i = 0; i < MAXGROUPS; i++)
if (priv->gfargrp[i].regs)
@@ -541,7 +541,7 @@ static void unmap_group_regs(struct gfar_private *priv)
static void disable_napi(struct gfar_private *priv)
{
- int i = 0;
+ int i;
for (i = 0; i < priv->num_grps; i++)
napi_disable(&priv->gfargrp[i].napi);
@@ -549,7 +549,7 @@ static void disable_napi(struct gfar_private *priv)
static void enable_napi(struct gfar_private *priv)
{
- int i = 0;
+ int i;
for (i = 0; i < priv->num_grps; i++)
napi_enable(&priv->gfargrp[i].napi);
@@ -1514,7 +1514,7 @@ static void init_registers(struct net_device *dev)
{
struct gfar_private *priv = netdev_priv(dev);
struct gfar __iomem *regs = NULL;
- int i = 0;
+ int i;
for (i = 0; i < priv->num_grps; i++) {
regs = priv->gfargrp[i].regs;
@@ -1589,7 +1589,7 @@ static void gfar_halt_nodisable(struct net_device *dev)
struct gfar_private *priv = netdev_priv(dev);
struct gfar __iomem *regs = NULL;
u32 tempval;
- int i = 0;
+ int i;
for (i = 0; i < priv->num_grps; i++) {
regs = priv->gfargrp[i].regs;
@@ -1976,13 +1976,11 @@ static inline struct txfcb *gfar_add_fcb(struct sk_buff *skb)
static inline void gfar_tx_checksum(struct sk_buff *skb, struct txfcb *fcb,
int fcb_length)
{
- u8 flags = 0;
-
/* If we're here, it's a IP packet with a TCP or UDP
* payload. We set it to checksum, using a pseudo-header
* we provide
*/
- flags = TXFCB_DEFAULT;
+ u8 flags = TXFCB_DEFAULT;
/* Tell the controller what the protocol is
* And provide the already calculated phcs
@@ -2900,7 +2898,7 @@ static int gfar_poll(struct napi_struct *napi, int budget)
static void gfar_netpoll(struct net_device *dev)
{
struct gfar_private *priv = netdev_priv(dev);
- int i = 0;
+ int i;
/* If the device has multiple interrupts, run tx/rx */
if (priv->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) {
--
1.7.9.5
^ permalink raw reply related
* [PATCH net-next 2/5] gianfar: comment cleanup
From: Jan Ceuleers @ 2012-06-04 16:31 UTC (permalink / raw)
To: David S. Miller; +Cc: Jiajun Wu, Joe Perches, netdev
In-Reply-To: <1338827516-18425-1-git-send-email-jan.ceuleers@computer.org>
Signed-off-by: Jan Ceuleers <jan.ceuleers@computer.org>
---
drivers/net/ethernet/freescale/gianfar.c | 155 ++++++++++++++++--------------
1 file changed, 83 insertions(+), 72 deletions(-)
diff --git a/drivers/net/ethernet/freescale/gianfar.c b/drivers/net/ethernet/freescale/gianfar.c
index 5ca7b9e..3144560 100644
--- a/drivers/net/ethernet/freescale/gianfar.c
+++ b/drivers/net/ethernet/freescale/gianfar.c
@@ -1,5 +1,4 @@
-/*
- * drivers/net/ethernet/freescale/gianfar.c
+/* drivers/net/ethernet/freescale/gianfar.c
*
* Gianfar Ethernet Driver
* This driver is designed for the non-CPM ethernet controllers
@@ -405,7 +404,8 @@ static void gfar_init_mac(struct net_device *ndev)
gfar_write(®s->attreli, attrs);
/* Start with defaults, and add stashing or locking
- * depending on the approprate variables */
+ * depending on the approprate variables
+ */
attrs = ATTR_INIT_SETTINGS;
if (priv->bd_stash_en)
@@ -652,7 +652,7 @@ static int gfar_of_init(struct platform_device *ofdev, struct net_device **pdev)
priv->num_rx_queues = num_rx_qs;
priv->num_grps = 0x0;
- /* Init Rx queue filer rule set linked list*/
+ /* Init Rx queue filer rule set linked list */
INIT_LIST_HEAD(&priv->rx_list.list);
priv->rx_list.count = 0;
mutex_init(&priv->rx_queue_access);
@@ -960,7 +960,8 @@ static void gfar_detect_errata(struct gfar_private *priv)
}
/* Set up the ethernet device structure, private data,
- * and anything else we need before we start */
+ * and anything else we need before we start
+ */
static int gfar_probe(struct platform_device *ofdev)
{
u32 tempval;
@@ -991,8 +992,9 @@ static int gfar_probe(struct platform_device *ofdev)
gfar_detect_errata(priv);
- /* Stop the DMA engine now, in case it was running before */
- /* (The firmware could have used it, and left it running). */
+ /* Stop the DMA engine now, in case it was running before
+ * (The firmware could have used it, and left it running).
+ */
gfar_halt(dev);
/* Reset MAC layer */
@@ -1098,7 +1100,8 @@ static int gfar_probe(struct platform_device *ofdev)
/* Need to reverse the bit maps as bit_map's MSB is q0
* but, for_each_set_bit parses from right to left, which
- * basically reverses the queue numbers */
+ * basically reverses the queue numbers
+ */
for (i = 0; i< priv->num_grps; i++) {
priv->gfargrp[i].tx_bit_map = reverse_bitmap(
priv->gfargrp[i].tx_bit_map, MAX_TX_QS);
@@ -1107,7 +1110,8 @@ static int gfar_probe(struct platform_device *ofdev)
}
/* Calculate RSTAT, TSTAT, RQUEUE and TQUEUE values,
- * also assign queues to groups */
+ * also assign queues to groups
+ */
for (grp_idx = 0; grp_idx < priv->num_grps; grp_idx++) {
priv->gfargrp[grp_idx].num_rx_queues = 0x0;
for_each_set_bit(i, &priv->gfargrp[grp_idx].rx_bit_map,
@@ -1149,7 +1153,7 @@ static int gfar_probe(struct platform_device *ofdev)
priv->rx_queue[i]->rxic = DEFAULT_RXIC;
}
- /* always enable rx filer*/
+ /* always enable rx filer */
priv->rx_filer_enable = 1;
/* Enable most messages by default */
priv->msg_enable = (NETIF_MSG_IFUP << 1 ) - 1;
@@ -1189,8 +1193,9 @@ static int gfar_probe(struct platform_device *ofdev)
/* Print out the device info */
netdev_info(dev, "mac: %pM\n", dev->dev_addr);
- /* Even more device info helps when determining which kernel */
- /* provided which set of benchmarks. */
+ /* Even more device info helps when determining which kernel
+ * provided which set of benchmarks.
+ */
netdev_info(dev, "Running with NAPI enabled\n");
for (i = 0; i < priv->num_rx_queues; i++)
netdev_info(dev, "RX BD ring size for Q[%d]: %d\n",
@@ -1398,8 +1403,7 @@ static phy_interface_t gfar_get_interface(struct net_device *dev)
else {
phy_interface_t interface = priv->interface;
- /*
- * This isn't autodetected right now, so it must
+ /* This isn't autodetected right now, so it must
* be set by the device tree or platform code.
*/
if (interface == PHY_INTERFACE_MODE_RGMII_ID)
@@ -1453,8 +1457,7 @@ static int init_phy(struct net_device *dev)
return 0;
}
-/*
- * Initialize TBI PHY interface for communicating with the
+/* Initialize TBI PHY interface for communicating with the
* SERDES lynx PHY on the chip. We communicate with this PHY
* through the MDIO bus on each controller, treating it as a
* "normal" PHY at the address found in the TBIPA register. We assume
@@ -1479,8 +1482,7 @@ static void gfar_configure_serdes(struct net_device *dev)
return;
}
- /*
- * If the link is already up, we must already be ok, and don't need to
+ /* If the link is already up, we must already be ok, and don't need to
* configure and reset the TBI<->SerDes link. Maybe U-Boot configured
* everything for us? Resetting it takes the link down and requires
* several seconds for it to come back.
@@ -1554,15 +1556,13 @@ static int __gfar_is_rx_idle(struct gfar_private *priv)
{
u32 res;
- /*
- * Normaly TSEC should not hang on GRS commands, so we should
+ /* Normaly TSEC should not hang on GRS commands, so we should
* actually wait for IEVENT_GRSC flag.
*/
if (likely(!gfar_has_errata(priv, GFAR_ERRATA_A002)))
return 0;
- /*
- * Read the eTSEC register at offset 0xD1C. If bits 7-14 are
+ /* Read the eTSEC register at offset 0xD1C. If bits 7-14 are
* the same as bits 23-30, the eTSEC Rx is assumed to be idle
* and the Rx can be safely reset.
*/
@@ -1718,7 +1718,8 @@ static void free_skb_rx_queue(struct gfar_priv_rx_q *rx_queue)
}
/* If there are any tx skbs or rx skbs still around, free them.
- * Then free tx_skbuff and rx_skbuff */
+ * Then free tx_skbuff and rx_skbuff
+ */
static void free_skb_resources(struct gfar_private *priv)
{
struct gfar_priv_tx_q *tx_queue = NULL;
@@ -1827,10 +1828,12 @@ static int register_grp_irqs(struct gfar_priv_grp *grp)
int err;
/* If the device has multiple interrupts, register for
- * them. Otherwise, only register for the one */
+ * them. Otherwise, only register for the one
+ */
if (priv->device_flags & FSL_GIANFAR_DEV_HAS_MULTI_INTR) {
/* Install our interrupt handlers for Error,
- * Transmit, and Receive */
+ * Transmit, and Receive
+ */
if ((err = request_irq(grp->interruptError, gfar_error, 0,
grp->int_name_er,grp)) < 0) {
netif_err(priv, intr, dev, "Can't get IRQ %d\n",
@@ -1914,8 +1917,9 @@ irq_fail:
return err;
}
-/* Called when something needs to use the ethernet device */
-/* Returns 0 for success. */
+/* Called when something needs to use the ethernet device
+ * Returns 0 for success.
+ */
static int gfar_enet_open(struct net_device *dev)
{
struct gfar_private *priv = netdev_priv(dev);
@@ -1970,8 +1974,9 @@ static inline void gfar_tx_checksum(struct sk_buff *skb, struct txfcb *fcb,
*/
flags = TXFCB_DEFAULT;
- /* Tell the controller what the protocol is */
- /* And provide the already calculated phcs */
+ /* Tell the controller what the protocol is
+ * And provide the already calculated phcs
+ */
if (ip_hdr(skb)->protocol == IPPROTO_UDP) {
flags |= TXFCB_UDP;
fcb->phcs = udp_hdr(skb)->check;
@@ -1981,7 +1986,8 @@ static inline void gfar_tx_checksum(struct sk_buff *skb, struct txfcb *fcb,
/* l3os is the distance between the start of the
* frame (skb->data) and the start of the IP hdr.
* l4os is the distance between the start of the
- * l3 hdr and the l4 hdr */
+ * l3 hdr and the l4 hdr
+ */
fcb->l3os = (u16)(skb_network_offset(skb) - fcb_length);
fcb->l4os = skb_network_header_len(skb);
@@ -2008,8 +2014,9 @@ static inline struct txbd8 *next_txbd(struct txbd8 *bdp, struct txbd8 *base,
return skip_txbd(bdp, 1, base, ring_size);
}
-/* This is called by the kernel when a frame is ready for transmission. */
-/* It is pointed to by the dev->hard_start_xmit function pointer */
+/* This is called by the kernel when a frame is ready for transmission.
+ * It is pointed to by the dev->hard_start_xmit function pointer
+ */
static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
{
struct gfar_private *priv = netdev_priv(dev);
@@ -2024,8 +2031,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
unsigned long flags;
unsigned int nr_frags, nr_txbds, length, fcb_length = GMAC_FCB_LEN;
- /*
- * TOE=1 frames larger than 2500 bytes may see excess delays
+ /* TOE=1 frames larger than 2500 bytes may see excess delays
* before start of transmission.
*/
if (unlikely(gfar_has_errata(priv, GFAR_ERRATA_76) &&
@@ -2177,8 +2183,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
txbdp_start->bufPtr = dma_map_single(&priv->ofdev->dev, skb->data,
skb_headlen(skb), DMA_TO_DEVICE);
- /*
- * If time stamping is requested one additional TxBD must be set up. The
+ /* If time stamping is requested one additional TxBD must be set up. The
* first TxBD points to the FCB and must have a data length of
* GMAC_FCB_LEN. The second TxBD points to the actual frame data with
* the full frame length.
@@ -2194,8 +2199,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
netdev_tx_sent_queue(txq, skb->len);
- /*
- * We can work in parallel with gfar_clean_tx_ring(), except
+ /* We can work in parallel with gfar_clean_tx_ring(), except
* when modifying num_txbdfree. Note that we didn't grab the lock
* when we were reading the num_txbdfree and checking for available
* space, that's because outside of this function it can only grow,
@@ -2208,8 +2212,7 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
*/
spin_lock_irqsave(&tx_queue->txlock, flags);
- /*
- * The powerpc-specific eieio() is used, as wmb() has too strong
+ /* The powerpc-specific eieio() is used, as wmb() has too strong
* semantics (it requires synchronization between cacheable and
* uncacheable mappings, which eieio doesn't provide and which we
* don't need), thus requiring a more expensive sync instruction. At
@@ -2225,7 +2228,8 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
tx_queue->tx_skbuff[tx_queue->skb_curtx] = skb;
/* Update the current skb pointer to the next entry we will use
- * (wrapping if necessary) */
+ * (wrapping if necessary)
+ */
tx_queue->skb_curtx = (tx_queue->skb_curtx + 1) &
TX_RING_MOD_MASK(tx_queue->tx_ring_size);
@@ -2235,7 +2239,8 @@ static int gfar_start_xmit(struct sk_buff *skb, struct net_device *dev)
tx_queue->num_txbdfree -= (nr_txbds);
/* If the next BD still needs to be cleaned up, then the bds
- are full. We need to tell the kernel to stop sending us stuff. */
+ * are full. We need to tell the kernel to stop sending us stuff.
+ */
if (!tx_queue->num_txbdfree) {
netif_tx_stop_queue(txq);
@@ -2365,7 +2370,8 @@ static int gfar_change_mtu(struct net_device *dev, int new_mtu)
INCREMENTAL_BUFFER_SIZE;
/* Only stop and start the controller if it isn't already
- * stopped, and we changed something */
+ * stopped, and we changed something
+ */
if ((oldsize != tempsize) && (dev->flags & IFF_UP))
stop_gfar(dev);
@@ -2378,7 +2384,8 @@ static int gfar_change_mtu(struct net_device *dev, int new_mtu)
/* If the mtu is larger than the max size for standard
* ethernet frames (ie, a jumbo frame), then set maccfg2
- * to allow huge frames, and to check the length */
+ * to allow huge frames, and to check the length
+ */
tempval = gfar_read(®s->maccfg2);
if (priv->rx_buffer_size > DEFAULT_RX_BUFFER_SIZE ||
@@ -2464,8 +2471,7 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue)
frags = skb_shinfo(skb)->nr_frags;
- /*
- * When time stamping, one additional TxBD must be freed.
+ /* When time stamping, one additional TxBD must be freed.
* Also, we need to dma_unmap_single() the TxPAL.
*/
if (unlikely(skb_shinfo(skb)->tx_flags & SKBTX_IN_PROGRESS))
@@ -2516,8 +2522,7 @@ static int gfar_clean_tx_ring(struct gfar_priv_tx_q *tx_queue)
bytes_sent += skb->len;
- /*
- * If there's room in the queue (limit it to rx_buffer_size)
+ /* If there's room in the queue (limit it to rx_buffer_size)
* we add this skb back into the pool, if it's the right size
*/
if (skb_queue_len(&priv->rx_recycle) < rx_queue->rx_ring_size &&
@@ -2561,8 +2566,7 @@ static void gfar_schedule_cleanup(struct gfar_priv_grp *gfargrp)
gfar_write(&gfargrp->regs->imask, IMASK_RTX_DISABLED);
__napi_schedule(&gfargrp->napi);
} else {
- /*
- * Clear IEVENT, so interrupts aren't called again
+ /* Clear IEVENT, so interrupts aren't called again
* because of the packets that have already arrived.
*/
gfar_write(&gfargrp->regs->ievent, IEVENT_RTX_MASK);
@@ -2622,8 +2626,7 @@ static inline void count_errors(unsigned short status, struct net_device *dev)
struct net_device_stats *stats = &dev->stats;
struct gfar_extra_stats *estats = &priv->extra_stats;
- /* If the packet was truncated, none of the other errors
- * matter */
+ /* If the packet was truncated, none of the other errors matter */
if (status & RXBD_TRUNCATED) {
stats->rx_length_errors++;
@@ -2664,7 +2667,8 @@ static inline void gfar_rx_checksum(struct sk_buff *skb, struct rxfcb *fcb)
{
/* If valid headers were found, and valid sums
* were verified, then we tell the kernel that no
- * checksumming is necessary. Otherwise, it is */
+ * checksumming is necessary. Otherwise, it is [FIXME]
+ */
if ((fcb->flags & RXFCB_CSUM_MASK) == (RXFCB_CIP | RXFCB_CTU))
skb->ip_summed = CHECKSUM_UNNECESSARY;
else
@@ -2672,8 +2676,7 @@ static inline void gfar_rx_checksum(struct sk_buff *skb, struct rxfcb *fcb)
}
-/* gfar_process_frame() -- handle one incoming packet if skb
- * isn't NULL. */
+/* gfar_process_frame() -- handle one incoming packet if skb isn't NULL. */
static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb,
int amount_pull, struct napi_struct *napi)
{
@@ -2685,8 +2688,9 @@ static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb,
/* fcb is at the beginning if exists */
fcb = (struct rxfcb *)skb->data;
- /* Remove the FCB from the skb */
- /* Remove the padded bytes, if there are any */
+ /* Remove the FCB from the skb
+ * Remove the padded bytes, if there are any
+ */
if (amount_pull) {
skb_record_rx_queue(skb, fcb->rq);
skb_pull(skb, amount_pull);
@@ -2709,8 +2713,7 @@ static int gfar_process_frame(struct net_device *dev, struct sk_buff *skb,
/* Tell the skb what kind of packet this is */
skb->protocol = eth_type_trans(skb, dev);
- /*
- * There's need to check for NETIF_F_HW_VLAN_RX here.
+ /* There's need to check for NETIF_F_HW_VLAN_RX here.
* Even if vlan rx accel is disabled, on some chips
* RXFCB_VLN is pseudo randomly set.
*/
@@ -2831,7 +2834,8 @@ static int gfar_poll(struct napi_struct *napi, int budget)
budget_per_queue = budget/num_queues;
/* Clear IEVENT, so interrupts aren't called again
- * because of the packets that have already arrived */
+ * because of the packets that have already arrived
+ */
gfar_write(®s->ievent, IEVENT_RTX_MASK);
while (num_queues && left_over_budget) {
@@ -2869,8 +2873,9 @@ static int gfar_poll(struct napi_struct *napi, int budget)
gfar_write(®s->imask, IMASK_DEFAULT);
- /* If we are coalescing interrupts, update the timer */
- /* Otherwise, clear it */
+ /* If we are coalescing interrupts, update the timer
+ * Otherwise, clear it
+ */
gfar_configure_coalescing(priv,
gfargrp->rx_bit_map, gfargrp->tx_bit_map);
}
@@ -2879,8 +2884,7 @@ static int gfar_poll(struct napi_struct *napi, int budget)
}
#ifdef CONFIG_NET_POLL_CONTROLLER
-/*
- * Polling 'interrupt' - used by things like netconsole to send skbs
+/* Polling 'interrupt' - used by things like netconsole to send skbs
* without having to re-enable interrupts. It's not called while
* the interrupt routine is executing.
*/
@@ -2957,7 +2961,8 @@ static void adjust_link(struct net_device *dev)
u32 ecntrl = gfar_read(®s->ecntrl);
/* Now we make sure that we can be in full duplex mode.
- * If not, we operate in half-duplex mode. */
+ * If not, we operate in half-duplex mode.
+ */
if (phydev->duplex != priv->oldduplex) {
new_state = 1;
if (!(phydev->duplex))
@@ -2983,7 +2988,8 @@ static void adjust_link(struct net_device *dev)
((tempval & ~(MACCFG2_IF)) | MACCFG2_MII);
/* Reduced mode distinguishes
- * between 10 and 100 */
+ * between 10 and 100
+ */
if (phydev->speed == SPEED_100)
ecntrl |= ECNTRL_R100;
else
@@ -3022,7 +3028,8 @@ static void adjust_link(struct net_device *dev)
/* Update the hash table based on the current list of multicast
* addresses we subscribe to. Also, change the promiscuity of
* the device based on the flags (this function is called
- * whenever dev->flags is changed */
+ * whenever dev->flags is changed
+ */
static void gfar_set_multi(struct net_device *dev)
{
struct netdev_hw_addr *ha;
@@ -3084,7 +3091,8 @@ static void gfar_set_multi(struct net_device *dev)
/* If we have extended hash tables, we need to
* clear the exact match registers to prepare for
- * setting them */
+ * setting them
+ */
if (priv->extended_hash) {
em_num = GFAR_EM_NUM + 1;
gfar_clear_exact_match(dev);
@@ -3110,7 +3118,8 @@ static void gfar_set_multi(struct net_device *dev)
/* Clears each of the exact match registers to zero, so they
- * don't interfere with normal reception */
+ * don't interfere with normal reception
+ */
static void gfar_clear_exact_match(struct net_device *dev)
{
int idx;
@@ -3132,7 +3141,8 @@ static void gfar_clear_exact_match(struct net_device *dev)
* hash index which gaddr register to use, and the 5 other bits
* indicate which bit (assuming an IBM numbering scheme, which
* for PowerPC (tm) is usually the case) in the register holds
- * the entry. */
+ * the entry.
+ */
static void gfar_set_hash_for_addr(struct net_device *dev, u8 *addr)
{
u32 tempval;
@@ -3164,8 +3174,9 @@ static void gfar_set_mac_for_addr(struct net_device *dev, int num,
macptr += num*2;
- /* Now copy it into the mac registers backwards, cuz */
- /* little endian is silly */
+ /* Now copy it into the mac registers backwards, cuz
+ * little endian is silly
+ */
for (idx = 0; idx < ETH_ALEN; idx++)
tmpbuf[ETH_ALEN - 1 - idx] = addr[idx];
--
1.7.9.5
^ 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