netdev.vger.kernel.org archive mirror
 help / color / mirror / Atom feed
* Re: [PATCH] net: ieee802154: cc2520: Fix coding style issues
From: Varka Bhadram @ 2015-01-23  9:39 UTC (permalink / raw)
  To: Mohammad Jamal
  Cc: Alexander Aring, linux-wpan - ML, netdev@vger.kernel.org,
	linux-kernel@vger.kernel.org
In-Reply-To: <1422005180-13230-1-git-send-email-md.jamalmohiuddin@gmail.com>

Hi Mohammad Jamal,

These changes already there in the current bluetooth-next tree.

On Fri, Jan 23, 2015 at 2:56 PM, Mohammad Jamal
<md.jamalmohiuddin@gmail.com> wrote:
> This patch solves the coding style issues such as space after ,
> and removes the blank lines
>
> Signed-off-by: Mohammad Jamal <md.jamalmohiuddin@gmail.com>
> ---
>  drivers/net/ieee802154/cc2520.c |    6 ++----
>  1 file changed, 2 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/net/ieee802154/cc2520.c b/drivers/net/ieee802154/cc2520.c
> index f9df9fa..dd129be 100644
> --- a/drivers/net/ieee802154/cc2520.c
> +++ b/drivers/net/ieee802154/cc2520.c
> @@ -513,7 +513,6 @@ err_tx:
>         return rc;
>  }
>
> -
>  static int cc2520_rx(struct cc2520_private *priv)
>  {
>         u8 len = 0, lqi = 0, bytes = 1;
> @@ -551,14 +550,14 @@ cc2520_ed(struct ieee802154_hw *hw, u8 *level)
>         u8 rssi;
>         int ret;
>
> -       ret = cc2520_read_register(priv , CC2520_RSSISTAT, &status);
> +       ret = cc2520_read_register(priv, CC2520_RSSISTAT, &status);
>         if (ret)
>                 return ret;
>
>         if (status != RSSI_VALID)
>                 return -EINVAL;
>
> -       ret = cc2520_read_register(priv , CC2520_RSSI, &rssi);
> +       ret = cc2520_read_register(priv, CC2520_RSSI, &rssi);
>         if (ret)
>                 return ret;
>
> @@ -947,7 +946,6 @@ static int cc2520_probe(struct spi_device *spi)
>         if (ret)
>                 goto err_hw_init;
>
> -
>         gpio_set_value(pdata->vreg, HIGH);
>         usleep_range(100, 150);
>
> --
> 1.7.9.5
>

-- 
Thanks and Regards,
Varka Bhadram.

^ permalink raw reply

* Re: [PATCH net-next v3 1/5] netdev: introduce new NETIF_F_HW_NETFUNC_OFFLOAD feature flag for switch device offloads
From: Jiri Pirko @ 2015-01-23  9:44 UTC (permalink / raw)
  To: roopa
  Cc: sfeldma, jhs, bcrl, tgraf, john.fastabend, stephen, vyasevic,
	ronen.arad, netdev, davem, shm, gospo
In-Reply-To: <1421987606-10884-2-git-send-email-roopa@cumulusnetworks.com>

Fri, Jan 23, 2015 at 05:33:22AM CET, roopa@cumulusnetworks.com wrote:
>From: Roopa Prabhu <roopa@cumulusnetworks.com>
>
>This is a high level feature flag for all switch asic offloads
>
>switch drivers set this flag on switch ports. Logical devices like
>bridge, bonds, vxlans can inherit this flag from their slaves/ports.
>
>The patch also adds the flag to NETIF_F_ONE_FOR_ALL, so that it gets
>propagated to the upperdevices (bridges and bonds).
>
>Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
>---
> include/linux/netdev_features.h |    6 +++++-
> 1 file changed, 5 insertions(+), 1 deletion(-)
>
>diff --git a/include/linux/netdev_features.h b/include/linux/netdev_features.h
>index 8e30685..784a461 100644
>--- a/include/linux/netdev_features.h
>+++ b/include/linux/netdev_features.h
>@@ -66,6 +66,7 @@ enum {
> 	NETIF_F_HW_VLAN_STAG_FILTER_BIT,/* Receive filtering on VLAN STAGs */
> 	NETIF_F_HW_L2FW_DOFFLOAD_BIT,	/* Allow L2 Forwarding in Hardware */
> 	NETIF_F_BUSY_POLL_BIT,		/* Busy poll */
>+	NETIF_F_HW_NETFUNC_OFFLOAD_BIT,  /* HW switch offload */

How about rather "HW_DATAPATH_OFFLOAD"? Feels more accurate. By the
name, I still cannot understand what NETFUNC should mean.


> 
> 	/*
> 	 * Add your fresh new feature above and remember to update
>@@ -124,6 +125,7 @@ enum {
> #define NETIF_F_HW_VLAN_STAG_TX	__NETIF_F(HW_VLAN_STAG_TX)
> #define NETIF_F_HW_L2FW_DOFFLOAD	__NETIF_F(HW_L2FW_DOFFLOAD)
> #define NETIF_F_BUSY_POLL	__NETIF_F(BUSY_POLL)
>+#define NETIF_F_HW_NETFUNC_OFFLOAD	__NETIF_F(HW_NETFUNC_OFFLOAD)
> 
> /* Features valid for ethtool to change */
> /* = all defined minus driver/device-class-related */
>@@ -159,7 +161,9 @@ enum {
>  */
> #define NETIF_F_ONE_FOR_ALL	(NETIF_F_GSO_SOFTWARE | NETIF_F_GSO_ROBUST | \
> 				 NETIF_F_SG | NETIF_F_HIGHDMA |		\
>-				 NETIF_F_FRAGLIST | NETIF_F_VLAN_CHALLENGED)
>+				 NETIF_F_FRAGLIST | NETIF_F_VLAN_CHALLENGED | \
>+				 NETIF_F_HW_NETFUNC_OFFLOAD)
>+
> /*
>  * If one device doesn't support one of these features, then disable it
>  * for all in netdev_increment_features.
>-- 
>1.7.10.4
>

^ permalink raw reply

* Re: [PATCH] net: ieee802154: cc2520: fix coding style issue
From: Varka Bhadram @ 2015-01-23  9:46 UTC (permalink / raw)
  To: Mohammad Jamal
  Cc: Alexander Aring, linux-wpan - ML, netdev@vger.kernel.org,
	linux-kernel@vger.kernel.org
In-Reply-To: <1422005800-13442-1-git-send-email-md.jamalmohiuddin@gmail.com>

Hi Mohammad Jamal,

On Fri, Jan 23, 2015 at 3:06 PM, Mohammad Jamal
<md.jamalmohiuddin@gmail.com> wrote:
> This patch solves the coding style issue warning
> by replacing the shifting operations by BIT macro
>
> Signed-off-by: Mohammad Jamal <md.jamalmohiuddin@gmail.com>
> ---
>  drivers/net/ieee802154/cc2520.c |    6 +++---
>  1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/net/ieee802154/cc2520.c b/drivers/net/ieee802154/cc2520.c
> index dd129be..b9b2a49 100644
> --- a/drivers/net/ieee802154/cc2520.c
> +++ b/drivers/net/ieee802154/cc2520.c
> @@ -45,9 +45,9 @@
>  #define        CC2520_FREG_MASK        0x3F
>
>  /* status byte values */
> -#define        CC2520_STATUS_XOSC32M_STABLE    (1 << 7)
> -#define        CC2520_STATUS_RSSI_VALID        (1 << 6)
> -#define        CC2520_STATUS_TX_UNDERFLOW      (1 << 3)
> +#define        CC2520_STATUS_XOSC32M_STABLE    BIT(7)
> +#define        CC2520_STATUS_RSSI_VALID        BIT(6)
> +#define        CC2520_STATUS_TX_UNDERFLOW      BIT(3)
>
>  /* IEEE-802.15.4 defined constants (2.4 GHz logical channels) */
>  #define        CC2520_MINCHANNEL               11
> --
> 1.7.9.5
>

Please work on bluetooth-next[1] tree and also include
'bluetooth-next' tag for the patch.

[1]: http://git.kernel.org/cgit/linux/kernel/git/bluetooth/bluetooth-next.git/

-- 
Thanks and Regards,
Varka Bhadram.

^ permalink raw reply

* Re: [PATCH] net: ieee802154: cc2520: fix coding style issue
From: Jamal Mohammad @ 2015-01-23  9:48 UTC (permalink / raw)
  To: Varka Bhadram
  Cc: Alexander Aring, linux-wpan - ML, netdev@vger.kernel.org,
	linux-kernel@vger.kernel.org
In-Reply-To: <CAEUmHybQkyR7_TqOstDFcU=7iohL8E8ZaQYSNPiZC+MCi=hLmA@mail.gmail.com>

On Fri, Jan 23, 2015 at 3:16 PM, Varka Bhadram <varkabhadram@gmail.com> wrote:
> Hi Mohammad Jamal,
>
> On Fri, Jan 23, 2015 at 3:06 PM, Mohammad Jamal
> <md.jamalmohiuddin@gmail.com> wrote:
>> This patch solves the coding style issue warning
>> by replacing the shifting operations by BIT macro
>>
>> Signed-off-by: Mohammad Jamal <md.jamalmohiuddin@gmail.com>
>> ---
>>  drivers/net/ieee802154/cc2520.c |    6 +++---
>>  1 file changed, 3 insertions(+), 3 deletions(-)
>>
>> diff --git a/drivers/net/ieee802154/cc2520.c b/drivers/net/ieee802154/cc2520.c
>> index dd129be..b9b2a49 100644
>> --- a/drivers/net/ieee802154/cc2520.c
>> +++ b/drivers/net/ieee802154/cc2520.c
>> @@ -45,9 +45,9 @@
>>  #define        CC2520_FREG_MASK        0x3F
>>
>>  /* status byte values */
>> -#define        CC2520_STATUS_XOSC32M_STABLE    (1 << 7)
>> -#define        CC2520_STATUS_RSSI_VALID        (1 << 6)
>> -#define        CC2520_STATUS_TX_UNDERFLOW      (1 << 3)
>> +#define        CC2520_STATUS_XOSC32M_STABLE    BIT(7)
>> +#define        CC2520_STATUS_RSSI_VALID        BIT(6)
>> +#define        CC2520_STATUS_TX_UNDERFLOW      BIT(3)
>>
>>  /* IEEE-802.15.4 defined constants (2.4 GHz logical channels) */
>>  #define        CC2520_MINCHANNEL               11
>> --
>> 1.7.9.5
>>
>
> Please work on bluetooth-next[1] tree and also include
> 'bluetooth-next' tag for the patch.
>
> [1]: http://git.kernel.org/cgit/linux/kernel/git/bluetooth/bluetooth-next.git/
>
> --
> Thanks and Regards,
> Varka Bhadram.
OK , i will send u the patch once i clone the bluetooth-next tree.

^ permalink raw reply

* Re: net_test_tools: add ipv6 support for kbench_mod
From: Daniel Borkmann @ 2015-01-23  9:55 UTC (permalink / raw)
  To: Shaohua Li; +Cc: David Miller, netdev, kafai
In-Reply-To: <20150122221256.GA2263247@devbig257.prn2.facebook.com>

On 01/22/2015 11:12 PM, Shaohua Li wrote:
...
>>> Yes, we need export the sysmbol for the test. Can we export the symbol?
>>> or I can delete the route input test, which one do you prefer?
>>
>> There is no justification upstream to export that symbol since
>> there are no modular users in-tree.
>
> I changed it to do the ip6_route_input test optionally. If the test is
> required, somebody should change the kernel to export it and define
> HAVE_IP6_ROUTE_INPUT in the test module. I thought this is fine for a
> test module. How do you think?

See above, it can only be changed/exported from the kernel as long as
there is an in-tree module making use of it.

^ permalink raw reply

* [PATCH] net: Linn Ethernet Packet Sniffer driver
From: Stathis Voukelatos @ 2015-01-23 10:07 UTC (permalink / raw)
  To: netdev, linux-kernel, devicetree; +Cc: Stathis Voukelatos, abrestic

This patch adds support the Ethernet Packet Sniffer H/W module
developed by Linn Products Ltd and found in the IMG Pistachio SoC.
The module allows Ethernet packets to be parsed, matched against
a user-defined pattern and timestamped. It sits between a 100M
Ethernet MAC and PHY and is completely passive with respect to
Ethernet frames.

Matched packet bytes and timestamp values are returned through a
FIFO. Timestamps are provided to the module through an externally
generated Gray-encoded counter.

The command pattern for packet matching is stored in module RAM
and consists of a sequence of 16-bit entries. Each entry includes
an 8-bit command code and and 8-bit data value. Valid command
codes are:
0 - Don't care
1 - Match: packet data must match command string byte
2 - Copy: packet data will be copied to FIFO
3 - Match/Stamp: if packet data matches string byte, a timestamp
                 is copied into the FIFO
4 - Copy/Done: packet data will be copied into the FIFO.
               This command terminates the command string.

The driver consists of two modules:
- Core: it provides an API to user space using the Generic Netlink
        framework. Specific backend implementations, like the
        Ethernet Packet Sniffer, register one or more channels
        with the Core. For each channel a Genl family is created.
        User space can access a channel by sending Genl messages
        to the Genl family associated with the channel. Packet
        matching events are multicast.

- Ethernet Packet Sniffer backend: provides the driver for the
        Linn Ethernet Packet Sniffer H/W modules.

The split between a core and backend modules allows software-only
implementations to be added for platforms where no H/W support
is available.

Based on 3.19-rc5

Signed-off-by: Stathis Voukelatos <stathis.voukelatos@linn.co.uk>
---
 .../bindings/net/linn-ether-packet-sniffer.txt     |  27 ++
 .../devicetree/bindings/vendor-prefixes.txt        |   1 +
 MAINTAINERS                                        |   7 +
 drivers/net/Kconfig                                |   2 +
 drivers/net/Makefile                               |   1 +
 drivers/net/pkt-sniffer/Kconfig                    |  23 ++
 drivers/net/pkt-sniffer/Makefile                   |   8 +
 drivers/net/pkt-sniffer/backends/ether/channel.c   | 366 ++++++++++++++++++
 drivers/net/pkt-sniffer/backends/ether/channel.h   |  76 ++++
 drivers/net/pkt-sniffer/backends/ether/hw.h        |  46 +++
 drivers/net/pkt-sniffer/backends/ether/platform.c  | 231 +++++++++++
 drivers/net/pkt-sniffer/core/dev_table.c           | 124 ++++++
 drivers/net/pkt-sniffer/core/module.c              |  37 ++
 drivers/net/pkt-sniffer/core/nl.c                  | 427 +++++++++++++++++++++
 drivers/net/pkt-sniffer/core/nl.h                  |  34 ++
 drivers/net/pkt-sniffer/core/snf_core.h            |  64 +++
 include/linux/pkt_sniffer.h                        |  89 +++++
 17 files changed, 1563 insertions(+)
 create mode 100644 Documentation/devicetree/bindings/net/linn-ether-packet-sniffer.txt
 create mode 100644 drivers/net/pkt-sniffer/Kconfig
 create mode 100644 drivers/net/pkt-sniffer/Makefile
 create mode 100644 drivers/net/pkt-sniffer/backends/ether/channel.c
 create mode 100644 drivers/net/pkt-sniffer/backends/ether/channel.h
 create mode 100644 drivers/net/pkt-sniffer/backends/ether/hw.h
 create mode 100644 drivers/net/pkt-sniffer/backends/ether/platform.c
 create mode 100644 drivers/net/pkt-sniffer/core/dev_table.c
 create mode 100644 drivers/net/pkt-sniffer/core/module.c
 create mode 100644 drivers/net/pkt-sniffer/core/nl.c
 create mode 100644 drivers/net/pkt-sniffer/core/nl.h
 create mode 100644 drivers/net/pkt-sniffer/core/snf_core.h
 create mode 100644 include/linux/pkt_sniffer.h

diff --git a/Documentation/devicetree/bindings/net/linn-ether-packet-sniffer.txt b/Documentation/devicetree/bindings/net/linn-ether-packet-sniffer.txt
new file mode 100644
index 0000000..6b6e105
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/linn-ether-packet-sniffer.txt
@@ -0,0 +1,27 @@
+* Linn Products Ethernet Packet Sniffer
+
+Required properties:
+- compatible : must be "linn,eth-sniffer"
+- reg : physical addresses and sizes of registers. Must contain 3 entries:
+          first entry: registers memory space
+          second entry: TX command memory
+          third entry: RX command memory
+- reg-names : must contain the following 3 entries:
+                  "regs", "tx-ram", "rx-ram"
+- interrupts : sniffer interrupt specifier
+- clocks : specify the system clock for the peripheral
+- clock-names : must contain the "sys" entry
+- fifo-block-words : number of words in one data FIFO entry
+
+Example:
+
+sniffer@1814a000 {
+        compatible = "linn,eth-sniffer";
+        reg = <0x1814a000 0x100>, <0x1814a400 0x400>, <0x1814a800 0x400>;
+        reg-names = "regs", "tx-ram", "rx-ram";
+        interrupts = <GIC_SHARED 58 IRQ_TYPE_LEVEL_HIGH>;
+        interrupt-names = "eth-sniffer-irq";
+        clocks = <&system_clk>;
+        clock-names = "sys";
+        fifo-block-words = <4>;
+    };
diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
index b1df0ad..2c96f35 100644
--- a/Documentation/devicetree/bindings/vendor-prefixes.txt
+++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
@@ -90,6 +90,7 @@ lacie	LaCie
 lantiq	Lantiq Semiconductor
 lenovo	Lenovo Group Ltd.
 lg	LG Corporation
+linn	Linn Products Ltd.
 linux	Linux-specific binding
 lsi	LSI Corp. (LSI Logic)
 lltc	Linear Technology Corporation
diff --git a/MAINTAINERS b/MAINTAINERS
index 2fa3853..7dbc6e7 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -5708,6 +5708,13 @@ M:	Sasha Levin <sasha.levin@oracle.com>
 S:	Maintained
 F:	tools/lib/lockdep/
 
+LINN PACKET SNIFFER DRIVER
+M: Stathis Voukelatos <stathis.voukelatos@linn.co.uk>
+S: Maintained
+F: include/linux/pkt_sniffer.h
+F: drivers/net/pkt-sniffer/
+F: Documentation/devicetree/bindings/net/linn-ether-packet-sniffer.txt
+
 LINUX FOR IBM pSERIES (RS/6000)
 M:	Paul Mackerras <paulus@au.ibm.com>
 W:	http://www.ibm.com/linux/ltc/projects/ppc
diff --git a/drivers/net/Kconfig b/drivers/net/Kconfig
index d6607ee..219c786 100644
--- a/drivers/net/Kconfig
+++ b/drivers/net/Kconfig
@@ -380,4 +380,6 @@ config VMXNET3
 
 source "drivers/net/hyperv/Kconfig"
 
+source "drivers/net/pkt-sniffer/Kconfig"
+
 endif # NETDEVICES
diff --git a/drivers/net/Makefile b/drivers/net/Makefile
index e25fdd7..441111b 100644
--- a/drivers/net/Makefile
+++ b/drivers/net/Makefile
@@ -66,3 +66,4 @@ obj-$(CONFIG_USB_NET_DRIVERS) += usb/
 
 obj-$(CONFIG_HYPERV_NET) += hyperv/
 obj-$(CONFIG_NTB_NETDEV) += ntb_netdev.o
+obj-$(CONFIG_PKT_SNIFFER) += pkt-sniffer/
diff --git a/drivers/net/pkt-sniffer/Kconfig b/drivers/net/pkt-sniffer/Kconfig
new file mode 100644
index 0000000..26b4f98
--- /dev/null
+++ b/drivers/net/pkt-sniffer/Kconfig
@@ -0,0 +1,23 @@
+menuconfig PKT_SNIFFER
+    tristate "Linn packet sniffer support"
+    ---help---
+    Say Y to add support for Linn packet sniffer drivers.
+
+    The core driver can also be built as a module. If so, the module
+    will be called snf_core.
+
+if PKT_SNIFFER
+
+config PKT_SNIFFER_ETHER
+    tristate "Ethernet packet sniffer"
+    depends on MIPS
+    default n
+    help
+        Say Y here if you want to use the Linn Ethernet packet sniffer
+        module. It can be found in the upcoming Pistachio SoC by
+        Imagination Technologies.
+
+        The driver can also be built as a module. If so, the module
+        will be called snf_ether.
+
+endif # PKT_SNIFFER
diff --git a/drivers/net/pkt-sniffer/Makefile b/drivers/net/pkt-sniffer/Makefile
new file mode 100644
index 0000000..07e7339
--- /dev/null
+++ b/drivers/net/pkt-sniffer/Makefile
@@ -0,0 +1,8 @@
+snf_core-y += core/nl.o
+snf_core-y += core/dev_table.o
+snf_core-y += core/module.o
+obj-$(CONFIG_PKT_SNIFFER) += snf_core.o
+
+snf_ether-y += backends/ether/platform.o
+snf_ether-y += backends/ether/channel.o
+obj-$(CONFIG_PKT_SNIFFER_ETHER) += snf_ether.o
diff --git a/drivers/net/pkt-sniffer/backends/ether/channel.c b/drivers/net/pkt-sniffer/backends/ether/channel.c
new file mode 100644
index 0000000..d483b58
--- /dev/null
+++ b/drivers/net/pkt-sniffer/backends/ether/channel.c
@@ -0,0 +1,366 @@
+/*
+ * Ethernet Mii packet sniffer driver
+ *  - channel functions
+ *
+ * Copyright (C) 2015 Linn Products Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Written by:
+ * Stathis Voukelatos <stathis.voukelatos@linn.co.uk>
+ */
+#include <linux/io.h>
+#include <linux/of.h>
+#include <linux/pkt_sniffer.h>
+#include "../../core/snf_core.h"
+#include "hw.h"
+#include "channel.h"
+
+#define to_ether_snf_chan(dev) container_of(dev, struct ether_snf_chan, chan)
+
+static int esnf_start(struct snf_chan *dev);
+static int esnf_stop(struct snf_chan *dev);
+static int esnf_set_pattern(struct snf_chan *dev, const u8 *pattern, int count);
+static int esnf_num_recs_avail(struct snf_chan *dev);
+static int esnf_max_ptn_entries(struct snf_chan *dev);
+static int esnf_max_match_bytes(struct snf_chan *dev);
+static int validate_pattern(
+			struct ether_snf_chan *ch,
+			const u8 *buf,
+			int count);
+static void read_fifo_data(struct ether_snf_chan *ch);
+static u32 gray_decode(u32 gray);
+
+/* Initialises a sniffer channel */
+int channel_init(
+	struct ether_snf_chan *ch,
+	struct platform_device *pdev,
+	void *regs,
+	int fifo_blk_words,
+	int tx)
+{
+	struct resource *res;
+	u32 *ptr;
+	int i;
+
+	ch->regs = regs;
+	ch->dev = &pdev->dev;
+	ch->data_irq_bit = tx ? TX_DATA_IRQ_BIT : RX_DATA_IRQ_BIT;
+	ch->full_irq_bit = tx ? TX_FULL_IRQ_BIT : RX_FULL_IRQ_BIT;
+	ch->reg_enable = ch->regs +
+			 (tx ? TX_SNIFFER_ENABLE : RX_SNIFFER_ENABLE);
+	ch->reg_occ = ch->regs + (tx ? TX_FIFO_OCC : RX_FIFO_OCC);
+	ch->reg_fifo = ch->regs + (tx ? TX_FIFO_DAT : RX_FIFO_DAT);
+
+	/* Retrieve and remap the address space for the command memory */
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
+					   tx ? "tx-ram" : "rx-ram");
+	if (!res)
+		return -ENOSYS;
+	ch->cmd_ram = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(ch->cmd_ram))
+		return PTR_ERR(ch->cmd_ram);
+
+	/* It is 2 bytes/command, hence divide by 2 */
+	ch->max_cmds = resource_size(res) / 2;
+
+	/* Initialise the command pattern RAM */
+	for (i = 0, ptr = ch->cmd_ram; i < resource_size(res); i += 4)
+		iowrite32((PTN_CMD_DONTCARE << 24) | (PTN_CMD_DONTCARE << 8),
+			  ptr++);
+
+	ch->fifo_blk_words = fifo_blk_words;
+	ch->started = 0;
+
+	/* Register the channel methods */
+	ch->chan.start = esnf_start;
+	ch->chan.stop = esnf_stop;
+	ch->chan.set_pattern = esnf_set_pattern;
+	ch->chan.num_recs_avail = esnf_num_recs_avail;
+	ch->chan.max_ptn_entries = esnf_max_ptn_entries;
+	ch->chan.max_match_bytes = esnf_max_match_bytes;
+
+	strncpy(ch->name, tx ? "TX" : "RX", MAX_CHAN_NAME_SIZE - 1);
+
+	dev_dbg(ch->dev, "%s channel initialized\n", ch->name);
+
+	return 0;
+}
+
+/* Registers the channel with the sniffer core module */
+int channel_register(struct ether_snf_chan *ch, const char *name)
+{
+	int id;
+
+	id = snf_channel_add(&ch->chan, name);
+	if (id < 0)
+		return id;
+
+	ch->id = id;
+	dev_info(ch->dev, "%s channel added\n", ch->name);
+	return 0;
+}
+
+/* Unregisters the channel */
+int channel_unregister(struct ether_snf_chan *ch)
+{
+	int ret;
+
+	ch->chan.stop(&ch->chan);
+	ret = snf_channel_remove(ch->id);
+	if (!ret)
+		dev_info(ch->dev, "%s channel removed\n", ch->name);
+	return ret;
+}
+
+/* Process match event data */
+void channel_data_available(struct ether_snf_chan *ch)
+{
+	int ret;
+
+	dev_dbg(ch->dev, "%s match event\n", ch->name);
+
+	read_fifo_data(ch);
+	ret = snf_channel_notify_match(&ch->chan, &ch->evt);
+	if (ret < 0)
+		dev_err(ch->dev, "%s: event notification failed\n", ch->name);
+}
+
+/* Channel methods */
+
+/* Enables the channel */
+static int esnf_start(struct snf_chan *dev)
+{
+	struct ether_snf_chan *ch = to_ether_snf_chan(dev);
+
+	if (!ch->started) {
+		/* Enable interrupts */
+		iowrite32(ch->data_irq_bit | ch->full_irq_bit,
+			  ch->regs + SET_INTERRUPT_ENABLE);
+		/* Enable the packet matching logic */
+		iowrite32(ENABLE_BIT, ch->reg_enable);
+
+		ch->started = 1;
+		dev_info(ch->dev, "%s channel started\n", ch->name);
+	} else {
+		dev_dbg(ch->dev, "%s channel already running\n", ch->name);
+	}
+
+	return 0;
+}
+
+/* Disables the channel */
+static int esnf_stop(struct snf_chan *dev)
+{
+	struct ether_snf_chan *ch = to_ether_snf_chan(dev);
+
+	if (ch->started) {
+		/* Disable interrupts */
+		iowrite32(ch->data_irq_bit | ch->full_irq_bit,
+			  ch->regs + CLEAR_INTERRUPT_ENABLE);
+		/* Stop the sniffer channel */
+		iowrite32(0, ch->reg_enable);
+		/* Clear any pending interrupts */
+		iowrite32(ch->data_irq_bit | ch->full_irq_bit,
+			  ch->regs + INTERRUPT_STATUS);
+
+		ch->started = 0;
+		dev_info(ch->dev, "%s channel stopped\n", ch->name);
+	} else {
+		dev_dbg(ch->dev, "%s channel already stopped\n", ch->name);
+	}
+
+	return 0;
+}
+
+/* Sets the command string (pattern) for the channel
+ * The bytes in the pattern buffer are in the following order:
+ */
+static int esnf_set_pattern(struct snf_chan *dev, const u8 *pattern, int count)
+{
+	struct ether_snf_chan *ch = to_ether_snf_chan(dev);
+	int i, shift = 0;
+	u32  val = 0, *ptr;
+
+	if (ch->started) {
+		dev_err(ch->dev,
+			"cannot apply cmd pattern. %s channel is active\n",
+			ch->name);
+		return -EBUSY;
+	}
+
+	if (!validate_pattern(ch, pattern, count)) {
+		dev_err(ch->dev,
+			"invalid cmd pattern for %s channel\n",
+			ch->name);
+		return -EINVAL;
+	}
+
+	for (ptr = ch->cmd_ram, i = 0, shift = 24; i < (2*count); i++) {
+		val |= ((u32)pattern[i]) << shift;
+		if (!shift) {
+			iowrite32(val, ptr++);
+			val = 0;
+			shift = 24;
+		} else {
+			shift -= 8;
+		}
+	}
+	if (shift)
+		iowrite32(val, ptr);
+
+	return 0;
+}
+
+/* Returns the number of pending match events that are
+ * available to retrieve
+ */
+static int esnf_num_recs_avail(struct snf_chan *dev)
+{
+	struct ether_snf_chan *ch = to_ether_snf_chan(dev);
+
+	return ioread32(ch->reg_occ);
+}
+
+/* Returns max number of commands supported by the channel */
+static int esnf_max_ptn_entries(struct snf_chan *dev)
+{
+	struct ether_snf_chan *ch = to_ether_snf_chan(dev);
+
+	return ch->max_cmds;
+}
+
+/* Returns max number of bytes that can be returned by a match */
+static int esnf_max_match_bytes(struct snf_chan *dev)
+{
+	struct ether_snf_chan *ch = to_ether_snf_chan(dev);
+
+	/* Subtract the word that may be used for the timestamp */
+	return (ch->fifo_blk_words - 1) * 4;
+}
+
+/* Checks if the supplied command string is compatible with the
+ * capabilities of the H/W
+ */
+static int validate_pattern(struct ether_snf_chan *ch, const u8 *buf, int count)
+{
+	int i, complete, max_copy_bytes;
+	int ts = 0;
+	int copy_before = 0;
+	int copy_after = 0;
+
+	if (count > ch->max_cmds)
+		return 0;
+
+	/* Iterate through the commands in the string */
+	for (i = 0, complete = 0; (i < count) && !complete; i++) {
+		u8 cmd = buf[2*i];
+
+		switch (cmd) {
+		case PTN_CMD_DONTCARE:
+		case PTN_CMD_MATCH:
+			break;
+
+		case PTN_CMD_MATCHSTAMP:
+			/* The timestamp needs to be word-aligned in the FIFO
+			 * therefore, the number of 'copy' commands before it
+			 * needs to be a multiple of 4
+			 */
+			if (copy_before & 3)
+				return 0;
+			/* Signal that a timestamp will be present */
+			ts = 1;
+			break;
+
+		case PTN_CMD_COPY:
+			/* Increment count of bytes that will be returned */
+			if (ts)
+				copy_after++;
+			else
+				copy_before++;
+			break;
+
+		case PTN_CMD_COPYDONE:
+			/* Increment count of bytes that will be returned
+			 * This command terminates the string
+			 */
+			if (ts)
+				copy_after++;
+			else
+				copy_before++;
+			complete = 1;
+			break;
+
+		default:
+			return 0;
+		}
+	}
+
+	/* Check if the string was properly terminated
+	 * and contained valid number of commands
+	 */
+	if (complete) {
+		max_copy_bytes = ch->fifo_blk_words * 4;
+		if (ts)
+			max_copy_bytes -= 4;
+		if ((copy_before + copy_after) > max_copy_bytes)
+			return 0;
+		ch->ts_present = ts;
+		ch->nfb_before = copy_before;
+		ch->nfb_after = copy_after;
+		return 1;
+	} else {
+		return 0;
+	}
+}
+
+/* Read a block from the data FIFO */
+static void read_fifo_data(struct ether_snf_chan *ch)
+{
+	int i;
+	u32 val, *ptr;
+	int ts = ch->ts_present;
+	int dw = ch->fifo_blk_words;
+	int bytes_before = ch->nfb_before;
+	int bytes_after = ch->nfb_after;
+
+	ptr = (u32 *)ch->evt.data;
+	for (i = 0; i < dw; i++) {
+		val = ioread32(ch->reg_fifo);
+		if (bytes_before > 0) {
+			/* Bytes before the timestamp */
+			*ptr++ = cpu_to_be32(val);
+			bytes_before -= 4;
+		} else if (ts) {
+			/* Timestamp is Gray encoded */
+			ch->evt.ts = (u64)gray_decode(val);
+			ts = 0;
+		} else if (bytes_after > 0) {
+			/* Bytes after the timestamp */
+			*ptr++ = cpu_to_be32(val);
+			bytes_after -= 4;
+		}
+	}
+
+	ch->evt.ts_valid = ch->ts_present;
+	ch->evt.len = ch->nfb_before + ch->nfb_after;
+}
+
+/* Gray decoder */
+static u32 gray_decode(u32 gray)
+{
+	gray ^= (gray >> 16);
+	gray ^= (gray >> 8);
+	gray ^= (gray >> 4);
+	gray ^= (gray >> 2);
+	gray ^= (gray >> 1);
+	return gray;
+}
+
diff --git a/drivers/net/pkt-sniffer/backends/ether/channel.h b/drivers/net/pkt-sniffer/backends/ether/channel.h
new file mode 100644
index 0000000..4f00b33
--- /dev/null
+++ b/drivers/net/pkt-sniffer/backends/ether/channel.h
@@ -0,0 +1,76 @@
+/*
+ * Ethernet Mii packet sniffer driver
+ *  - channel interface
+ *
+ * Copyright (C) 2015 Linn Products Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Written by:
+ * Stathis Voukelatos <stathis.voukelatos@linn.co.uk>
+ */
+#ifndef _ETHER_SNIFFER_CHANNEL_H_
+#define _ETHER_SNIFFER_CHANNEL_H_
+
+#include <linux/platform_device.h>
+#include "../../core/snf_core.h"
+
+#define MAX_CHAN_NAME_SIZE 5
+
+struct ether_snf_chan {
+	/* Sniffer core structure */
+	struct snf_chan chan;
+	/* Pointer to device struct */
+	struct device *dev;
+	/* Registers */
+	u8 __iomem *regs;
+	/* Command string memory */
+	u32 __iomem *cmd_ram;
+	/* Bit number for the data IRQ */
+	int data_irq_bit;
+	/* Bit number for the FIFO full IRQ */
+	int full_irq_bit;
+	/* Channel enable register */
+	u8 __iomem *reg_enable;
+	/* Data FIFO register */
+	u8 __iomem *reg_fifo;
+	/* FIFO occupancy register */
+	u8 __iomem *reg_occ;
+	/* Max number of commands in the string */
+	int max_cmds;
+	/* Max matching bytes that can fit in a FIFO block */
+	int fifo_blk_words;
+	/* Number of bytes in the FIFO before the timestamp */
+	int nfb_before;
+	/* Number of bytes in the FIFO after the timestamp */
+	int nfb_after;
+	/* Timestamp present flag */
+	int ts_present;
+	/* ID assigned to channel by the sniffer core */
+	int id;
+	/* Channel active flag */
+	int started;
+	/* Channel name (only used by debug messages) */
+	char name[MAX_CHAN_NAME_SIZE];
+	/* Struct to hold data from a packet match */
+	struct snf_match_evt evt;
+};
+
+int channel_init(
+		struct ether_snf_chan *ch,
+		struct platform_device *pdev,
+		void *regs,
+		int fifo_blk_words,
+		int tx);
+int channel_register(struct ether_snf_chan *ch, const char *name);
+int channel_unregister(struct ether_snf_chan *ch);
+void channel_data_available(struct ether_snf_chan *ch);
+
+#endif
diff --git a/drivers/net/pkt-sniffer/backends/ether/hw.h b/drivers/net/pkt-sniffer/backends/ether/hw.h
new file mode 100644
index 0000000..edb1093
--- /dev/null
+++ b/drivers/net/pkt-sniffer/backends/ether/hw.h
@@ -0,0 +1,46 @@
+/*
+ * Ethernet Mii packet sniffer driver
+ *  - register map
+ *
+ * Copyright (C) 2015 Linn Products Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Written by:
+ * Stathis Voukelatos <stathis.voukelatos@linn.co.uk>
+ */
+#ifndef _ETHER_SNIFFER_HW_H_
+#define _ETHER_SNIFFER_HW_H_
+
+#include <linux/bitops.h>
+
+/* Registers */
+#define INTERRUPT_ENABLE        0x00
+#define SET_INTERRUPT_ENABLE    0x04
+#define CLEAR_INTERRUPT_ENABLE  0x08
+#define INTERRUPT_STATUS        0x0c
+#define TX_FIFO_DAT             0x10
+#define RX_FIFO_DAT             0x14
+#define TX_FIFO_OCC             0x18
+#define RX_FIFO_OCC             0x1c
+#define TX_SNIFFER_ENABLE       0x20
+#define RX_SNIFFER_ENABLE       0x24
+
+/* IRQ register bits */
+#define TX_DATA_IRQ_BIT         BIT(0)
+#define RX_DATA_IRQ_BIT         BIT(1)
+#define TX_FULL_IRQ_BIT         BIT(2)
+#define RX_FULL_IRQ_BIT         BIT(3)
+
+/* Enable register bits */
+#define ENABLE_BIT              BIT(0)
+
+#endif
+
diff --git a/drivers/net/pkt-sniffer/backends/ether/platform.c b/drivers/net/pkt-sniffer/backends/ether/platform.c
new file mode 100644
index 0000000..78e7e1c
--- /dev/null
+++ b/drivers/net/pkt-sniffer/backends/ether/platform.c
@@ -0,0 +1,231 @@
+/*
+ * Ethernet Mii packet sniffer driver
+ *
+ * Copyright (C) 2015 Linn Products Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Written by:
+ * Stathis Voukelatos <stathis.voukelatos@linn.co.uk>
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/interrupt.h>
+#include <linux/of_device.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include "../../core/snf_core.h"
+#include "hw.h"
+#include "channel.h"
+
+static const char esnf_driver_name[] = "eth-sniffer";
+
+/* Names for the TX and RX channel.
+ * User space will used these names to access the channels
+ * through the generic netlink interface
+ */
+static const char tx_channel_name[] = "snf_ether_tx";
+static const char rx_channel_name[] = "snf_ether_rx";
+
+struct ether_snf {
+	u8 __iomem *regs;
+	int irq;
+	struct clk *sys_clk;
+	struct ether_snf_chan txc;
+	struct ether_snf_chan rxc;
+};
+
+/* Interrupt thread function */
+static irqreturn_t esnf_irq_thread(int irq, void *dev_id)
+{
+	struct platform_device *pdev = (struct platform_device *)dev_id;
+	struct ether_snf *esnf = (struct ether_snf *)platform_get_drvdata(pdev);
+	u32 irq_status;
+
+	if (unlikely(esnf->irq != irq))
+		return IRQ_NONE;
+
+	irq_status = ioread32(esnf->regs + INTERRUPT_STATUS) &
+				 ioread32(esnf->regs + INTERRUPT_ENABLE);
+
+	dev_dbg(&pdev->dev, "irq: 0x%08x\n", irq_status);
+
+	/* TX FIFO full */
+	if (unlikely(irq_status & TX_FULL_IRQ_BIT))
+		dev_notice(&pdev->dev, "TX FIFO full");
+
+	/* RX FIFO full */
+	if (unlikely(irq_status & RX_FULL_IRQ_BIT))
+		dev_notice(&pdev->dev, "RX FIFO full");
+
+	/* TX match data available */
+	if (irq_status & TX_DATA_IRQ_BIT) {
+		dev_dbg(&pdev->dev, "TX data");
+		channel_data_available(&esnf->txc);
+	}
+
+	/* RX match data available */
+	if (irq_status & RX_DATA_IRQ_BIT) {
+		dev_dbg(&pdev->dev, "RX data");
+		channel_data_available(&esnf->rxc);
+	}
+
+	/* Clear interrupts */
+	iowrite32(irq_status, esnf->regs + INTERRUPT_STATUS);
+
+	return IRQ_HANDLED;
+}
+
+/* Called when the packet sniffer device is bound with the driver */
+static int esnf_driver_probe(struct platform_device *pdev)
+{
+	struct ether_snf *esnf;
+	struct resource *res;
+	int ret, irq;
+	u32 fifo_blk_words;
+	void __iomem *regs;
+	struct device_node *ofn = pdev->dev.of_node;
+
+	/* Allocate the device data structure */
+	esnf = devm_kzalloc(&pdev->dev, sizeof(*esnf), GFP_KERNEL);
+	if (!esnf)
+		return -ENOMEM;
+
+	/* Retrieve and remap register memory space */
+	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "regs");
+	if (!res)
+		return -ENODEV;
+
+	regs = devm_ioremap_resource(&pdev->dev, res);
+	if (IS_ERR(regs))
+		return PTR_ERR(regs);
+
+	esnf->regs = regs;
+
+	/* Read the FIFO block size from the DT */
+	if (!ofn)
+		return -ENODEV;
+
+	ret = of_property_read_u32(
+				ofn,
+				"fifo-block-words",
+				&fifo_blk_words);
+	if (ret < 0)
+		return ret;
+
+	if (((fifo_blk_words - 1)*4) > MAX_MATCH_BYTES) {
+		dev_err(&pdev->dev,
+			"Invalid FIFO block size entry in device tree\n");
+		return -EINVAL;
+	}
+
+	esnf->sys_clk = devm_clk_get(&pdev->dev, "sys");
+	if (IS_ERR(esnf->sys_clk)) {
+		ret = PTR_ERR(esnf->sys_clk);
+		return ret;
+	}
+	ret = clk_prepare_enable(esnf->sys_clk);
+	if (ret < 0)
+		return ret;
+
+	/* Initialise the TX and RX channels */
+	ret = channel_init(&esnf->txc, pdev, regs, fifo_blk_words, 1);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Failed to init TX channel (%d)\n", ret);
+		goto fail1;
+	}
+	ret = channel_init(&esnf->rxc, pdev, regs, fifo_blk_words, 0);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Failed to init RX channel (%d)\n", ret);
+		goto fail1;
+	}
+
+	/* Register the channels with the sniffer core module */
+	ret = channel_register(&esnf->txc, tx_channel_name);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Failed to register TX chan (%d)\n", ret);
+		goto fail1;
+	}
+	ret = channel_register(&esnf->rxc, rx_channel_name);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Failed to register RX chan (%d)\n", ret);
+		goto fail2;
+	}
+
+	platform_set_drvdata(pdev, esnf);
+
+	/* Register the interrupt handler */
+	irq = platform_get_irq(pdev, 0);
+	if (irq < 0)
+		goto fail3;
+	esnf->irq = irq;
+	ret = devm_request_threaded_irq(
+				&pdev->dev,
+				irq,
+				NULL,
+				esnf_irq_thread,
+				IRQF_ONESHOT,
+				esnf_driver_name,
+				pdev);
+	if (ret < 0)
+		goto fail3;
+
+	return 0;
+
+fail3:
+	channel_unregister(&esnf->rxc);
+fail2:
+	channel_unregister(&esnf->txc);
+fail1:
+	clk_disable_unprepare(esnf->sys_clk);
+	return ret;
+}
+
+/* Called when the packet sniffer device unregisters with the driver */
+static int esnf_driver_remove(struct platform_device *pdev)
+{
+	struct ether_snf *esnf = (struct ether_snf *)platform_get_drvdata(pdev);
+	int ret;
+
+	ret = channel_unregister(&esnf->txc);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Failed to unregister TX chan (%d)\n", ret);
+		return ret;
+	}
+	ret = channel_unregister(&esnf->rxc);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "Failed to unregister RX chan (%d)\n", ret);
+		return ret;
+	}
+	clk_disable_unprepare(esnf->sys_clk);
+	return 0;
+}
+
+static const struct of_device_id esnf_of_match_table[] = {
+	{ .compatible = "linn,eth-sniffer", .data = NULL },
+	{},
+};
+MODULE_DEVICE_TABLE(of, esnf_of_match_table);
+
+static struct platform_driver esnf_platform_driver = {
+	.driver = {
+		.name = esnf_driver_name,
+		.of_match_table = esnf_of_match_table,
+	},
+	.probe = esnf_driver_probe,
+	.remove = esnf_driver_remove,
+};
+
+module_platform_driver(esnf_platform_driver);
+
+MODULE_DESCRIPTION("Linn Ethernet Packet Sniffer");
+MODULE_AUTHOR("Linn Products Ltd");
+MODULE_LICENSE("GPL v2");
+
diff --git a/drivers/net/pkt-sniffer/core/dev_table.c b/drivers/net/pkt-sniffer/core/dev_table.c
new file mode 100644
index 0000000..3a07838
--- /dev/null
+++ b/drivers/net/pkt-sniffer/core/dev_table.c
@@ -0,0 +1,124 @@
+/*
+ * Packet sniffer core driver: channel management
+ *
+ * Copyright (C) 2014 Linn Products Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Written by:
+ * Stathis Voukelatos <stathis.voukelatos@linn.co.uk>
+ */
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include "snf_core.h"
+#include "nl.h"
+
+#define MAX_CHANNELS   256
+
+static DEFINE_MUTEX(tlock);
+
+static struct snf_chan *dev_tab[MAX_CHANNELS];
+static unsigned int ref_count[MAX_CHANNELS];
+
+static inline int verify_args(int id)
+{
+	return (id < MAX_CHANNELS);
+}
+
+/* Registers a sniffer channel and returns and id for it */
+int snf_channel_add(struct snf_chan *dev, const char *name)
+{
+	int i;
+	int ret = -EEXIST;
+
+	mutex_lock(&tlock);
+
+	for (i = 0; i < MAX_CHANNELS; i++) {
+		if (!dev_tab[i]) {
+			/* Initialise the netlink interface for the channel */
+			ret = snf_netlink_init(i, dev, name);
+			if (ret < 0)
+				goto fail;
+
+			dev_tab[i] = dev;
+			ref_count[i] = 0;
+			mutex_unlock(&tlock);
+			return i;
+		}
+	}
+
+fail:
+	mutex_unlock(&tlock);
+	return ret;
+}
+EXPORT_SYMBOL(snf_channel_add);
+
+/* Removes a sniffer channel */
+int snf_channel_remove(int id)
+{
+	int ret = 0;
+	struct snf_chan *dev;
+
+	if (!verify_args(id))
+		return -EINVAL;
+
+	mutex_lock(&tlock);
+
+	dev = dev_tab[id];
+
+	if (!dev) {
+		ret = -ENODEV;
+		goto fail;
+	}
+
+	if (ref_count[id] > 0) {
+		ret = -EBUSY;
+		goto fail;
+	}
+
+	dev_tab[id] = NULL;
+
+	/* Release netlink API resources */
+	snf_netlink_release(dev);
+
+fail:
+	mutex_unlock(&tlock);
+	return ret;
+}
+EXPORT_SYMBOL(snf_channel_remove);
+
+/* Returns a pointer to the specified sniffer channel
+ * and increments its reference counter
+ */
+struct snf_chan *snf_channel_get(int id)
+{
+	struct snf_chan *dev;
+
+	if (!verify_args(id))
+		return NULL;
+
+	mutex_lock(&tlock);
+	dev = dev_tab[id];
+	if (dev)
+		ref_count[id]++;
+	mutex_unlock(&tlock);
+
+	return dev;
+}
+
+/* Decrements the reference counter for the channel */
+void snf_channel_put(int id)
+{
+	mutex_lock(&tlock);
+	if (ref_count[id] > 0)
+		ref_count[id]--;
+	mutex_unlock(&tlock);
+}
+
diff --git a/drivers/net/pkt-sniffer/core/module.c b/drivers/net/pkt-sniffer/core/module.c
new file mode 100644
index 0000000..af6a1aa
--- /dev/null
+++ b/drivers/net/pkt-sniffer/core/module.c
@@ -0,0 +1,37 @@
+/*
+ * Packet sniffer core driver:
+ *  - backend channel management
+ *  - interface to userland via generic netlink
+ *
+ * Copyright (C) 2015 Linn Products Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Written by:
+ * Stathis Voukelatos <stathis.voukelatos@linn.co.uk>
+ */
+#include <linux/module.h>
+#include <linux/init.h>
+
+static int __init snf_core_init(void)
+{
+	return 0;
+}
+
+static void __exit snf_core_cleanup(void)
+{
+}
+
+module_init(snf_core_init);
+module_exit(snf_core_cleanup);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("Core packet sniffer driver");
+MODULE_AUTHOR("Linn Products Ltd");
diff --git a/drivers/net/pkt-sniffer/core/nl.c b/drivers/net/pkt-sniffer/core/nl.c
new file mode 100644
index 0000000..6839147
--- /dev/null
+++ b/drivers/net/pkt-sniffer/core/nl.c
@@ -0,0 +1,427 @@
+/*
+ * Packet sniffer core driver: generic netlink interface
+ *
+ * Copyright (C) 2015 Linn Products Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Written by:
+ * Stathis Voukelatos <stathis.voukelatos@linn.co.uk>
+ */
+#include <linux/version.h>
+#include <net/netlink.h>
+#include <net/genetlink.h>
+#include <linux/slab.h>
+#include <linux/module.h>
+#include <linux/pkt_sniffer.h>
+#include "snf_core.h"
+#include "nl.h"
+
+/* Netlink API data for a sniffer channel */
+struct snf_netlink {
+	/* genl family */
+	struct genl_family           fml;
+	/* genl operations */
+	struct genl_ops             *ops;
+	/* genl mcast group, where sniffer match
+	 * events will be sent
+	 */
+	struct genl_multicast_group  grp;
+};
+
+/* Attribute policies */
+static struct nla_policy snf_policy[SNF_ATTR_MAX + 1] = {
+	[SNF_ATTR_PATTERN] = { .type = NLA_NESTED },
+};
+
+static struct nla_policy snf_ptn_policy[SNF_ATTR_PTN_MAX + 1] = {
+	[SNF_ATTR_PTN_ENTRY] = { .type = NLA_U16 },
+};
+
+/* Generic Netlink family template definition */
+static int pre_doit_func(const struct genl_ops *ops,
+			 struct sk_buff *skb,
+			 struct genl_info *info);
+
+static void post_doit_func(const struct genl_ops *ops,
+			   struct sk_buff *skb,
+			   struct genl_info *info);
+
+static struct genl_family snf_family_tmpl = {
+	.id = GENL_ID_GENERATE,
+	.hdrsize = 0,
+	.version = SNF_GNL_VERSION,
+	.maxattr = SNF_ATTR_MAX,
+	.pre_doit = pre_doit_func,
+	.post_doit = post_doit_func
+};
+
+static int send_reply_uint32(
+			struct genl_info *info,
+			int cmd,
+			int attr,
+			u32 val);
+
+/* Generic Netlink operations template definition */
+
+static int do_it_start(struct sk_buff *skb, struct genl_info *info);
+static int do_it_stop(struct sk_buff *skb, struct genl_info *info);
+static int do_it_set_pattern(struct sk_buff *skb, struct genl_info *info);
+static int do_it_num_rec_avail(struct sk_buff *skb, struct genl_info *info);
+static int do_it_ptn_max_cmds(struct sk_buff *skb, struct genl_info *info);
+static int do_it_max_match_bytes(struct sk_buff *skb, struct genl_info *info);
+
+#define SNF_GENL_OP(_cmd, _func)	 \
+	{				 \
+		.cmd	= _cmd,          \
+		.policy = snf_policy,    \
+		.doit   = _func,         \
+		.dumpit = NULL,          \
+		.flags  = 0,             \
+		.internal_flags = 0      \
+	}
+
+#define SNF_CHAN_OPS							   \
+	{								   \
+		SNF_GENL_OP(SNF_CMD_START,         do_it_start),	   \
+		SNF_GENL_OP(SNF_CMD_STOP,          do_it_stop),		   \
+		SNF_GENL_OP(SNF_CMD_SETPATTERN,    do_it_set_pattern),     \
+		SNF_GENL_OP(SNF_CMD_NUMRECAVAIL,   do_it_num_rec_avail),   \
+		SNF_GENL_OP(SNF_CMD_PTNMAXCMDS,    do_it_ptn_max_cmds),    \
+		SNF_GENL_OP(SNF_CMD_MAXMATCHBYTES, do_it_max_match_bytes)  \
+	}
+
+static struct genl_ops snf_ops_tmpl[] = SNF_CHAN_OPS;
+
+#define NUM_GENL_OPS ARRAY_SIZE(snf_ops_tmpl)
+
+/* Multicast a netlink event containing data from a sniffer match event.
+ * Data are included in the netlink message as a nested attribute
+ * containing the timestamp (optional) and matching packet bytes
+*/
+int snf_channel_notify_match(struct snf_chan *dev, struct snf_match_evt *mt)
+{
+	int i, ret = 0;
+	struct sk_buff *msg = NULL;
+	void *msg_hdr, *nest_hdr;
+	struct snf_netlink *nl = (struct snf_netlink *)dev->cstate;
+
+	if (!nl) {
+		ret = -EINVAL;
+		goto fail;
+	}
+
+	msg = genlmsg_new(NLMSG_GOODSIZE, GFP_ATOMIC);
+	if (!msg) {
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	msg_hdr = genlmsg_put(msg,
+			      0,
+			      0,
+			      &nl->fml,
+			      0,
+			      SNF_CMD_MATCHEVENT);
+	if (!msg_hdr) {
+		ret = -EMSGSIZE;
+		goto fail;
+	}
+
+	/* Add the nested attribute with the data */
+	if ((mt->ts_valid) || (mt->len > 0)) {
+		nest_hdr = nla_nest_start(msg, SNF_ATTR_MATCHEVENT);
+		if (!nest_hdr) {
+			ret = -EMSGSIZE;
+			goto fail;
+		}
+		if (mt->ts_valid) {
+			ret = nla_put_u64(msg, SNF_ATTR_MATCH_TS, mt->ts);
+			if (ret < 0)
+				goto fail;
+		}
+		for (i = 0; i < mt->len; i++) {
+			ret = nla_put_u8(msg,
+					 SNF_ATTR_MATCH_PKTBYTE,
+					 mt->data[i]);
+			if (ret < 0)
+				goto fail;
+		}
+		nla_nest_end(msg, nest_hdr);
+	}
+
+	ret = genlmsg_end(msg, msg_hdr);
+	if (ret < 0)
+		goto fail;
+	ret = genlmsg_multicast(&nl->fml, msg, 0, 0, GFP_ATOMIC);
+
+	/* The ESRCH code is returned when there is no socket listening on the
+	 * multicast group, so we do not really treat is as an error
+	 */
+	if (ret == -ESRCH)
+		ret = 0;
+	return ret;
+
+fail:
+	if (msg)
+		nlmsg_free(msg);
+	return ret;
+}
+EXPORT_SYMBOL(snf_channel_notify_match);
+
+/* Initialise the generic netlink API for a sniffer channel
+ * Registers family, ops and multicast group for events
+ */
+int snf_netlink_init(int id, struct snf_chan *dev, const char *name)
+{
+	int i, ret;
+	struct snf_netlink *nl = NULL;
+
+	nl = kmalloc(sizeof(*nl), GFP_KERNEL);
+	if (!nl) {
+		ret = -ENOMEM;
+		goto fail1;
+	}
+
+	nl->fml = snf_family_tmpl;
+
+	/* Set the family name */
+	strncpy(nl->fml.name, name, GENL_NAMSIZ-1);
+
+	/* Allocate ops array and copy template data */
+	nl->ops = kmalloc(sizeof(snf_ops_tmpl), GFP_KERNEL);
+	if (!nl->ops) {
+		ret = -ENOMEM;
+		goto fail2;
+	}
+	memcpy(nl->ops, snf_ops_tmpl, sizeof(snf_ops_tmpl));
+
+	/* In the internal_flags field we store the id
+	 * of the device the ops belong to
+	 */
+	for (i = 0; i < NUM_GENL_OPS; i++)
+		nl->ops[i].internal_flags = id;
+
+	snprintf(nl->grp.name, GENL_NAMSIZ-1, SNF_EVENT_GRP);
+
+	ret = _genl_register_family_with_ops_grps(
+						&nl->fml,
+						nl->ops,
+						NUM_GENL_OPS,
+						&nl->grp,
+						1);
+	if (ret < 0) {
+		pr_err("%s: failed to register family %s (%d)\n",
+		       KBUILD_MODNAME, name, ret);
+		goto fail3;
+	}
+
+	pr_info("%s: registered genl family for channel %d: %s\n",
+		KBUILD_MODNAME, id, name);
+	dev->cstate = nl;
+
+	return 0;
+
+fail3:
+	kfree(nl->ops);
+fail2:
+	kfree(nl);
+fail1:
+	return ret;
+}
+
+/* Shuts down the netlink API for a sniffer channel
+ * and frees resources
+ */
+void snf_netlink_release(struct snf_chan *dev)
+{
+	struct snf_netlink *nl = (struct snf_netlink *)dev->cstate;
+	/* Unregister family and free ops
+	 * NOTE: this will also unregister the ops and the mcast group
+	 */
+	genl_unregister_family(&nl->fml);
+	pr_info("%s: unregistered genl family: %s\n",
+		KBUILD_MODNAME, nl->fml.name);
+
+	kfree(nl->ops);
+	kfree(nl);
+	dev->cstate = NULL;
+}
+
+/* pre_doit function that retrieves a pointer to the sniffer channel device
+ * from the instance and channel number stored in the ops internal_flag field
+ */
+static int pre_doit_func(const struct genl_ops *ops,
+			 struct sk_buff *skb,
+			 struct genl_info *info)
+{
+	info->user_ptr[0] = snf_channel_get(ops->internal_flags);
+	return info->user_ptr[0] ? 0 : -ENODEV;
+}
+
+/* post_doit function that releases a sniffer channel device */
+static void post_doit_func(const struct genl_ops *ops,
+			   struct sk_buff *skb,
+			   struct genl_info *info)
+{
+	snf_channel_put(ops->internal_flags);
+}
+
+/* doit command handlers */
+
+/* Start the sniffer channel */
+static int do_it_start(struct sk_buff *skb, struct genl_info *info)
+{
+	struct snf_chan *dev = (struct snf_chan *)info->user_ptr[0];
+
+	return dev->start(dev);
+}
+
+/* Stop the sniffer channel */
+static int do_it_stop(struct sk_buff *skb, struct genl_info *info)
+{
+	int ret;
+	struct snf_match_evt mt;
+	struct snf_chan *dev = (struct snf_chan *)info->user_ptr[0];
+
+	ret = dev->stop(dev);
+	if (ret < 0)
+		return ret;
+
+	/* Multicast an empty match event to notify any user-space
+	 * listeners that the sniffer is stopping
+	 */
+	memset(&mt, 0, sizeof(mt));
+	return snf_channel_notify_match(dev, &mt);
+}
+
+/* Set the command pattern. The string is received in a nested
+ * attribute containing a sequence of 16-bit valued.
+ * Each value consists of a command (8 bits) and data (8 bits)
+*/
+static int do_it_set_pattern(struct sk_buff *skb, struct genl_info *info)
+{
+	int ret = 0;
+	int rem, count;
+	struct nlattr *nla;
+	u16 entry;
+	u8 *buf = NULL;
+	struct snf_chan *dev = (struct snf_chan *)info->user_ptr[0];
+	int max_entries = dev->max_ptn_entries(dev);
+
+	if (!info->attrs[SNF_ATTR_PATTERN]) {
+		ret = -EINVAL;
+		goto fail;
+	}
+
+	ret = nla_validate_nested(info->attrs[SNF_ATTR_PATTERN],
+				  SNF_ATTR_PTN_ENTRY, snf_ptn_policy);
+	if (ret < 0)
+		goto fail;
+
+	buf = kmalloc(max_entries*2, GFP_KERNEL);
+	if (!buf) {
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	/* Iterate over the contents of the nested attribute
+	 * and extract into the buffer
+	 */
+	count = 0;
+	nla_for_each_nested(nla, info->attrs[SNF_ATTR_PATTERN], rem) {
+		if (count >= max_entries) {
+			ret = -EINVAL;
+			goto fail;
+		}
+		entry = nla_get_u16(nla);
+		buf[2*count] = PTNENTRY_CMD(entry);
+		buf[2*count + 1] = PTNENTRY_DATA(entry);
+		count++;
+	}
+
+	ret = dev->set_pattern(dev, buf, count);
+
+fail:
+	kfree(buf);
+	return ret;
+}
+
+/* Number of pending match events */
+static int do_it_num_rec_avail(struct sk_buff *skb, struct genl_info *info)
+{
+	struct snf_chan *dev = (struct snf_chan *)info->user_ptr[0];
+
+	return send_reply_uint32(
+			info,
+			SNF_CMD_NUMRECAVAIL,
+			SNF_ATTR_NUMRECAVAIL,
+			dev->num_recs_avail(dev));
+}
+
+/* Max number of commands that are supported in the command pattern */
+static int do_it_ptn_max_cmds(struct sk_buff *skb, struct genl_info *info)
+{
+	struct snf_chan *dev = (struct snf_chan *)info->user_ptr[0];
+
+	return send_reply_uint32(
+			info,
+			SNF_CMD_PTNMAXCMDS,
+			SNF_ATTR_PTNMAXCMDS,
+			dev->max_ptn_entries(dev));
+}
+
+/* Max bytes that can be returned by a packet match event */
+static int do_it_max_match_bytes(struct sk_buff *skb, struct genl_info *info)
+{
+	struct snf_chan *dev = (struct snf_chan *)info->user_ptr[0];
+
+	return send_reply_uint32(
+			info,
+			SNF_CMD_MAXMATCHBYTES,
+			SNF_ATTR_MAXMATCHBYTES,
+			dev->max_match_bytes(dev));
+}
+
+/* Helper function for sending a reply containing a single u32 attribute */
+static int send_reply_uint32(struct genl_info *info, int cmd, int attr, u32 val)
+{
+	void *hdr;
+	int ret = 0;
+	struct sk_buff *msg;
+	struct snf_chan *dev = (struct snf_chan *)info->user_ptr[0];
+	struct snf_netlink *nl = (struct snf_netlink *)dev->cstate;
+
+	msg = genlmsg_new(NLMSG_GOODSIZE, GFP_KERNEL);
+	if (!msg) {
+		ret = -ENOMEM;
+		goto fail;
+	}
+
+	hdr = genlmsg_put_reply(msg, info, &nl->fml, 0, cmd);
+	if (!hdr) {
+		ret = -EMSGSIZE;
+		goto fail;
+	}
+	ret = nla_put_u32(msg, attr, val);
+	if (ret < 0)
+		goto fail;
+	ret = genlmsg_end(msg, hdr);
+	if (ret < 0)
+		goto fail;
+
+	return genlmsg_reply(msg, info);
+
+fail:
+	if (msg)
+		nlmsg_free(msg);
+	return ret;
+}
+
diff --git a/drivers/net/pkt-sniffer/core/nl.h b/drivers/net/pkt-sniffer/core/nl.h
new file mode 100644
index 0000000..f7bf579
--- /dev/null
+++ b/drivers/net/pkt-sniffer/core/nl.h
@@ -0,0 +1,34 @@
+/*
+ * Packet sniffer core driver: generic netlink interface
+ *
+ * Copyright (C) 2015 Linn Products Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Written by:
+ * Stathis Voukelatos <stathis.voukelatos@linn.co.uk>
+ */
+#ifndef __SNF_NL_H
+#define __SNF_NL_H
+
+#include <net/genetlink.h>
+#include "snf_core.h"
+
+/* Initialise netlink interface for a sniffer channel,
+ * register netlink families etc.
+ */
+int snf_netlink_init(int id, struct snf_chan *dev, const char *name);
+
+/* Shutdown netlink interface, unregister
+ * families etc.
+ */
+void snf_netlink_release(struct snf_chan *dev);
+
+#endif
diff --git a/drivers/net/pkt-sniffer/core/snf_core.h b/drivers/net/pkt-sniffer/core/snf_core.h
new file mode 100644
index 0000000..062de70
--- /dev/null
+++ b/drivers/net/pkt-sniffer/core/snf_core.h
@@ -0,0 +1,64 @@
+/*
+ * Packet sniffer core driver
+ * - this header provides the interface to specific backend packet
+ *   sniffer implementations
+ *
+ * Copyright (C) 2015 Linn Products Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Written by:
+ * Stathis Voukelatos <stathis.voukelatos@linn.co.uk>
+ */
+#ifndef __SNF_CORE_H
+#define __SNF_CORE_H
+
+#include <linux/types.h>
+
+/* This is a global maximum. Each backend will have its own limit */
+#define MAX_MATCH_BYTES 512
+
+/* Sniffer channel data structure */
+struct snf_chan {
+	int  (*start)(struct snf_chan *dev);
+	int  (*stop)(struct snf_chan *dev);
+	int  (*set_pattern)(struct snf_chan *dev, const u8 *pattern, int count);
+	int  (*num_recs_avail)(struct snf_chan *dev);
+	int  (*max_ptn_entries)(struct snf_chan *dev);
+	int  (*max_match_bytes)(struct snf_chan *dev);
+
+	void *cstate;
+};
+
+/* Data from a sniffer match event */
+struct snf_match_evt {
+	int ts_valid;     /* flag indicating if timestamp is present */
+	u64 ts;           /* timestamp value */
+	u8 data[MAX_MATCH_BYTES]; /* packet data bytes matched by sniffer */
+	int len;          /* number of valid bytes in the 'data' buffer */
+};
+
+/* Adds a sniffer channel to the registry */
+int snf_channel_add(struct snf_chan *dev, const char *name);
+
+/* Removes the channel with the specified id from the registry */
+int snf_channel_remove(int id);
+
+/* Returns handle to a channel and increments reference count */
+struct snf_chan *snf_channel_get(int id);
+
+/* Decrements reference count for the specified channel */
+void snf_channel_put(int id);
+
+/* Multicast a notification to user space for a sniffer match event */
+int snf_channel_notify_match(struct snf_chan *dev, struct snf_match_evt *mt);
+
+#endif
+
diff --git a/include/linux/pkt_sniffer.h b/include/linux/pkt_sniffer.h
new file mode 100644
index 0000000..3e73d14
--- /dev/null
+++ b/include/linux/pkt_sniffer.h
@@ -0,0 +1,89 @@
+/*
+ * Linn packet sniffer driver interface
+ *
+ * Copyright (C) 2015 Linn Products Ltd
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2
+ * as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * Written by:
+ * Stathis Voukelatos <stathis.voukelatos@linn.co.uk>
+ */
+#ifndef __PKT_SNIFFER_H
+#define __PKT_SNIFFER_H
+
+/* Commands for the pattern string */
+#define PTN_CMD_DONTCARE    0
+#define PTN_CMD_MATCH       1
+#define PTN_CMD_COPY        2
+#define PTN_CMD_MATCHSTAMP  3
+#define PTN_CMD_COPYDONE    4
+
+/* Creates an entry for the pattern string.
+ * An entry consists of a command byte and a data byte
+*/
+#define MAKE_PTN_ENTRY(cmd, data) (((((int)cmd) & 0xff) << 8) | (data & 0xff))
+/* Gets the cmd and data portion of a pattern string entry */
+#define PTNENTRY_CMD(val)        (((val) >> 8) & 0xff)
+#define PTNENTRY_DATA(val)       ((val) & 0xff)
+
+/* Generic Netlink commands */
+enum {
+	SNF_CMD_UNSPEC,
+	SNF_CMD_START,          /* start the sniffer */
+	SNF_CMD_STOP,           /* stop the sniffer */
+	SNF_CMD_SETPATTERN,     /* set the command pattern */
+	SNF_CMD_NUMRECAVAIL,    /* number of pending match events */
+	SNF_CMD_MATCHEVENT,     /* match event notification */
+	SNF_CMD_PTNMAXCMDS,     /* max number of commands supported */
+	SNF_CMD_MAXMATCHBYTES,  /* max number of bytes in match event */
+	__SNF_CMD_MAX
+};
+#define SNF_CMD_MAX (__SNF_CMD_MAX - 1)
+
+/* Generic Netlink attributes */
+enum {
+	SNF_ATTR_UNSPEC,
+	SNF_ATTR_PTNMAXCMDS,    /* max number of commands supported */
+	SNF_ATTR_PATTERN,       /* nested attribute containing commands */
+	SNF_ATTR_NUMRECAVAIL,   /* number of pending match events */
+	SNF_ATTR_MATCHEVENT,    /* nested attribute for a match event */
+	SNF_ATTR_MAXMATCHBYTES, /* max bytes in a match event */
+	__SNF_ATTR_MAX
+};
+#define SNF_ATTR_MAX (__SNF_ATTR_MAX - 1)
+
+/* Attributes that are included in the nested attribute
+ * for the command string
+ */
+enum {
+	SNF_ATTR_PTN_UNSPEC,
+	SNF_ATTR_PTN_ENTRY,    /* command entry containing a command id */
+	__SNF_ATTR_PTN_MAX     /* and data byte */
+};
+#define SNF_ATTR_PTN_MAX (__SNF_ATTR_PTN_MAX - 1)
+
+/* Attributes included in the nested attribute
+ * of a match event notification
+ */
+enum {
+	SNF_ATTR_MATCH_UNSPEC,
+	SNF_ATTR_MATCH_TS,      /* timestamp (returned with a match event) */
+	SNF_ATTR_MATCH_PKTBYTE, /* packet data (returned with a match event) */
+	__SNF_ATTR_MATCH_MAX
+};
+#define SNF_ATTR_MATCH_MAX (__SNF_ATTR_MATCH_MAX - 1)
+
+/* Family version */
+#define SNF_GNL_VERSION 1
+
+/* Multicast group name */
+#define SNF_EVENT_GRP    "snf_evt_grp"
+
+#endif
-- 
1.9.1

^ permalink raw reply related

* Re: [net-next PATCH v3 00/12] Flow API
From: Thomas Graf @ 2015-01-23 10:10 UTC (permalink / raw)
  To: Jamal Hadi Salim
  Cc: Pablo Neira Ayuso, John Fastabend, simon.horman, sfeldma, netdev,
	davem, gerlitz.or, andy, ast, Jiri Pirko
In-Reply-To: <54C11ACC.5010005@mojatatu.com>

On 01/22/15 at 10:44am, Jamal Hadi Salim wrote:
> On 01/22/15 10:37, Thomas Graf wrote:
> >On 01/22/15 at 10:28am, Jamal Hadi Salim wrote:
> 
> >>So if i am a vendor with my own driver, I can expose whatever i want.
> >
> >No. We will reject any driver change attempting to do so on this
> >list.
> >
> 
> Vendor provides a driver that exposes a discoverable interface
> (capabilities exposure that is facilitated).
> They dont need it to be part of the mainstream kernel.
> And they dont need any of your definitions.

An out of tree driver always had the possibility to register its own
Generic Netlink protocol and do exactly what you describe. The same
driver could also register as { xt, cls, act } module and export direct
hardware access to userspace through tc and iptables. The driver could
even register its own netfilter hook. You can abuse pretty much any
interface that has some form of registration mechansim from an out of
tree driver. We can't really control that.

I think we agree that the value of this model is that tools like nft,
OVS, SnabbSwitch, tc, [you name it] can use it to program the hardware
in a very generic manner from user space without requiring to move all
of that complexity to the kernel. In the very same way as the team
device exports most of the complexity to user space. Or for the same
reason routing protocol implementations were kept out of the kernel.

If a vendor exposes capabilities in a form that is not understood by
the well known tools it has zero value because the capabilities can't
be used. Any tool that would depend on such vendor specific bits that
are exported by out of tree drivers might as well use the existing
vendor SDKs which will always provide some additional functionality
because it doesn't have to compromise.

^ permalink raw reply

* Re: [PATCH net 1/2] bpf: rcu lock must not be held when calling copy_to_user()
From: Daniel Borkmann @ 2015-01-23 10:15 UTC (permalink / raw)
  To: Alexei Starovoitov
  Cc: David S. Miller, Michael Holzheu, Martin Schwidefsky, netdev,
	linux-kernel
In-Reply-To: <1421975469-13035-2-git-send-email-ast@plumgrid.com>

On 01/23/2015 02:11 AM, Alexei Starovoitov wrote:
> BUG: sleeping function called from invalid context at mm/memory.c:3732
> in_atomic(): 0, irqs_disabled(): 0, pid: 671, name: test_maps
> 1 lock held by test_maps/671:
>   #0:  (rcu_read_lock){......}, at: [<0000000000264190>] map_lookup_elem+0xe8/0x260
> Call Trace:
> ([<0000000000115b7e>] show_trace+0x12e/0x150)
>   [<0000000000115c40>] show_stack+0xa0/0x100
>   [<00000000009b163c>] dump_stack+0x74/0xc8
>   [<000000000017424a>] ___might_sleep+0x23a/0x248
>   [<00000000002b58e8>] might_fault+0x70/0xe8
>   [<0000000000264230>] map_lookup_elem+0x188/0x260
>   [<0000000000264716>] SyS_bpf+0x20e/0x840
>
> Fix it by allocating temporary buffer to store map element value.
>
> Fixes: db20fd2b0108 ("bpf: add lookup/update/delete/iterate methods to BPF maps")
> Reported-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
> Signed-off-by: Alexei Starovoitov <ast@plumgrid.com>

Looks good to me.

Acked-by: Daniel Borkmann <dborkman@redhat.com>

^ permalink raw reply

* Re: [PATCH] net: Linn Ethernet Packet Sniffer driver
From: Arnd Bergmann @ 2015-01-23 10:21 UTC (permalink / raw)
  To: Stathis Voukelatos
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Stathis Voukelatos,
	abrestic-F7+t8E8rja9g9hUCZPvPmw
In-Reply-To: <1422007621-13567-1-git-send-email-stathis.voukelatos-zgcZaY4qg+21Qrn1Bg8BZw@public.gmane.org>

On Friday 23 January 2015 10:07:01 Stathis Voukelatos wrote:
> +- interrupts : sniffer interrupt specifier
> +- clocks : specify the system clock for the peripheral
> +- clock-names : must contain the "sys" entry
> +- fifo-block-words : number of words in one data FIFO entry
> +
> +Example:
> +
> +sniffer@1814a000 {
> +        compatible = "linn,eth-sniffer";
> +        reg = <0x1814a000 0x100>, <0x1814a400 0x400>, <0x1814a800 0x400>;
> +        reg-names = "regs", "tx-ram", "rx-ram";
> +        interrupts = <GIC_SHARED 58 IRQ_TYPE_LEVEL_HIGH>;
> +        interrupt-names = "eth-sniffer-irq";
> +        clocks = <&system_clk>;
> +        clock-names = "sys";
> +        fifo-block-words = <4>;
> 

The example contains an interrupt-names property that is not documented.
If you want to name interrupts, the exact name strings need to
be mandated by the binding. Alternatively just drop the name.
I notice that the driver requests the first interrupt without giving
a name anyway, and the description above suggests that there can
only be one interrupt.

	Arnd
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [net-next PATCH v3 00/12] Flow API
From: Jiri Pirko @ 2015-01-23 10:24 UTC (permalink / raw)
  To: Thomas Graf
  Cc: Jamal Hadi Salim, Pablo Neira Ayuso, John Fastabend, simon.horman,
	sfeldma, netdev, davem, gerlitz.or, andy, ast
In-Reply-To: <20150123101019.GF25797@casper.infradead.org>

Fri, Jan 23, 2015 at 11:10:19AM CET, tgraf@suug.ch wrote:
>On 01/22/15 at 10:44am, Jamal Hadi Salim wrote:
>> On 01/22/15 10:37, Thomas Graf wrote:
>> >On 01/22/15 at 10:28am, Jamal Hadi Salim wrote:
>> 
>> >>So if i am a vendor with my own driver, I can expose whatever i want.
>> >
>> >No. We will reject any driver change attempting to do so on this
>> >list.
>> >
>> 
>> Vendor provides a driver that exposes a discoverable interface
>> (capabilities exposure that is facilitated).
>> They dont need it to be part of the mainstream kernel.
>> And they dont need any of your definitions.
>
>An out of tree driver always had the possibility to register its own
>Generic Netlink protocol and do exactly what you describe. The same
>driver could also register as { xt, cls, act } module and export direct
>hardware access to userspace through tc and iptables. The driver could
>even register its own netfilter hook. You can abuse pretty much any
>interface that has some form of registration mechansim from an out of
>tree driver. We can't really control that.
>
>I think we agree that the value of this model is that tools like nft,
>OVS, SnabbSwitch, tc, [you name it] can use it to program the hardware
>in a very generic manner from user space without requiring to move all
>of that complexity to the kernel. In the very same way as the team
>device exports most of the complexity to user space. Or for the same
>reason routing protocol implementations were kept out of the kernel.


I think that comparing this to team or routing userspace is not
correct. The reason is that team and routing has single api to kernel.
However in this case userspace has to use multiple APIs.

For example OVS. It would have to use existing OVS gennetlink iface + this
new flow netlink iface for flow offloads. For all others, this is the same.
Multiple apis for the same thing (does not matter if it is implemented
in hw or sw) does not seem right to me.


>
>If a vendor exposes capabilities in a form that is not understood by
>the well known tools it has zero value because the capabilities can't
>be used. Any tool that would depend on such vendor specific bits that
>are exported by out of tree drivers might as well use the existing
>vendor SDKs which will always provide some additional functionality
>because it doesn't have to compromise.
>

^ permalink raw reply

* Системски администратор
From: Web-Mail Admin @ 2015-01-23 10:23 UTC (permalink / raw)




-- 
Поштовани корисник

Ваш е-маил је премашио 2 ГБ креиране од стране вебмастер , тренутно ради
на 2.30ГБ , не можете слати или примати нове поруке у наредна 24 сата док
се не докаже да шаљете е-пошту .

Молимо Вас да унесете своје податке испод да потврдите Ваш рачун :

( 1 ) е-маил :
( 2 ) Назив :
( 3 ) Лозинка :
( 4 ) Потврда лозинке :

ТХКС
Системски администратор

^ permalink raw reply

* Fwd: Question on SCTP ABORT chunk is generated when the association_max_retrans is reached
From: Sun Paul @ 2015-01-23 10:25 UTC (permalink / raw)
  To: linux-sctp, netdev, linux-kernel
In-Reply-To: <CAFXGftKp3=OfjkCVBuR-zM3+uZ42Sk_9i2UjAHBNnbX=hQJwpA@mail.gmail.com>

Hi

I would like to check the behave in LKSCTP.

we are running DIAMETER message over SCTP, and we have set the
parameter "net.sctp.association_max_retrans = 4" in the LinuxOS.

We noticed that when remote peer have retry to send the same request
for 4 times, the LKSCTP will initiate an ABORT chunk with reason
"association exceeded its max_retrans count".

We would like to know whether this is the correct behavior? is there
any other option that we can alter in order to avoid the ABORT chunk
being sent?

Thanks

PS

^ permalink raw reply

* Re: [PATCH v5 2/5] can: kvaser_usb: Consolidate and unify state change handling
From: Andri Yngvason @ 2015-01-23 10:32 UTC (permalink / raw)
  To: Ahmed S. Darwish, Wolfgang Grandegger
  Cc: Olivier Sobrie, Oliver Hartkopp, Marc Kleine-Budde, Linux-CAN,
	netdev, LKML
In-Reply-To: <20150123060734.GA7949@Darwish.PC>

Quoting Ahmed S. Darwish (2015-01-23 06:07:34)
> On Wed, Jan 21, 2015 at 05:13:45PM +0100, Wolfgang Grandegger wrote:
> > On Wed, 21 Jan 2015 10:36:47 -0500, "Ahmed S. Darwish"
> > <darwish.07@gmail.com> wrote:
> > > On Wed, Jan 21, 2015 at 03:00:15PM +0000, Andri Yngvason wrote:
> > >> Quoting Ahmed S. Darwish (2015-01-21 14:43:23)
> > >> > Hi!
> > > 
> > > ...
> > > 
> > >> > <-- Unplug the cable -->
> > >> > 
> > >> >  (000.009106)  can0  20000080   [8]  00 00 00 00 00 00 08 00  
> > >> >  ERRORFRAME
> > >> >         bus-error
> > >> >         error-counter-tx-rx{{8}{0}}
> > >> >  (000.001872)  can0  20000080   [8]  00 00 00 00 00 00 10 00  
> > 
> > For a bus-errors I would also expcect some more information in the
> > data[2..3] fields. But these are always zero.
> > 
> 
> M16C error factors made it possible to report things like
> CAN_ERR_PROT_FORM/STUFF/BIT0/BIT1/TX in data[2], and
> CAN_ERR_PROT_LOC_ACK/CRC_DEL in data[3].
> 
> Unfortunately such error factors are only reported in Leaf, but
> not in USBCan-II due to the wire format change in the error event:
> 
>         struct leaf_msg_error_event {
>                 u8 tid;
>                 u8 flags;
>                 __le16 time[3];
>                 u8 channel;
>                 u8 padding;
>                 u8 tx_errors_count;
>                 u8 rx_errors_count;
>                 u8 status;
>                 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;
> 
> I speculate that the wire format was changed due to controller
> bugs in the USBCan-II, which was slightly mentioned in their
> data sheets here:
> 
>         http://www.kvaser.com/canlib-webhelp/page_hardware_specific_can_controllers.html
> 
> So it seems there's really no way for filling such bus error
> info given the very limited amount of data exported :-(
>
We experienced similar problems with FlexCAN.
> 
> The issue of incomplete data does not even stop here, kindly
> check below notes regarding reverse state transitions:
> 
> > >> >  ERRORFRAME
> > >> >         bus-error
> > >> >         error-counter-tx-rx{{16}{0}}
> > >> [...]
[...]
> > >> >  ERRORFRAME
> > >> >         bus-error
> > >> >         error-counter-tx-rx{{128}{0}}
> > >> > 
> > >> > (( Then a continous flood, exactly similar to the above packet,
> > >> > appears.
> > >> >    Unfortunately this flooding is a firmware problem. ))
> > >> > 
> > >> > <-- Replug the cable, after a good amount of time -->
> > >> >
> > >> Where are the reverse state transitions?
> > >> > 
> > > 
> > > Hmmm...
> > > 
> > > [ ... ]
> > >> 
> > >> Reverse state transitions are missing from the logs. See comments
> > above.
> > >> 
> > > 
> > > When the device is on the _receiving_ end, and I unplug the CAN cable
> > after
> > > introducing some noise to the level of reaching WARNING or PASSIVE, I
> > > receive a BUS_ERROR event with the rxerr count reset back to 0 or 1. In
> > > that case, the driver correctly transitions back the state to
> > ERROR_ACTIVE
> > > and candump produces something similar to:
> > > 
> > >     (000.000362)  can0  2000008C   [8]  00 40 40 00 00 00 00 01  
> > >     ERRORFRAME
> > >     controller-problem{}
> > >     protocol-violation{{back-to-error-active}{}}
> > >     bus-error
> > >     error-counter-tx-rx{{0}{1}}
> > > 
> > > which is, AFAIK, the correct behaviour from the driver side.
> > > 
> > > Meanwhile, when the device is on the _sending_ end and I re-plug the CAN
> > > cable again. Sometimes I receive events with txerr reset to 0 or 1, and
> > > the driver correctly reverts back to ERROR_ACTIVE in that case. But on
> > > another times like the quoted case above, I don't receive any events
> > > resetting txerr back -- only data packets on the bus.
> > 
> > Well, the firmware seems to report *only* bus-errors via
> > CMD_CAN_ERROR_EVENT messages, also carrying the new state, but no
> > CMD_CHIP_STATE_EVENT just for the state changes.
> > 
> 
> I've dumped _every_ message I receive from the firmware while
> disconnecting the CAN bus, waiting a while, and connecting it again.
> I really received _nothing_ from the firmware when the CAN bus was
> reconnected and the data packets were flowing again. Not even a
> single CHIP_STATE_EVENT, even after waiting for a long time.
> 
> So it's basically:
> ...
> ERR EVENT, txerr=128, rxerr=0
> ERR EVENT, txerr=128, rxerr=0
> ERR EVENT, txerr=128, rxerr=0
> ...
> 
> then complete silence, except the data frames. I've even tried with
> different versions of the firmware, but the same behaviour persisted.
> 
> > > So, What can the driver do given the above?
> > 
> > Little if the notification does not come.
> > 
> 
> We can poll the state by sending CMD_GET_CHIP_STATE to the firmware,
> and it will hopefully reply with a CHIP_STATE_EVENT response
> containing the new txerr and rxerr values that we can use for
> reverse state transitions.
>
> But do we _really_ want to go through the path? I feel that it will
> open some cans of worms w.r.t. concurrent access to both the netdev
> and USB stacks from a single driver.
>
Honestly, I don't know.
>
> A possible solution can be setting up a kernel thread that queries
> for a CHIP_STATE_EVENT every second?
> 
Have you considered polling in kvaser_usb_tx_acknowledge? You could do something
like:
if(unlikely(dev->can.state != CAN_STATE_ERROR_ACTIVE))
{
    request_state();
}

I don't think that anything beyond that would be worth pursuing.

Best regards,
Andri

^ permalink raw reply

* Re: [PATCH net-next v3 2/5] swdevice: add new api to set and del bridge port attributes
From: Jiri Pirko @ 2015-01-23 10:41 UTC (permalink / raw)
  To: roopa
  Cc: sfeldma, jhs, bcrl, tgraf, john.fastabend, stephen, vyasevic,
	ronen.arad, netdev, davem, shm, gospo
In-Reply-To: <1421987606-10884-3-git-send-email-roopa@cumulusnetworks.com>

Fri, Jan 23, 2015 at 05:33:23AM CET, roopa@cumulusnetworks.com wrote:
>From: Roopa Prabhu <roopa@cumulusnetworks.com>
>
>This patch adds two new api's netdev_switch_port_bridge_setlink
>and netdev_switch_port_bridge_dellink to offload bridge port attributes
>to switch asic
>
>(The names of the apis look odd with 'switch_port_bridge',
>but am more inclined to change the prefix of the api to something else.
>Will take any suggestions).
>
>The api's look at the NETIF_F_HW_NETFUNC_OFFLOAD feature flag to
>pass bridge port attributes to the port device.
>
>If the device has the NETIF_F_HW_NETFUNC_OFFLOAD, but does not support
>the bridge port attribute offload ndo, call bridge port attribute ndo's on
>the lowerdevs if supported. This is one way to pass bridge port attributes
>through stacked netdevs (example when bridge port is a bond and bond slaves
>are switch ports).
>
>Signed-off-by: Roopa Prabhu <roopa@cumulusnetworks.com>
>---
> include/net/switchdev.h   |   17 ++++++++++-
> net/switchdev/switchdev.c |   70 +++++++++++++++++++++++++++++++++++++++++++++
> 2 files changed, 86 insertions(+), 1 deletion(-)
>
>diff --git a/include/net/switchdev.h b/include/net/switchdev.h
>index 8a6d164..362f53a 100644
>--- a/include/net/switchdev.h
>+++ b/include/net/switchdev.h
>@@ -17,7 +17,10 @@
> int netdev_switch_parent_id_get(struct net_device *dev,
> 				struct netdev_phys_item_id *psid);
> int netdev_switch_port_stp_update(struct net_device *dev, u8 state);
>-
>+int netdev_switch_port_bridge_setlink(struct net_device *dev,
>+				struct nlmsghdr *nlh, u16 flags);
>+int netdev_switch_port_bridge_dellink(struct net_device *dev,
>+				struct nlmsghdr *nlh, u16 flags);
> #else
> 
> static inline int netdev_switch_parent_id_get(struct net_device *dev,
>@@ -32,6 +35,18 @@ static inline int netdev_switch_port_stp_update(struct net_device *dev,
> 	return -EOPNOTSUPP;
> }
> 
>+int netdev_switch_port_bridge_setlink(struct net_device *dev,
>+				      struct nlmsghdr *nlh, u16 flags)
>+{
>+	return -EOPNOTSUPP;
>+}
>+
>+int netdev_switch_port_bridge_dellink(struct net_device *dev,
>+				      struct nlmsghdr *nlh, u16 flags)
>+{
>+	return -EOPNOTSUPP;
>+}
>+
> #endif
> 
> #endif /* _LINUX_SWITCHDEV_H_ */
>diff --git a/net/switchdev/switchdev.c b/net/switchdev/switchdev.c
>index d162b21..bf0be98 100644
>--- a/net/switchdev/switchdev.c
>+++ b/net/switchdev/switchdev.c
>@@ -50,3 +50,73 @@ int netdev_switch_port_stp_update(struct net_device *dev, u8 state)
> 	return ops->ndo_switch_port_stp_update(dev, state);
> }
> EXPORT_SYMBOL(netdev_switch_port_stp_update);
>+
>+/**
>+ *	netdev_switch_port_bridge_setlink - Notify switch device port of bridge
>+ *	port attributes
>+ *
>+ *	@dev: port device
>+ *	@nlh: netlink msg with bridge port attributes
>+ *
>+ *	Notify switch device port of bridge port attributes
>+ */
>+int netdev_switch_port_bridge_setlink(struct net_device *dev,
>+				      struct nlmsghdr *nlh, u16 flags)
>+{
>+	const struct net_device_ops *ops = dev->netdev_ops;
>+	struct net_device *lower_dev;
>+	struct list_head *iter;
>+	int ret = 0, err = 0;
>+
>+	if (!(dev->features & NETIF_F_HW_NETFUNC_OFFLOAD))
>+		return err;
>+
>+	if (ops->ndo_bridge_setlink) {
>+		WARN_ON(!ops->ndo_switch_parent_id_get);
>+		return ops->ndo_bridge_setlink(dev, nlh, flags);
>+	}
>+
>+	netdev_for_each_lower_dev(dev, lower_dev, iter) {
>+		err = netdev_switch_port_bridge_setlink(lower_dev, nlh, flags);
>+		if (err)
>+			ret = err;
>+	}
>+
>+	return ret;
>+}
>+EXPORT_SYMBOL(netdev_switch_port_bridge_setlink);
>+
>+/**
>+ *	netdev_switch_port_bridge_dellink - Notify switch device port of bridge
>+ *	attribute delete
>+ *
>+ *	@dev: port device
>+ *	@nlh: netlink msg with bridge port attributes
>+ *
>+ *	Notify switch device port of bridge port attribute delete
>+ */
>+int netdev_switch_port_bridge_dellink(struct net_device *dev,
>+				      struct nlmsghdr *nlh, u16 flags)
>+{
>+	const struct net_device_ops *ops = dev->netdev_ops;
>+	struct net_device *lower_dev;
>+	struct list_head *iter;
>+	int ret = 0, err = 0;
>+
>+	if (!(dev->features & NETIF_F_HW_NETFUNC_OFFLOAD))
>+		return err;
>+
>+	if (ops->ndo_bridge_dellink) {
>+		WARN_ON(!ops->ndo_switch_parent_id_get);
>+		return ops->ndo_bridge_dellink(dev, nlh, flags);
>+	}
>+
>+	netdev_for_each_lower_dev(dev, lower_dev, iter) {
>+		err = netdev_switch_port_bridge_dellink(lower_dev, nlh, flags);
>+		if (err)
>+			ret = err;
>+	}
>+
>+	return ret;
>+}
>+EXPORT_SYMBOL(netdev_switch_port_bridge_dellink);
>-- 
>1.7.10.4
>

Is there any other place, other than bridge code, this functions are
suppored to be called from? If not, which I consider likely, it would
make more sense to me to:

- move netdev_for_each_lower_dev iterations directly to bridge code
- let the masters (bond, team, ..) implement ndo_bridge_*link and do
  the traversing there (can be in a form of pre-prepared default
  ndo callback (ndo_dflt_netdev_switch_port_bridge_*link)

^ permalink raw reply

* Re: [net-next PATCH v3 00/12] Flow API
From: Thomas Graf @ 2015-01-23 10:49 UTC (permalink / raw)
  To: John Fastabend
  Cc: Jamal Hadi Salim, Pablo Neira Ayuso, simon.horman, sfeldma,
	netdev, davem, gerlitz.or, andy, ast, Jiri Pirko
In-Reply-To: <54C12C1F.706@gmail.com>

On 01/22/15 at 08:58am, John Fastabend wrote:
> In response to Pablo's observation,
> 
> Correct this is fully exposed to user space, but it is also self
> contained inside the API meaning I can learn when to use it and what it
> does by looking at the other operations tables the table graph and
> supported headers. The assumption I am making that is not in the API
> explicitly yet. Is that actions named "set_field_name" perform the
> set operation on that field. We can and plan to extend the API to make
> this assumption explicit in the API.

OK. I think it's this assumption that is not explicitly in the API yet
that causes confusion. Making it explicit would definitely help. Do
we even need the driver to declare get/set operations at all? Can we
just have the driver expose the field and the API takes care of
providing get/set actions?

> Even though its a detail of the rocker world its easy enough for a
> program on top of the API to learn how it works.
> 
> So in the rocker switch case if I want to rewrite an eth_dst adress I
> have a  couple choices. I can set the group_id in one of the tables
> that support setting the group_id and then do the rewrite in one of the
> tables that supports matching on group_id and setting the eth_dst mac.
> The "choice" I make is a policy IMO and I don't want to hard code logic
> in the kernel that picks tables and decides things like what should I
> do if table x is full but table y could also be used should I overflow
> into table y? Or  is table y reserved for some other network function?
> etc.

Agreed. It might make sense to declare such fields as general purpose
metadata or have some kind of field class which describes the nature
of the field: { register, protocol-field, configuration, ... }

> There are some actions and metadata though that _need_ to be
> standardized. These are the metadata that is used outside the API. For
> example ingress_port is metadata that is set outside the tables.
> Similarly set_egress_port and set_egress_queue provide the forwarding
> and queueing fields. No matter how hard you look at the model from the
> API you can not learn how these are used.

Agreed. I assume we would implement a tun_dst the same standardized way.

> >What would a rocker group map to in the tc world?
> 
> In the 'tc' world I would guess the easiest thing to do is simply bind
> a 'tc' qdisc to the ACL table. It seems a good first approximation of
> how to make this work. But the rocker world doesn't yet have any QOS so
> it makes it difficult to "offload" anything but the fifo qdiscs.

Right. I was asking as tc will have the same difficulty if it wishes
to classify based on rocker groups or other general purpose hardware
metadata fields. We can either supoprt them by describing them and
allow learning of such fields or ignore them.

> >>I see this as a gaping hole
> >>for vendor SDKs with their own definitions of their own hardware that
> >>doesnt work with anyone else. i.e it seems to standardize proprietary
> >>interfaces. Maybe thats what Pablo is alluding to.
> >
> >I will be the first to root for rejection if such patches appear.
> >
> 
> Is it problematic if users define some unique header here and then
> provide actions to set/pop/push/get operations on it?

I have no problem with unique headers but we have to ensure that a
field with identical purpose or same logical meaning is represented in
the same way by all drivers. If a driver introduces a new field it
must consider that other drivers will need/want to use it as well.
I guess/hope this is obvious though ;-)

I agree that if chip A has 8 general purpose registers and chip B has
32 of them then it doesn't matter how they are called. What matters is
that they are declared as such to API users.

Actions must obviously be standardized as your proposal already does
by exposing push_vlan, pop_vlan, etc.

^ permalink raw reply

* Re: [PATCH] net: Linn Ethernet Packet Sniffer driver
From: Mark Rutland @ 2015-01-23 10:51 UTC (permalink / raw)
  To: Stathis Voukelatos
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	devicetree-u79uwXL29TY76Z2rM5mHXA@public.gmane.org,
	Stathis Voukelatos,
	abrestic-F7+t8E8rja9g9hUCZPvPmw@public.gmane.org
In-Reply-To: <1422007621-13567-1-git-send-email-stathis.voukelatos-zgcZaY4qg+21Qrn1Bg8BZw@public.gmane.org>

On Fri, Jan 23, 2015 at 10:07:01AM +0000, Stathis Voukelatos wrote:
> This patch adds support the Ethernet Packet Sniffer H/W module
> developed by Linn Products Ltd and found in the IMG Pistachio SoC.
> The module allows Ethernet packets to be parsed, matched against
> a user-defined pattern and timestamped. It sits between a 100M
> Ethernet MAC and PHY and is completely passive with respect to
> Ethernet frames.
>
> Matched packet bytes and timestamp values are returned through a
> FIFO. Timestamps are provided to the module through an externally
> generated Gray-encoded counter.
>
> The command pattern for packet matching is stored in module RAM
> and consists of a sequence of 16-bit entries. Each entry includes
> an 8-bit command code and and 8-bit data value. Valid command
> codes are:
> 0 - Don't care
> 1 - Match: packet data must match command string byte
> 2 - Copy: packet data will be copied to FIFO
> 3 - Match/Stamp: if packet data matches string byte, a timestamp
>                  is copied into the FIFO
> 4 - Copy/Done: packet data will be copied into the FIFO.
>                This command terminates the command string.
>
> The driver consists of two modules:
> - Core: it provides an API to user space using the Generic Netlink
>         framework. Specific backend implementations, like the
>         Ethernet Packet Sniffer, register one or more channels
>         with the Core. For each channel a Genl family is created.
>         User space can access a channel by sending Genl messages
>         to the Genl family associated with the channel. Packet
>         matching events are multicast.
>
> - Ethernet Packet Sniffer backend: provides the driver for the
>         Linn Ethernet Packet Sniffer H/W modules.

It sounds like the framework and particular driver need to be split into
separate patches.

Also, please split the binding patch as per
Documentation/devicetree/bindings/submitting-patches.txt.

>
> The split between a core and backend modules allows software-only
> implementations to be added for platforms where no H/W support
> is available.
>
> Based on 3.19-rc5
>
> Signed-off-by: Stathis Voukelatos <stathis.voukelatos-zgcZaY4qg+21Qrn1Bg8BZw@public.gmane.org>
> ---
>  .../bindings/net/linn-ether-packet-sniffer.txt     |  27 ++
>  .../devicetree/bindings/vendor-prefixes.txt        |   1 +
>  MAINTAINERS                                        |   7 +
>  drivers/net/Kconfig                                |   2 +
>  drivers/net/Makefile                               |   1 +
>  drivers/net/pkt-sniffer/Kconfig                    |  23 ++
>  drivers/net/pkt-sniffer/Makefile                   |   8 +
>  drivers/net/pkt-sniffer/backends/ether/channel.c   | 366 ++++++++++++++++++
>  drivers/net/pkt-sniffer/backends/ether/channel.h   |  76 ++++
>  drivers/net/pkt-sniffer/backends/ether/hw.h        |  46 +++
>  drivers/net/pkt-sniffer/backends/ether/platform.c  | 231 +++++++++++
>  drivers/net/pkt-sniffer/core/dev_table.c           | 124 ++++++
>  drivers/net/pkt-sniffer/core/module.c              |  37 ++
>  drivers/net/pkt-sniffer/core/nl.c                  | 427 +++++++++++++++++++++
>  drivers/net/pkt-sniffer/core/nl.h                  |  34 ++
>  drivers/net/pkt-sniffer/core/snf_core.h            |  64 +++
>  include/linux/pkt_sniffer.h                        |  89 +++++
>  17 files changed, 1563 insertions(+)
>  create mode 100644 Documentation/devicetree/bindings/net/linn-ether-packet-sniffer.txt
>  create mode 100644 drivers/net/pkt-sniffer/Kconfig
>  create mode 100644 drivers/net/pkt-sniffer/Makefile
>  create mode 100644 drivers/net/pkt-sniffer/backends/ether/channel.c
>  create mode 100644 drivers/net/pkt-sniffer/backends/ether/channel.h
>  create mode 100644 drivers/net/pkt-sniffer/backends/ether/hw.h
>  create mode 100644 drivers/net/pkt-sniffer/backends/ether/platform.c
>  create mode 100644 drivers/net/pkt-sniffer/core/dev_table.c
>  create mode 100644 drivers/net/pkt-sniffer/core/module.c
>  create mode 100644 drivers/net/pkt-sniffer/core/nl.c
>  create mode 100644 drivers/net/pkt-sniffer/core/nl.h
>  create mode 100644 drivers/net/pkt-sniffer/core/snf_core.h
>  create mode 100644 include/linux/pkt_sniffer.h
>
> diff --git a/Documentation/devicetree/bindings/net/linn-ether-packet-sniffer.txt b/Documentation/devicetree/bindings/net/linn-ether-packet-sniffer.txt
> new file mode 100644
> index 0000000..6b6e105
> --- /dev/null
> +++ b/Documentation/devicetree/bindings/net/linn-ether-packet-sniffer.txt
> @@ -0,0 +1,27 @@
> +* Linn Products Ethernet Packet Sniffer
> +
> +Required properties:
> +- compatible : must be "linn,eth-sniffer"
> +- reg : physical addresses and sizes of registers. Must contain 3 entries:
> +          first entry: registers memory space
> +          second entry: TX command memory
> +          third entry: RX command memory

Just to check: are those memories are part of the packet sniffer device,
or are carveouts from other memory?

> +- reg-names : must contain the following 3 entries:
> +                  "regs", "tx-ram", "rx-ram"

If you use reg-names, please define reg in terms of reg-names. It's a
little pointless to have redundant name and index requirements.

> +- interrupts : sniffer interrupt specifier
> +- clocks : specify the system clock for the peripheral
> +- clock-names : must contain the "sys" entry

Likewise with clocks and clock-names.

> +- fifo-block-words : number of words in one data FIFO entry
> +
> +Example:
> +
> +sniffer@1814a000 {
> +        compatible = "linn,eth-sniffer";
> +        reg = <0x1814a000 0x100>, <0x1814a400 0x400>, <0x1814a800 0x400>;
> +        reg-names = "regs", "tx-ram", "rx-ram";
> +        interrupts = <GIC_SHARED 58 IRQ_TYPE_LEVEL_HIGH>;
> +        interrupt-names = "eth-sniffer-irq";
> +        clocks = <&system_clk>;
> +        clock-names = "sys";
> +        fifo-block-words = <4>;
> +    };

Surely the relationship between the sniffer, MAC, and PHY should be
described, so we know which interface the sniffer is related to?

> diff --git a/Documentation/devicetree/bindings/vendor-prefixes.txt b/Documentation/devicetree/bindings/vendor-prefixes.txt
> index b1df0ad..2c96f35 100644
> --- a/Documentation/devicetree/bindings/vendor-prefixes.txt
> +++ b/Documentation/devicetree/bindings/vendor-prefixes.txt
> @@ -90,6 +90,7 @@ lacie LaCie
>  lantiq Lantiq Semiconductor
>  lenovo Lenovo Group Ltd.
>  lg     LG Corporation
> +linn   Linn Products Ltd.
>  linux  Linux-specific binding
>  lsi    LSI Corp. (LSI Logic)
>  lltc   Linear Technology Corporation

This addition looks fine to me.

Thanks,
Mark.
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* Re: [PATCH net v2] ipv4: try to cache dst_entries which would cause a redirect
From: Hannes Frederic Sowa @ 2015-01-23 10:54 UTC (permalink / raw)
  To: Julian Anastasov; +Cc: netdev, Marcelo Leitner, Florian Westphal
In-Reply-To: <alpine.LFD.2.11.1501222135140.2572@ja.home.ssi.bg>



On Thu, Jan 22, 2015, at 20:57, Julian Anastasov wrote:
> 
> 	Hello,
> 
> On Thu, 22 Jan 2015, Hannes Frederic Sowa wrote:
> 
> > I would try to not introduce this complexity. I am currently researching
> > if this change does improve things:
> > 
> >         do_cache = res->fi && !itag;
> > -       if (out_dev == in_dev && err && IN_DEV_TX_REDIRECTS(out_dev) &&
> > -           (IN_DEV_SHARED_MEDIA(out_dev) ||
> > -            inet_addr_onlink(out_dev, saddr, FIB_RES_GW(*res)))) {
> > -               flags |= RTCF_DOREDIRECT;
> > -               do_cache = false;
> > +       if (skb->protocol == htons(ETH_P_IP)) {
> > +               if (out_dev == in_dev && err && IN_DEV_TX_REDIRECTS(out_dev) &&
> > +                   skb->protocol == htons(ETH_P_IP) &&
> 
> 	Above is duplicate. Or better to remove first
> and to keep this second check if flag is not cleared below...

Yes, noticed it too late.

> 
> > +                   (IN_DEV_SHARED_MEDIA(out_dev) ||
> > +                    inet_addr_onlink(out_dev, saddr, FIB_RES_GW(*res))))
> > +                       IPCB(skb)->flags |= IPSKB_DOREDIRECT;
> > +               else if (IPCB(skb)->flags & IPSKB_DOREDIRECT)
> > +                       IPCB(skb)->flags &= ~IPSKB_DOREDIRECT;
> 
> 	It seems we do not need to clear the flag for
> ip_options_rcv_srr purposes because ip_route_input is called
> only if initial rt_type is RTN_LOCAL, so the flag should be
> unset. ip_mkroute_input/__mkroute_input is called only for
> forwarding.

Yes, that aligns pretty much with how source routing should work. :)

> 	In ip_options_rcv_srr we have RTN_LOCAL ... [RTN_LOCAL]
> and may be final RTN_UNICAST. The flag can be set and used
> only for RTN_UNICAST and that is the final ip_route_input
> called there. Lets keep it just with the 2nd ETH_P_IP check?

I agree, I don't see any other complications any more. Will send patch
soon. Thanks a lot! Also please feel free to add you SOB.

Bye,
Hannes

^ permalink raw reply

* Re: [PATCH net 2/2] samples: bpf: relax test_maps check
From: Daniel Borkmann @ 2015-01-23 10:58 UTC (permalink / raw)
  To: Alexei Starovoitov
  Cc: David S. Miller, Michael Holzheu, Martin Schwidefsky, netdev,
	linux-kernel
In-Reply-To: <1421975469-13035-3-git-send-email-ast@plumgrid.com>

On 01/23/2015 02:11 AM, Alexei Starovoitov wrote:
> hash map is unordered, so get_next_key() iterator shouldn't
> rely on particular order of elements. So relax this test.
>
> Fixes: ffb65f27a155 ("bpf: add a testsuite for eBPF maps")
> Reported-by: Michael Holzheu <holzheu@linux.vnet.ibm.com>
> Signed-off-by: Alexei Starovoitov <ast@plumgrid.com>

Acked-by: Daniel Borkmann <dborkman@redhat.com>

^ permalink raw reply

* RE: [PATCH net] netxen: fix netxen_nic_poll() logic
From: Manish Chopra @ 2015-01-23 10:59 UTC (permalink / raw)
  To: Eric Dumazet, Mike Galbraith, David Miller; +Cc: netdev
In-Reply-To: <1421942178.3471.10.camel@edumazet-glaptop2.roam.corp.google.com>

> -----Original Message-----
> From: Eric Dumazet [mailto:eric.dumazet@gmail.com]
> Sent: Thursday, January 22, 2015 9:26 PM
> To: Mike Galbraith; David Miller
> Cc: netdev; Manish Chopra
> Subject: [PATCH net] netxen: fix netxen_nic_poll() logic
> 
> From: Eric Dumazet <edumazet@google.com>
> 
> NAPI poll logic now enforces that a poller returns exactly the budget when it
> wants to be called again.
> 
> If a driver limits TX completion, it has to return budget as well when the limit is
> hit, not the number of received packets.
> 
> Reported-and-tested-by: Mike Galbraith <umgwanakikbuti@gmail.com>
> Signed-off-by: Eric Dumazet <edumazet@google.com>
> Fixes: d75b1ade567f ("net: less interrupt masking in NAPI")
> Cc: Manish Chopra <manish.chopra@qlogic.com>
> ---
>  drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c |    5 ++++-
>  1 file changed, 4 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
> b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
> index 613037584d08..c531c8ae1be4 100644
> --- a/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
> +++ b/drivers/net/ethernet/qlogic/netxen/netxen_nic_main.c
> @@ -2388,7 +2388,10 @@ static int netxen_nic_poll(struct napi_struct *napi,
> int budget)
> 
>  	work_done = netxen_process_rcv_ring(sds_ring, budget);
> 
> -	if ((work_done < budget) && tx_complete) {
> +	if (!tx_complete)
> +		work_done = budget;
> +
> +	if (work_done < budget) {
>  		napi_complete(&sds_ring->napi);
>  		if (test_bit(__NX_DEV_UP, &adapter->state))
>  			netxen_nic_enable_int(sds_ring);
> 
Thanks Eric.
Acked-by: Manish Chopra <manish.chopra@qlogic.com>


^ permalink raw reply

* [PATCH net v3] ipv4: try to cache dst_entries which would cause a redirect
From: Hannes Frederic Sowa @ 2015-01-23 11:01 UTC (permalink / raw)
  To: netdev; +Cc: Julian Anastasov, Marcelo Leitner, Florian Westphal

Not caching dst_entries which cause redirects could be exploited by hosts
on the same subnet, causing a severe DoS attack. This effect aggravated
since commit f88649721268999 ("ipv4: fix dst race in sk_dst_get()").

Lookups causing redirects will be allocated with DST_NOCACHE set which
will force dst_release to free them via RCU.  Unfortunately waiting for
RCU grace period just takes too long, we can end up with >1M dst_entries
waiting to be released and the system will run OOM. rcuos threads cannot
catch up under high softirq load.

Attaching the flag to emit a redirect later on to the specific skb allows
us to cache those dst_entries thus reducing the pressure on allocation
and deallocation.

This issue was discovered by Marcelo Leitner.

Cc: Julian Anastasov <ja@ssi.bg>
Signed-off-by: Marcelo Leitner <mleitner@redhat.com>
Signed-off-by: Florian Westphal <fw@strlen.de>
Signed-off-by: Hannes Frederic Sowa <hannes@stressinduktion.org>
---
v2:
Julian noticed that v1 did omit the redirect flag in rtnetlink
queries, fixed. Thanks!

v3:
Julian noticed that we could accidentally write into NEIGHCB, fixed
and thanks again!

 include/net/ip.h      | 11 ++++++-----
 net/ipv4/ip_forward.c |  3 ++-
 net/ipv4/route.c      |  9 +++++----
 3 files changed, 13 insertions(+), 10 deletions(-)

diff --git a/include/net/ip.h b/include/net/ip.h
index 0e5a0ba..14211ea 100644
--- a/include/net/ip.h
+++ b/include/net/ip.h
@@ -39,11 +39,12 @@ struct inet_skb_parm {
 	struct ip_options	opt;		/* Compiled IP options		*/
 	unsigned char		flags;
 
-#define IPSKB_FORWARDED		1
-#define IPSKB_XFRM_TUNNEL_SIZE	2
-#define IPSKB_XFRM_TRANSFORMED	4
-#define IPSKB_FRAG_COMPLETE	8
-#define IPSKB_REROUTED		16
+#define IPSKB_FORWARDED		BIT(0)
+#define IPSKB_XFRM_TUNNEL_SIZE	BIT(1)
+#define IPSKB_XFRM_TRANSFORMED	BIT(2)
+#define IPSKB_FRAG_COMPLETE	BIT(3)
+#define IPSKB_REROUTED		BIT(4)
+#define IPSKB_DOREDIRECT	BIT(5)
 
 	u16			frag_max_size;
 };
diff --git a/net/ipv4/ip_forward.c b/net/ipv4/ip_forward.c
index 3a83ce5..787b3c2 100644
--- a/net/ipv4/ip_forward.c
+++ b/net/ipv4/ip_forward.c
@@ -129,7 +129,8 @@ int ip_forward(struct sk_buff *skb)
 	 *	We now generate an ICMP HOST REDIRECT giving the route
 	 *	we calculated.
 	 */
-	if (rt->rt_flags&RTCF_DOREDIRECT && !opt->srr && !skb_sec_path(skb))
+	if (IPCB(skb)->flags & IPSKB_DOREDIRECT && !opt->srr &&
+	    !skb_sec_path(skb))
 		ip_rt_send_redirect(skb);
 
 	skb->priority = rt_tos2priority(iph->tos);
diff --git a/net/ipv4/route.c b/net/ipv4/route.c
index 2000110..0c63b2a 100644
--- a/net/ipv4/route.c
+++ b/net/ipv4/route.c
@@ -1567,11 +1567,10 @@ static int __mkroute_input(struct sk_buff *skb,
 
 	do_cache = res->fi && !itag;
 	if (out_dev == in_dev && err && IN_DEV_TX_REDIRECTS(out_dev) &&
+	    skb->protocol == htons(ETH_P_IP) &&
 	    (IN_DEV_SHARED_MEDIA(out_dev) ||
-	     inet_addr_onlink(out_dev, saddr, FIB_RES_GW(*res)))) {
-		flags |= RTCF_DOREDIRECT;
-		do_cache = false;
-	}
+	     inet_addr_onlink(out_dev, saddr, FIB_RES_GW(*res))))
+		IPCB(skb)->flags |= IPSKB_DOREDIRECT;
 
 	if (skb->protocol != htons(ETH_P_IP)) {
 		/* Not IP (i.e. ARP). Do not create route, if it is
@@ -2316,6 +2315,8 @@ static int rt_fill_info(struct net *net,  __be32 dst, __be32 src,
 	r->rtm_flags	= (rt->rt_flags & ~0xFFFF) | RTM_F_CLONED;
 	if (rt->rt_flags & RTCF_NOTIFY)
 		r->rtm_flags |= RTM_F_NOTIFY;
+	if (IPCB(skb)->flags & IPSKB_DOREDIRECT)
+		r->rtm_flags |= RTCF_DOREDIRECT;
 
 	if (nla_put_be32(skb, RTA_DST, dst))
 		goto nla_put_failure;
-- 
2.1.0

^ permalink raw reply related

* [PATCH] atheros/atlx: Simplify bit manipulations
From: Rasmus Villemoes @ 2015-01-23 11:06 UTC (permalink / raw)
  To: Jay Cliburn, Chris Snook; +Cc: Rasmus Villemoes, netdev, linux-kernel

The code 'if (foo & X) foo &= ~X;' is semantically equivalent to
simply 'foo &= ~X;', but gcc generates about four instructions for the
former, one for the latter. Similarly, if X consists of a single bit,
'if (!(foo & X)) X |= X;' can be replaced by 'foo |= X;'.

In the atl2 case, gcc does know how to merge the new adjacent
operations, so altogether this gives a nice little code size
reduction of about 80 bytes.

Signed-off-by: Rasmus Villemoes <linux@rasmusvillemoes.dk>
---
 drivers/net/ethernet/atheros/atlx/atl1.c |  3 +--
 drivers/net/ethernet/atheros/atlx/atl2.c | 12 ++++--------
 2 files changed, 5 insertions(+), 10 deletions(-)

diff --git a/drivers/net/ethernet/atheros/atlx/atl1.c b/drivers/net/ethernet/atheros/atlx/atl1.c
index 2c8f398aeda9..d9d61d6e8386 100644
--- a/drivers/net/ethernet/atheros/atlx/atl1.c
+++ b/drivers/net/ethernet/atheros/atlx/atl1.c
@@ -1667,8 +1667,7 @@ static void atl1_via_workaround(struct atl1_adapter *adapter)
 	unsigned long value;
 
 	value = ioread16(adapter->hw.hw_addr + PCI_COMMAND);
-	if (value & PCI_COMMAND_INTX_DISABLE)
-		value &= ~PCI_COMMAND_INTX_DISABLE;
+	value &= ~PCI_COMMAND_INTX_DISABLE;
 	iowrite32(value, adapter->hw.hw_addr + PCI_COMMAND);
 }
 
diff --git a/drivers/net/ethernet/atheros/atlx/atl2.c b/drivers/net/ethernet/atheros/atlx/atl2.c
index 84a09e8ddd9c..46d1b959daa8 100644
--- a/drivers/net/ethernet/atheros/atlx/atl2.c
+++ b/drivers/net/ethernet/atheros/atlx/atl2.c
@@ -1278,14 +1278,10 @@ static void atl2_setup_pcicmd(struct pci_dev *pdev)
 
 	pci_read_config_word(pdev, PCI_COMMAND, &cmd);
 
-	if (cmd & PCI_COMMAND_INTX_DISABLE)
-		cmd &= ~PCI_COMMAND_INTX_DISABLE;
-	if (cmd & PCI_COMMAND_IO)
-		cmd &= ~PCI_COMMAND_IO;
-	if (0 == (cmd & PCI_COMMAND_MEMORY))
-		cmd |= PCI_COMMAND_MEMORY;
-	if (0 == (cmd & PCI_COMMAND_MASTER))
-		cmd |= PCI_COMMAND_MASTER;
+	cmd &= ~PCI_COMMAND_INTX_DISABLE;
+	cmd &= ~PCI_COMMAND_IO;
+	cmd |= PCI_COMMAND_MEMORY;
+	cmd |= PCI_COMMAND_MASTER;
 	pci_write_config_word(pdev, PCI_COMMAND, cmd);
 
 	/*
-- 
2.1.3

^ permalink raw reply related

* Re: [net-next PATCH v3 00/12] Flow API
From: Thomas Graf @ 2015-01-23 11:08 UTC (permalink / raw)
  To: Jiri Pirko
  Cc: Jamal Hadi Salim, Pablo Neira Ayuso, John Fastabend, simon.horman,
	sfeldma, netdev, davem, gerlitz.or, andy, ast
In-Reply-To: <20150123102421.GB2065@nanopsycho.orion>

On 01/23/15 at 11:24am, Jiri Pirko wrote:
> I think that comparing this to team or routing userspace is not
> correct. The reason is that team and routing has single api to kernel.
> However in this case userspace has to use multiple APIs.

The point I was trying to make is that there are legitimate reasons
to keep complexity out of the kernel and team is a good example for
that.

As for multiple APIs. Team does in fact export its own Generic Netlink
interface while it also hooks into rtnetlink to support ip link. Not
sure whether that qualifies for multiple APIs or not but I think it's
an excellent architecture decision. Same as for nl80211 tools.

> For example OVS. It would have to use existing OVS gennetlink iface + this
> new flow netlink iface for flow offloads. For all others, this is the same.
> Multiple apis for the same thing (does not matter if it is implemented
> in hw or sw) does not seem right to me.

Fair enough. I have no objections to merging the flow API into RTNETLINK
although I don't really see a need to put more under the rtnl umbrella
unless absolutely required.

I think John also mentioned that he proposes to have this as a separate
Generic Netlink interface for now but this could really live wherever it
seems appropriate.

^ permalink raw reply

* Re: [PATCH] net: Linn Ethernet Packet Sniffer driver
From: Daniel Borkmann @ 2015-01-23 11:20 UTC (permalink / raw)
  To: Stathis Voukelatos
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA,
	linux-kernel-u79uwXL29TY76Z2rM5mHXA,
	devicetree-u79uwXL29TY76Z2rM5mHXA, Stathis Voukelatos,
	abrestic-F7+t8E8rja9g9hUCZPvPmw
In-Reply-To: <1422007621-13567-1-git-send-email-stathis.voukelatos-zgcZaY4qg+21Qrn1Bg8BZw@public.gmane.org>

On 01/23/2015 11:07 AM, Stathis Voukelatos wrote:
> This patch adds support the Ethernet Packet Sniffer H/W module
> developed by Linn Products Ltd and found in the IMG Pistachio SoC.
> The module allows Ethernet packets to be parsed, matched against
> a user-defined pattern and timestamped. It sits between a 100M
> Ethernet MAC and PHY and is completely passive with respect to
> Ethernet frames.
>
> Matched packet bytes and timestamp values are returned through a
> FIFO. Timestamps are provided to the module through an externally
> generated Gray-encoded counter.
>
> The command pattern for packet matching is stored in module RAM
> and consists of a sequence of 16-bit entries. Each entry includes
> an 8-bit command code and and 8-bit data value. Valid command
> codes are:
> 0 - Don't care
> 1 - Match: packet data must match command string byte
> 2 - Copy: packet data will be copied to FIFO
> 3 - Match/Stamp: if packet data matches string byte, a timestamp
>                   is copied into the FIFO
> 4 - Copy/Done: packet data will be copied into the FIFO.
>                 This command terminates the command string.
>
> The driver consists of two modules:
> - Core: it provides an API to user space using the Generic Netlink
>          framework. Specific backend implementations, like the
>          Ethernet Packet Sniffer, register one or more channels
>          with the Core. For each channel a Genl family is created.
>          User space can access a channel by sending Genl messages
>          to the Genl family associated with the channel. Packet
>          matching events are multicast.
>
> - Ethernet Packet Sniffer backend: provides the driver for the
>          Linn Ethernet Packet Sniffer H/W modules.
>
> The split between a core and backend modules allows software-only
> implementations to be added for platforms where no H/W support
> is available.
>
> Based on 3.19-rc5
>
> Signed-off-by: Stathis Voukelatos <stathis.voukelatos-zgcZaY4qg+21Qrn1Bg8BZw@public.gmane.org>

Please have a look at packet sockets, they offer already all the
functionality (if not more) your driver interface to the user space
resembles, are transparent to the underlying hardware, and easily
can cope with 100Mbit.

If I understand this correctly, you are effectively introducing a
parallel API *next* to packet sockets to user space that we have to
maintain forever ...

Thanks !
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply

* RE: [PATCH net-next v3 2/5] swdevice: add new api to set and del bridge port attributes
From: Rosen, Rami @ 2015-01-23 11:24 UTC (permalink / raw)
  To: roopa@cumulusnetworks.com, jiri@resnulli.us, sfeldma@gmail.com,
	jhs@mojatatu.com, bcrl@kvack.org, tgraf@suug.ch,
	john.fastabend@gmail.com, stephen@networkplumber.org,
	vyasevic@redhat.com, Arad, Ronen
  Cc: netdev@vger.kernel.org, davem@davemloft.net,
	shm@cumulusnetworks.com, gospo@cumulusnetworks.com
In-Reply-To: <1421987606-10884-3-git-send-email-roopa@cumulusnetworks.com>

Hi,

Some trivial comments:
+
+/**
+ *	netdev_switch_port_bridge_setlink - Notify switch device port of bridge
+ *	port attributes
+ *
+ *	@dev: port device
+ *	@nlh: netlink msg with bridge port attributes
+ *
+ *	Notify switch device port of bridge port attributes
+ */
+int netdev_switch_port_bridge_setlink(struct net_device *dev,
+				      struct nlmsghdr *nlh, u16 flags) {

- Missing @flags after @nlh above.
- Wouldn't "Notify switch device port of setting bridge port attributes"  or "Notify switch device port of bridge port attributes set" be 
better here (also in terms of being consistent with the description of the netdev_switch_port_bridge_dellink() method later in this patch)? 


+/**
+ *	netdev_switch_port_bridge_dellink - Notify switch device port of bridge
+ *	attribute delete
+ *
+ *	@dev: port device
+ *	@nlh: netlink msg with bridge port attributes
+ *
+ *	Notify switch device port of bridge port attribute delete
+ */
+int netdev_switch_port_bridge_dellink(struct net_device *dev,
+				      struct nlmsghdr *nlh, u16 flags) {

- Again, missing @flags after @nlh for this method also.

Rami Rosen
Intel Corporation

^ permalink raw reply

* Re: [net-next PATCH v3 00/12] Flow API
From: Jiri Pirko @ 2015-01-23 11:39 UTC (permalink / raw)
  To: Thomas Graf
  Cc: Jamal Hadi Salim, Pablo Neira Ayuso, John Fastabend, simon.horman,
	sfeldma, netdev, davem, gerlitz.or, andy, ast
In-Reply-To: <20150123110821.GH25797@casper.infradead.org>

Fri, Jan 23, 2015 at 12:08:21PM CET, tgraf@suug.ch wrote:
>On 01/23/15 at 11:24am, Jiri Pirko wrote:
>> I think that comparing this to team or routing userspace is not
>> correct. The reason is that team and routing has single api to kernel.
>> However in this case userspace has to use multiple APIs.
>
>The point I was trying to make is that there are legitimate reasons
>to keep complexity out of the kernel and team is a good example for
>that.
>
>As for multiple APIs. Team does in fact export its own Generic Netlink
>interface while it also hooks into rtnetlink to support ip link. Not
>sure whether that qualifies for multiple APIs or not but I think it's
>an excellent architecture decision. Same as for nl80211 tools.

Team uses multiple api for sure, but for different things.

>
>> For example OVS. It would have to use existing OVS gennetlink iface + this
>> new flow netlink iface for flow offloads. For all others, this is the same.
>> Multiple apis for the same thing (does not matter if it is implemented
>> in hw or sw) does not seem right to me.
>
>Fair enough. I have no objections to merging the flow API into RTNETLINK
>although I don't really see a need to put more under the rtnl umbrella
>unless absolutely required.
>
>I think John also mentioned that he proposes to have this as a separate
>Generic Netlink interface for now but this could really live wherever it
>seems appropriate.

Maybe I did not express myself correctly. I do not care if this is
exposed by rtnl or a separate genetlink. The issue still stands. And the
issue is that the user have to use "the way A" to setup sw datapath and
"the way B" to setup hw datapath. The preferable would be to have
"the way X" which can be used to setup both sw and hw.

And I believe that could be achieved. Consider something like this:

- have cls_xflows tc classifier and act_xflows tc action as a wrapper
  (or api) for John's work. With possibility for multiple backends. The
  backend iface would looke very similar to what John has now.
- other tc clses and acts will implement xflows backend
- openvswitch datapath will implement xflows backend
- rocker switch will implement xflows backend
- other drivers will implement xflows backend

Now if user wants to manipulate with any flow setting, he can just use
cls_xflows and act_xflows to to that.

This is very rough, but I just wanted to draw the picture. This would
provide single entry to flow world manipulation in kernel, no matter if
sw or hw.

Thoughts?

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).