* [PATCH 0/2] ARM EXYNOS5 & net: add fixed phy support
From: Ming Lei @ 2015-01-23 7:48 UTC (permalink / raw)
To: linux-arm-kernel, David S. Miller
Cc: linux-samsung-soc, Kukjin Kim, netdev, Byungho An,
Florian Fainelli
Hi,
These two patches adds fixed phy support using the fixed-link DT binding
for stmmac.
Thanks,
Ming Lei
^ permalink raw reply
* [PATCH 2/2] net: stmmac: add fixed_phy support via fixed-link DT binding
From: Ming Lei @ 2015-01-23 7:48 UTC (permalink / raw)
To: linux-arm-kernel, David S. Miller
Cc: linux-samsung-soc, Kukjin Kim, netdev, Byungho An,
Florian Fainelli, Ming Lei
In-Reply-To: <1421999305-19267-1-git-send-email-ming.lei@canonical.com>
Signed-off-by: Ming Lei <ming.lei@canonical.com>
---
.../net/ethernet/stmicro/stmmac/stmmac_platform.c | 10 ++++++++++
1 file changed, 10 insertions(+)
diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
index 3039de2..73a3ced 100644
--- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
+++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
@@ -27,6 +27,7 @@
#include <linux/of.h>
#include <linux/of_net.h>
#include <linux/of_device.h>
+#include <linux/of_mdio.h>
#include "stmmac.h"
#include "stmmac_platform.h"
@@ -216,6 +217,15 @@ static int stmmac_probe_config_dt(struct platform_device *pdev,
plat->pmt = 1;
}
+ if (of_phy_is_fixed_link(np)) {
+ int ret = of_phy_register_fixed_link(np);
+ if (ret) {
+ dev_err(&pdev->dev, "failed to register fixed PHY\n");
+ return ret;
+ }
+ plat->phy_bus_name = "fixed";
+ }
+
if (of_device_is_compatible(np, "snps,dwmac-3.610") ||
of_device_is_compatible(np, "snps,dwmac-3.710")) {
plat->enh_desc = 1;
--
1.7.9.5
^ permalink raw reply related
* [PATCH 1/2] ARM: exynos5440-sd5v1: switch to fixed-link DT binding
From: Ming Lei @ 2015-01-23 7:48 UTC (permalink / raw)
To: linux-arm-kernel, David S. Miller
Cc: linux-samsung-soc, Kukjin Kim, netdev, Byungho An,
Florian Fainelli, Ming Lei
In-Reply-To: <1421999305-19267-1-git-send-email-ming.lei@canonical.com>
The previous dts property isn't standard way for fixed phy
support, and switch to the fixed-link DT binding.
Signed-off-by: Ming Lei <ming.lei@canonical.com>
---
arch/arm/boot/dts/exynos5440-sd5v1.dts | 6 ++++--
1 file changed, 4 insertions(+), 2 deletions(-)
diff --git a/arch/arm/boot/dts/exynos5440-sd5v1.dts b/arch/arm/boot/dts/exynos5440-sd5v1.dts
index 268609a..ee65a5c 100644
--- a/arch/arm/boot/dts/exynos5440-sd5v1.dts
+++ b/arch/arm/boot/dts/exynos5440-sd5v1.dts
@@ -28,8 +28,10 @@
};
gmac: ethernet@00230000 {
- fixed_phy;
- phy_addr = <1>;
+ fixed-link {
+ speed = <1000>;
+ full-duplex;
+ };
};
spi {
--
1.7.9.5
^ permalink raw reply related
* Re: [PATCH v1] usbnet: re-use native hex2bin()
From: Oliver Neukum @ 2015-01-23 8:12 UTC (permalink / raw)
To: Andy Shevchenko; +Cc: netdev
In-Reply-To: <1421962032-25497-1-git-send-email-andy.shevchenko@gmail.com>
On Thu, 2015-01-22 at 23:27 +0200, Andy Shevchenko wrote:
> Call hex2bin() library function, instead of doing conversion here.
>
> Signed-off-by: Andy Shevchenko <andy.shevchenko@gmail.com>
Acked-by: Oliver Neukum <oneukum@suse.de>
^ permalink raw reply
* Re: [PATCH 2/2] net: stmmac: add fixed_phy support via fixed-link DT binding
From: Ming Lei @ 2015-01-23 8:28 UTC (permalink / raw)
To: linux-arm-kernel, David S. Miller
Cc: linux-samsung-soc, Kukjin Kim, netdev, Byungho An,
Florian Fainelli, Ming Lei
In-Reply-To: <1421999305-19267-3-git-send-email-ming.lei@canonical.com>
On 1/23/15, Ming Lei <ming.lei@canonical.com> wrote:
> Signed-off-by: Ming Lei <ming.lei@canonical.com>
> ---
> .../net/ethernet/stmicro/stmmac/stmmac_platform.c | 10 ++++++++++
> 1 file changed, 10 insertions(+)
>
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
> b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
> index 3039de2..73a3ced 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_platform.c
> @@ -27,6 +27,7 @@
> #include <linux/of.h>
> #include <linux/of_net.h>
> #include <linux/of_device.h>
> +#include <linux/of_mdio.h>
>
> #include "stmmac.h"
> #include "stmmac_platform.h"
> @@ -216,6 +217,15 @@ static int stmmac_probe_config_dt(struct
> platform_device *pdev,
> plat->pmt = 1;
> }
>
> + if (of_phy_is_fixed_link(np)) {
> + int ret = of_phy_register_fixed_link(np);
> + if (ret) {
> + dev_err(&pdev->dev, "failed to register fixed PHY\n");
> + return ret;
> + }
> + plat->phy_bus_name = "fixed";
> + }
> +
> if (of_device_is_compatible(np, "snps,dwmac-3.610") ||
> of_device_is_compatible(np, "snps,dwmac-3.710")) {
> plat->enh_desc = 1;
Sorry, bypassing check on phy id is missed in this patch, and will
submit v1 later.
Thanks,
Ming Lei
^ permalink raw reply
* [PATCH] net: macb: Remove CONFIG_PM ifdef because of compilation warning
From: Michal Simek @ 2015-01-23 8:36 UTC (permalink / raw)
To: linux-kernel, monstr; +Cc: Nicolas Ferre, netdev
[-- Attachment #1: Type: text/plain, Size: 1563 bytes --]
Fix compilation warning:
drivers/net/ethernet/cadence/macb.c:2415:12: warning: 'macb_suspend'
defined but not used [-Wunused-function]
static int macb_suspend(struct device *dev)
drivers/net/ethernet/cadence/macb.c:2432:12: warning: 'macb_resume'
defined but not used [-Wunused-function]
static int macb_resume(struct device *dev)
when CONFIG_PM=y, CONFIG_PM_SLEEP=n are used.
Signed-off-by: Michal Simek <michal.simek@xilinx.com>
---
drivers/net/ethernet/cadence/macb.c | 6 ++----
1 file changed, 2 insertions(+), 4 deletions(-)
diff --git a/drivers/net/ethernet/cadence/macb.c b/drivers/net/ethernet/cadence/macb.c
index 3767271c7667..23ae32f118c2 100644
--- a/drivers/net/ethernet/cadence/macb.c
+++ b/drivers/net/ethernet/cadence/macb.c
@@ -2411,8 +2411,7 @@ static int __exit macb_remove(struct platform_device *pdev)
return 0;
}
-#ifdef CONFIG_PM
-static int macb_suspend(struct device *dev)
+static int __maybe_unused macb_suspend(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct net_device *netdev = platform_get_drvdata(pdev);
@@ -2429,7 +2428,7 @@ static int macb_suspend(struct device *dev)
return 0;
}
-static int macb_resume(struct device *dev)
+static int __maybe_unused macb_resume(struct device *dev)
{
struct platform_device *pdev = to_platform_device(dev);
struct net_device *netdev = platform_get_drvdata(pdev);
@@ -2444,7 +2443,6 @@ static int macb_resume(struct device *dev)
return 0;
}
-#endif
static SIMPLE_DEV_PM_OPS(macb_pm_ops, macb_suspend, macb_resume);
--
1.8.2.3
[-- Attachment #2: Type: application/pgp-signature, Size: 198 bytes --]
^ permalink raw reply related
* Re: [PATCH] ethernet: atheros: Add nss-gmac driver
From: David Miller @ 2015-01-23 8:54 UTC (permalink / raw)
To: arnd
Cc: wstephen, jcliburn, grant.likely, robh+dt, linux-kernel, netdev,
devicetree
In-Reply-To: <1753817.oBE21Kj2o0@wuerfel>
From: Arnd Bergmann <arnd@arndb.de>
Date: Thu, 22 Jan 2015 11:18:50 +0100
> I see. In this case, I think merging your new driver is not a good idea:
+1
^ permalink raw reply
* Re: [PATCH net-next 0/3] openvswitch: Add STT support.
From: David Miller @ 2015-01-23 9:00 UTC (permalink / raw)
To: therbert; +Cc: vincent.jardin, jesse, pshelar, netdev
In-Reply-To: <CA+mtBx9pnkJBVftqFTK6fcd-toAxsJrvB=drTxWQs_=5s9C0+A@mail.gmail.com>
From: Tom Herbert <therbert@google.com>
Date: Thu, 22 Jan 2015 08:24:15 -0800
> STT is undoubtedly a creative and unique solution I'll give you that,
> but the potential repercussions of allowing this to be widely deployed
> are profound. IMO this needs to be fully explored before it can ever
> be allowed in the kernel. If there has already been discussion on this
> please forward a pointer (I didn't find anything in the IETF mailing
> list archives other than the draft posting announcements), but at the
> minimum these patches warrant a lot of scrutiny.
+1
^ permalink raw reply
* Re: [net-next PATCH v3 00/12] Flow API
From: David Miller @ 2015-01-23 9:00 UTC (permalink / raw)
To: pablo
Cc: tgraf, jhs, john.fastabend, simon.horman, sfeldma, netdev,
gerlitz.or, andy, ast, jiri
In-Reply-To: <20150122164951.GA3417@salvia>
From: Pablo Neira Ayuso <pablo@netfilter.org>
Date: Thu, 22 Jan 2015 17:49:51 +0100
> I think those vendors do not want to push those driver changes
> mainstream. They will likely use these new ndo's to fully expose their
> vendor-specific capabilities distributed in proprietary blobs.
+1
^ permalink raw reply
* Re: [PATCH net-next 0/3] openvswitch: Add STT support.
From: David Miller @ 2015-01-23 9:04 UTC (permalink / raw)
To: vincent.jardin; +Cc: therbert, jesse, pshelar, netdev
In-Reply-To: <54C138BB.7000407@6wind.com>
From: Vincent JARDIN <vincent.jardin@6wind.com>
Date: Thu, 22 Jan 2015 18:51:55 +0100
> Same: LRO/GRO is is bad features: it breaks many times networking
> (most IP forwarders must disable it), but it helps for servers. Same
> for STT in fact, it has its narrow set of use-cases which are valid.
False, GRO helps for forwarders too, because it decreases the number
of IP route lookups, one of the most expensive operations during
formwarding.
Please do not spread misinformation, and especially do not try to show
that GRO is in _ANY_ way something like STT. That's completely wrong.
^ permalink raw reply
* [PATCH] net: ieee802154: cc2520: Fix coding style issues
From: Mohammad Jamal @ 2015-01-23 9:26 UTC (permalink / raw)
To: varkabhadram, alex.aring, linux-wpan, netdev, linux-kernel; +Cc: Mohammad Jamal
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
^ permalink raw reply related
* [PATCH] net: ieee802154: cc2520: fix coding style issue
From: Mohammad Jamal @ 2015-01-23 9:36 UTC (permalink / raw)
To: varkabhadram, alex.aring, linux-wpan, netdev, linux-kernel; +Cc: Mohammad Jamal
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
^ permalink raw reply related
* 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
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox