* Re: [net-next PATCH v3 00/12] Flow API
From: Jamal Hadi Salim @ 2015-01-22 15:00 UTC (permalink / raw)
To: Pablo Neira Ayuso, Thomas Graf
Cc: John Fastabend, simon.horman, sfeldma, netdev, davem, gerlitz.or,
andy, ast, Jiri Pirko
In-Reply-To: <20150122140022.GA5674@salvia>
On 01/22/15 09:00, Pablo Neira Ayuso wrote:
>
> +/* rocker specific action definitions */
> +struct net_flow_action_arg rocker_set_group_id_args[] = {
> + {
> + .name = "group_id",
> + .type = NFL_ACTION_ARG_TYPE_U32,
> + .value_u32 = 0,
> + },
>
> that is retrieved via ndo_flow_get_actions and fully exposed to
> userspace.
>
My main concern is along similar lines (I did express it earlier and
I think Jiri chimed in as well).
The API exposes direct access to hardware. I am sure this was a result
of trying to replace the ethtool interface (which was primitive).
By providing vendors direct access to the hardware - they do not need
to use any traditional Linux tooling/APIs. 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.
Interfacing tc or nftables (or pick your favorite linux tool here) would
be preferable.
cheers,
jamal
^ permalink raw reply
* Re: [PATCH net 4/4] sh_eth: Fix serialisation of interrupt disable with interrupt & NAPI handlers
From: Ben Hutchings @ 2015-01-22 15:06 UTC (permalink / raw)
To: Sergei Shtylyov
Cc: David S.Miller, netdev, linux-kernel, Nobuhiro Iwamatsu,
Mitsuhiro Kimura, Hisashi Nakamura, Yoshihiro Kaneko
In-Reply-To: <54C1002D.7090508@cogentembedded.com>
On Thu, 2015-01-22 at 16:50 +0300, Sergei Shtylyov wrote:
> Hello.
>
> On 1/22/2015 3:44 PM, Ben Hutchings wrote:
>
> > In order to stop the RX path accessing the RX ring while it's being
> > stopped or resized, we clear the interrupt mask (EESIPR) and then call
> > free_irq() or synchronise_irq(). This is insufficient because the
> > interrupt handler or NAPI poller may set EESIPR again after we clear
> > it.
>
> Hm, how come the interrupt handler gets called when we have disabled all
> interrupts?
It may be running on another processor and racing with the function that
clears EESIPR.
> Is it unmaskable EESR.ECI interrupt? BTW, I'm not seeing where the
> interrupt handler enables interrupts again; only NAPI poller does that AFAIK.
Normally it only clears EESR_RX_CHECK, but as it cannot atomically clear
a single bit of EESIPR this can result in setting other bits.
> > Also, in sh_eth_set_ringparam() we currently don't disable NAPI
> > polling at all.
>
> > I could easily trigger a crash by running the loop:
>
> > while ethtool -G eth0 rx 128 && ethtool -G eth0 rx 64; do echo -n .; done
>
> Oh, never done any 'ethtool' tests...
You should also be able to trigger this by bringing the device up and
down, but you have to wait for the PHY to bring the link up before any
packets will be received in between. Thus each cycle takes longer.
[...]
> > diff --git a/drivers/net/ethernet/renesas/sh_eth.h b/drivers/net/ethernet/renesas/sh_eth.h
> > index 7bfaf1c..259d03f 100644
> > --- a/drivers/net/ethernet/renesas/sh_eth.h
> > +++ b/drivers/net/ethernet/renesas/sh_eth.h
> > @@ -513,6 +513,7 @@ struct sh_eth_private {
> > u32 rx_buf_sz; /* Based on MTU+slack. */
> > int edmac_endian;
> > struct napi_struct napi;
> > + bool irq_enabled;
> > /* MII transceiver section. */
> > u32 phy_id; /* PHY ID */
> > struct mii_bus *mii_bus; /* MDIO bus control */
>
> In order to conserve space, I'd have added that field after
> 'vlan_num_ids', just before the 1-bit fields...
I don't think it's worth micro-optimising the size of a per-device
structure.
Ben.
^ permalink raw reply
* Re: [net-next PATCH v3 00/12] Flow API
From: Thomas Graf @ 2015-01-22 15:13 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: <54C11094.2000807@mojatatu.com>
On 01/22/15 at 10:00am, Jamal Hadi Salim wrote:
> On 01/22/15 09:00, Pablo Neira Ayuso wrote:
>
> >
> >+/* rocker specific action definitions */
> >+struct net_flow_action_arg rocker_set_group_id_args[] = {
> >+ {
> >+ .name = "group_id",
> >+ .type = NFL_ACTION_ARG_TYPE_U32,
> >+ .value_u32 = 0,
> >+ },
> >
> >that is retrieved via ndo_flow_get_actions and fully exposed to
> >userspace.
> >
>
> My main concern is along similar lines (I did express it earlier and
> I think Jiri chimed in as well).
> The API exposes direct access to hardware. I am sure this was a result
> of trying to replace the ethtool interface (which was primitive).
> By providing vendors direct access to the hardware - they do not need
> to use any traditional Linux tooling/APIs.
I don't follow this. John's proposal allows to decide on a case by
case basis what we want to export. Just like with ethtool or
RTNETLINK. There is no direct access to hardware. A user can only
configure what is being exposed by the kernel.
Pablo raises an interesting point though. How do we handle unique
features like Rocker groups.
Maybe Jiri and Scott can chime in and describe if we can map this to
something more generic and avoid exporting anything Rocker specific.
What would a rocker group map to in the tc world?
> 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.
^ permalink raw reply
* Re: [patch net-next RFC] tc: introduce OpenFlow classifier
From: Jiri Pirko @ 2015-01-22 15:25 UTC (permalink / raw)
To: Rosen, Rami; +Cc: netdev@vger.kernel.org, davem@davemloft.net, jhs@mojatatu.com
In-Reply-To: <9B0331B6EBBD0E4684FBFAEDA55776F918903CD5@HASMSX110.ger.corp.intel.com>
Thu, Jan 22, 2015 at 02:48:29PM CET, rami.rosen@intel.com wrote:
>+config NET_CLS_OPENFLOW
>+ tristate "OpenFlow classifier"
>+ select NET_CLS
>+ ---help---
>+ If you say Y here, you will be able to classify packets based on
>+ a configurable combination of packet keys and masks accordint to
>+ OpenFlow standard.
>+
>
>Should be: according to
I fixed this in my git. Thanks!
>
>Regards,
>Rami Rosen
>
^ permalink raw reply
* [PATCH 0/4] NFC: nxp-nci: Add support for NXP-NCI NFC controllers
From: clement.perrochaud-BPEPtVrvniRWk0Htik3J/w @ 2015-01-22 15:27 UTC (permalink / raw)
To: linux-nfc-hn68Rpc1hR1g9hUCZPvPmw
Cc: Clément Perrochaud, sunil.jogi-3arQi8VN3Tc,
jerome.pele-3arQi8VN3Tc, Charles.Gorand-Effinnov-3arQi8VN3Tc,
lauro.venancio-430g2QfJUUCGglJvpFV4uA,
aloisio.almeida-430g2QfJUUCGglJvpFV4uA,
sameo-VuQAYsv1563Yd54FQh9/CA, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
pawel.moll-5wv7dgnIgG8, mark.rutland-5wv7dgnIgG8,
ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
galak-sgV2jX0FEOL9JmXXK+q4OQ, davem-fT/PcQaiUtIeIZ0/mPfg9Q,
grant.likely-QSEj5FYQhm4dnm+yROfE0A,
clement.perrochaud-3arQi8VN3Tc, lefrique-eYqpPyKDWXRBDgjK7y7TUQ,
christophe.ricard-Re5JQEeQqe8AvxtiuMwx3w,
cuissard-eYqpPyKDWXRBDgjK7y7TUQ, bzhao-eYqpPyKDWXRBDgjK7y7TUQ,
hirent-eYqpPyKDWXRBDgjK7y7TUQ, akarwar-eYqpPyKDWXRBDgjK7y7TUQ,
linux-wireless-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA
From: Clément Perrochaud <clement.perrochaud-BPEPtVrvniRWk0Htik3J/w@public.gmane.org>
This patch brings support for the NXP-NCI NFC controllers family.
It has been successfully tested on the following SoC boards:
- BeagleBone
- BeagleBone Black
- Raspberry Pi B
- Raspberry Pi B+
The submission is broken into four patches:
- The first one adds firmware download support to NCI ;
- The second one adds the NXP-NCI driver's core ;
- The third one adds I2C support to the driver ;
- The fourth one allows for module removal during download.
It is based on 767dec21d7f5a9787401ff44568852cb3782de64 (Merge tag
'nfc-next-3.19-1' of nfc-next into wireless-next) from the nfc-next master
branch.
Clément Perrochaud (4):
NFC: nci: Add FWDL support
NFC: nxp-nci: Add support for NXP NCI chips
NFC: nxp-nci_i2c: Add I2C support to NXP NCI driver
NFC: nxp-nci: Allow module removal during download
.../devicetree/bindings/net/nfc/nxp-nci.txt | 35 ++
MAINTAINERS | 9 +-
drivers/nfc/Kconfig | 2 +
drivers/nfc/Makefile | 1 +
drivers/nfc/nxp-nci/Kconfig | 24 ++
drivers/nfc/nxp-nci/Makefile | 11 +
drivers/nfc/nxp-nci/core.c | 186 ++++++++
drivers/nfc/nxp-nci/firmware.c | 324 ++++++++++++++
drivers/nfc/nxp-nci/i2c.c | 468 +++++++++++++++++++++
drivers/nfc/nxp-nci/nxp-nci.h | 91 ++++
include/linux/platform_data/nxp-nci.h | 27 ++
include/net/nfc/nci_core.h | 1 +
net/nfc/nci/core.c | 11 +
13 files changed, 1189 insertions(+), 1 deletion(-)
create mode 100644 Documentation/devicetree/bindings/net/nfc/nxp-nci.txt
create mode 100644 drivers/nfc/nxp-nci/Kconfig
create mode 100644 drivers/nfc/nxp-nci/Makefile
create mode 100644 drivers/nfc/nxp-nci/core.c
create mode 100644 drivers/nfc/nxp-nci/firmware.c
create mode 100644 drivers/nfc/nxp-nci/i2c.c
create mode 100644 drivers/nfc/nxp-nci/nxp-nci.h
create mode 100644 include/linux/platform_data/nxp-nci.h
--
Clément Perrochaud
Eff'Innov Technologies
Caen, Aix-En-Provence, Grenoble
Eff'Innov Technologies
Campus EffiScience
2, Esplanade Anton Philips
14460 Colombelles, FRANCE
http://www.effinnov.com
--
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
* [PATCH 1/4] NFC: nci: Add FWDL support
From: clement.perrochaud-BPEPtVrvniRWk0Htik3J/w @ 2015-01-22 15:27 UTC (permalink / raw)
To: linux-nfc-hn68Rpc1hR1g9hUCZPvPmw
Cc: Clément Perrochaud, sunil.jogi-3arQi8VN3Tc,
jerome.pele-3arQi8VN3Tc, Charles.Gorand-Effinnov-3arQi8VN3Tc,
lauro.venancio-430g2QfJUUCGglJvpFV4uA,
aloisio.almeida-430g2QfJUUCGglJvpFV4uA,
sameo-VuQAYsv1563Yd54FQh9/CA, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
pawel.moll-5wv7dgnIgG8, mark.rutland-5wv7dgnIgG8,
ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
galak-sgV2jX0FEOL9JmXXK+q4OQ, davem-fT/PcQaiUtIeIZ0/mPfg9Q,
grant.likely-QSEj5FYQhm4dnm+yROfE0A,
lefrique-eYqpPyKDWXRBDgjK7y7TUQ,
christophe.ricard-Re5JQEeQqe8AvxtiuMwx3w,
cuissard-eYqpPyKDWXRBDgjK7y7TUQ, bzhao-eYqpPyKDWXRBDgjK7y7TUQ,
hirent-eYqpPyKDWXRBDgjK7y7TUQ, akarwar-eYqpPyKDWXRBDgjK7y7TUQ,
linux-wireless-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA, Clément Perrochaud
In-Reply-To: <1421940460-14049-1-git-send-email-clement.perrochaud-BPEPtVrvniRWk0Htik3J/w@public.gmane.org>
From: Clément Perrochaud <clement.perrochaud-3arQi8VN3Tc@public.gmane.org>
Signed-off-by: Clément Perrochaud <clement.perrochaud-3arQi8VN3Tc@public.gmane.org>
Signed-off-by: Clément Perrochaud <clement.perrochaud-BPEPtVrvniRWk0Htik3J/w@public.gmane.org>
---
include/net/nfc/nci_core.h | 1 +
net/nfc/nci/core.c | 11 +++++++++++
2 files changed, 12 insertions(+)
diff --git a/include/net/nfc/nci_core.h b/include/net/nfc/nci_core.h
index 9e51bb4..137e059 100644
--- a/include/net/nfc/nci_core.h
+++ b/include/net/nfc/nci_core.h
@@ -71,6 +71,7 @@ struct nci_ops {
int (*close)(struct nci_dev *ndev);
int (*send)(struct nci_dev *ndev, struct sk_buff *skb);
int (*setup)(struct nci_dev *ndev);
+ int (*fw_download)(struct nci_dev *ndev, const char *firmware_name);
__u32 (*get_rfprotocol)(struct nci_dev *ndev, __u8 rf_protocol);
int (*discover_se)(struct nci_dev *ndev);
int (*disable_se)(struct nci_dev *ndev, u32 se_idx);
diff --git a/net/nfc/nci/core.c b/net/nfc/nci/core.c
index 51feb5e..1342c7d 100644
--- a/net/nfc/nci/core.c
+++ b/net/nfc/nci/core.c
@@ -789,6 +789,16 @@ static int nci_se_io(struct nfc_dev *nfc_dev, u32 se_idx,
return 0;
}
+static int nci_fw_download(struct nfc_dev *nfc_dev, const char *firmware_name)
+{
+ struct nci_dev *ndev = nfc_get_drvdata(nfc_dev);
+
+ if (!ndev->ops->fw_download)
+ return -ENOTSUPP;
+
+ return ndev->ops->fw_download(ndev, firmware_name);
+}
+
static struct nfc_ops nci_nfc_ops = {
.dev_up = nci_dev_up,
.dev_down = nci_dev_down,
@@ -804,6 +814,7 @@ static struct nfc_ops nci_nfc_ops = {
.disable_se = nci_disable_se,
.discover_se = nci_discover_se,
.se_io = nci_se_io,
+ .fw_download = nci_fw_download,
};
/* ---- Interface to NCI drivers ---- */
--
Clément Perrochaud
Eff'Innov Technologies
Caen, Aix-En-Provence, Grenoble
Eff'Innov Technologies
Campus EffiScience
2, Esplanade Anton Philips
14460 Colombelles, FRANCE
http://www.effinnov.com
--
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 related
* [PATCH 2/4] NFC: nxp-nci: Add support for NXP NCI chips
From: clement.perrochaud-BPEPtVrvniRWk0Htik3J/w @ 2015-01-22 15:27 UTC (permalink / raw)
To: linux-nfc-hn68Rpc1hR1g9hUCZPvPmw
Cc: Clément Perrochaud, sunil.jogi-3arQi8VN3Tc,
jerome.pele-3arQi8VN3Tc, Charles.Gorand-Effinnov-3arQi8VN3Tc,
lauro.venancio-430g2QfJUUCGglJvpFV4uA,
aloisio.almeida-430g2QfJUUCGglJvpFV4uA,
sameo-VuQAYsv1563Yd54FQh9/CA, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
pawel.moll-5wv7dgnIgG8, mark.rutland-5wv7dgnIgG8,
ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
galak-sgV2jX0FEOL9JmXXK+q4OQ, davem-fT/PcQaiUtIeIZ0/mPfg9Q,
grant.likely-QSEj5FYQhm4dnm+yROfE0A,
lefrique-eYqpPyKDWXRBDgjK7y7TUQ,
christophe.ricard-Re5JQEeQqe8AvxtiuMwx3w,
cuissard-eYqpPyKDWXRBDgjK7y7TUQ, bzhao-eYqpPyKDWXRBDgjK7y7TUQ,
hirent-eYqpPyKDWXRBDgjK7y7TUQ, akarwar-eYqpPyKDWXRBDgjK7y7TUQ,
linux-wireless-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA, Clément Perrochaud
In-Reply-To: <1421940460-14049-1-git-send-email-clement.perrochaud-BPEPtVrvniRWk0Htik3J/w@public.gmane.org>
From: Clément Perrochaud <clement.perrochaud-3arQi8VN3Tc@public.gmane.org>
Add support for NXP NCI NFC controllers.
Signed-off-by: Clément Perrochaud <clement.perrochaud-3arQi8VN3Tc@public.gmane.org>
Signed-off-by: Clément Perrochaud <clement.perrochaud-BPEPtVrvniRWk0Htik3J/w@public.gmane.org>
---
MAINTAINERS | 9 +-
drivers/nfc/Kconfig | 2 +
drivers/nfc/Makefile | 1 +
drivers/nfc/nxp-nci/Kconfig | 12 ++
drivers/nfc/nxp-nci/Makefile | 9 +
drivers/nfc/nxp-nci/core.c | 187 ++++++++++++++++++++
drivers/nfc/nxp-nci/firmware.c | 321 ++++++++++++++++++++++++++++++++++
drivers/nfc/nxp-nci/nxp-nci.h | 91 ++++++++++
include/linux/platform_data/nxp-nci.h | 27 +++
9 files changed, 658 insertions(+), 1 deletion(-)
create mode 100644 drivers/nfc/nxp-nci/Kconfig
create mode 100644 drivers/nfc/nxp-nci/Makefile
create mode 100644 drivers/nfc/nxp-nci/core.c
create mode 100644 drivers/nfc/nxp-nci/firmware.c
create mode 100644 drivers/nfc/nxp-nci/nxp-nci.h
create mode 100644 include/linux/platform_data/nxp-nci.h
diff --git a/MAINTAINERS b/MAINTAINERS
index 7ec37a3..48b92f3 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -686,7 +686,7 @@ L: alsa-devel-K7yf7f+aM1XWsZ/bQMPhNw@public.gmane.org (moderated for non-subscribers)
W: http://blackfin.uclinux.org/
S: Supported
F: sound/soc/blackfin/*
-
+
ANALOG DEVICES INC IIO DRIVERS
M: Lars-Peter Clausen <lars-Qo5EllUWu/uELgA04lAiVw@public.gmane.org>
M: Michael Hennerich <Michael.Hennerich-OyLXuOCK7orQT0dZR+AlfA@public.gmane.org>
@@ -6577,6 +6577,13 @@ S: Supported
F: drivers/block/nvme*
F: include/linux/nvme.h
+NXP-NCI NFC DRIVER
+M: Clément Perrochaud <clement.perrochaud-BPEPtVrvniRWk0Htik3J/w@public.gmane.org>
+R: Charles Gorand <charles.gorand-BPEPtVrvniRWk0Htik3J/w@public.gmane.org>
+L: linux-nfc-hn68Rpc1hR1g9hUCZPvPmw@public.gmane.org (moderated for non-subscribers)
+S: Supported
+F: drivers/nfc/nxp-nci
+
NXP TDA998X DRM DRIVER
M: Russell King <rmk+kernel-lFZ/pmaqli7XmaaqVzeoHQ@public.gmane.org>
S: Supported
diff --git a/drivers/nfc/Kconfig b/drivers/nfc/Kconfig
index 7929fac..3da31e9 100644
--- a/drivers/nfc/Kconfig
+++ b/drivers/nfc/Kconfig
@@ -73,4 +73,6 @@ source "drivers/nfc/microread/Kconfig"
source "drivers/nfc/nfcmrvl/Kconfig"
source "drivers/nfc/st21nfca/Kconfig"
source "drivers/nfc/st21nfcb/Kconfig"
+source "drivers/nfc/nxp-nci/Kconfig"
+
endmenu
diff --git a/drivers/nfc/Makefile b/drivers/nfc/Makefile
index 6b23a2c..a4292d79 100644
--- a/drivers/nfc/Makefile
+++ b/drivers/nfc/Makefile
@@ -13,5 +13,6 @@ obj-$(CONFIG_NFC_MRVL) += nfcmrvl/
obj-$(CONFIG_NFC_TRF7970A) += trf7970a.o
obj-$(CONFIG_NFC_ST21NFCA) += st21nfca/
obj-$(CONFIG_NFC_ST21NFCB) += st21nfcb/
+obj-$(CONFIG_NFC_NXP_NCI) += nxp-nci/
ccflags-$(CONFIG_NFC_DEBUG) := -DDEBUG
diff --git a/drivers/nfc/nxp-nci/Kconfig b/drivers/nfc/nxp-nci/Kconfig
new file mode 100644
index 0000000..5107edd
--- /dev/null
+++ b/drivers/nfc/nxp-nci/Kconfig
@@ -0,0 +1,12 @@
+config NFC_NXP_NCI
+ tristate "NXP-NCI NFC driver"
+ depends on NFC_NCI
+ default n
+ ---help---
+ Generic core driver for NXP NCI chips.
+ This is a driver based on the NCI NFC kernel layers and
+ will thus not work with NXP libnfc library.
+
+ To compile this driver as a module, choose m here. The module will
+ be called nxp_nci.
+ Say N if unsure.
diff --git a/drivers/nfc/nxp-nci/Makefile b/drivers/nfc/nxp-nci/Makefile
new file mode 100644
index 0000000..8f1e328
--- /dev/null
+++ b/drivers/nfc/nxp-nci/Makefile
@@ -0,0 +1,9 @@
+#
+# Makefile for NXP-NCI NFC driver
+#
+
+nxp-nci-objs = core.o firmware.o
+
+obj-$(CONFIG_NFC_NXP_NCI) += nxp-nci.o
+
+ccflags-$(CONFIG_NFC_DEBUG) := -DDEBUG
diff --git a/drivers/nfc/nxp-nci/core.c b/drivers/nfc/nxp-nci/core.c
new file mode 100644
index 0000000..d3643ef
--- /dev/null
+++ b/drivers/nfc/nxp-nci/core.c
@@ -0,0 +1,187 @@
+/*
+ * Generic driver for NXP NCI NFC chips
+ *
+ * Copyright (C) 2014 NXP Semiconductors All rights reserved.
+ *
+ * Authors: Clément Perrochaud <clement.perrochaud-3arQi8VN3Tc@public.gmane.org>
+ *
+ * Derived from PN544 device driver:
+ * Copyright (C) 2012 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/delay.h>
+#include <linux/gpio.h>
+#include <linux/module.h>
+#include <linux/nfc.h>
+#include <linux/platform_data/nxp-nci.h>
+
+#include <net/nfc/nci_core.h>
+
+#include "nxp-nci.h"
+
+#define NXP_NCI_HDR_LEN 4
+
+#define NXP_NCI_NFC_PROTOCOLS (NFC_PROTO_JEWEL_MASK | \
+ NFC_PROTO_MIFARE_MASK | \
+ NFC_PROTO_FELICA_MASK | \
+ NFC_PROTO_ISO14443_MASK | \
+ NFC_PROTO_ISO14443_B_MASK | \
+ NFC_PROTO_NFC_DEP_MASK)
+
+static int nxp_nci_open(struct nci_dev *ndev)
+{
+ struct nxp_nci_info *info = nci_get_drvdata(ndev);
+ int r = 0;
+
+ mutex_lock(&info->info_lock);
+
+ if (info->mode != NXP_NCI_MODE_COLD) {
+ r = -EBUSY;
+ goto open_exit;
+ }
+
+ if (info->phy_ops->enable)
+ r = info->phy_ops->enable(info->phy_id);
+
+ info->mode = NXP_NCI_MODE_NCI;
+
+open_exit:
+ mutex_unlock(&info->info_lock);
+ return r;
+}
+
+static int nxp_nci_close(struct nci_dev *ndev)
+{
+ struct nxp_nci_info *info = nci_get_drvdata(ndev);
+ int r = 0;
+
+ mutex_lock(&info->info_lock);
+
+ if (info->phy_ops->disable)
+ r = info->phy_ops->disable(info->phy_id);
+
+ info->mode = NXP_NCI_MODE_COLD;
+
+ mutex_unlock(&info->info_lock);
+ return r;
+}
+
+static int nxp_nci_send(struct nci_dev *ndev, struct sk_buff *skb)
+{
+ struct nxp_nci_info *info = nci_get_drvdata(ndev);
+ int r;
+
+ if (!info->phy_ops->write) {
+ r = -ENOTSUPP;
+ goto send_exit;
+ }
+
+ if (info->mode != NXP_NCI_MODE_NCI) {
+ r = -EINVAL;
+ goto send_exit;
+ }
+
+ r = info->phy_ops->write(info->phy_id, skb);
+ if (r < 0)
+ kfree_skb(skb);
+
+send_exit:
+ return r;
+}
+
+static struct nci_ops nxp_nci_ops = {
+ .open = nxp_nci_open,
+ .close = nxp_nci_close,
+ .send = nxp_nci_send,
+ .fw_download = nxp_nci_fw_download,
+};
+
+int nxp_nci_probe(void *phy_id, struct device *pdev,
+ struct nxp_nci_phy_ops *phy_ops, unsigned int max_payload,
+ struct nci_dev **ndev)
+{
+ struct nxp_nci_info *info;
+ int r;
+
+ info = devm_kzalloc(pdev, sizeof(struct nxp_nci_info), GFP_KERNEL);
+ if (!info) {
+ r = -ENOMEM;
+ goto probe_exit;
+ }
+
+ info->phy_id = phy_id;
+ info->pdev = pdev;
+ info->phy_ops = phy_ops;
+ info->max_payload = max_payload;
+ INIT_WORK(&info->fw_info.work, nxp_nci_fw_work);
+ init_completion(&info->fw_info.cmd_completion);
+ mutex_init(&info->info_lock);
+
+ if (info->phy_ops->disable) {
+ r = info->phy_ops->disable(info->phy_id);
+ if (r < 0)
+ goto probe_exit;
+ }
+
+ info->mode = NXP_NCI_MODE_COLD;
+
+ info->ndev = nci_allocate_device(&nxp_nci_ops, NXP_NCI_NFC_PROTOCOLS,
+ NXP_NCI_HDR_LEN, 0);
+ if (!info->ndev) {
+ r = -ENOMEM;
+ goto probe_exit;
+ }
+
+ nci_set_parent_dev(info->ndev, pdev);
+ nci_set_drvdata(info->ndev, info);
+ r = nci_register_device(info->ndev);
+ if (r < 0)
+ goto probe_exit_free_nci;
+
+ *ndev = info->ndev;
+
+ goto probe_exit;
+
+probe_exit_free_nci:
+ nci_free_device(info->ndev);
+probe_exit:
+ return r;
+}
+EXPORT_SYMBOL(nxp_nci_probe);
+
+void nxp_nci_remove(struct nci_dev *ndev)
+{
+ struct nxp_nci_info *info = nci_get_drvdata(ndev);
+
+ mutex_lock(&info->info_lock);
+
+ cancel_work_sync(&info->fw_info.work);
+
+ if (info->mode == NXP_NCI_MODE_FW)
+ nxp_nci_fw_work_complete(info, -ESHUTDOWN);
+
+ if (info->phy_ops->disable)
+ info->phy_ops->disable(info->phy_id);
+
+ nci_unregister_device(ndev);
+ nci_free_device(ndev);
+
+ mutex_unlock(&info->info_lock);
+}
+EXPORT_SYMBOL(nxp_nci_remove);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("NXP NCI NFC driver");
+MODULE_AUTHOR("Clément Perrochaud <clement.perrochaud-3arQi8VN3Tc@public.gmane.org>");
diff --git a/drivers/nfc/nxp-nci/firmware.c b/drivers/nfc/nxp-nci/firmware.c
new file mode 100644
index 0000000..1814e9f
--- /dev/null
+++ b/drivers/nfc/nxp-nci/firmware.c
@@ -0,0 +1,321 @@
+/*
+ * Generic driver for NXP NCI NFC chips
+ *
+ * Copyright (C) 2014 NXP Semiconductors All rights reserved.
+ *
+ * Author: Clément Perrochaud <clement.perrochaud-3arQi8VN3Tc@public.gmane.org>
+ *
+ * Derived from PN544 device driver:
+ * Copyright (C) 2012 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/completion.h>
+#include <linux/firmware.h>
+#include <linux/nfc.h>
+#include <linux/unaligned/access_ok.h>
+
+#include "nxp-nci.h"
+
+/* Crypto operations can take up to 30 seconds */
+#define NXP_NCI_FW_ANSWER_TIMEOUT msecs_to_jiffies(30000)
+
+#define NXP_NCI_FW_CMD_RESET 0xF0
+#define NXP_NCI_FW_CMD_GETVERSION 0xF1
+#define NXP_NCI_FW_CMD_CHECKINTEGRITY 0xE0
+#define NXP_NCI_FW_CMD_WRITE 0xC0
+#define NXP_NCI_FW_CMD_READ 0xA2
+#define NXP_NCI_FW_CMD_GETSESSIONSTATE 0xF2
+#define NXP_NCI_FW_CMD_LOG 0xA7
+#define NXP_NCI_FW_CMD_FORCE 0xD0
+#define NXP_NCI_FW_CMD_GET_DIE_ID 0xF4
+
+#define NXP_NCI_FW_CHUNK_FLAG 0x0400
+
+#define NXP_NCI_FW_RESULT_OK 0x00
+#define NXP_NCI_FW_RESULT_INVALID_ADDR 0x01
+#define NXP_NCI_FW_RESULT_GENERIC_ERROR 0x02
+#define NXP_NCI_FW_RESULT_UNKNOWN_CMD 0x0B
+#define NXP_NCI_FW_RESULT_ABORTED_CMD 0x0C
+#define NXP_NCI_FW_RESULT_PLL_ERROR 0x0D
+#define NXP_NCI_FW_RESULT_ADDR_RANGE_OFL_ERROR 0x1E
+#define NXP_NCI_FW_RESULT_BUFFER_OFL_ERROR 0x1F
+#define NXP_NCI_FW_RESULT_MEM_BSY 0x20
+#define NXP_NCI_FW_RESULT_SIGNATURE_ERROR 0x21
+#define NXP_NCI_FW_RESULT_FIRMWARE_VERSION_ERROR 0x24
+#define NXP_NCI_FW_RESULT_PROTOCOL_ERROR 0x28
+#define NXP_NCI_FW_RESULT_SFWU_DEGRADED 0x2A
+#define NXP_NCI_FW_RESULT_PH_STATUS_FIRST_CHUNK 0x2D
+#define NXP_NCI_FW_RESULT_PH_STATUS_NEXT_CHUNK 0x2E
+#define NXP_NCI_FW_RESULT_PH_STATUS_INTERNAL_ERROR_5 0xC5
+
+void nxp_nci_fw_work_complete(struct nxp_nci_info *info, int result)
+{
+ struct nxp_nci_fw_info *fw_info = &info->fw_info;
+ int r;
+
+ if (info->phy_ops->disable) {
+ r = info->phy_ops->disable(info->phy_id);
+ if (r < 0 && result == 0)
+ result = -r;
+ }
+
+ info->mode = NXP_NCI_MODE_COLD;
+
+ if (fw_info->fw) {
+ release_firmware(fw_info->fw);
+ fw_info->fw = NULL;
+ }
+
+ nfc_fw_download_done(info->ndev->nfc_dev, fw_info->name, (u32) -result);
+}
+
+/* crc_ccitt cannot be used since it is computed MSB first and not LSB first */
+static u16 nxp_nci_fw_crc(u8 const *buffer, size_t len)
+{
+ u16 crc = 0xffff;
+
+ while (len--) {
+ crc = ((crc >> 8) | (crc << 8)) ^ *buffer++;
+ crc ^= (crc & 0xff) >> 4;
+ crc ^= (crc & 0xff) << 12;
+ crc ^= (crc & 0xff) << 5;
+ }
+
+ return crc;
+}
+
+static int nxp_nci_fw_send_chunk(struct nxp_nci_info *info)
+{
+ struct nxp_nci_fw_info *fw_info = &info->fw_info;
+ u16 header, crc;
+ struct sk_buff *skb;
+ size_t chunk_len;
+ size_t remaining_len;
+ int r;
+
+ skb = nci_skb_alloc(info->ndev, info->max_payload, GFP_KERNEL);
+ if (!skb) {
+ r = -ENOMEM;
+ goto chunk_exit;
+ }
+
+ chunk_len = info->max_payload - NXP_NCI_FW_HDR_LEN - NXP_NCI_FW_CRC_LEN;
+ remaining_len = fw_info->frame_size - fw_info->written;
+
+ if (remaining_len > chunk_len) {
+ header = NXP_NCI_FW_CHUNK_FLAG;
+ } else {
+ chunk_len = remaining_len;
+ header = 0x0000;
+ }
+
+ header |= chunk_len & NXP_NCI_FW_FRAME_LEN_MASK;
+ put_unaligned_be16(header, skb_put(skb, NXP_NCI_FW_HDR_LEN));
+
+ memcpy(skb_put(skb, chunk_len), fw_info->data + fw_info->written,
+ chunk_len);
+
+ crc = nxp_nci_fw_crc(skb->data, chunk_len + NXP_NCI_FW_HDR_LEN);
+ put_unaligned_be16(crc, skb_put(skb, NXP_NCI_FW_CRC_LEN));
+
+ r = info->phy_ops->write(info->phy_id, skb);
+ if (r >= 0)
+ r = chunk_len;
+
+ kfree_skb(skb);
+
+chunk_exit:
+ return r;
+}
+
+static int nxp_nci_fw_send(struct nxp_nci_info *info)
+{
+ struct nxp_nci_fw_info *fw_info = &info->fw_info;
+ long completion_rc;
+ int r;
+
+ reinit_completion(&fw_info->cmd_completion);
+
+ if (fw_info->written == 0) {
+ fw_info->frame_size = get_unaligned_be16(fw_info->data) &
+ NXP_NCI_FW_FRAME_LEN_MASK;
+ fw_info->data += NXP_NCI_FW_HDR_LEN;
+ fw_info->size -= NXP_NCI_FW_HDR_LEN;
+ }
+
+ if (fw_info->frame_size > fw_info->size)
+ return -EMSGSIZE;
+
+ r = nxp_nci_fw_send_chunk(info);
+ if (r < 0)
+ return r;
+
+ fw_info->written += r;
+
+ if (*fw_info->data == NXP_NCI_FW_CMD_RESET) {
+ fw_info->cmd_result = 0;
+ schedule_work(&fw_info->work);
+ } else {
+ completion_rc = wait_for_completion_interruptible_timeout(
+ &fw_info->cmd_completion, NXP_NCI_FW_ANSWER_TIMEOUT);
+ if (completion_rc == 0)
+ return -ETIMEDOUT;
+ }
+
+ return 0;
+}
+
+void nxp_nci_fw_work(struct work_struct *work)
+{
+ struct nxp_nci_info *info;
+ struct nxp_nci_fw_info *fw_info;
+ int r;
+
+ fw_info = container_of(work, struct nxp_nci_fw_info, work);
+ info = container_of(fw_info, struct nxp_nci_info, fw_info);
+
+ mutex_lock(&info->info_lock);
+
+ r = fw_info->cmd_result;
+ if (r < 0)
+ goto exit_work;
+
+ if (fw_info->written == fw_info->frame_size) {
+ fw_info->data += fw_info->frame_size;
+ fw_info->size -= fw_info->frame_size;
+ fw_info->written = 0;
+ }
+
+ if (fw_info->size > 0)
+ r = nxp_nci_fw_send(info);
+
+exit_work:
+ if (r < 0 || fw_info->size == 0)
+ nxp_nci_fw_work_complete(info, r);
+ mutex_unlock(&info->info_lock);
+}
+
+int nxp_nci_fw_download(struct nci_dev *ndev, const char *firmware_name)
+{
+ struct nxp_nci_info *info = nci_get_drvdata(ndev);
+ struct nxp_nci_fw_info *fw_info = &info->fw_info;
+ int r;
+
+ mutex_lock(&info->info_lock);
+
+ if (!info->phy_ops->fw_enable || !info->phy_ops->write) {
+ r = -ENOTSUPP;
+ goto fw_download_exit;
+ }
+
+ if (!firmware_name || firmware_name[0] == '\0') {
+ r = -EINVAL;
+ goto fw_download_exit;
+ }
+
+ strcpy(fw_info->name, firmware_name);
+
+ r = request_firmware(&fw_info->fw, firmware_name,
+ ndev->nfc_dev->dev.parent);
+ if (r < 0)
+ goto fw_download_exit;
+
+ r = info->phy_ops->fw_enable(info->phy_id);
+ if (r < 0)
+ goto fw_download_exit;
+
+ info->mode = NXP_NCI_MODE_FW;
+
+ fw_info->data = fw_info->fw->data;
+ fw_info->size = fw_info->fw->size;
+ fw_info->written = 0;
+ fw_info->frame_size = 0;
+ fw_info->cmd_result = 0;
+
+ schedule_work(&fw_info->work);
+
+fw_download_exit:
+ mutex_unlock(&info->info_lock);
+ return r;
+}
+
+static int nxp_nci_fw_read_status(u8 stat)
+{
+ switch (stat) {
+ case NXP_NCI_FW_RESULT_OK:
+ return 0;
+ case NXP_NCI_FW_RESULT_INVALID_ADDR:
+ return -EINVAL;
+ case NXP_NCI_FW_RESULT_UNKNOWN_CMD:
+ return -EINVAL;
+ case NXP_NCI_FW_RESULT_ABORTED_CMD:
+ return -EMSGSIZE;
+ case NXP_NCI_FW_RESULT_ADDR_RANGE_OFL_ERROR:
+ return -EADDRNOTAVAIL;
+ case NXP_NCI_FW_RESULT_BUFFER_OFL_ERROR:
+ return -ENOBUFS;
+ case NXP_NCI_FW_RESULT_MEM_BSY:
+ return -ENOKEY;
+ case NXP_NCI_FW_RESULT_SIGNATURE_ERROR:
+ return -EKEYREJECTED;
+ case NXP_NCI_FW_RESULT_FIRMWARE_VERSION_ERROR:
+ return -EALREADY;
+ case NXP_NCI_FW_RESULT_PROTOCOL_ERROR:
+ return -EPROTO;
+ case NXP_NCI_FW_RESULT_SFWU_DEGRADED:
+ return -EHWPOISON;
+ case NXP_NCI_FW_RESULT_PH_STATUS_FIRST_CHUNK:
+ return 0;
+ case NXP_NCI_FW_RESULT_PH_STATUS_NEXT_CHUNK:
+ return 0;
+ case NXP_NCI_FW_RESULT_PH_STATUS_INTERNAL_ERROR_5:
+ return -EINVAL;
+ default:
+ return -EIO;
+ }
+}
+
+static u16 nxp_nci_fw_check_crc(struct sk_buff *skb)
+{
+ u16 crc, frame_crc;
+ size_t len = skb->len - NXP_NCI_FW_CRC_LEN;
+
+ crc = nxp_nci_fw_crc(skb->data, len);
+ frame_crc = get_unaligned_be16(skb->data + len);
+
+ return (crc ^ frame_crc);
+}
+
+void nxp_nci_fw_recv_frame(struct nci_dev *ndev, struct sk_buff *skb)
+{
+ struct nxp_nci_info *info = nci_get_drvdata(ndev);
+ struct nxp_nci_fw_info *fw_info = &info->fw_info;
+
+ complete(&fw_info->cmd_completion);
+
+ if (skb) {
+ if (nxp_nci_fw_check_crc(skb) != 0x00)
+ fw_info->cmd_result = -EBADMSG;
+ else
+ fw_info->cmd_result = nxp_nci_fw_read_status(
+ *skb_pull(skb, NXP_NCI_FW_HDR_LEN));
+ kfree_skb(skb);
+ } else {
+ fw_info->cmd_result = -EIO;
+ }
+
+ schedule_work(&fw_info->work);
+}
+EXPORT_SYMBOL(nxp_nci_fw_recv_frame);
diff --git a/drivers/nfc/nxp-nci/nxp-nci.h b/drivers/nfc/nxp-nci/nxp-nci.h
new file mode 100644
index 0000000..4309328
--- /dev/null
+++ b/drivers/nfc/nxp-nci/nxp-nci.h
@@ -0,0 +1,91 @@
+/*
+ * Copyright (C) 2014 NXP Semiconductors All rights reserved.
+ *
+ * Authors: Clément Perrochaud <clement.perrochaud-3arQi8VN3Tc@public.gmane.org>
+ *
+ * Derived from PN544 device driver:
+ * Copyright (C) 2012 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+*/
+
+#ifndef __LOCAL_NXP_NCI_H_
+#define __LOCAL_NXP_NCI_H_
+
+#include <linux/completion.h>
+#include <linux/firmware.h>
+#include <linux/nfc.h>
+#include <linux/platform_data/nxp-nci.h>
+
+#include <net/nfc/nci_core.h>
+
+#define NXP_NCI_FW_HDR_LEN 2
+#define NXP_NCI_FW_CRC_LEN 2
+
+#define NXP_NCI_FW_FRAME_LEN_MASK 0x03FF
+
+enum nxp_nci_mode {
+ NXP_NCI_MODE_COLD,
+ NXP_NCI_MODE_NCI,
+ NXP_NCI_MODE_FW
+};
+
+struct nxp_nci_phy_ops {
+ int (*enable)(void *id);
+ int (*fw_enable)(void *id);
+ int (*disable)(void *id);
+ int (*write)(void *id, struct sk_buff *skb);
+};
+
+struct nxp_nci_fw_info {
+ char name[NFC_FIRMWARE_NAME_MAXSIZE + 1];
+ const struct firmware *fw;
+
+ size_t size;
+ size_t written;
+
+ const u8 *data;
+ size_t frame_size;
+
+ struct work_struct work;
+ struct completion cmd_completion;
+
+ int cmd_result;
+};
+
+struct nxp_nci_info {
+ struct nci_dev *ndev;
+ void *phy_id;
+ struct device *pdev;
+
+ enum nxp_nci_mode mode;
+
+ struct nxp_nci_phy_ops *phy_ops;
+ unsigned int max_payload;
+
+ struct mutex info_lock;
+
+ struct nxp_nci_fw_info fw_info;
+};
+
+int nxp_nci_fw_download(struct nci_dev *ndev, const char *firmware_name);
+void nxp_nci_fw_work(struct work_struct *work);
+void nxp_nci_fw_recv_frame(struct nci_dev *ndev, struct sk_buff *skb);
+void nxp_nci_fw_work_complete(struct nxp_nci_info *info, int result);
+
+int nxp_nci_probe(void *phy_id, struct device *pdev,
+ struct nxp_nci_phy_ops *phy_ops, unsigned int max_payload,
+ struct nci_dev **ndev);
+void nxp_nci_remove(struct nci_dev *ndev);
+
+#endif /* __LOCAL_NXP_NCI_H_ */
diff --git a/include/linux/platform_data/nxp-nci.h b/include/linux/platform_data/nxp-nci.h
new file mode 100644
index 0000000..d6ed286
--- /dev/null
+++ b/include/linux/platform_data/nxp-nci.h
@@ -0,0 +1,27 @@
+/*
+ * Generic platform data for the NXP NCI NFC chips.
+ *
+ * Copyright (C) 2014 NXP Semiconductors All rights reserved.
+ *
+ * Authors: Clément Perrochaud <clement.perrochaud-3arQi8VN3Tc@public.gmane.org>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions 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.
+ */
+
+#ifndef _NXP_NCI_H_
+#define _NXP_NCI_H_
+
+struct nxp_nci_nfc_platform_data {
+ unsigned int gpio_en;
+ unsigned int gpio_fw;
+ unsigned int irq;
+};
+
+#endif /* _NXP_NCI_H_ */
--
Clément Perrochaud
Eff'Innov Technologies
Caen, Aix-En-Provence, Grenoble
Eff'Innov Technologies
Campus EffiScience
2, Esplanade Anton Philips
14460 Colombelles, FRANCE
http://www.effinnov.com
--
To unsubscribe from this list: send the line "unsubscribe linux-wireless" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply related
* [PATCH 3/4] NFC: nxp-nci_i2c: Add I2C support to NXP NCI driver
From: clement.perrochaud-BPEPtVrvniRWk0Htik3J/w @ 2015-01-22 15:27 UTC (permalink / raw)
To: linux-nfc-hn68Rpc1hR1g9hUCZPvPmw
Cc: Clément Perrochaud, sunil.jogi-3arQi8VN3Tc,
jerome.pele-3arQi8VN3Tc, Charles.Gorand-Effinnov-3arQi8VN3Tc,
lauro.venancio-430g2QfJUUCGglJvpFV4uA,
aloisio.almeida-430g2QfJUUCGglJvpFV4uA,
sameo-VuQAYsv1563Yd54FQh9/CA, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
pawel.moll-5wv7dgnIgG8, mark.rutland-5wv7dgnIgG8,
ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
galak-sgV2jX0FEOL9JmXXK+q4OQ, davem-fT/PcQaiUtIeIZ0/mPfg9Q,
grant.likely-QSEj5FYQhm4dnm+yROfE0A,
lefrique-eYqpPyKDWXRBDgjK7y7TUQ,
christophe.ricard-Re5JQEeQqe8AvxtiuMwx3w,
cuissard-eYqpPyKDWXRBDgjK7y7TUQ, bzhao-eYqpPyKDWXRBDgjK7y7TUQ,
hirent-eYqpPyKDWXRBDgjK7y7TUQ, akarwar-eYqpPyKDWXRBDgjK7y7TUQ,
linux-wireless-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA, Clément Perrochaud
In-Reply-To: <1421940460-14049-1-git-send-email-clement.perrochaud-BPEPtVrvniRWk0Htik3J/w@public.gmane.org>
From: Clément Perrochaud <clement.perrochaud-3arQi8VN3Tc@public.gmane.org>
Signed-off-by: Clément Perrochaud <clement.perrochaud-3arQi8VN3Tc@public.gmane.org>
Signed-off-by: Clément Perrochaud <clement.perrochaud-BPEPtVrvniRWk0Htik3J/w@public.gmane.org>
---
.../devicetree/bindings/net/nfc/nxp-nci.txt | 35 ++
drivers/nfc/nxp-nci/Kconfig | 12 +
drivers/nfc/nxp-nci/Makefile | 2 +
drivers/nfc/nxp-nci/i2c.c | 468 +++++++++++++++++++++
4 files changed, 517 insertions(+)
create mode 100644 Documentation/devicetree/bindings/net/nfc/nxp-nci.txt
create mode 100644 drivers/nfc/nxp-nci/i2c.c
diff --git a/Documentation/devicetree/bindings/net/nfc/nxp-nci.txt b/Documentation/devicetree/bindings/net/nfc/nxp-nci.txt
new file mode 100644
index 0000000..5b6cd9b
--- /dev/null
+++ b/Documentation/devicetree/bindings/net/nfc/nxp-nci.txt
@@ -0,0 +1,35 @@
+* NXP Semiconductors NXP NCI NFC Controllers
+
+Required properties:
+- compatible: Should be "nxp,nxp-nci-i2c".
+- clock-frequency: I²C work frequency.
+- reg: address on the bus
+- interrupt-parent: phandle for the interrupt gpio controller
+- interrupts: GPIO interrupt to which the chip is connected
+- enable-gpios: Output GPIO pin used for enabling/disabling the chip
+- firmware-gpios: Output GPIO pin used to enter firmware download mode
+
+Optional SoC Specific Properties:
+- pinctrl-names: Contains only one value - "default".
+- pintctrl-0: Specifies the pin control groups used for this controller.
+
+Example (for ARM-based BeagleBone with NPC100 NFC controller on I2C2):
+
+&i2c2 {
+
+ status = "okay";
+
+ npc100: npc100@29 {
+
+ compatible = "nxp,nxp-nci-i2c";
+
+ reg = <0x29>;
+ clock-frequency = <100000>;
+
+ interrupt-parent = <&gpio1>;
+ interrupts = <29 GPIO_ACTIVE_HIGH>;
+
+ enable-gpios = <&gpio0 30 GPIO_ACTIVE_HIGH>;
+ firmware-gpios = <&gpio0 31 GPIO_ACTIVE_HIGH>;
+ };
+};
diff --git a/drivers/nfc/nxp-nci/Kconfig b/drivers/nfc/nxp-nci/Kconfig
index 5107edd..ac54016 100644
--- a/drivers/nfc/nxp-nci/Kconfig
+++ b/drivers/nfc/nxp-nci/Kconfig
@@ -10,3 +10,15 @@ config NFC_NXP_NCI
To compile this driver as a module, choose m here. The module will
be called nxp_nci.
Say N if unsure.
+
+config NFC_NXP_NCI_I2C
+ tristate "NXP-NCI I2C support"
+ depends on NFC_NXP_NCI && I2C
+ ---help---
+ This module adds support for an I2C interface to the NXP NCI
+ chips.
+ Select this if your platform is using the I2C bus.
+
+ To compile this driver as a module, choose m here. The module will
+ be called nxp_nci_i2c.
+ Say Y if unsure.
diff --git a/drivers/nfc/nxp-nci/Makefile b/drivers/nfc/nxp-nci/Makefile
index 8f1e328..c008be3 100644
--- a/drivers/nfc/nxp-nci/Makefile
+++ b/drivers/nfc/nxp-nci/Makefile
@@ -3,7 +3,9 @@
#
nxp-nci-objs = core.o firmware.o
+nxp-nci_i2c-objs = i2c.o
obj-$(CONFIG_NFC_NXP_NCI) += nxp-nci.o
+obj-$(CONFIG_NFC_NXP_NCI_I2C) += nxp-nci_i2c.o
ccflags-$(CONFIG_NFC_DEBUG) := -DDEBUG
diff --git a/drivers/nfc/nxp-nci/i2c.c b/drivers/nfc/nxp-nci/i2c.c
new file mode 100644
index 0000000..4d6293b
--- /dev/null
+++ b/drivers/nfc/nxp-nci/i2c.c
@@ -0,0 +1,468 @@
+/*
+ * I2C link layer for the NXP NCI driver
+ *
+ * Copyright (C) 2014 NXP Semiconductors All rights reserved.
+ *
+ * Authors: Clément Perrochaud <clement.perrochaud-3arQi8VN3Tc@public.gmane.org>
+ *
+ * Derived from PN544 device driver:
+ * Copyright (C) 2012 Intel Corporation. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms and conditions 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.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, see <http://www.gnu.org/licenses/>.
+ */
+
+#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
+
+#include <linux/delay.h>
+#include <linux/i2c.h>
+#include <linux/interrupt.h>
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/nfc.h>
+#include <linux/of_gpio.h>
+#include <linux/of_irq.h>
+#include <linux/platform_data/nxp-nci.h>
+#include <linux/unaligned/access_ok.h>
+
+#include <net/nfc/nfc.h>
+
+#include "nxp-nci.h"
+
+#define NXP_NCI_I2C_DRIVER_NAME "nxp-nci_i2c"
+
+#define NXP_NCI_I2C_MAX_PAYLOAD 32
+
+struct nxp_nci_i2c_phy {
+ struct i2c_client *i2c_dev;
+ struct nci_dev *ndev;
+
+ unsigned int gpio_en;
+ unsigned int gpio_fw;
+
+ int hard_fault; /*
+ * < 0 if hardware error occurred (e.g. i2c err)
+ * and prevents normal operation.
+ */
+};
+
+static void nxp_nci_i2c_enable_mode(struct nxp_nci_i2c_phy *phy,
+ enum nxp_nci_mode mode)
+{
+ gpio_set_value(phy->gpio_fw, (mode == NXP_NCI_MODE_FW) ? 1 : 0);
+ gpio_set_value(phy->gpio_en, (mode != NXP_NCI_MODE_COLD) ? 1 : 0);
+ usleep_range(10000, 15000);
+}
+
+int nxp_nci_i2c_enable(void *phy_id)
+{
+ nxp_nci_i2c_enable_mode((struct nxp_nci_i2c_phy *) phy_id,
+ NXP_NCI_MODE_NCI);
+ return 0;
+}
+
+int nxp_nci_i2c_fw_enable(void *phy_id)
+{
+ nxp_nci_i2c_enable_mode((struct nxp_nci_i2c_phy *) phy_id,
+ NXP_NCI_MODE_FW);
+ return 0;
+}
+
+int nxp_nci_i2c_disable(void *phy_id)
+{
+ struct nxp_nci_i2c_phy *phy = phy_id;
+
+ nxp_nci_i2c_enable_mode(phy, NXP_NCI_MODE_COLD);
+ phy->hard_fault = 0;
+
+ return 0;
+}
+
+static int nxp_nci_i2c_write(void *phy_id, struct sk_buff *skb)
+{
+ int r;
+ struct nxp_nci_i2c_phy *phy = phy_id;
+ struct i2c_client *client = phy->i2c_dev;
+
+ if (phy->hard_fault != 0)
+ return phy->hard_fault;
+
+ r = i2c_master_send(client, skb->data, skb->len);
+ if (r == -EREMOTEIO) {
+ /* Retry, chip was in standby */
+ usleep_range(110000, 120000);
+ r = i2c_master_send(client, skb->data, skb->len);
+ }
+
+ if (r < 0) {
+ nfc_err(&client->dev, "Error %d on I2C send\n", r);
+ } else if (r != skb->len) {
+ nfc_err(&client->dev,
+ "Invalid length sent: %u (expected %u)\n",
+ r, skb->len);
+ r = -EREMOTEIO;
+ } else {
+ /* Success but return 0 and not number of bytes */
+ r = 0;
+ }
+
+ return r;
+}
+
+static struct nxp_nci_phy_ops i2c_phy_ops = {
+ .enable = nxp_nci_i2c_enable,
+ .fw_enable = nxp_nci_i2c_fw_enable,
+ .disable = nxp_nci_i2c_disable,
+ .write = nxp_nci_i2c_write,
+};
+
+static int nxp_nci_i2c_fw_read(struct nxp_nci_i2c_phy *phy,
+ struct sk_buff **skb)
+{
+ struct i2c_client *client = phy->i2c_dev;
+ u16 header;
+ size_t frame_len;
+ int r;
+
+ r = i2c_master_recv(client, (u8 *) &header, NXP_NCI_FW_HDR_LEN);
+ if (r < 0) {
+ goto fw_read_exit;
+ } else if (r != NXP_NCI_FW_HDR_LEN) {
+ nfc_err(&client->dev, "Incorrect header length: %u\n", r);
+ r = -EBADMSG;
+ goto fw_read_exit;
+ }
+
+ frame_len = (get_unaligned_be16(&header) & NXP_NCI_FW_FRAME_LEN_MASK) +
+ NXP_NCI_FW_CRC_LEN;
+
+ *skb = alloc_skb(NXP_NCI_FW_HDR_LEN + frame_len, GFP_KERNEL);
+ if (*skb == NULL) {
+ r = -ENOMEM;
+ goto fw_read_exit;
+ }
+
+ memcpy(skb_put(*skb, NXP_NCI_FW_HDR_LEN), &header, NXP_NCI_FW_HDR_LEN);
+
+ r = i2c_master_recv(client, skb_put(*skb, frame_len), frame_len);
+ if (r != frame_len) {
+ nfc_err(&client->dev,
+ "Invalid frame length: %u (expected %u)\n",
+ r, frame_len);
+ r = -EBADMSG;
+ goto fw_read_exit_free_skb;
+ }
+
+ r = 0;
+ goto fw_read_exit;
+
+fw_read_exit_free_skb:
+ kfree_skb(*skb);
+fw_read_exit:
+ return r;
+}
+
+static int nxp_nci_i2c_nci_read(struct nxp_nci_i2c_phy *phy,
+ struct sk_buff **skb)
+{
+ struct nci_ctrl_hdr header; /* May actually be a data header */
+ struct i2c_client *client = phy->i2c_dev;
+ int r;
+
+ r = i2c_master_recv(client, (u8 *) &header, NCI_CTRL_HDR_SIZE);
+ if (r < 0) {
+ goto nci_read_exit;
+ } else if (r != NCI_CTRL_HDR_SIZE) {
+ nfc_err(&client->dev, "Incorrect header length: %u\n", r);
+ r = -EBADMSG;
+ goto nci_read_exit;
+ }
+
+ *skb = alloc_skb(NCI_CTRL_HDR_SIZE + header.plen, GFP_KERNEL);
+ if (*skb == NULL) {
+ r = -ENOMEM;
+ goto nci_read_exit;
+ }
+
+ memcpy(skb_put(*skb, NCI_CTRL_HDR_SIZE), (void *) &header,
+ NCI_CTRL_HDR_SIZE);
+
+ r = i2c_master_recv(client, skb_put(*skb, header.plen), header.plen);
+ if (r != header.plen) {
+ nfc_err(&client->dev,
+ "Invalid frame payload length: %u (expected %u)\n",
+ r, header.plen);
+ r = -EBADMSG;
+ goto nci_read_exit_free_skb;
+ }
+
+ r = 0;
+ goto nci_read_exit;
+
+nci_read_exit_free_skb:
+ kfree_skb(*skb);
+nci_read_exit:
+ return r;
+}
+
+static irqreturn_t nxp_nci_i2c_irq_thread_fn(int irq, void *phy_id)
+{
+ struct nxp_nci_i2c_phy *phy = phy_id;
+ struct i2c_client *client;
+ struct nxp_nci_info *info;
+
+ struct sk_buff *skb = NULL;
+ int r = 0;
+
+ if (!phy || !phy->ndev)
+ goto exit_irq_none;
+
+ client = phy->i2c_dev;
+
+ if (!client || irq != client->irq)
+ goto exit_irq_none;
+
+ if (phy->hard_fault != 0)
+ goto exit_irq_handled;
+
+ info = nci_get_drvdata(phy->ndev);
+
+ switch (info->mode) {
+ case NXP_NCI_MODE_NCI:
+ r = nxp_nci_i2c_nci_read(phy, &skb);
+ break;
+ case NXP_NCI_MODE_FW:
+ r = nxp_nci_i2c_fw_read(phy, &skb);
+ break;
+ case NXP_NCI_MODE_COLD:
+ r = -EREMOTEIO;
+ break;
+ }
+
+ if (r == -EREMOTEIO) {
+ phy->hard_fault = r;
+ skb = NULL;
+ } else if (r < 0) {
+ nfc_err(&client->dev, "Read failed with error %d\n", r);
+ goto exit_irq_handled;
+ }
+
+ switch (info->mode) {
+ case NXP_NCI_MODE_NCI:
+ nci_recv_frame(phy->ndev, skb);
+ break;
+ case NXP_NCI_MODE_FW:
+ nxp_nci_fw_recv_frame(phy->ndev, skb);
+ break;
+ case NXP_NCI_MODE_COLD:
+ break;
+ }
+
+exit_irq_handled:
+ return IRQ_HANDLED;
+exit_irq_none:
+ WARN_ON_ONCE(1);
+ return IRQ_NONE;
+}
+
+#ifdef CONFIG_OF
+
+static int nxp_nci_i2c_parse_devtree(struct i2c_client *client)
+{
+ struct nxp_nci_i2c_phy *phy = i2c_get_clientdata(client);
+ struct device_node *pp;
+ int r;
+
+ pp = client->dev.of_node;
+ if (!pp)
+ return -ENODEV;
+
+ r = of_get_named_gpio(pp, "enable-gpios", 0);
+ if (r == -EPROBE_DEFER)
+ r = of_get_named_gpio(pp, "enable-gpios", 0);
+ if (r < 0) {
+ nfc_err(&client->dev, "Failed to get EN gpio, error: %d\n", r);
+ return r;
+ }
+ phy->gpio_en = r;
+
+ r = of_get_named_gpio(pp, "firmware-gpios", 0);
+ if (r == -EPROBE_DEFER)
+ r = of_get_named_gpio(pp, "firmware-gpios", 0);
+ if (r < 0) {
+ nfc_err(&client->dev, "Failed to get FW gpio, error: %d\n", r);
+ return r;
+ }
+ phy->gpio_fw = r;
+
+ r = irq_of_parse_and_map(pp, 0);
+ if (r < 0) {
+ nfc_err(&client->dev, "Unable to get irq, error: %d\n", r);
+ return r;
+ }
+ client->irq = r;
+
+ return 0;
+}
+
+#else
+
+static int nxp_nci_i2c_parse_devtree(struct i2c_client *client)
+{
+ return -ENODEV;
+}
+
+#endif
+
+static int nxp_nci_i2c_request_gpios(struct nxp_nci_i2c_phy *phy)
+{
+ int r;
+
+ r = gpio_request(phy->gpio_en, "nxp_nci_en");
+ if (r < 0)
+ goto err_out;
+
+ r = gpio_direction_output(phy->gpio_en, 0);
+ if (r < 0)
+ goto err_gpio_en;
+
+ r = gpio_request(phy->gpio_fw, "nxp_nci_fw");
+ if (r < 0)
+ goto err_gpio_en;
+
+ r = gpio_direction_output(phy->gpio_fw, 0);
+ if (r < 0)
+ goto err_gpio_fw;
+
+ goto err_out;
+
+err_gpio_fw:
+ gpio_free(phy->gpio_fw);
+err_gpio_en:
+ gpio_free(phy->gpio_en);
+err_out:
+ return r;
+}
+
+static void nxp_nci_i2c_free_gpios(struct nxp_nci_i2c_phy *phy)
+{
+ gpio_free(phy->gpio_fw);
+ gpio_free(phy->gpio_en);
+}
+
+static int nxp_nci_i2c_probe(struct i2c_client *client,
+ const struct i2c_device_id *id)
+{
+ struct nxp_nci_i2c_phy *phy;
+ struct nxp_nci_nfc_platform_data *pdata;
+ int r;
+
+ if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
+ nfc_err(&client->dev, "Need I2C_FUNC_I2C\n");
+ r = -ENODEV;
+ goto probe_exit;
+ }
+
+ phy = devm_kzalloc(&client->dev, sizeof(struct nxp_nci_i2c_phy),
+ GFP_KERNEL);
+ if (!phy) {
+ r = -ENOMEM;
+ goto probe_exit;
+ }
+
+ phy->i2c_dev = client;
+ i2c_set_clientdata(client, phy);
+
+ pdata = client->dev.platform_data;
+
+ if (!pdata && client->dev.of_node) {
+ r = nxp_nci_i2c_parse_devtree(client);
+ if (r < 0) {
+ nfc_err(&client->dev, "Failed to get DT data\n");
+ goto probe_exit;
+ }
+ } else if (pdata) {
+ phy->gpio_en = pdata->gpio_en;
+ phy->gpio_fw = pdata->gpio_fw;
+ client->irq = pdata->irq;
+ } else {
+ nfc_err(&client->dev, "No platform data\n");
+ r = -EINVAL;
+ goto probe_exit;
+ }
+
+ r = nxp_nci_i2c_request_gpios(phy);
+ if (r < 0)
+ goto probe_exit;
+
+ r = nxp_nci_probe(phy, &client->dev, &i2c_phy_ops,
+ NXP_NCI_I2C_MAX_PAYLOAD, &phy->ndev);
+ if (r < 0)
+ goto probe_exit_free_gpio;
+
+ r = request_threaded_irq(client->irq, NULL,
+ nxp_nci_i2c_irq_thread_fn,
+ IRQF_TRIGGER_RISING | IRQF_ONESHOT,
+ NXP_NCI_I2C_DRIVER_NAME, phy);
+ if (r < 0) {
+ nfc_err(&client->dev, "Unable to register IRQ handler\n");
+ goto probe_exit_free_gpio;
+ }
+
+ goto probe_exit;
+
+probe_exit_free_gpio:
+ nxp_nci_i2c_free_gpios(phy);
+probe_exit:
+ return r;
+}
+
+static int nxp_nci_i2c_remove(struct i2c_client *client)
+{
+ struct nxp_nci_i2c_phy *phy = i2c_get_clientdata(client);
+
+ nxp_nci_remove(phy->ndev);
+
+ nxp_nci_i2c_free_gpios(phy);
+ free_irq(client->irq, phy);
+
+ return 0;
+}
+
+static struct i2c_device_id nxp_nci_i2c_id_table[] = {
+ {"nxp-nci_i2c", 0},
+ {}
+};
+MODULE_DEVICE_TABLE(i2c, nxp_nci_i2c_id_table);
+
+static const struct of_device_id of_nxp_nci_i2c_match[] = {
+ { .compatible = "nxp,nxp-nci-i2c", },
+ {},
+};
+MODULE_DEVICE_TABLE(of, of_nxp_nci_i2c_match);
+
+static struct i2c_driver nxp_nci_i2c_driver = {
+ .driver = {
+ .name = NXP_NCI_I2C_DRIVER_NAME,
+ .owner = THIS_MODULE,
+ .of_match_table = of_match_ptr(of_nxp_nci_i2c_match),
+ },
+ .probe = nxp_nci_i2c_probe,
+ .id_table = nxp_nci_i2c_id_table,
+ .remove = nxp_nci_i2c_remove,
+};
+
+module_i2c_driver(nxp_nci_i2c_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("I2C driver for NXP NCI NFC controllers");
+MODULE_AUTHOR("Clément Perrochaud <clement.perrochaud-3arQi8VN3Tc@public.gmane.org>");
--
Clément Perrochaud
Eff'Innov Technologies
Caen, Aix-En-Provence, Grenoble
Eff'Innov Technologies
Campus EffiScience
2, Esplanade Anton Philips
14460 Colombelles, FRANCE
http://www.effinnov.com
--
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 related
* [PATCH 4/4] NFC: nxp-nci: Allow module removal during download
From: clement.perrochaud-BPEPtVrvniRWk0Htik3J/w @ 2015-01-22 15:27 UTC (permalink / raw)
To: linux-nfc-hn68Rpc1hR1g9hUCZPvPmw
Cc: Clément Perrochaud, sunil.jogi-3arQi8VN3Tc,
jerome.pele-3arQi8VN3Tc, Charles.Gorand-Effinnov-3arQi8VN3Tc,
lauro.venancio-430g2QfJUUCGglJvpFV4uA,
aloisio.almeida-430g2QfJUUCGglJvpFV4uA,
sameo-VuQAYsv1563Yd54FQh9/CA, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
pawel.moll-5wv7dgnIgG8, mark.rutland-5wv7dgnIgG8,
ijc+devicetree-KcIKpvwj1kUDXYZnReoRVg,
galak-sgV2jX0FEOL9JmXXK+q4OQ, davem-fT/PcQaiUtIeIZ0/mPfg9Q,
grant.likely-QSEj5FYQhm4dnm+yROfE0A,
lefrique-eYqpPyKDWXRBDgjK7y7TUQ,
christophe.ricard-Re5JQEeQqe8AvxtiuMwx3w,
cuissard-eYqpPyKDWXRBDgjK7y7TUQ, bzhao-eYqpPyKDWXRBDgjK7y7TUQ,
hirent-eYqpPyKDWXRBDgjK7y7TUQ, akarwar-eYqpPyKDWXRBDgjK7y7TUQ,
linux-wireless-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA, Clément Perrochaud
In-Reply-To: <1421940460-14049-1-git-send-email-clement.perrochaud-BPEPtVrvniRWk0Htik3J/w@public.gmane.org>
From: Clément Perrochaud <clement.perrochaud-3arQi8VN3Tc@public.gmane.org>
Signed-off-by: Clément Perrochaud <clement.perrochaud-3arQi8VN3Tc@public.gmane.org>
Signed-off-by: Clément Perrochaud <clement.perrochaud-BPEPtVrvniRWk0Htik3J/w@public.gmane.org>
---
drivers/nfc/nxp-nci/core.c | 7 +++----
drivers/nfc/nxp-nci/firmware.c | 9 ++++++---
2 files changed, 9 insertions(+), 7 deletions(-)
diff --git a/drivers/nfc/nxp-nci/core.c b/drivers/nfc/nxp-nci/core.c
index d3643ef..c15606d 100644
--- a/drivers/nfc/nxp-nci/core.c
+++ b/drivers/nfc/nxp-nci/core.c
@@ -165,12 +165,11 @@ void nxp_nci_remove(struct nci_dev *ndev)
{
struct nxp_nci_info *info = nci_get_drvdata(ndev);
- mutex_lock(&info->info_lock);
-
- cancel_work_sync(&info->fw_info.work);
-
if (info->mode == NXP_NCI_MODE_FW)
nxp_nci_fw_work_complete(info, -ESHUTDOWN);
+ cancel_work_sync(&info->fw_info.work);
+
+ mutex_lock(&info->info_lock);
if (info->phy_ops->disable)
info->phy_ops->disable(info->phy_id);
diff --git a/drivers/nfc/nxp-nci/firmware.c b/drivers/nfc/nxp-nci/firmware.c
index 1814e9f..de136e1 100644
--- a/drivers/nfc/nxp-nci/firmware.c
+++ b/drivers/nfc/nxp-nci/firmware.c
@@ -166,7 +166,8 @@ static int nxp_nci_fw_send(struct nxp_nci_info *info)
if (*fw_info->data == NXP_NCI_FW_CMD_RESET) {
fw_info->cmd_result = 0;
- schedule_work(&fw_info->work);
+ if (fw_info->fw)
+ schedule_work(&fw_info->work);
} else {
completion_rc = wait_for_completion_interruptible_timeout(
&fw_info->cmd_completion, NXP_NCI_FW_ANSWER_TIMEOUT);
@@ -244,7 +245,8 @@ int nxp_nci_fw_download(struct nci_dev *ndev, const char *firmware_name)
fw_info->frame_size = 0;
fw_info->cmd_result = 0;
- schedule_work(&fw_info->work);
+ if (fw_info->fw)
+ schedule_work(&fw_info->work);
fw_download_exit:
mutex_unlock(&info->info_lock);
@@ -316,6 +318,7 @@ void nxp_nci_fw_recv_frame(struct nci_dev *ndev, struct sk_buff *skb)
fw_info->cmd_result = -EIO;
}
- schedule_work(&fw_info->work);
+ if (fw_info->fw)
+ schedule_work(&fw_info->work);
}
EXPORT_SYMBOL(nxp_nci_fw_recv_frame);
--
Clément Perrochaud
Eff'Innov Technologies
Caen, Aix-En-Provence, Grenoble
Eff'Innov Technologies
Campus EffiScience
2, Esplanade Anton Philips
14460 Colombelles, FRANCE
http://www.effinnov.com
--
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 related
* Re: [net-next PATCH v3 00/12] Flow API
From: Jamal Hadi Salim @ 2015-01-22 15:28 UTC (permalink / raw)
To: Thomas Graf
Cc: Pablo Neira Ayuso, John Fastabend, simon.horman, sfeldma, netdev,
davem, gerlitz.or, andy, ast, Jiri Pirko
In-Reply-To: <20150122151316.GB25797@casper.infradead.org>
On 01/22/15 10:13, Thomas Graf wrote:
> I don't follow this. John's proposal allows to decide on a case by
> case basis what we want to export. Just like with ethtool or
> RTNETLINK. There is no direct access to hardware. A user can only
> configure what is being exposed by the kernel.
>
So if i am a vendor with my own driver, I can expose whatever i want.
Only my SDK needs to deal with what i expose. There is no needed
feature in the kernel other than the driver exposing it that is
required.
cheers,
jamal
^ permalink raw reply
* Re: [net-next PATCH v3 00/12] Flow API
From: Thomas Graf @ 2015-01-22 15:37 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: <54C11703.7030702@mojatatu.com>
On 01/22/15 at 10:28am, Jamal Hadi Salim wrote:
> On 01/22/15 10:13, Thomas Graf wrote:
>
> >I don't follow this. John's proposal allows to decide on a case by
> >case basis what we want to export. Just like with ethtool or
> >RTNETLINK. There is no direct access to hardware. A user can only
> >configure what is being exposed by the kernel.
> >
>
> 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.
This is the whole point of this: Coming up with a model that allows
to describe capabilities and offer flow programming capabilities
in a Vendor neutral way. A "push_vlan" or "pop_vlan" action will work
with any driver that supports it.
^ permalink raw reply
* Re: [net-next PATCH v3 00/12] Flow API
From: Jamal Hadi Salim @ 2015-01-22 15:44 UTC (permalink / raw)
To: Thomas Graf
Cc: Pablo Neira Ayuso, John Fastabend, simon.horman, sfeldma, netdev,
davem, gerlitz.or, andy, ast, Jiri Pirko
In-Reply-To: <20150122153727.GC25797@casper.infradead.org>
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.
cheers,
jamal
^ permalink raw reply
* Re: [net-next PATCH v3 00/12] Flow API
From: Jiri Pirko @ 2015-01-22 15:48 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: <20150122153727.GC25797@casper.infradead.org>
Thu, Jan 22, 2015 at 04:37:27PM CET, tgraf@suug.ch wrote:
>On 01/22/15 at 10:28am, Jamal Hadi Salim wrote:
>> On 01/22/15 10:13, Thomas Graf wrote:
>>
>> >I don't follow this. John's proposal allows to decide on a case by
>> >case basis what we want to export. Just like with ethtool or
>> >RTNETLINK. There is no direct access to hardware. A user can only
>> >configure what is being exposed by the kernel.
>> >
>>
>> 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.
That is not 100%, on contrary. If the infrastructure would be made to
explicitly disallow that kind of behaviour, it would be much safer.
>
>This is the whole point of this: Coming up with a model that allows
>to describe capabilities and offer flow programming capabilities
>in a Vendor neutral way. A "push_vlan" or "pop_vlan" action will work
>with any driver that supports it.
^ permalink raw reply
* Re: [patch net-next RFC] tc: introduce OpenFlow classifier
From: Jamal Hadi Salim @ 2015-01-22 15:50 UTC (permalink / raw)
To: Jiri Pirko, netdev; +Cc: davem
In-Reply-To: <1421933824-17916-1-git-send-email-jiri@resnulli.us>
On 01/22/15 08:37, Jiri Pirko wrote:
> This patch introduces OpenFlow-based filter. So far, the very essential
> packet fields are supported (according to OpenFlow v1.4 spec).
>
> Known issues: skb_flow_dissect hashes out ipv6 addresses. That needs
> to be changed to store them somewhere so they can be used later on.
>
> Signed-off-by: Jiri Pirko <jiri@resnulli.us>
> ---
> include/uapi/linux/pkt_cls.h | 33 +++
> net/sched/Kconfig | 11 +
> net/sched/Makefile | 1 +
> net/sched/cls_openflow.c | 514 +++++++++++++++++++++++++++++++++++++++++++
> 4 files changed, 559 insertions(+)
> create mode 100644 net/sched/cls_openflow.c
>
> diff --git a/include/uapi/linux/pkt_cls.h b/include/uapi/linux/pkt_cls.h
> index 25731df..d4cef16 100644
> --- a/include/uapi/linux/pkt_cls.h
> +++ b/include/uapi/linux/pkt_cls.h
> @@ -402,6 +402,39 @@ enum {
>
> #define TCA_BPF_MAX (__TCA_BPF_MAX - 1)
>
> +/* OpenFlow classifier */
> +
> +enum {
> + TCA_OF_UNSPEC,
> + TCA_OF_CLASSID,
> + TCA_OF_POLICE,
> + TCA_OF_INDEV,
I think POLICE is an old way of doing policing and INDEV if i am not
mistaken is only legit for u32 classifier.
So i am not sure you want to keep them.
Other than that looks good - will be interested to see how perfomance
looks on this with the list walking ;->
cheers,
jamal
^ permalink raw reply
* [PATCH net] netxen: fix netxen_nic_poll() logic
From: Eric Dumazet @ 2015-01-22 15:56 UTC (permalink / raw)
To: Mike Galbraith, David Miller; +Cc: netdev, Manish Chopra
In-Reply-To: <1421915821.5286.71.camel@marge.simpson.net>
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);
^ permalink raw reply related
* ITECIR 8710 not recognized by any kernel
From: J.Pujó @ 2015-01-22 16:00 UTC (permalink / raw)
To: netdev
Hello,
My laptop comes with a ITECIR 8710 infrared receiver, but is not
recognized by any kernel. I tried newer and older versions but nothing
changed.
It's an integrated infrared receiver, which is working like a charm on
Windows partition, so the device is working (obviously, not in Linux).
I tried to search on the net, but I couldn't see anything useful to
make it work with Linux. I guess the drivers never were developed. Is
that possible?
Moreover, there is no /dev/lircX nor /sys/class/rc on my system. So
it's not recognized at all.
Here you have journalctl, dmesg, lsusb, lspci and lircd log.
journalctl: https://dl.dropboxusercontent.com/u/2135959/journalctl.txt
dmesg: https://dl.dropboxusercontent.com/u/2135959/dmesg.txt
lsusb: https://dl.dropboxusercontent.com/u/2135959/lsusb.txt
lspci: https://dl.dropboxusercontent.com/u/2135959/lspci.txt
lircd: https://dl.dropboxusercontent.com/u/2135959/lircd
Let me know if you need more info or details and if it's possible to
make it work with Linux.
Thanks.
^ permalink raw reply
* Re: [PATCH 2/2] nfc: NXP PN544 ACPI support
From: Daniel Baluta @ 2015-01-22 16:07 UTC (permalink / raw)
To: Robert Dolca
Cc: linux-nfc, Linux Kernel Mailing List,
linux-wireless@vger.kernel.org, netdev@vger.kernel.org,
Lauro Ramos Venancio, Aloisio Almeida Jr, Samuel Ortiz,
David S. Miller, Johannes Berg, Clement Perrochaud
In-Reply-To: <1420804937-10787-2-git-send-email-robert.dolca@intel.com>
On Fri, Jan 9, 2015 at 2:02 PM, Robert Dolca <robert.dolca@intel.com> wrote:
> Device id: NXP5440
> Pin mapping:
> - 0 IRQ pin
> - 1 enable pin
> - 2 firmware pin
>
> Signed-off-by: Robert Dolca <robert.dolca@intel.com>
> ---
> drivers/nfc/Kconfig | 1 +
> drivers/nfc/pn544/i2c.c | 115 ++++++++++++++++++++++++++++++++++++++++++++++--
> net/nfc/core.c | 1 +
> 3 files changed, 114 insertions(+), 3 deletions(-)
>
> diff --git a/drivers/nfc/Kconfig b/drivers/nfc/Kconfig
> index 7929fac..a25e712 100644
> --- a/drivers/nfc/Kconfig
> +++ b/drivers/nfc/Kconfig
> @@ -68,6 +68,7 @@ config NFC_PORT100
>
> If unsure, say N.
>
> +source "drivers/nfc/pn547/Kconfig"
I think this line shouldn't be here :).
> source "drivers/nfc/pn544/Kconfig"
> source "drivers/nfc/microread/Kconfig"
> source "drivers/nfc/nfcmrvl/Kconfig"
> diff --git a/drivers/nfc/pn544/i2c.c b/drivers/nfc/pn544/i2c.c
> index 5f4b9c1..58b9029 100644
> --- a/drivers/nfc/pn544/i2c.c
> +++ b/drivers/nfc/pn544/i2c.c
> @@ -24,6 +24,7 @@
> #include <linux/gpio.h>
> #include <linux/of_gpio.h>
> #include <linux/of_irq.h>
> +#include <linux/acpi.h>
> #include <linux/miscdevice.h>
> #include <linux/interrupt.h>
> #include <linux/delay.h>
> @@ -41,6 +42,11 @@
> #define PN544_I2C_FRAME_HEADROOM 1
> #define PN544_I2C_FRAME_TAILROOM 2
>
> +/* GPIO names */
> +#define PN544_GPIO_NAME_IRQ "pn544_irq"
> +#define PN544_GPIO_NAME_FW "pn544_fw"
> +#define PN544_GPIO_NAME_EN "pn544_en"
> +
> /* framing in HCI mode */
> #define PN544_HCI_I2C_LLC_LEN 1
> #define PN544_HCI_I2C_LLC_CRC 2
> @@ -58,6 +64,13 @@ static struct i2c_device_id pn544_hci_i2c_id_table[] = {
>
> MODULE_DEVICE_TABLE(i2c, pn544_hci_i2c_id_table);
>
> +static const struct acpi_device_id pn544_hci_i2c_acpi_match[] = {
> + {"NXP5440", 0},
> + {}
> +};
> +
> +MODULE_DEVICE_TABLE(acpi, pn544_hci_i2c_acpi_match);
> +
> #define PN544_HCI_I2C_DRIVER_NAME "pn544_hci_i2c"
>
> /*
> @@ -859,6 +872,90 @@ exit_state_wait_secure_write_answer:
> }
> }
>
> +static int pn544_hci_i2c_acpi_request_resources(struct i2c_client *client)
> +{
> + struct pn544_i2c_phy *phy = i2c_get_clientdata(client);
> + const struct acpi_device_id *id;
> + struct gpio_desc *gpiod_en, *gpiod_irq, *gpiod_fw;
> + struct device *dev;
> + int ret;
> +
> + if (!client)
> + return -EINVAL;
> +
> + dev = &client->dev;
> +
> + /* Match the struct device against a given list of ACPI IDs */
> + id = acpi_match_device(dev->driver->acpi_match_table, dev);
> +
> + if (!id)
> + return -ENODEV;
> +
> + /* Get EN GPIO from ACPI */
> + gpiod_en = devm_gpiod_get_index(dev, PN544_GPIO_NAME_EN, 1);
> + if (IS_ERR(gpiod_en)) {
> + nfc_err(dev,
> + "Unable to get EN GPIO\n");
> + return -ENODEV;
> + }
> +
> + phy->gpio_en = desc_to_gpio(gpiod_en);
> +
> + /* Configuration EN GPIO */
> + ret = gpiod_direction_output(gpiod_en, 0);
> + if (ret) {
> + nfc_err(dev, "Fail EN pin direction\n");
> + return ret;
> + }
> +
> + /* Get FW GPIO from ACPI */
> + gpiod_fw = devm_gpiod_get_index(dev, PN544_GPIO_NAME_FW, 2);
> + if (IS_ERR(gpiod_fw)) {
> + nfc_err(dev,
> + "Unable to get FW GPIO\n");
> + return -ENODEV;
> + }
> +
> + phy->gpio_fw = desc_to_gpio(gpiod_fw);
> +
> + /* Configuration FW GPIO */
> + ret = gpiod_direction_output(gpiod_fw, 0);
> + if (ret) {
> + nfc_err(dev, "Fail FW pin direction\n");
> + return ret;
> + }
> +
> + /* Get IRQ GPIO */
> + gpiod_irq = devm_gpiod_get_index(dev, PN544_GPIO_NAME_IRQ, 0);
> + if (IS_ERR(gpiod_irq)) {
> + nfc_err(dev,
> + "Unable to get IRQ GPIO\n");
> + return -ENODEV;
> + }
> +
> + phy->gpio_irq = desc_to_gpio(gpiod_irq);
> +
> + /* Configure IRQ GPIO */
> + ret = gpiod_direction_input(gpiod_irq);
> + if (ret) {
> + nfc_err(dev, "Fail IRQ pin direction\n");
> + return ret;
> + }
> +
> + /* Map the pin to an IRQ */
> + ret = gpiod_to_irq(gpiod_irq);
> + if (ret < 0) {
> + nfc_err(dev, "Fail pin IRQ mapping\n");
> + return ret;
> + }
> +
> + nfc_info(dev, "GPIO resource, no:%d irq:%d\n",
> + desc_to_gpio(gpiod_irq), ret);
> + client->irq = ret;
> +
> + return 0;
> +}
> +
> #ifdef CONFIG_OF
>
> static int pn544_hci_i2c_of_request_resources(struct i2c_client *client)
> @@ -884,7 +981,7 @@ static int pn544_hci_i2c_of_request_resources(struct i2c_client *client)
> phy->gpio_en = ret;
>
> /* Configuration of EN GPIO */
> - ret = gpio_request(phy->gpio_en, "pn544_en");
> + ret = gpio_request(phy->gpio_en, PN544_GPIO_NAME_EN);
> if (ret) {
> nfc_err(&client->dev, "Fail EN pin\n");
> goto err_dt;
> @@ -906,7 +1003,7 @@ static int pn544_hci_i2c_of_request_resources(struct i2c_client *client)
> phy->gpio_fw = ret;
>
> /* Configuration of FW GPIO */
> - ret = gpio_request(phy->gpio_fw, "pn544_fw");
> + ret = gpio_request(phy->gpio_fw, PN544_GPIO_NAME_FW);
> if (ret) {
> nfc_err(&client->dev, "Fail FW pin\n");
> goto err_gpio_en;
> @@ -1001,6 +1098,14 @@ static int pn544_hci_i2c_probe(struct i2c_client *client,
> phy->gpio_en = pdata->get_gpio(NFC_GPIO_ENABLE);
> phy->gpio_fw = pdata->get_gpio(NFC_GPIO_FW_RESET);
> phy->gpio_irq = pdata->get_gpio(NFC_GPIO_IRQ);
> + /* Using ACPI */
> + } else if (ACPI_HANDLE(&client->dev)) {
> + r = pn544_hci_i2c_acpi_request_resources(client);
> + if (r) {
> + nfc_err(&client->dev,
> + "Cannot get ACPI data\n");
> + return r;
> + }
> } else {
> nfc_err(&client->dev, "No platform data\n");
> return -EINVAL;
> @@ -1020,9 +1125,12 @@ static int pn544_hci_i2c_probe(struct i2c_client *client,
> PN544_I2C_FRAME_HEADROOM, PN544_I2C_FRAME_TAILROOM,
> PN544_HCI_I2C_LLC_MAX_PAYLOAD,
> pn544_hci_i2c_fw_download, &phy->hdev);
> - if (r < 0)
> + if (r < 0) {
> + nfc_err(&client->dev, "HCI Probing error\n");
> goto err_hci;
> + }
>
> + nfc_info(&client->dev, "NFC I2C driver loaded\n");
> return 0;
>
> err_hci:
> @@ -1080,6 +1188,7 @@ static struct i2c_driver pn544_hci_i2c_driver = {
> .name = PN544_HCI_I2C_DRIVER_NAME,
> .owner = THIS_MODULE,
> .of_match_table = of_match_ptr(of_pn544_i2c_match),
> + .acpi_match_table = ACPI_PTR(pn544_hci_i2c_acpi_match),
> },
> .probe = pn544_hci_i2c_probe,
> .id_table = pn544_hci_i2c_id_table,
> diff --git a/net/nfc/core.c b/net/nfc/core.c
> index 819b877..a53c2cc 100644
> --- a/net/nfc/core.c
> +++ b/net/nfc/core.c
> @@ -32,6 +32,7 @@
>
> #include "nfc.h"
>
> +#define DEBUG
> #define VERSION "0.1"
>
> #define NFC_CHECK_PRES_FREQ_MS 2000
> --
> 1.9.1
>
> --
> To unsubscribe from this list: send the line "unsubscribe netdev" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH net-next 2/2] flow_dissector: add tipc support
From: erik.hugne @ 2015-01-22 16:10 UTC (permalink / raw)
To: richard.alpe, netdev, jon.maloy, ying.xue; +Cc: tipc-discussion
In-Reply-To: <1421943032-29924-1-git-send-email-erik.hugne@ericsson.com>
From: Erik Hugne <erik.hugne@ericsson.com>
The flows are hashed on the sending node address, which allows us
to spread out the TIPC link processing to RPS enabled cores. There
is no point to include the destination address in the hash as that
will always be the same for all inbound links. We have experimented
with a 3-tuple hash over [srcnode, sport, dport], but this showed to
give slightly lower performance because of increased lock contention
when the same link was handled by multiple cores.
Signed-off-by: Ying Xue <ying.xue@windriver.com>
Signed-off-by: Erik Hugne <erik.hugne@ericsson.com>
Reviewed-by: Jon Maloy <jon.maloy@ericsson.com>
---
net/core/flow_dissector.c | 14 ++++++++++++++
1 file changed, 14 insertions(+)
diff --git a/net/core/flow_dissector.c b/net/core/flow_dissector.c
index 4508493..beb83d1 100644
--- a/net/core/flow_dissector.c
+++ b/net/core/flow_dissector.c
@@ -178,6 +178,20 @@ ipv6:
return false;
}
}
+ case htons(ETH_P_TIPC): {
+ struct {
+ __be32 pre[3];
+ __be32 srcnode;
+ } *hdr, _hdr;
+ hdr = __skb_header_pointer(skb, nhoff, sizeof(_hdr), data, hlen, &_hdr);
+ if (!hdr)
+ return false;
+ flow->src = hdr->srcnode;
+ flow->dst = 0;
+ flow->n_proto = proto;
+ flow->thoff = (u16)nhoff;
+ return true;
+ }
case htons(ETH_P_FCOE):
flow->thoff = (u16)(nhoff + FCOE_HEADER_LEN);
/* fall through */
--
2.1.3
------------------------------------------------------------------------------
New Year. New Location. New Benefits. New Data Center in Ashburn, VA.
GigeNET is offering a free month of service with a new server in Ashburn.
Choose from 2 high performing configs, both with 100TB of bandwidth.
Higher redundancy.Lower latency.Increased capacity.Completely compliant.
http://p.sf.net/sfu/gigenet
^ permalink raw reply related
* [PATCH net-next 1/2] tipc: fix excessive network event logging
From: erik.hugne @ 2015-01-22 16:10 UTC (permalink / raw)
To: richard.alpe, netdev, jon.maloy, ying.xue; +Cc: tipc-discussion, Erik Hugne
From: Erik Hugne <erik.hugne@ericsson.com>
If a large number of namespaces is spawned on a node and TIPC is
enabled in each of these, the excessive printk tracing of network
events will cause the system to grind down to a near halt.
The traces are still of debug value, so instead of removing them
completely we fix it by changing the link state and node availability
logging debug traces.
Signed-off-by: Erik Hugne <erik.hugne@ericsson.com>
---
net/tipc/link.c | 20 ++++++++++----------
net/tipc/node.c | 22 +++++++++++-----------
2 files changed, 21 insertions(+), 21 deletions(-)
diff --git a/net/tipc/link.c b/net/tipc/link.c
index 193bc15..2846ad80 100644
--- a/net/tipc/link.c
+++ b/net/tipc/link.c
@@ -538,8 +538,8 @@ static void link_state_event(struct tipc_link *l_ptr, unsigned int event)
link_set_timer(l_ptr, cont_intv / 4);
break;
case RESET_MSG:
- pr_info("%s<%s>, requested by peer\n", link_rst_msg,
- l_ptr->name);
+ pr_debug("%s<%s>, requested by peer\n",
+ link_rst_msg, l_ptr->name);
tipc_link_reset(l_ptr);
l_ptr->state = RESET_RESET;
l_ptr->fsm_msg_cnt = 0;
@@ -549,7 +549,7 @@ static void link_state_event(struct tipc_link *l_ptr, unsigned int event)
link_set_timer(l_ptr, cont_intv);
break;
default:
- pr_err("%s%u in WW state\n", link_unk_evt, event);
+ pr_debug("%s%u in WW state\n", link_unk_evt, event);
}
break;
case WORKING_UNKNOWN:
@@ -561,8 +561,8 @@ static void link_state_event(struct tipc_link *l_ptr, unsigned int event)
link_set_timer(l_ptr, cont_intv);
break;
case RESET_MSG:
- pr_info("%s<%s>, requested by peer while probing\n",
- link_rst_msg, l_ptr->name);
+ pr_debug("%s<%s>, requested by peer while probing\n",
+ link_rst_msg, l_ptr->name);
tipc_link_reset(l_ptr);
l_ptr->state = RESET_RESET;
l_ptr->fsm_msg_cnt = 0;
@@ -588,8 +588,8 @@ static void link_state_event(struct tipc_link *l_ptr, unsigned int event)
l_ptr->fsm_msg_cnt++;
link_set_timer(l_ptr, cont_intv / 4);
} else { /* Link has failed */
- pr_warn("%s<%s>, peer not responding\n",
- link_rst_msg, l_ptr->name);
+ pr_debug("%s<%s>, peer not responding\n",
+ link_rst_msg, l_ptr->name);
tipc_link_reset(l_ptr);
l_ptr->state = RESET_UNKNOWN;
l_ptr->fsm_msg_cnt = 0;
@@ -1568,9 +1568,9 @@ static void tipc_link_proto_rcv(struct net *net, struct tipc_link *l_ptr,
if (msg_linkprio(msg) &&
(msg_linkprio(msg) != l_ptr->priority)) {
- pr_warn("%s<%s>, priority change %u->%u\n",
- link_rst_msg, l_ptr->name, l_ptr->priority,
- msg_linkprio(msg));
+ pr_debug("%s<%s>, priority change %u->%u\n",
+ link_rst_msg, l_ptr->name,
+ l_ptr->priority, msg_linkprio(msg));
l_ptr->priority = msg_linkprio(msg);
tipc_link_reset(l_ptr); /* Enforce change to take effect */
break;
diff --git a/net/tipc/node.c b/net/tipc/node.c
index b1eb092..ee5d33c 100644
--- a/net/tipc/node.c
+++ b/net/tipc/node.c
@@ -230,8 +230,8 @@ void tipc_node_link_up(struct tipc_node *n_ptr, struct tipc_link *l_ptr)
n_ptr->action_flags |= TIPC_NOTIFY_LINK_UP;
n_ptr->link_id = l_ptr->peer_bearer_id << 16 | l_ptr->bearer_id;
- pr_info("Established link <%s> on network plane %c\n",
- l_ptr->name, l_ptr->net_plane);
+ pr_debug("Established link <%s> on network plane %c\n",
+ l_ptr->name, l_ptr->net_plane);
if (!active[0]) {
active[0] = active[1] = l_ptr;
@@ -239,7 +239,7 @@ void tipc_node_link_up(struct tipc_node *n_ptr, struct tipc_link *l_ptr)
goto exit;
}
if (l_ptr->priority < active[0]->priority) {
- pr_info("New link <%s> becomes standby\n", l_ptr->name);
+ pr_debug("New link <%s> becomes standby\n", l_ptr->name);
goto exit;
}
tipc_link_dup_queue_xmit(active[0], l_ptr);
@@ -247,9 +247,9 @@ void tipc_node_link_up(struct tipc_node *n_ptr, struct tipc_link *l_ptr)
active[0] = l_ptr;
goto exit;
}
- pr_info("Old link <%s> becomes standby\n", active[0]->name);
+ pr_debug("Old link <%s> becomes standby\n", active[0]->name);
if (active[1] != active[0])
- pr_info("Old link <%s> becomes standby\n", active[1]->name);
+ pr_debug("Old link <%s> becomes standby\n", active[1]->name);
active[0] = active[1] = l_ptr;
exit:
/* Leave room for changeover header when returning 'mtu' to users: */
@@ -297,12 +297,12 @@ void tipc_node_link_down(struct tipc_node *n_ptr, struct tipc_link *l_ptr)
n_ptr->link_id = l_ptr->peer_bearer_id << 16 | l_ptr->bearer_id;
if (!tipc_link_is_active(l_ptr)) {
- pr_info("Lost standby link <%s> on network plane %c\n",
- l_ptr->name, l_ptr->net_plane);
+ pr_debug("Lost standby link <%s> on network plane %c\n",
+ l_ptr->name, l_ptr->net_plane);
return;
}
- pr_info("Lost link <%s> on network plane %c\n",
- l_ptr->name, l_ptr->net_plane);
+ pr_debug("Lost link <%s> on network plane %c\n",
+ l_ptr->name, l_ptr->net_plane);
active = &n_ptr->active_links[0];
if (active[0] == l_ptr)
@@ -380,8 +380,8 @@ static void node_lost_contact(struct tipc_node *n_ptr)
char addr_string[16];
u32 i;
- pr_info("Lost contact with %s\n",
- tipc_addr_string_fill(addr_string, n_ptr->addr));
+ pr_debug("Lost contact with %s\n",
+ tipc_addr_string_fill(addr_string, n_ptr->addr));
/* Flush broadcast link info associated with lost node */
if (n_ptr->bclink.recv_permitted) {
--
2.1.3
^ permalink raw reply related
* Re: [patch net-next RFC] tc: introduce OpenFlow classifier
From: Jiri Pirko @ 2015-01-22 16:16 UTC (permalink / raw)
To: Jamal Hadi Salim; +Cc: netdev, davem
In-Reply-To: <54C11C4A.1070206@mojatatu.com>
Thu, Jan 22, 2015 at 04:50:34PM CET, jhs@mojatatu.com wrote:
>On 01/22/15 08:37, Jiri Pirko wrote:
>>This patch introduces OpenFlow-based filter. So far, the very essential
>>packet fields are supported (according to OpenFlow v1.4 spec).
>>
>>Known issues: skb_flow_dissect hashes out ipv6 addresses. That needs
>>to be changed to store them somewhere so they can be used later on.
>>
>>Signed-off-by: Jiri Pirko <jiri@resnulli.us>
>>---
>> include/uapi/linux/pkt_cls.h | 33 +++
>> net/sched/Kconfig | 11 +
>> net/sched/Makefile | 1 +
>> net/sched/cls_openflow.c | 514 +++++++++++++++++++++++++++++++++++++++++++
>> 4 files changed, 559 insertions(+)
>> create mode 100644 net/sched/cls_openflow.c
>>
>>diff --git a/include/uapi/linux/pkt_cls.h b/include/uapi/linux/pkt_cls.h
>>index 25731df..d4cef16 100644
>>--- a/include/uapi/linux/pkt_cls.h
>>+++ b/include/uapi/linux/pkt_cls.h
>>@@ -402,6 +402,39 @@ enum {
>>
>> #define TCA_BPF_MAX (__TCA_BPF_MAX - 1)
>>
>>+/* OpenFlow classifier */
>>+
>>+enum {
>>+ TCA_OF_UNSPEC,
>>+ TCA_OF_CLASSID,
>>+ TCA_OF_POLICE,
>>+ TCA_OF_INDEV,
>
>I think POLICE is an old way of doing policing and INDEV if i am not
>mistaken is only legit for u32 classifier.
>So i am not sure you want to keep them.
I use INDEV for matching skb input device. I can move this to
TCA_OF_KEY_INDEV but since I spotted TCA_*_INDEV, I made this to be the
same.
The POLICE, I just copied from the other cls's
>
>Other than that looks good - will be interested to see how perfomance looks
>on this with the list walking ;->
I plan to do some optimizations as follow-ups. (hash list for example)
>
>cheers,
>jamal
^ permalink raw reply
* Re: [PATCH net-next 0/3] openvswitch: Add STT support.
From: Tom Herbert @ 2015-01-22 16:24 UTC (permalink / raw)
To: Vincent JARDIN
Cc: Jesse Gross, Pravin Shelar, David Miller, Linux Netdev List
In-Reply-To: <54C03A57.4080002@6wind.com>
On Wed, Jan 21, 2015 at 3:46 PM, Vincent JARDIN
<vincent.jardin@6wind.com> wrote:
> Jesse, Tom,
>
> On 21/01/2015 23:14, Jesse Gross wrote:
>>>
>>> I'm not going to try to draw conclusions from data which is obviously
>>> >biased and incomplete. If you want to move forward on this, then just
>>> >provide network interface for STT so we can independently run our own
>>> >comparisons against other encapsulations like we've been doing all
>>> >along.
>>
>> You have the source code, so you are totally free to run whatever
>> tests you like to draw your own conclusions. Personally, I find a more
>> than doubling of performance in the environments that I have seen
>> compelling. Your mileage may vary.
>
>
> +1 for STT in the kernel:
> - whatever the performances, it is needed because it happened to be used.
Vincent, it's not that simple. This is not just another case of an
encapsulation protocol that we can easily ignore and filter because it
hides behind a UDP port or even a new protocol number. This is adding
a new definition to *the* most critical protocol on the planet. I
don't see how this anyone can claim this doesn't violate a whole bunch
of long standing RFCs and break a whole bunch of baked in assumptions
we make about TCP (IP protocol number 6).
For example, TCP MUST have congestion avoidance as per RFC2581:
"The slow start and congestion avoidance algorithms MUST be used by a
TCP sender to control the amount of outstanding data being injected
into the network."
But from STT draft:
"STT segments are transmitted as IP datagrams using the TCP protocol
number (6)."-- that makes this a TCP sender.
"STT does not provide any sort of congestion control."-- that puts STT
in clear violation of RFC2581.
Congestion avoidance for TCP is not just a nice to have, it's not
optional, it's not just best effort like UDP is. There is no provision
for reusing the TCP protocol number and claiming to be exempt from
standards compliance because it's now a different protocol. We build
whole data centers around these principles, and in fact the very
operation of the Internet depends on them. For instance, if we allow
this into the kernel and this becomes available on billions of
devices, what assurances do we have that people won't start abusing
this because they find congestion avoidance annoying and this a
convenient way to bypass it?
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.
Thanks,
Tom
> If the patch can be optimized, someone will do and provide the related
> patches. The patch from Pravin is ok but...
>
> - ...I agree with Tom, a netdevice is a must have to ack't this patch.
> Such feature should not be added into openvswitch without its counter-part
> netdevice.
>
> thank you,
> Vincent
^ permalink raw reply
* Re: [PATCH net 4/4] sh_eth: Fix serialisation of interrupt disable with interrupt & NAPI handlers
From: Sergei Shtylyov @ 2015-01-22 16:35 UTC (permalink / raw)
To: Ben Hutchings
Cc: David S.Miller, netdev, linux-kernel, Nobuhiro Iwamatsu,
Mitsuhiro Kimura, Hisashi Nakamura, Yoshihiro Kaneko
In-Reply-To: <1421939177.1222.298.camel@xylophone.i.decadent.org.uk>
Hello.
On 01/22/2015 06:06 PM, Ben Hutchings wrote:
>>> In order to stop the RX path accessing the RX ring while it's being
>>> stopped or resized, we clear the interrupt mask (EESIPR) and then call
>>> free_irq() or synchronise_irq(). This is insufficient because the
>>> interrupt handler or NAPI poller may set EESIPR again after we clear
>>> it.
>> Hm, how come the interrupt handler gets called when we have disabled all
>> interrupts?
> It may be running on another processor and racing with the function that
> clears EESIPR.
Ah, I didn't think about SMP... but then we need more spinlock protection
instead, no?
>> Is it unmaskable EESR.ECI interrupt? BTW, I'm not seeing where the
>> interrupt handler enables interrupts again; only NAPI poller does that AFAIK.
> Normally it only clears EESR_RX_CHECK, but as it cannot atomically clear
> a single bit of EESIPR this can result in setting other bits.
This is again only possible on SMP kernel, right?
[...]
> Ben.
WBR, Sergei
^ permalink raw reply
* Re: [PATCH net 1/2] net: cls_bpf: fix size mismatch on filter preparation
From: Alexei Starovoitov @ 2015-01-22 16:39 UTC (permalink / raw)
To: Daniel Borkmann
Cc: David S. Miller, Jiří Pírko,
netdev@vger.kernel.org
On Thu, Jan 22, 2015 at 1:41 AM, Daniel Borkmann <dborkman@redhat.com> wrote:
> In cls_bpf_modify_existing(), we read out the number of filter blocks,
> do some sanity checks, allocate a block on that size, and copy over the
> BPF instruction blob from user space, then pass everything through the
> classic BPF checker prior to installation of the classifier.
>
> We should reject mismatches here, there are 2 scenarios: the number of
> filter blocks could be smaller than the provided instruction blob, so
> we do a partial copy of the BPF program, and thus the instructions will
> either be rejected from the verifier or a valid BPF program will be run;
> in the other case, we'll end up copying more than we're supposed to,
> and most likely the trailing garbage will be rejected by the verifier
> as well (i.e. we need to fit instruction pattern, ret {A,K} needs to be
> last instruction, load/stores must be correct, etc); in case not, we
> would leak memory when dumping back instruction patterns. The code should
> have only used nla_len() as Dave noted to avoid this from the beginning.
> Anyway, lets fix it by rejecting such load attempts.
>
> Fixes: 7d1d65cb84e1 ("net: sched: cls_bpf: add BPF-based classifier")
> Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
> Acked-by: Jiri Pirko <jiri@resnulli.us>
Acked-by: Alexei Starovoitov <ast@plumgrid.com>
^ permalink raw reply
* Re: [PATCH net-next 2/2] net: act_bpf: fix size mismatch on filter preparation
From: Alexei Starovoitov @ 2015-01-22 16:44 UTC (permalink / raw)
To: Daniel Borkmann
Cc: David S. Miller, Jiří Pírko,
netdev@vger.kernel.org
In-Reply-To: <1421920699-26556-3-git-send-email-dborkman@redhat.com>
On Thu, Jan 22, 2015 at 1:58 AM, Daniel Borkmann <dborkman@redhat.com> wrote:
> Similarly as in cls_bpf, also this code needs to reject mismatches.
>
> Reference: http://article.gmane.org/gmane.linux.network/347406
> Fixes: d23b8ad8ab23 ("tc: add BPF based action")
> Signed-off-by: Daniel Borkmann <dborkman@redhat.com>
> Acked-by: Jiri Pirko <jiri@resnulli.us>
Acked-by: Alexei Starovoitov <ast@plumgrid.com>
^ permalink raw reply
* Re: [net-next PATCH v3 00/12] Flow API
From: Pablo Neira Ayuso @ 2015-01-22 16:49 UTC (permalink / raw)
To: Thomas Graf
Cc: Jamal Hadi Salim, John Fastabend, simon.horman, sfeldma, netdev,
davem, gerlitz.or, andy, ast, Jiri Pirko
In-Reply-To: <20150122153727.GC25797@casper.infradead.org>
On Thu, Jan 22, 2015 at 03:37:27PM +0000, Thomas Graf wrote:
> On 01/22/15 at 10:28am, Jamal Hadi Salim wrote:
> > On 01/22/15 10:13, Thomas Graf wrote:
> >
> > >I don't follow this. John's proposal allows to decide on a case by
> > >case basis what we want to export. Just like with ethtool or
> > >RTNETLINK. There is no direct access to hardware. A user can only
> > >configure what is being exposed by the kernel.
> > >
> >
> > 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.
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.
I remember to have seen one ugly patch for netfilter that added
several hook functions (not netfilter hooks) at different positions of
the NAT code, the goal was to offload NAT through hardware. I was told
the code that was using those ad-hoc hooks was distributed in a binary
blob.
> This is the whole point of this: Coming up with a model that allows
> to describe capabilities and offer flow programming capabilities
> in a Vendor neutral way. A "push_vlan" or "pop_vlan" action will work
> with any driver that supports it.
Right, we need an abstraction for actions too, and the infrastructure
should not provide any means to circunvent and expose vendor specific
details.
^ 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