* Re: [PATCH perf/core REBASE 3/5] tools lib bpf: Add bpf_prog_{attach,detach}
From: Arnaldo Carvalho de Melo @ 2016-12-20 14:32 UTC (permalink / raw)
To: Joe Stringer; +Cc: linux-kernel, netdev, wangnan0, ast, daniel
In-Reply-To: <20161220141851.GB32756@kernel.org>
Em Tue, Dec 20, 2016 at 11:18:51AM -0300, Arnaldo Carvalho de Melo escreveu:
> Em Wed, Dec 14, 2016 at 02:43:40PM -0800, Joe Stringer escreveu:
> > Commit d8c5b17f2bc0 ("samples: bpf: add userspace example for attaching
> > eBPF programs to cgroups") added these functions to samples/libbpf, but
> > during this merge all of the samples libbpf functionality is shifting to
> > tools/lib/bpf. Shift these functions there.
> >
> > Signed-off-by: Joe Stringer <joe@ovn.org>
> > ---
> > Arnaldo, this is a new patch you didn't previously review which I've
> > prepared due to the conflict with net-next. I figured it's better to try
> > to get samples/bpf properly switched over this window rather than defer the
> > problem and end up having to deal with another merge problem next time
> > around. I hope that is fine for you. If not, this patch onwards will need
> > to be dropped
> >
> > It's a simple copy/paste/delete with a minor change for sys_bpf() vs
> > syscall().
> > ---
> > samples/bpf/libbpf.c | 21 ---------------------
> > samples/bpf/libbpf.h | 3 ---
> > tools/lib/bpf/bpf.c | 21 +++++++++++++++++++++
> > tools/lib/bpf/bpf.h | 3 +++
> > 4 files changed, 24 insertions(+), 24 deletions(-)
> >
> > diff --git a/samples/bpf/libbpf.c b/samples/bpf/libbpf.c
> > index 3391225ad7e9..d9af876b4a2c 100644
> > --- a/samples/bpf/libbpf.c
> > +++ b/samples/bpf/libbpf.c
> > @@ -11,27 +11,6 @@
> > #include <arpa/inet.h>
> > #include "libbpf.h"
> >
> > -int bpf_prog_attach(int prog_fd, int target_fd, enum bpf_attach_type type)
> > -{
> > - union bpf_attr attr = {
> > - .target_fd = target_fd,
> > - .attach_bpf_fd = prog_fd,
> > - .attach_type = type,
> > - };
> > -
> > - return syscall(__NR_bpf, BPF_PROG_ATTACH, &attr, sizeof(attr));
>
> This one makes it fail for CentOS 5 and 6, others may fail as well,
> still building, investigating...
Ok, fixed it by making it follow the model of the other sys_bpf wrappers
setting up that bpf_attr union wrt initializing unamed struct members:
int bpf_prog_attach(int prog_fd, int target_fd, enum bpf_attach_type type)
{
- union bpf_attr attr = {
- .target_fd = target_fd,
- .attach_bpf_fd = prog_fd,
- .attach_type = type,
- };
+ union bpf_attr attr;
+
+ bzero(&attr, sizeof(attr));
+ attr.target_fd = target_fd;
+ attr.attach_bpf_fd = prog_fd;
+ attr.attach_type = type;
return sys_bpf(BPF_PROG_ATTACH, &attr, sizeof(attr));
}
>
> 4 10.853874028 centos:5: FAIL
> ... glibc: [ on ]
> ... gtk2: [ OFF ]
> ... libaudit: [ on ]
> ... libbfd: [ OFF ]
> ... libelf: [ on ]
> ... libnuma: [ on ]
> ... numa_num_possible_cpus: [ OFF ]
> ... libperl: [ on ]
> ... libpython: [ OFF ]
> ... libslang: [ on ]
> ... libcrypto: [ on ]
> ... libunwind: [ OFF ]
> ... libdw-dwarf-unwind: [ OFF ]
> ... zlib: [ on ]
> ... lzma: [ on ]
> ... get_cpuid: [ OFF ]
> ... bpf: [ on ]
>
> Makefile.config:290: No libdw DWARF unwind found, Please install elfutils-devel/libdw-dev >= 0.158 and/or set LIBDW_DIR
> Makefile.config:294: No libdw.h found or old libdw.h found or elfutils is older than 0.138, disables dwarf support. Please install new elfutils-devel/libdw-dev
> Makefile.config:363: DWARF support is off, BPF prologue is disabled
> Makefile.config:417: No libunwind found. Please install libunwind-dev[el] >= 1.1 and/or set LIBUNWIND_DIR
> Makefile.config:444: Disabling post unwind, no support found.
> Makefile.config:530: GTK2 not found, disables GTK2 support. Please install gtk2-devel or libgtk2.0-dev
> Makefile.config:569: No timerfd support. Disables 'perf kvm stat live'
> Makefile.config:589: No 'python-config' tool was found: disables Python support - please install python-devel/python-dev
> Makefile.config:662: No bfd.h/libbfd found, please install binutils-dev[el]/zlib-static/libiberty-dev to gain symbol demangling
> Makefile.config:708: Old numa library found, disables 'perf bench numa mem' benchmark, please install numactl-devel/libnuma-devel/libnuma-dev >= 2.0.8
> Makefile.config:762: Your gcc lacks the __get_cpuid() builtin, disables support for auxtrace/Intel PT, please install a newer gcc
> Makefile.config:792: No openjdk development package found, please install JDK package
> GEN /tmp/build/perf/common-cmds.h
> MKDIR /tmp/build/perf/fd/
> CC /tmp/build/perf/fd/array.o
> CC /tmp/build/perf/event-parse.o
> CC /tmp/build/perf/exec-cmd.o
> MKDIR /tmp/build/perf/fd/
> CC /tmp/build/perf/help.o
> LD /tmp/build/perf/fd/libapi-in.o
> MKDIR /tmp/build/perf/fs/
> CC /tmp/build/perf/fs/fs.o
> CC /tmp/build/perf/event-plugin.o
> CC /tmp/build/perf/pager.o
> MKDIR /tmp/build/perf/fs/
> CC /tmp/build/perf/fs/tracing_path.o
> CC /tmp/build/perf/trace-seq.o
> CC /tmp/build/perf/parse-options.o
> CC /tmp/build/perf/parse-filter.o
> MKDIR /tmp/build/perf/fs/
> LD /tmp/build/perf/fs/libapi-in.o
> CC /tmp/build/perf/cpu.o
> CC /tmp/build/perf/debug.o
> CC /tmp/build/perf/str_error_r.o
> CC /tmp/build/perf/parse-utils.o
> CC /tmp/build/perf/kbuffer-parse.o
> LD /tmp/build/perf/libapi-in.o
> AR /tmp/build/perf/libapi.a
> LD /tmp/build/perf/libtraceevent-in.o
> CC /tmp/build/perf/libbpf.o
> LINK /tmp/build/perf/libtraceevent.a
> MKDIR /tmp/build/perf/pmu-events/
> HOSTCC /tmp/build/perf/pmu-events/json.o
> CC /tmp/build/perf/run-command.o
> MKDIR /tmp/build/perf/pmu-events/
> HOSTCC /tmp/build/perf/pmu-events/jsmn.o
> MKDIR /tmp/build/perf/pmu-events/
> HOSTCC /tmp/build/perf/pmu-events/jevents.o
> CC /tmp/build/perf/bpf.o
> PERF_VERSION = 4.9.0
> CC /tmp/build/perf/sigchain.o
> bpf.c: In function 'bpf_prog_attach':
> bpf.c:174: error: unknown field 'target_fd' specified in initializer
> cc1: warnings being treated as errors
> bpf.c:174: warning: missing braces around initializer
> bpf.c:174: warning: (near initialization for 'attr.<anonymous>')
> bpf.c:175: error: unknown field 'attach_bpf_fd' specified in initializer
> bpf.c:175: warning: excess elements in union initializer
> bpf.c:175: warning: (near initialization for 'attr')
> bpf.c:176: error: unknown field 'attach_type' specified in initializer
> bpf.c:176: warning: excess elements in union initializer
> bpf.c:176: warning: (near initialization for 'attr')
> bpf.c: In function 'bpf_prog_detach':
> bpf.c:185: error: unknown field 'target_fd' specified in initializer
> bpf.c:185: warning: missing braces around initializer
> bpf.c:185: warning: (near initialization for 'attr.<anonymous>')
> bpf.c:186: error: unknown field 'attach_type' specified in initializer
> bpf.c:186: warning: excess elements in union initializer
> bpf.c:186: warning: (near initialization for 'attr')
> mv: cannot stat `/tmp/build/perf/.bpf.o.tmp': No such file or directory
> make[4]: *** [/tmp/build/perf/bpf.o] Error 1
> make[3]: *** [/tmp/build/perf/libbpf-in.o] Error 2
> make[2]: *** [/tmp/build/perf/libbpf.a] Error 2
> make[2]: *** Waiting for unfinished jobs....
> CC /tmp/build/perf/subcmd-config.o
> MKDIR /tmp/build/perf/pmu-events/
> HOSTLD /tmp/build/perf/pmu-events/jevents-in.o
> LD /tmp/build/perf/libsubcmd-in.o
> AR /tmp/build/perf/libsubcmd.a
> make[1]: *** [sub-make] Error 2
> make: *** [all] Error 2
> make: Leaving directory `/git/linux/tools/perf'
>
^ permalink raw reply
* Re: [PATCH] stmmac: enable rx queues
From: Niklas Cassel @ 2016-12-20 14:43 UTC (permalink / raw)
To: Joao Pinto, peppe.cavallaro, davem
Cc: hock.leong.kweh, pavel, linux-kernel, netdev
In-Reply-To: <9a8911dfd2ed07391106e9cd0f90475742a798dc.1482238007.git.jpinto@synopsys.com>
On 12/20/2016 01:55 PM, Joao Pinto wrote:
> When the hardware is synthesized with multiple queues, all queues are
> disabled for default. This patch adds the rx queues configuration.
> This patch was successfully tested in a Synopsys QoS Reference design.
>
> Signed-off-by: Joao Pinto <jpinto@synopsys.com>
> ---
> drivers/net/ethernet/stmicro/stmmac/common.h | 2 ++
> drivers/net/ethernet/stmicro/stmmac/dwmac4.h | 4 ++++
> drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c | 11 +++++++++++
> drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 21 +++++++++++++++++++++
> 4 files changed, 38 insertions(+)
>
> diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
> index b13a144..61bab50 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/common.h
> +++ b/drivers/net/ethernet/stmicro/stmmac/common.h
> @@ -454,6 +454,8 @@ struct stmmac_ops {
> void (*core_init)(struct mac_device_info *hw, int mtu);
> /* Enable and verify that the IPC module is supported */
> int (*rx_ipc)(struct mac_device_info *hw);
> + /* Enable RX Queues */
> + void (*rx_queue_enable)(struct mac_device_info *hw, u32 queue);
> /* Dump MAC registers */
> void (*dump_regs)(struct mac_device_info *hw);
> /* Handle extra events on specific interrupts hw dependent */
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
> index 3e8d4fe..fd013bd 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
> @@ -22,6 +22,7 @@
> #define GMAC_HASH_TAB_32_63 0x00000014
> #define GMAC_RX_FLOW_CTRL 0x00000090
> #define GMAC_QX_TX_FLOW_CTRL(x) (0x70 + x * 4)
> +#define GMAC_RXQ_CTRL0 0x000000a0
> #define GMAC_INT_STATUS 0x000000b0
> #define GMAC_INT_EN 0x000000b4
> #define GMAC_PCS_BASE 0x000000e0
> @@ -44,6 +45,9 @@
>
> #define GMAC_MAX_PERFECT_ADDRESSES 128
>
> +/* MAC RX Queue Enable*/
> +#define GMAC_RX_QUEUE_ENABLE(queue) BIT(queue * 2)
Always have parentheses around a variable in a
macro, otherwise strange things could happen.
Imagine if you send 5 - 4 as argument,
it will then expand to 5 - 4 * 2 = -3,
instead of (5 - 4) * 2 = 2
> +
> /* MAC Flow Control RX */
> #define GMAC_RX_FLOW_CTRL_RFE BIT(0)
>
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
> index eaed7cb..7ec1887 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
> @@ -59,6 +59,16 @@ static void dwmac4_core_init(struct mac_device_info *hw, int mtu)
> writel(value, ioaddr + GMAC_INT_EN);
> }
>
> +static void dwmac4_rx_queue_enable(struct mac_device_info *hw, u32 queue)
> +{
> + void __iomem *ioaddr = hw->pcsr;
> + u32 value = readl(ioaddr + GMAC_RXQ_CTRL0);
> +
> + value |= GMAC_RX_QUEUE_ENABLE(queue);
> +
> + writel(value, ioaddr + GMAC_RXQ_CTRL0);
> +}
> +
> static void dwmac4_dump_regs(struct mac_device_info *hw)
> {
> void __iomem *ioaddr = hw->pcsr;
> @@ -392,6 +402,7 @@ static void dwmac4_debug(void __iomem *ioaddr, struct stmmac_extra_stats *x)
> static const struct stmmac_ops dwmac4_ops = {
> .core_init = dwmac4_core_init,
> .rx_ipc = dwmac4_rx_ipc_enable,
> + .rx_queue_enable = dwmac4_rx_queue_enable,
> .dump_regs = dwmac4_dump_regs,
> .host_irq_status = dwmac4_irq_status,
> .flow_ctrl = dwmac4_flow_ctrl,
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> index 3e40578..e30034d 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> @@ -1271,6 +1271,24 @@ static void free_dma_desc_resources(struct stmmac_priv *priv)
> }
>
> /**
> + * stmmac_mac_enable_rx_queues - Enable MAC rx queues
> + * @priv: driver private structure
> + * Description: It is used for enabling the rx queues in the MAC
> + */
> +static void stmmac_mac_enable_rx_queues(struct stmmac_priv *priv)
> +{
> + int rx_count = priv->dma_cap.number_rx_channel;
priv->dma_cap.number_rx_channel
actually contains the value from register
MAC_HW_Feature2, field RXCHCNT,
which is the number of DMA rx channels.
This is not the same as the number of MTL
receive queues, field RXQCNT in MAC_HW_Feature2.
I guess they will often have the same value,
but since there actually are two different fields
for them, I suppose that is not always the case.
Reading the comments in dwmac4_dma.*
#define DMA_CHANNEL_NB_MAX 1
"Only Channel 0 is actually configured and used"
"Following code only done for channel 0, other channels not yet supported"
Is there any point in actually enabling more than RX queue 0 if the
driver does not yet support more than one channel.
Can RXCHCNT ever be different from RXQCNT?
If so, when? Maybe when using an external DMA IP?
> + int queue = 0;
> +
> + /* If GMAC does not have multiqueues, then this is not necessary*/
> + if (rx_count == 1)
> + return;
> +
> + for (queue = 0; queue < rx_count; queue++)
> + priv->hw->mac->rx_queue_enable(priv->hw, queue);
> +}
> +
> +/**
> * stmmac_dma_operation_mode - HW DMA operation mode
> * @priv: driver private structure
> * Description: it is used for configuring the DMA operation mode register in
> @@ -1691,6 +1709,9 @@ static int stmmac_hw_setup(struct net_device *dev, bool init_ptp)
> /* Initialize the MAC Core */
> priv->hw->mac->core_init(priv->hw, dev->mtu);
>
> + /* Initialize MAC RX Queues */
> + stmmac_mac_enable_rx_queues(priv);
> +
> ret = priv->hw->mac->rx_ipc(priv->hw);
> if (!ret) {
> netdev_warn(priv->dev, "RX IPC Checksum Offload disabled\n");
^ permalink raw reply
* Re: [PATCH] stmmac: enable rx queues
From: Seraphin BONNAFFE @ 2016-12-20 14:52 UTC (permalink / raw)
To: Joao Pinto, peppe.cavallaro, davem
Cc: hock.leong.kweh, niklas.cassel, pavel, linux-kernel, netdev
In-Reply-To: <9a8911dfd2ed07391106e9cd0f90475742a798dc.1482238007.git.jpinto@synopsys.com>
Hi Joao,
Please see my in-line comments.
Regards,
Séraphin
--
Seraphin BONNAFFE | Tel: +33244027061
STMicroelectronics | ADG | S/W Design
On 12/20/2016 01:55 PM, Joao Pinto wrote:
> When the hardware is synthesized with multiple queues, all queues are
> disabled for default. This patch adds the rx queues configuration.
> This patch was successfully tested in a Synopsys QoS Reference design.
>
> Signed-off-by: Joao Pinto <jpinto@synopsys.com>
> ---
> drivers/net/ethernet/stmicro/stmmac/common.h | 2 ++
> drivers/net/ethernet/stmicro/stmmac/dwmac4.h | 4 ++++
> drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c | 11 +++++++++++
> drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 21 +++++++++++++++++++++
> 4 files changed, 38 insertions(+)
>
> diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
> index b13a144..61bab50 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/common.h
> +++ b/drivers/net/ethernet/stmicro/stmmac/common.h
> @@ -454,6 +454,8 @@ struct stmmac_ops {
> void (*core_init)(struct mac_device_info *hw, int mtu);
> /* Enable and verify that the IPC module is supported */
> int (*rx_ipc)(struct mac_device_info *hw);
> + /* Enable RX Queues */
> + void (*rx_queue_enable)(struct mac_device_info *hw, u32 queue);
> /* Dump MAC registers */
> void (*dump_regs)(struct mac_device_info *hw);
> /* Handle extra events on specific interrupts hw dependent */
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
> index 3e8d4fe..fd013bd 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
> @@ -22,6 +22,7 @@
> #define GMAC_HASH_TAB_32_63 0x00000014
> #define GMAC_RX_FLOW_CTRL 0x00000090
> #define GMAC_QX_TX_FLOW_CTRL(x) (0x70 + x * 4)
> +#define GMAC_RXQ_CTRL0 0x000000a0
> #define GMAC_INT_STATUS 0x000000b0
> #define GMAC_INT_EN 0x000000b4
> #define GMAC_PCS_BASE 0x000000e0
> @@ -44,6 +45,9 @@
>
> #define GMAC_MAX_PERFECT_ADDRESSES 128
>
> +/* MAC RX Queue Enable*/
> +#define GMAC_RX_QUEUE_ENABLE(queue) BIT(queue * 2)
According to the GMAC_RXQ0 register description from the dwc_ether_qos_databok, I guess this will enable the queues in AV only.
What if we would like to enable them in DCB (10)b ?
> +
> /* MAC Flow Control RX */
> #define GMAC_RX_FLOW_CTRL_RFE BIT(0)
>
> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
> index eaed7cb..7ec1887 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
> @@ -59,6 +59,16 @@ static void dwmac4_core_init(struct mac_device_info *hw, int mtu)
> writel(value, ioaddr + GMAC_INT_EN);
> }
>
> +static void dwmac4_rx_queue_enable(struct mac_device_info *hw, u32 queue)
> +{
> + void __iomem *ioaddr = hw->pcsr;
> + u32 value = readl(ioaddr + GMAC_RXQ_CTRL0);
> +
> + value |= GMAC_RX_QUEUE_ENABLE(queue);
What happen if for some reason the previous value of the register was 0xffff ?
The OR mask, by itself, won't clear the bits. AFAIU each queue is enabled with a 2-bit value, and (11)b don't have the same effect as (01)b, does it ?
I would suggest to clear the RXQ-enable bits before writing a new value.
Something like
value &= GMAC_RX_QUEUE_CLEAR(queue)
value |= GMAC_RX_QUEUE_ENABLE(queue);
What do you think about that ?
> +
> + writel(value, ioaddr + GMAC_RXQ_CTRL0);
> +}
> +
> static void dwmac4_dump_regs(struct mac_device_info *hw)
> {
> void __iomem *ioaddr = hw->pcsr;
> @@ -392,6 +402,7 @@ static void dwmac4_debug(void __iomem *ioaddr, struct stmmac_extra_stats *x)
> static const struct stmmac_ops dwmac4_ops = {
> .core_init = dwmac4_core_init,
> .rx_ipc = dwmac4_rx_ipc_enable,
> + .rx_queue_enable = dwmac4_rx_queue_enable,
> .dump_regs = dwmac4_dump_regs,
> .host_irq_status = dwmac4_irq_status,
> .flow_ctrl = dwmac4_flow_ctrl,
> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> index 3e40578..e30034d 100644
> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
> @@ -1271,6 +1271,24 @@ static void free_dma_desc_resources(struct stmmac_priv *priv)
> }
>
> /**
> + * stmmac_mac_enable_rx_queues - Enable MAC rx queues
> + * @priv: driver private structure
> + * Description: It is used for enabling the rx queues in the MAC
> + */
> +static void stmmac_mac_enable_rx_queues(struct stmmac_priv *priv)
> +{
> + int rx_count = priv->dma_cap.number_rx_channel;
> + int queue = 0;
> +
> + /* If GMAC does not have multiqueues, then this is not necessary*/
> + if (rx_count == 1)
> + return;
> +
> + for (queue = 0; queue < rx_count; queue++)
> + priv->hw->mac->rx_queue_enable(priv->hw, queue);
Maybe it is worth checking if (priv->hw->mac->rx_queue_enable)
before actually calling this callback ?
I can see you have implemented it for dwmac4, but not for dwmac100 and dwmac100
In that case we may have a null pointer exception here.
> +}
> +
> +/**
> * stmmac_dma_operation_mode - HW DMA operation mode
> * @priv: driver private structure
> * Description: it is used for configuring the DMA operation mode register in
> @@ -1691,6 +1709,9 @@ static int stmmac_hw_setup(struct net_device *dev, bool init_ptp)
> /* Initialize the MAC Core */
> priv->hw->mac->core_init(priv->hw, dev->mtu);
>
> + /* Initialize MAC RX Queues */
> + stmmac_mac_enable_rx_queues(priv);
> +
> ret = priv->hw->mac->rx_ipc(priv->hw);
> if (!ret) {
> netdev_warn(priv->dev, "RX IPC Checksum Offload disabled\n");
>
^ permalink raw reply
* Re: [PATCH] stmmac: enable rx queues
From: Joao Pinto @ 2016-12-20 14:52 UTC (permalink / raw)
To: Niklas Cassel, Joao Pinto, peppe.cavallaro, davem
Cc: hock.leong.kweh, pavel, linux-kernel, netdev
In-Reply-To: <f5cda4a7-8c41-86b7-b133-cf41eaec0370@axis.com>
Hi Niklas,
Às 2:43 PM de 12/20/2016, Niklas Cassel escreveu:
>
>
> On 12/20/2016 01:55 PM, Joao Pinto wrote:
>> When the hardware is synthesized with multiple queues, all queues are
>> disabled for default. This patch adds the rx queues configuration.
>> This patch was successfully tested in a Synopsys QoS Reference design.
>>
>> Signed-off-by: Joao Pinto <jpinto@synopsys.com>
>> ---
>> drivers/net/ethernet/stmicro/stmmac/common.h | 2 ++
>> drivers/net/ethernet/stmicro/stmmac/dwmac4.h | 4 ++++
>> drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c | 11 +++++++++++
>> drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 21 +++++++++++++++++++++
>> 4 files changed, 38 insertions(+)
>>
>> diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
>> index b13a144..61bab50 100644
>> --- a/drivers/net/ethernet/stmicro/stmmac/common.h
>> +++ b/drivers/net/ethernet/stmicro/stmmac/common.h
>> @@ -454,6 +454,8 @@ struct stmmac_ops {
>> void (*core_init)(struct mac_device_info *hw, int mtu);
>> /* Enable and verify that the IPC module is supported */
>> int (*rx_ipc)(struct mac_device_info *hw);
>> + /* Enable RX Queues */
>> + void (*rx_queue_enable)(struct mac_device_info *hw, u32 queue);
>> /* Dump MAC registers */
>> void (*dump_regs)(struct mac_device_info *hw);
>> /* Handle extra events on specific interrupts hw dependent */
>> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
>> index 3e8d4fe..fd013bd 100644
>> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
>> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
>> @@ -22,6 +22,7 @@
>> #define GMAC_HASH_TAB_32_63 0x00000014
>> #define GMAC_RX_FLOW_CTRL 0x00000090
>> #define GMAC_QX_TX_FLOW_CTRL(x) (0x70 + x * 4)
>> +#define GMAC_RXQ_CTRL0 0x000000a0
>> #define GMAC_INT_STATUS 0x000000b0
>> #define GMAC_INT_EN 0x000000b4
>> #define GMAC_PCS_BASE 0x000000e0
>> @@ -44,6 +45,9 @@
>>
>> #define GMAC_MAX_PERFECT_ADDRESSES 128
>>
>> +/* MAC RX Queue Enable*/
>> +#define GMAC_RX_QUEUE_ENABLE(queue) BIT(queue * 2)
>
> Always have parentheses around a variable in a
> macro, otherwise strange things could happen.
> Imagine if you send 5 - 4 as argument,
> it will then expand to 5 - 4 * 2 = -3,
> instead of (5 - 4) * 2 = 2
Right. I am going to do that.
>
>> +
>> /* MAC Flow Control RX */
>> #define GMAC_RX_FLOW_CTRL_RFE BIT(0)
>>
>> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
>> index eaed7cb..7ec1887 100644
>> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
>> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
>> @@ -59,6 +59,16 @@ static void dwmac4_core_init(struct mac_device_info *hw, int mtu)
>> writel(value, ioaddr + GMAC_INT_EN);
>> }
>>
>> +static void dwmac4_rx_queue_enable(struct mac_device_info *hw, u32 queue)
>> +{
>> + void __iomem *ioaddr = hw->pcsr;
>> + u32 value = readl(ioaddr + GMAC_RXQ_CTRL0);
>> +
>> + value |= GMAC_RX_QUEUE_ENABLE(queue);
>> +
>> + writel(value, ioaddr + GMAC_RXQ_CTRL0);
>> +}
>> +
>> static void dwmac4_dump_regs(struct mac_device_info *hw)
>> {
>> void __iomem *ioaddr = hw->pcsr;
>> @@ -392,6 +402,7 @@ static void dwmac4_debug(void __iomem *ioaddr, struct stmmac_extra_stats *x)
>> static const struct stmmac_ops dwmac4_ops = {
>> .core_init = dwmac4_core_init,
>> .rx_ipc = dwmac4_rx_ipc_enable,
>> + .rx_queue_enable = dwmac4_rx_queue_enable,
>> .dump_regs = dwmac4_dump_regs,
>> .host_irq_status = dwmac4_irq_status,
>> .flow_ctrl = dwmac4_flow_ctrl,
>> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>> index 3e40578..e30034d 100644
>> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>> @@ -1271,6 +1271,24 @@ static void free_dma_desc_resources(struct stmmac_priv *priv)
>> }
>>
>> /**
>> + * stmmac_mac_enable_rx_queues - Enable MAC rx queues
>> + * @priv: driver private structure
>> + * Description: It is used for enabling the rx queues in the MAC
>> + */
>> +static void stmmac_mac_enable_rx_queues(struct stmmac_priv *priv)
>> +{
>> + int rx_count = priv->dma_cap.number_rx_channel;
>
> priv->dma_cap.number_rx_channel
> actually contains the value from register
> MAC_HW_Feature2, field RXCHCNT,
> which is the number of DMA rx channels.
>
> This is not the same as the number of MTL
> receive queues, field RXQCNT in MAC_HW_Feature2.
>
> I guess they will often have the same value,
> but since there actually are two different fields
> for them, I suppose that is not always the case.
Yes, you typically have a match between channels and queues.
But I can use RXQCNT of course, I agree.
>
>
>
> Reading the comments in dwmac4_dma.*
>
> #define DMA_CHANNEL_NB_MAX 1
>
> "Only Channel 0 is actually configured and used"
>
> "Following code only done for channel 0, other channels not yet supported"
>
> Is there any point in actually enabling more than RX queue 0 if the
> driver does not yet support more than one channel.
> Can RXCHCNT ever be different from RXQCNT?
> If so, when? Maybe when using an external DMA IP?
Yes, currently stmmac only supports 1 Channel. Bt it needs this feature if the
hardware is multi-channel. The hardware I have is multi-channel and so you have
to enable RX queue for it to work and that's why I made this fix.
In the future I will develope multi channel support for stmmac and this RX queue
enable will be already made.
>
>
>> + int queue = 0;
>> +
>> + /* If GMAC does not have multiqueues, then this is not necessary*/
>> + if (rx_count == 1)
>> + return;
>> +
>> + for (queue = 0; queue < rx_count; queue++)
>> + priv->hw->mac->rx_queue_enable(priv->hw, queue);
>> +}
>> +
>> +/**
>> * stmmac_dma_operation_mode - HW DMA operation mode
>> * @priv: driver private structure
>> * Description: it is used for configuring the DMA operation mode register in
>> @@ -1691,6 +1709,9 @@ static int stmmac_hw_setup(struct net_device *dev, bool init_ptp)
>> /* Initialize the MAC Core */
>> priv->hw->mac->core_init(priv->hw, dev->mtu);
>>
>> + /* Initialize MAC RX Queues */
>> + stmmac_mac_enable_rx_queues(priv);
>> +
>> ret = priv->hw->mac->rx_ipc(priv->hw);
>> if (!ret) {
>> netdev_warn(priv->dev, "RX IPC Checksum Offload disabled\n");
>
^ permalink raw reply
* Re: [PATCH] stmmac: enable rx queues
From: Joao Pinto @ 2016-12-20 14:59 UTC (permalink / raw)
To: Seraphin BONNAFFE, Joao Pinto, peppe.cavallaro, davem
Cc: hock.leong.kweh, niklas.cassel, pavel, linux-kernel, netdev
In-Reply-To: <ba998f36-4ae2-10f3-2483-14b0bf351037@st.com>
Hi Séraphin,
Às 2:52 PM de 12/20/2016, Seraphin BONNAFFE escreveu:
> Hi Joao,
>
> Please see my in-line comments.
>
> Regards,
> Séraphin
> --
> Seraphin BONNAFFE | Tel: +33244027061
> STMicroelectronics | ADG | S/W Design
>
> On 12/20/2016 01:55 PM, Joao Pinto wrote:
>> When the hardware is synthesized with multiple queues, all queues are
>> disabled for default. This patch adds the rx queues configuration.
>> This patch was successfully tested in a Synopsys QoS Reference design.
>>
>> Signed-off-by: Joao Pinto <jpinto@synopsys.com>
>> ---
>> drivers/net/ethernet/stmicro/stmmac/common.h | 2 ++
>> drivers/net/ethernet/stmicro/stmmac/dwmac4.h | 4 ++++
>> drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c | 11 +++++++++++
>> drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 21 +++++++++++++++++++++
>> 4 files changed, 38 insertions(+)
>>
>> diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h
>> b/drivers/net/ethernet/stmicro/stmmac/common.h
>> index b13a144..61bab50 100644
>> --- a/drivers/net/ethernet/stmicro/stmmac/common.h
>> +++ b/drivers/net/ethernet/stmicro/stmmac/common.h
>> @@ -454,6 +454,8 @@ struct stmmac_ops {
>> void (*core_init)(struct mac_device_info *hw, int mtu);
>> /* Enable and verify that the IPC module is supported */
>> int (*rx_ipc)(struct mac_device_info *hw);
>> + /* Enable RX Queues */
>> + void (*rx_queue_enable)(struct mac_device_info *hw, u32 queue);
>> /* Dump MAC registers */
>> void (*dump_regs)(struct mac_device_info *hw);
>> /* Handle extra events on specific interrupts hw dependent */
>> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
>> b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
>> index 3e8d4fe..fd013bd 100644
>> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
>> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
>> @@ -22,6 +22,7 @@
>> #define GMAC_HASH_TAB_32_63 0x00000014
>> #define GMAC_RX_FLOW_CTRL 0x00000090
>> #define GMAC_QX_TX_FLOW_CTRL(x) (0x70 + x * 4)
>> +#define GMAC_RXQ_CTRL0 0x000000a0
>> #define GMAC_INT_STATUS 0x000000b0
>> #define GMAC_INT_EN 0x000000b4
>> #define GMAC_PCS_BASE 0x000000e0
>> @@ -44,6 +45,9 @@
>>
>> #define GMAC_MAX_PERFECT_ADDRESSES 128
>>
>> +/* MAC RX Queue Enable*/
>> +#define GMAC_RX_QUEUE_ENABLE(queue) BIT(queue * 2)
>
> According to the GMAC_RXQ0 register description from the dwc_ether_qos_databok,
> I guess this will enable the queues in AV only.
> What if we would like to enable them in DCB (10)b ?
Correct, I am enabling AV only. What you are saying makes perfect sense. What
about adding a variable to plat in order to configure the RX queue type?
Example:
plat->rx_queue_type = RX_QUEUE_DCB or plat->rx_queue_type = RX_QUEUE_AV
>
>
>> +
>> /* MAC Flow Control RX */
>> #define GMAC_RX_FLOW_CTRL_RFE BIT(0)
>>
>> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
>> b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
>> index eaed7cb..7ec1887 100644
>> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
>> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
>> @@ -59,6 +59,16 @@ static void dwmac4_core_init(struct mac_device_info *hw,
>> int mtu)
>> writel(value, ioaddr + GMAC_INT_EN);
>> }
>>
>> +static void dwmac4_rx_queue_enable(struct mac_device_info *hw, u32 queue)
>> +{
>> + void __iomem *ioaddr = hw->pcsr;
>> + u32 value = readl(ioaddr + GMAC_RXQ_CTRL0);
>> +
>> + value |= GMAC_RX_QUEUE_ENABLE(queue);
>
> What happen if for some reason the previous value of the register was 0xffff ?
> The OR mask, by itself, won't clear the bits. AFAIU each queue is enabled with a
> 2-bit value, and (11)b don't have the same effect as (01)b, does it ?
>
> I would suggest to clear the RXQ-enable bits before writing a new value.
> Something like
> value &= GMAC_RX_QUEUE_CLEAR(queue)
> value |= GMAC_RX_QUEUE_ENABLE(queue);
>
> What do you think about that ?
According to the databook, these values are always reset, but we can force it to
clear as you suggest.
>
>> +
>> + writel(value, ioaddr + GMAC_RXQ_CTRL0);
>> +}
>> +
>> static void dwmac4_dump_regs(struct mac_device_info *hw)
>> {
>> void __iomem *ioaddr = hw->pcsr;
>> @@ -392,6 +402,7 @@ static void dwmac4_debug(void __iomem *ioaddr, struct
>> stmmac_extra_stats *x)
>> static const struct stmmac_ops dwmac4_ops = {
>> .core_init = dwmac4_core_init,
>> .rx_ipc = dwmac4_rx_ipc_enable,
>> + .rx_queue_enable = dwmac4_rx_queue_enable,
>> .dump_regs = dwmac4_dump_regs,
>> .host_irq_status = dwmac4_irq_status,
>> .flow_ctrl = dwmac4_flow_ctrl,
>> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>> b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>> index 3e40578..e30034d 100644
>> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>> @@ -1271,6 +1271,24 @@ static void free_dma_desc_resources(struct stmmac_priv
>> *priv)
>> }
>>
>> /**
>> + * stmmac_mac_enable_rx_queues - Enable MAC rx queues
>> + * @priv: driver private structure
>> + * Description: It is used for enabling the rx queues in the MAC
>> + */
>> +static void stmmac_mac_enable_rx_queues(struct stmmac_priv *priv)
>> +{
>> + int rx_count = priv->dma_cap.number_rx_channel;
>> + int queue = 0;
>> +
>> + /* If GMAC does not have multiqueues, then this is not necessary*/
>> + if (rx_count == 1)
>> + return;
>> +
>> + for (queue = 0; queue < rx_count; queue++)
>> + priv->hw->mac->rx_queue_enable(priv->hw, queue);
>
>
> Maybe it is worth checking if (priv->hw->mac->rx_queue_enable)
> before actually calling this callback ?
> I can see you have implemented it for dwmac4, but not for dwmac100 and dwmac100
> In that case we may have a null pointer exception here.
Yes, you are absolutely correct. Since I am using gmac4, I forgot that stmmac
can use other types.
>
>> +}
>> +
>> +/**
>> * stmmac_dma_operation_mode - HW DMA operation mode
>> * @priv: driver private structure
>> * Description: it is used for configuring the DMA operation mode register in
>> @@ -1691,6 +1709,9 @@ static int stmmac_hw_setup(struct net_device *dev, bool
>> init_ptp)
>> /* Initialize the MAC Core */
>> priv->hw->mac->core_init(priv->hw, dev->mtu);
>>
>> + /* Initialize MAC RX Queues */
>> + stmmac_mac_enable_rx_queues(priv);
>> +
>> ret = priv->hw->mac->rx_ipc(priv->hw);
>> if (!ret) {
>> netdev_warn(priv->dev, "RX IPC Checksum Offload disabled\n");
>>
Thanks.
^ permalink raw reply
* Re: [PATCH] stmmac: enable rx queues
From: Niklas Cassel @ 2016-12-20 15:05 UTC (permalink / raw)
To: Joao Pinto, peppe.cavallaro, davem
Cc: hock.leong.kweh, pavel, linux-kernel, netdev
In-Reply-To: <020e1c77-504e-3cfc-e526-ce1645fd6b32@synopsys.com>
On 12/20/2016 03:52 PM, Joao Pinto wrote:
> Hi Niklas,
>
> Às 2:43 PM de 12/20/2016, Niklas Cassel escreveu:
>>
>> On 12/20/2016 01:55 PM, Joao Pinto wrote:
>>> When the hardware is synthesized with multiple queues, all queues are
>>> disabled for default. This patch adds the rx queues configuration.
>>> This patch was successfully tested in a Synopsys QoS Reference design.
>>>
>>> Signed-off-by: Joao Pinto <jpinto@synopsys.com>
>>> ---
>>> drivers/net/ethernet/stmicro/stmmac/common.h | 2 ++
>>> drivers/net/ethernet/stmicro/stmmac/dwmac4.h | 4 ++++
>>> drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c | 11 +++++++++++
>>> drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 21 +++++++++++++++++++++
>>> 4 files changed, 38 insertions(+)
>>>
>>> diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
>>> index b13a144..61bab50 100644
>>> --- a/drivers/net/ethernet/stmicro/stmmac/common.h
>>> +++ b/drivers/net/ethernet/stmicro/stmmac/common.h
>>> @@ -454,6 +454,8 @@ struct stmmac_ops {
>>> void (*core_init)(struct mac_device_info *hw, int mtu);
>>> /* Enable and verify that the IPC module is supported */
>>> int (*rx_ipc)(struct mac_device_info *hw);
>>> + /* Enable RX Queues */
>>> + void (*rx_queue_enable)(struct mac_device_info *hw, u32 queue);
>>> /* Dump MAC registers */
>>> void (*dump_regs)(struct mac_device_info *hw);
>>> /* Handle extra events on specific interrupts hw dependent */
>>> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
>>> index 3e8d4fe..fd013bd 100644
>>> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
>>> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
>>> @@ -22,6 +22,7 @@
>>> #define GMAC_HASH_TAB_32_63 0x00000014
>>> #define GMAC_RX_FLOW_CTRL 0x00000090
>>> #define GMAC_QX_TX_FLOW_CTRL(x) (0x70 + x * 4)
>>> +#define GMAC_RXQ_CTRL0 0x000000a0
>>> #define GMAC_INT_STATUS 0x000000b0
>>> #define GMAC_INT_EN 0x000000b4
>>> #define GMAC_PCS_BASE 0x000000e0
>>> @@ -44,6 +45,9 @@
>>>
>>> #define GMAC_MAX_PERFECT_ADDRESSES 128
>>>
>>> +/* MAC RX Queue Enable*/
>>> +#define GMAC_RX_QUEUE_ENABLE(queue) BIT(queue * 2)
>> Always have parentheses around a variable in a
>> macro, otherwise strange things could happen.
>> Imagine if you send 5 - 4 as argument,
>> it will then expand to 5 - 4 * 2 = -3,
>> instead of (5 - 4) * 2 = 2
> Right. I am going to do that.
>
>>> +
>>> /* MAC Flow Control RX */
>>> #define GMAC_RX_FLOW_CTRL_RFE BIT(0)
>>>
>>> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
>>> index eaed7cb..7ec1887 100644
>>> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
>>> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
>>> @@ -59,6 +59,16 @@ static void dwmac4_core_init(struct mac_device_info *hw, int mtu)
>>> writel(value, ioaddr + GMAC_INT_EN);
>>> }
>>>
>>> +static void dwmac4_rx_queue_enable(struct mac_device_info *hw, u32 queue)
>>> +{
>>> + void __iomem *ioaddr = hw->pcsr;
>>> + u32 value = readl(ioaddr + GMAC_RXQ_CTRL0);
>>> +
>>> + value |= GMAC_RX_QUEUE_ENABLE(queue);
>>> +
>>> + writel(value, ioaddr + GMAC_RXQ_CTRL0);
>>> +}
>>> +
>>> static void dwmac4_dump_regs(struct mac_device_info *hw)
>>> {
>>> void __iomem *ioaddr = hw->pcsr;
>>> @@ -392,6 +402,7 @@ static void dwmac4_debug(void __iomem *ioaddr, struct stmmac_extra_stats *x)
>>> static const struct stmmac_ops dwmac4_ops = {
>>> .core_init = dwmac4_core_init,
>>> .rx_ipc = dwmac4_rx_ipc_enable,
>>> + .rx_queue_enable = dwmac4_rx_queue_enable,
>>> .dump_regs = dwmac4_dump_regs,
>>> .host_irq_status = dwmac4_irq_status,
>>> .flow_ctrl = dwmac4_flow_ctrl,
>>> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>>> index 3e40578..e30034d 100644
>>> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>>> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>>> @@ -1271,6 +1271,24 @@ static void free_dma_desc_resources(struct stmmac_priv *priv)
>>> }
>>>
>>> /**
>>> + * stmmac_mac_enable_rx_queues - Enable MAC rx queues
>>> + * @priv: driver private structure
>>> + * Description: It is used for enabling the rx queues in the MAC
>>> + */
>>> +static void stmmac_mac_enable_rx_queues(struct stmmac_priv *priv)
>>> +{
>>> + int rx_count = priv->dma_cap.number_rx_channel;
>> priv->dma_cap.number_rx_channel
>> actually contains the value from register
>> MAC_HW_Feature2, field RXCHCNT,
>> which is the number of DMA rx channels.
>>
>> This is not the same as the number of MTL
>> receive queues, field RXQCNT in MAC_HW_Feature2.
>>
>> I guess they will often have the same value,
>> but since there actually are two different fields
>> for them, I suppose that is not always the case.
> Yes, you typically have a match between channels and queues.
> But I can use RXQCNT of course, I agree.
>
>>
>>
>> Reading the comments in dwmac4_dma.*
>>
>> #define DMA_CHANNEL_NB_MAX 1
>>
>> "Only Channel 0 is actually configured and used"
>>
>> "Following code only done for channel 0, other channels not yet supported"
>>
>> Is there any point in actually enabling more than RX queue 0 if the
>> driver does not yet support more than one channel.
>> Can RXCHCNT ever be different from RXQCNT?
>> If so, when? Maybe when using an external DMA IP?
> Yes, currently stmmac only supports 1 Channel. Bt it needs this feature if the
> hardware is multi-channel. The hardware I have is multi-channel and so you have
> to enable RX queue for it to work and that's why I made this fix.
> In the future I will develope multi channel support for stmmac and this RX queue
> enable will be already made.
I understand that for multi-queue hardware, RX queue 0 is default off,
but perhaps it is safer to only enable RX queue 0,
even if you have more than one RX queue.
(Only until you have implemented actual support for multi-queues
in the driver.)
But if you know that it's safe to enable all RX queues even if the
driver only uses RX queue 0, then perhaps it doesn't matter.
>
>>
>>> + int queue = 0;
>>> +
>>> + /* If GMAC does not have multiqueues, then this is not necessary*/
>>> + if (rx_count == 1)
>>> + return;
>>> +
>>> + for (queue = 0; queue < rx_count; queue++)
>>> + priv->hw->mac->rx_queue_enable(priv->hw, queue);
>>> +}
>>> +
>>> +/**
>>> * stmmac_dma_operation_mode - HW DMA operation mode
>>> * @priv: driver private structure
>>> * Description: it is used for configuring the DMA operation mode register in
>>> @@ -1691,6 +1709,9 @@ static int stmmac_hw_setup(struct net_device *dev, bool init_ptp)
>>> /* Initialize the MAC Core */
>>> priv->hw->mac->core_init(priv->hw, dev->mtu);
>>>
>>> + /* Initialize MAC RX Queues */
>>> + stmmac_mac_enable_rx_queues(priv);
>>> +
>>> ret = priv->hw->mac->rx_ipc(priv->hw);
>>> if (!ret) {
>>> netdev_warn(priv->dev, "RX IPC Checksum Offload disabled\n");
^ permalink raw reply
* Re: [PATCH] stmmac: enable rx queues
From: Joao Pinto @ 2016-12-20 15:09 UTC (permalink / raw)
To: Niklas Cassel, Joao Pinto, peppe.cavallaro, davem
Cc: hock.leong.kweh, pavel, linux-kernel, netdev
In-Reply-To: <a345494e-0e8b-9233-ed13-9dedc88328c2@axis.com>
Às 3:05 PM de 12/20/2016, Niklas Cassel escreveu:
>
>
> On 12/20/2016 03:52 PM, Joao Pinto wrote:
>> Hi Niklas,
>>
>> Às 2:43 PM de 12/20/2016, Niklas Cassel escreveu:
>>>
>>> On 12/20/2016 01:55 PM, Joao Pinto wrote:
>>>> When the hardware is synthesized with multiple queues, all queues are
>>>> disabled for default. This patch adds the rx queues configuration.
>>>> This patch was successfully tested in a Synopsys QoS Reference design.
>>>>
>>>> Signed-off-by: Joao Pinto <jpinto@synopsys.com>
>>>> ---
>>>> drivers/net/ethernet/stmicro/stmmac/common.h | 2 ++
>>>> drivers/net/ethernet/stmicro/stmmac/dwmac4.h | 4 ++++
>>>> drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c | 11 +++++++++++
>>>> drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 21 +++++++++++++++++++++
>>>> 4 files changed, 38 insertions(+)
>>>>
>>>> diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h b/drivers/net/ethernet/stmicro/stmmac/common.h
>>>> index b13a144..61bab50 100644
>>>> --- a/drivers/net/ethernet/stmicro/stmmac/common.h
>>>> +++ b/drivers/net/ethernet/stmicro/stmmac/common.h
>>>> @@ -454,6 +454,8 @@ struct stmmac_ops {
>>>> void (*core_init)(struct mac_device_info *hw, int mtu);
>>>> /* Enable and verify that the IPC module is supported */
>>>> int (*rx_ipc)(struct mac_device_info *hw);
>>>> + /* Enable RX Queues */
>>>> + void (*rx_queue_enable)(struct mac_device_info *hw, u32 queue);
>>>> /* Dump MAC registers */
>>>> void (*dump_regs)(struct mac_device_info *hw);
>>>> /* Handle extra events on specific interrupts hw dependent */
>>>> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
>>>> index 3e8d4fe..fd013bd 100644
>>>> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
>>>> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
>>>> @@ -22,6 +22,7 @@
>>>> #define GMAC_HASH_TAB_32_63 0x00000014
>>>> #define GMAC_RX_FLOW_CTRL 0x00000090
>>>> #define GMAC_QX_TX_FLOW_CTRL(x) (0x70 + x * 4)
>>>> +#define GMAC_RXQ_CTRL0 0x000000a0
>>>> #define GMAC_INT_STATUS 0x000000b0
>>>> #define GMAC_INT_EN 0x000000b4
>>>> #define GMAC_PCS_BASE 0x000000e0
>>>> @@ -44,6 +45,9 @@
>>>>
>>>> #define GMAC_MAX_PERFECT_ADDRESSES 128
>>>>
>>>> +/* MAC RX Queue Enable*/
>>>> +#define GMAC_RX_QUEUE_ENABLE(queue) BIT(queue * 2)
>>> Always have parentheses around a variable in a
>>> macro, otherwise strange things could happen.
>>> Imagine if you send 5 - 4 as argument,
>>> it will then expand to 5 - 4 * 2 = -3,
>>> instead of (5 - 4) * 2 = 2
>> Right. I am going to do that.
>>
>>>> +
>>>> /* MAC Flow Control RX */
>>>> #define GMAC_RX_FLOW_CTRL_RFE BIT(0)
>>>>
>>>> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
>>>> index eaed7cb..7ec1887 100644
>>>> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
>>>> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
>>>> @@ -59,6 +59,16 @@ static void dwmac4_core_init(struct mac_device_info *hw, int mtu)
>>>> writel(value, ioaddr + GMAC_INT_EN);
>>>> }
>>>>
>>>> +static void dwmac4_rx_queue_enable(struct mac_device_info *hw, u32 queue)
>>>> +{
>>>> + void __iomem *ioaddr = hw->pcsr;
>>>> + u32 value = readl(ioaddr + GMAC_RXQ_CTRL0);
>>>> +
>>>> + value |= GMAC_RX_QUEUE_ENABLE(queue);
>>>> +
>>>> + writel(value, ioaddr + GMAC_RXQ_CTRL0);
>>>> +}
>>>> +
>>>> static void dwmac4_dump_regs(struct mac_device_info *hw)
>>>> {
>>>> void __iomem *ioaddr = hw->pcsr;
>>>> @@ -392,6 +402,7 @@ static void dwmac4_debug(void __iomem *ioaddr, struct stmmac_extra_stats *x)
>>>> static const struct stmmac_ops dwmac4_ops = {
>>>> .core_init = dwmac4_core_init,
>>>> .rx_ipc = dwmac4_rx_ipc_enable,
>>>> + .rx_queue_enable = dwmac4_rx_queue_enable,
>>>> .dump_regs = dwmac4_dump_regs,
>>>> .host_irq_status = dwmac4_irq_status,
>>>> .flow_ctrl = dwmac4_flow_ctrl,
>>>> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>>>> index 3e40578..e30034d 100644
>>>> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>>>> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>>>> @@ -1271,6 +1271,24 @@ static void free_dma_desc_resources(struct stmmac_priv *priv)
>>>> }
>>>>
>>>> /**
>>>> + * stmmac_mac_enable_rx_queues - Enable MAC rx queues
>>>> + * @priv: driver private structure
>>>> + * Description: It is used for enabling the rx queues in the MAC
>>>> + */
>>>> +static void stmmac_mac_enable_rx_queues(struct stmmac_priv *priv)
>>>> +{
>>>> + int rx_count = priv->dma_cap.number_rx_channel;
>>> priv->dma_cap.number_rx_channel
>>> actually contains the value from register
>>> MAC_HW_Feature2, field RXCHCNT,
>>> which is the number of DMA rx channels.
>>>
>>> This is not the same as the number of MTL
>>> receive queues, field RXQCNT in MAC_HW_Feature2.
>>>
>>> I guess they will often have the same value,
>>> but since there actually are two different fields
>>> for them, I suppose that is not always the case.
>> Yes, you typically have a match between channels and queues.
>> But I can use RXQCNT of course, I agree.
>>
>>>
>>>
>>> Reading the comments in dwmac4_dma.*
>>>
>>> #define DMA_CHANNEL_NB_MAX 1
>>>
>>> "Only Channel 0 is actually configured and used"
>>>
>>> "Following code only done for channel 0, other channels not yet supported"
>>>
>>> Is there any point in actually enabling more than RX queue 0 if the
>>> driver does not yet support more than one channel.
>>> Can RXCHCNT ever be different from RXQCNT?
>>> If so, when? Maybe when using an external DMA IP?
>> Yes, currently stmmac only supports 1 Channel. Bt it needs this feature if the
>> hardware is multi-channel. The hardware I have is multi-channel and so you have
>> to enable RX queue for it to work and that's why I made this fix.
>> In the future I will develope multi channel support for stmmac and this RX queue
>> enable will be already made.
>
> I understand that for multi-queue hardware, RX queue 0 is default off,
> but perhaps it is safer to only enable RX queue 0,
> even if you have more than one RX queue.
> (Only until you have implemented actual support for multi-queues
> in the driver.)
>
> But if you know that it's safe to enable all RX queues even if the
> driver only uses RX queue 0, then perhaps it doesn't matter.
I think it won't bring problems to enable all the available queues even if the
driver only uses queue 0. My QoS reference design has 4 RX queues and it works fine.
>
>
>>
>>>
>>>> + int queue = 0;
>>>> +
>>>> + /* If GMAC does not have multiqueues, then this is not necessary*/
>>>> + if (rx_count == 1)
>>>> + return;
>>>> +
>>>> + for (queue = 0; queue < rx_count; queue++)
>>>> + priv->hw->mac->rx_queue_enable(priv->hw, queue);
>>>> +}
>>>> +
>>>> +/**
>>>> * stmmac_dma_operation_mode - HW DMA operation mode
>>>> * @priv: driver private structure
>>>> * Description: it is used for configuring the DMA operation mode register in
>>>> @@ -1691,6 +1709,9 @@ static int stmmac_hw_setup(struct net_device *dev, bool init_ptp)
>>>> /* Initialize the MAC Core */
>>>> priv->hw->mac->core_init(priv->hw, dev->mtu);
>>>>
>>>> + /* Initialize MAC RX Queues */
>>>> + stmmac_mac_enable_rx_queues(priv);
>>>> +
>>>> ret = priv->hw->mac->rx_ipc(priv->hw);
>>>> if (!ret) {
>>>> netdev_warn(priv->dev, "RX IPC Checksum Offload disabled\n");
>
^ permalink raw reply
* [PATCH net] be2net: Increase skb headroom size to 256 bytes
From: Suresh Reddy @ 2016-12-20 15:14 UTC (permalink / raw)
To: netdev, kalesh-anakkur.purayil
From: Kalesh A P <kalesh-anakkur.purayil@broadcom.com>
The driver currently allocates 128 bytes of skb headroom.
This was found to be insufficient with some configurations
like Geneve tunnels, which resulted in skb head reallocations.
Increase the headroom to 256 bytes to fix this.
Signed-off-by: Kalesh A P <kalesh-anakkur.purayil@broadcom.com>
Signed-off-by: Suresh Reddy <suresh.reddy@broadcom.com>
---
drivers/net/ethernet/emulex/benet/be.h | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/ethernet/emulex/benet/be.h b/drivers/net/ethernet/emulex/benet/be.h
index 6cfa63a..4c30c44 100644
--- a/drivers/net/ethernet/emulex/benet/be.h
+++ b/drivers/net/ethernet/emulex/benet/be.h
@@ -65,7 +65,7 @@
/* Number of bytes of an RX frame that are copied to skb->data */
#define BE_HDR_LEN ((u16) 64)
/* allocate extra space to allow tunneling decapsulation without head reallocation */
-#define BE_RX_SKB_ALLOC_SIZE (BE_HDR_LEN + 64)
+#define BE_RX_SKB_ALLOC_SIZE 256
#define BE_MAX_JUMBO_FRAME_SIZE 9018
#define BE_MIN_MTU 256
--
2.10.1
^ permalink raw reply related
* Re: [PATCH] stmmac: enable rx queues
From: Seraphin BONNAFFE @ 2016-12-20 15:31 UTC (permalink / raw)
To: Joao Pinto, peppe.cavallaro, davem
Cc: hock.leong.kweh, niklas.cassel, pavel, linux-kernel, netdev
In-Reply-To: <bb31d7ca-667a-65cc-4c93-76688ef95ccb@synopsys.com>
Hi Joao,
On 12/20/2016 03:59 PM, Joao Pinto wrote:
>
> Hi Séraphin,
>
> Às 2:52 PM de 12/20/2016, Seraphin BONNAFFE escreveu:
>> Hi Joao,
>>
>> Please see my in-line comments.
>>
>> Regards,
>> Séraphin
>> --
>> Seraphin BONNAFFE | Tel: +33244027061
>> STMicroelectronics | ADG | S/W Design
>>
>> On 12/20/2016 01:55 PM, Joao Pinto wrote:
>>> When the hardware is synthesized with multiple queues, all queues are
>>> disabled for default. This patch adds the rx queues configuration.
>>> This patch was successfully tested in a Synopsys QoS Reference design.
>>>
>>> Signed-off-by: Joao Pinto <jpinto@synopsys.com>
>>> ---
>>> drivers/net/ethernet/stmicro/stmmac/common.h | 2 ++
>>> drivers/net/ethernet/stmicro/stmmac/dwmac4.h | 4 ++++
>>> drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c | 11 +++++++++++
>>> drivers/net/ethernet/stmicro/stmmac/stmmac_main.c | 21 +++++++++++++++++++++
>>> 4 files changed, 38 insertions(+)
>>>
>>> diff --git a/drivers/net/ethernet/stmicro/stmmac/common.h
>>> b/drivers/net/ethernet/stmicro/stmmac/common.h
>>> index b13a144..61bab50 100644
>>> --- a/drivers/net/ethernet/stmicro/stmmac/common.h
>>> +++ b/drivers/net/ethernet/stmicro/stmmac/common.h
>>> @@ -454,6 +454,8 @@ struct stmmac_ops {
>>> void (*core_init)(struct mac_device_info *hw, int mtu);
>>> /* Enable and verify that the IPC module is supported */
>>> int (*rx_ipc)(struct mac_device_info *hw);
>>> + /* Enable RX Queues */
>>> + void (*rx_queue_enable)(struct mac_device_info *hw, u32 queue);
>>> /* Dump MAC registers */
>>> void (*dump_regs)(struct mac_device_info *hw);
>>> /* Handle extra events on specific interrupts hw dependent */
>>> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
>>> b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
>>> index 3e8d4fe..fd013bd 100644
>>> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
>>> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4.h
>>> @@ -22,6 +22,7 @@
>>> #define GMAC_HASH_TAB_32_63 0x00000014
>>> #define GMAC_RX_FLOW_CTRL 0x00000090
>>> #define GMAC_QX_TX_FLOW_CTRL(x) (0x70 + x * 4)
>>> +#define GMAC_RXQ_CTRL0 0x000000a0
>>> #define GMAC_INT_STATUS 0x000000b0
>>> #define GMAC_INT_EN 0x000000b4
>>> #define GMAC_PCS_BASE 0x000000e0
>>> @@ -44,6 +45,9 @@
>>>
>>> #define GMAC_MAX_PERFECT_ADDRESSES 128
>>>
>>> +/* MAC RX Queue Enable*/
>>> +#define GMAC_RX_QUEUE_ENABLE(queue) BIT(queue * 2)
>>
>> According to the GMAC_RXQ0 register description from the dwc_ether_qos_databok,
>> I guess this will enable the queues in AV only.
>> What if we would like to enable them in DCB (10)b ?
>
> Correct, I am enabling AV only. What you are saying makes perfect sense. What
> about adding a variable to plat in order to configure the RX queue type?
> Example:
> plat->rx_queue_type = RX_QUEUE_DCB or plat->rx_queue_type = RX_QUEUE_AV
>
I am just not 100% sure about what does enabling the Queues in DCB implies,
and I think it needs something more to support the DCB feature as a whole in the driver, which is not supported yet.
On the other side, I observed that the queues should be enabled in AV by default.
Maybe providing this DCB option to plat could bring some confusion.
I would rather specify in the Macro name or in the comment above, that we are enabling the Queue in AV,
and eventually provide the same macro for enabling queues in DCB.
>
>>
>>
>>> +
>>> /* MAC Flow Control RX */
>>> #define GMAC_RX_FLOW_CTRL_RFE BIT(0)
>>>
>>> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
>>> b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
>>> index eaed7cb..7ec1887 100644
>>> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
>>> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac4_core.c
>>> @@ -59,6 +59,16 @@ static void dwmac4_core_init(struct mac_device_info *hw,
>>> int mtu)
>>> writel(value, ioaddr + GMAC_INT_EN);
>>> }
>>>
>>> +static void dwmac4_rx_queue_enable(struct mac_device_info *hw, u32 queue)
>>> +{
>>> + void __iomem *ioaddr = hw->pcsr;
>>> + u32 value = readl(ioaddr + GMAC_RXQ_CTRL0);
>>> +
>>> + value |= GMAC_RX_QUEUE_ENABLE(queue);
>>
>> What happen if for some reason the previous value of the register was 0xffff ?
>> The OR mask, by itself, won't clear the bits. AFAIU each queue is enabled with a
>> 2-bit value, and (11)b don't have the same effect as (01)b, does it ?
>>
>> I would suggest to clear the RXQ-enable bits before writing a new value.
>> Something like
>> value &= GMAC_RX_QUEUE_CLEAR(queue)
>> value |= GMAC_RX_QUEUE_ENABLE(queue);
>>
>> What do you think about that ?
>
> According to the databook, these values are always reset, but we can force it to
> clear as you suggest.
>
Yes, just in case. We may have another driver controlling the IP in a bootloader for example, and we don't know in which state it will let the controller.
...unless we have a IP reset at stmmac init (?). Anyway, it is more careful to control what we write to that register.
>>
>>> +
>>> + writel(value, ioaddr + GMAC_RXQ_CTRL0);
>>> +}
>>> +
>>> static void dwmac4_dump_regs(struct mac_device_info *hw)
>>> {
>>> void __iomem *ioaddr = hw->pcsr;
>>> @@ -392,6 +402,7 @@ static void dwmac4_debug(void __iomem *ioaddr, struct
>>> stmmac_extra_stats *x)
>>> static const struct stmmac_ops dwmac4_ops = {
>>> .core_init = dwmac4_core_init,
>>> .rx_ipc = dwmac4_rx_ipc_enable,
>>> + .rx_queue_enable = dwmac4_rx_queue_enable,
>>> .dump_regs = dwmac4_dump_regs,
>>> .host_irq_status = dwmac4_irq_status,
>>> .flow_ctrl = dwmac4_flow_ctrl,
>>> diff --git a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>>> b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>>> index 3e40578..e30034d 100644
>>> --- a/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>>> +++ b/drivers/net/ethernet/stmicro/stmmac/stmmac_main.c
>>> @@ -1271,6 +1271,24 @@ static void free_dma_desc_resources(struct stmmac_priv
>>> *priv)
>>> }
>>>
>>> /**
>>> + * stmmac_mac_enable_rx_queues - Enable MAC rx queues
>>> + * @priv: driver private structure
>>> + * Description: It is used for enabling the rx queues in the MAC
>>> + */
>>> +static void stmmac_mac_enable_rx_queues(struct stmmac_priv *priv)
>>> +{
>>> + int rx_count = priv->dma_cap.number_rx_channel;
>>> + int queue = 0;
>>> +
>>> + /* If GMAC does not have multiqueues, then this is not necessary*/
>>> + if (rx_count == 1)
>>> + return;
>>> +
>>> + for (queue = 0; queue < rx_count; queue++)
>>> + priv->hw->mac->rx_queue_enable(priv->hw, queue);
>>
>>
>> Maybe it is worth checking if (priv->hw->mac->rx_queue_enable)
>> before actually calling this callback ?
>> I can see you have implemented it for dwmac4, but not for dwmac100 and dwmac100
>> In that case we may have a null pointer exception here.
>
> Yes, you are absolutely correct. Since I am using gmac4, I forgot that stmmac
> can use other types.
>
By the way, do you have any idea if this RxQ enabling is necessary for dwmac version before 4.00?
Regards,
Séraphin
>>
>>> +}
>>> +
>>> +/**
>>> * stmmac_dma_operation_mode - HW DMA operation mode
>>> * @priv: driver private structure
>>> * Description: it is used for configuring the DMA operation mode register in
>>> @@ -1691,6 +1709,9 @@ static int stmmac_hw_setup(struct net_device *dev, bool
>>> init_ptp)
>>> /* Initialize the MAC Core */
>>> priv->hw->mac->core_init(priv->hw, dev->mtu);
>>>
>>> + /* Initialize MAC RX Queues */
>>> + stmmac_mac_enable_rx_queues(priv);
>>> +
>>> ret = priv->hw->mac->rx_ipc(priv->hw);
>>> if (!ret) {
>>> netdev_warn(priv->dev, "RX IPC Checksum Offload disabled\n");
>>>
>
> Thanks.
>
^ permalink raw reply
* Re: [PATCH v2 2/3] net: dsa: mv88e6xxx: Add support for ethernet switch 88E6341/88E6141
From: Andrew Lunn @ 2016-12-20 15:37 UTC (permalink / raw)
To: Romain Perier
Cc: Vivien Didelot, Florian Fainelli, Jason Cooper,
Sebastian Hesselbarth, Gregory Clement,
netdev-u79uwXL29TY76Z2rM5mHXA, devicetree-u79uwXL29TY76Z2rM5mHXA,
Rob Herring, Ian Campbell, Pawel Moll, Mark Rutland, Kumar Gala,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
Thomas Petazzoni, Nadav Haklai
In-Reply-To: <20161220085138.3998-3-romain.perier-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
On Tue, Dec 20, 2016 at 09:51:37AM +0100, Romain Perier wrote:
> The Marvell 88E6341 device is single-chip, 6-port ethernet switch with
> four integrated 10/100/1000Mbps ethernet transceivers and one high speed
> SerDes interfaces. It is compatible with switches of family 88E6352.
>
> This commit adds basic support for this switch by describing its
> capabilities to the driver.
>
> Signed-off-by: Romain Perier <romain.perier-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
Reviewed-by: Andrew Lunn <andrew-g2DYL2Zd6BY@public.gmane.org>
Andrew
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v2 3/3] arm64: dts: marvell: Add ethernet switch definition for the ESPRESSObin
From: Andrew Lunn @ 2016-12-20 15:42 UTC (permalink / raw)
To: Romain Perier
Cc: Vivien Didelot, Florian Fainelli, Jason Cooper,
Sebastian Hesselbarth, Gregory Clement,
netdev-u79uwXL29TY76Z2rM5mHXA, devicetree-u79uwXL29TY76Z2rM5mHXA,
Rob Herring, Ian Campbell, Pawel Moll, Mark Rutland, Kumar Gala,
linux-arm-kernel-IAPFreCvJWM7uuMidbF8XUB+6BGkLq7r,
Thomas Petazzoni, Nadav Haklai
In-Reply-To: <20161220085138.3998-4-romain.perier-wi1+55ScJUtKEb57/3fJTNBPR1lH4CV8@public.gmane.org>
> +&mdio {
> + switch0: switch0@0 {
> + compatible = "marvell,mv88e6085";
> + #address-cells = <1>;
> + #size-cells = <0>;
> + reg = <1>;
Ah, sorry, missed this last time. reg = <1>, that means switch0@1.
That is a general rule for all device tree bindings.
> + mdio {
> + #address-cells = <1>;
> + #size-cells = <0>;
> + reg = <1>;
what is this reg value for?
Andrew
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* Re: [PATCH v2] ipv4: Should use consistent conditional judgement for ip fragment in __ip_append_data and ip_finish_output
From: David Miller @ 2016-12-20 15:45 UTC (permalink / raw)
To: lizheng043
Cc: linux-kernel, netdev, kuznet, jmorris, yoshfuji, kaber,
james.z.li
In-Reply-To: <1481507765-3684-1-git-send-email-lizheng043@gmail.com>
From: Zheng Li <lizheng043@gmail.com>
Date: Mon, 12 Dec 2016 09:56:05 +0800
> From: zheng li <james.z.li@ericsson.com>
>
> There is an inconsistent conditional judgement in __ip_append_data and
> ip_finish_output functions, the variable length in __ip_append_data just
> include the length of application's payload and udp header, don't include
> the length of ip header, but in ip_finish_output use
> (skb->len > ip_skb_dst_mtu(skb)) as judgement, and skb->len include the
> length of ip header.
>
> That causes some particular application's udp payload whose length is
> between (MTU - IP Header) and MTU were fragmented by ip_fragment even
> though the rst->dev support UFO feature.
>
> Add the length of ip header to length in __ip_append_data to keep
> consistent conditional judgement as ip_finish_output for ip fragment.
>
> Signed-off-by: Zheng Li <james.z.li@ericsson.com>
Applied, thanks.
^ permalink raw reply
* Re: [PATCH v2 3/3] arm64: dts: marvell: Add ethernet switch definition for the ESPRESSObin
From: Romain Perier @ 2016-12-20 16:09 UTC (permalink / raw)
To: Andrew Lunn
Cc: Vivien Didelot, Florian Fainelli, Jason Cooper,
Sebastian Hesselbarth, Gregory Clement, netdev, devicetree,
Rob Herring, Ian Campbell, Pawel Moll, Mark Rutland, Kumar Gala,
linux-arm-kernel, Thomas Petazzoni, Nadav Haklai
In-Reply-To: <20161220154234.GC30952@lunn.ch>
Hi,
Le 20/12/2016 à 16:42, Andrew Lunn a écrit :
>> +&mdio {
>> + switch0: switch0@0 {
>> + compatible = "marvell,mv88e6085";
>> + #address-cells = <1>;
>> + #size-cells = <0>;
>> + reg = <1>;
>
> Ah, sorry, missed this last time. reg = <1>, that means switch0@1.
> That is a general rule for all device tree bindings.
Ahhh, I did not pay attention either :/
I will fix this.
>
>> + mdio {
>> + #address-cells = <1>;
>> + #size-cells = <0>;
>> + reg = <1>;
>
> what is this reg value for?
>
> Andrew
>
It was required to avoid a warning thrown by the mdio subsystem
Romain
^ permalink raw reply
* [PATCH 1/3] NFC: trf7970a: add device tree option for 27MHz clock
From: Geoff Lansberry @ 2016-12-20 16:10 UTC (permalink / raw)
To: linux-wireless
Cc: lauro.venancio, aloisio.almeida, sameo, robh+dt, mark.rutland,
netdev, devicetree, linux-kernel, mgreer, justin, Geoff Lansberry
From: Geoff Lansberry <geoff@kuvee.com>
The TRF7970A has configuration options to support hardware designs
which use a 27.12MHz clock. This commit adds a device tree option
'clock-frequency' to support configuring the this chip for default
13.56MHz clock or the optional 27.12MHz clock.
---
.../devicetree/bindings/net/nfc/trf7970a.txt | 4 ++
drivers/nfc/trf7970a.c | 50 +++++++++++++++++-----
2 files changed, 43 insertions(+), 11 deletions(-)
diff --git a/Documentation/devicetree/bindings/net/nfc/trf7970a.txt b/Documentation/devicetree/bindings/net/nfc/trf7970a.txt
index 32b35a0..e262ac1 100644
--- a/Documentation/devicetree/bindings/net/nfc/trf7970a.txt
+++ b/Documentation/devicetree/bindings/net/nfc/trf7970a.txt
@@ -21,6 +21,8 @@ Optional SoC Specific Properties:
- t5t-rmb-extra-byte-quirk: Specify that the trf7970a has the erratum
where an extra byte is returned by Read Multiple Block commands issued
to Type 5 tags.
+- clock-frequency: Set to specify that the input frequency to the trf7970a is 13560000Hz or 27120000Hz
+
Example (for ARM-based BeagleBone with TRF7970A on SPI1):
@@ -43,6 +45,8 @@ Example (for ARM-based BeagleBone with TRF7970A on SPI1):
irq-status-read-quirk;
en2-rf-quirk;
t5t-rmb-extra-byte-quirk;
+ vdd_io_1v8;
+ clock-frequency = <27120000>;
status = "okay";
};
};
diff --git a/drivers/nfc/trf7970a.c b/drivers/nfc/trf7970a.c
index 26c9dbb..4e051e9 100644
--- a/drivers/nfc/trf7970a.c
+++ b/drivers/nfc/trf7970a.c
@@ -124,6 +124,9 @@
NFC_PROTO_ISO15693_MASK | NFC_PROTO_NFC_DEP_MASK)
#define TRF7970A_AUTOSUSPEND_DELAY 30000 /* 30 seconds */
+#define TRF7970A_13MHZ_CLOCK_FREQUENCY 13560000
+#define TRF7970A_27MHZ_CLOCK_FREQUENCY 27120000
+
#define TRF7970A_RX_SKB_ALLOC_SIZE 256
@@ -1056,12 +1059,11 @@ static int trf7970a_init(struct trf7970a *trf)
trf->chip_status_ctrl &= ~TRF7970A_CHIP_STATUS_RF_ON;
- ret = trf7970a_write(trf, TRF7970A_MODULATOR_SYS_CLK_CTRL, 0);
+ ret = trf7970a_write(trf, TRF7970A_MODULATOR_SYS_CLK_CTRL,
+ trf->modulator_sys_clk_ctrl);
if (ret)
goto err_out;
- trf->modulator_sys_clk_ctrl = 0;
-
ret = trf7970a_write(trf, TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS,
TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS_WLH_96 |
TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS_WLL_32);
@@ -1181,27 +1183,37 @@ static int trf7970a_in_config_rf_tech(struct trf7970a *trf, int tech)
switch (tech) {
case NFC_DIGITAL_RF_TECH_106A:
trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_14443A_106;
- trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_OOK;
+ trf->modulator_sys_clk_ctrl =
+ (trf->modulator_sys_clk_ctrl & 0xF8) |
+ TRF7970A_MODULATOR_DEPTH_OOK;
trf->guard_time = TRF7970A_GUARD_TIME_NFCA;
break;
case NFC_DIGITAL_RF_TECH_106B:
trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_14443B_106;
- trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_ASK10;
+ trf->modulator_sys_clk_ctrl =
+ (trf->modulator_sys_clk_ctrl & 0xF8) |
+ TRF7970A_MODULATOR_DEPTH_ASK10;
trf->guard_time = TRF7970A_GUARD_TIME_NFCB;
break;
case NFC_DIGITAL_RF_TECH_212F:
trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_FELICA_212;
- trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_ASK10;
+ trf->modulator_sys_clk_ctrl =
+ (trf->modulator_sys_clk_ctrl & 0xF8) |
+ TRF7970A_MODULATOR_DEPTH_ASK10;
trf->guard_time = TRF7970A_GUARD_TIME_NFCF;
break;
case NFC_DIGITAL_RF_TECH_424F:
trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_FELICA_424;
- trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_ASK10;
+ trf->modulator_sys_clk_ctrl =
+ (trf->modulator_sys_clk_ctrl & 0xF8) |
+ TRF7970A_MODULATOR_DEPTH_ASK10;
trf->guard_time = TRF7970A_GUARD_TIME_NFCF;
break;
case NFC_DIGITAL_RF_TECH_ISO15693:
trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_15693_SGL_1OF4_2648;
- trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_OOK;
+ trf->modulator_sys_clk_ctrl =
+ (trf->modulator_sys_clk_ctrl & 0xF8) |
+ TRF7970A_MODULATOR_DEPTH_OOK;
trf->guard_time = TRF7970A_GUARD_TIME_15693;
break;
default:
@@ -1571,17 +1583,23 @@ static int trf7970a_tg_config_rf_tech(struct trf7970a *trf, int tech)
trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_NFC_NFC_CE_MODE |
TRF7970A_ISO_CTRL_NFC_CE |
TRF7970A_ISO_CTRL_NFC_CE_14443A;
- trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_OOK;
+ trf->modulator_sys_clk_ctrl =
+ (trf->modulator_sys_clk_ctrl & 0xF8) |
+ TRF7970A_MODULATOR_DEPTH_OOK;
break;
case NFC_DIGITAL_RF_TECH_212F:
trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_NFC_NFC_CE_MODE |
TRF7970A_ISO_CTRL_NFC_NFCF_212;
- trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_ASK10;
+ trf->modulator_sys_clk_ctrl =
+ (trf->modulator_sys_clk_ctrl & 0xF8) |
+ TRF7970A_MODULATOR_DEPTH_ASK10;
break;
case NFC_DIGITAL_RF_TECH_424F:
trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_NFC_NFC_CE_MODE |
TRF7970A_ISO_CTRL_NFC_NFCF_424;
- trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_ASK10;
+ trf->modulator_sys_clk_ctrl =
+ (trf->modulator_sys_clk_ctrl & 0xF8) |
+ TRF7970A_MODULATOR_DEPTH_ASK10;
break;
default:
dev_dbg(trf->dev, "Unsupported rf technology: %d\n", tech);
@@ -1987,6 +2005,7 @@ static int trf7970a_probe(struct spi_device *spi)
struct device_node *np = spi->dev.of_node;
struct trf7970a *trf;
int uvolts, autosuspend_delay, ret;
+ u32 clk_freq = 13560000;
if (!np) {
dev_err(&spi->dev, "No Device Tree entry\n");
@@ -2043,6 +2062,15 @@ static int trf7970a_probe(struct spi_device *spi)
return ret;
}
+ of_property_read_u32(np, "clock-frequency", &clk_freq);
+ if ((clk_freq != TRF7970A_27MHZ_CLOCK_FREQUENCY) ||
+ (clk_freq != TRF7970A_27MHZ_CLOCK_FREQUENCY)) {
+ dev_err(trf->dev,
+ "clock-frequency (%u Hz) unsupported\n",
+ clk_freq);
+ return -EINVAL;
+ }
+
if (of_property_read_bool(np, "en2-rf-quirk"))
trf->quirks |= TRF7970A_QUIRK_EN2_MUST_STAY_LOW;
--
Signed-off-by: Geoff Lansberry <geoff@kuvee.com>
^ permalink raw reply related
* [PATCH 1/3] NFC: trf7970a: Add device tree option of 1.8 Volt IO voltage
From: Geoff Lansberry @ 2016-12-20 16:10 UTC (permalink / raw)
To: linux-wireless-u79uwXL29TY76Z2rM5mHXA
Cc: lauro.venancio-430g2QfJUUCGglJvpFV4uA,
aloisio.almeida-430g2QfJUUCGglJvpFV4uA,
sameo-VuQAYsv1563Yd54FQh9/CA, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
mark.rutland-5wv7dgnIgG8, netdev-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
mgreer-luAo+O/VEmrlveNOaEYElw, justin-R+k406RtEhcAvxtiuMwx3w,
Geoff Lansberry
In-Reply-To: <1482250250-4192-1-git-send-email-glansberry-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
From: Geoff Lansberry <geoff-R+k406RtEhcAvxtiuMwx3w@public.gmane.org>
The TRF7970A has configuration options for supporting hardware designs
with 1.8 Volt or 3.3 Volt IO. This commit adds a device tree option,
using a fixed regulator binding, for setting the io voltage to match
the hardware configuration. If no option is supplied it defaults to
3.3 volt configuration.
---
.../devicetree/bindings/net/nfc/trf7970a.txt | 4 ++--
drivers/nfc/trf7970a.c | 28 +++++++++++++++++++++-
2 files changed, 29 insertions(+), 3 deletions(-)
diff --git a/Documentation/devicetree/bindings/net/nfc/trf7970a.txt b/Documentation/devicetree/bindings/net/nfc/trf7970a.txt
index e262ac1..b5777d8 100644
--- a/Documentation/devicetree/bindings/net/nfc/trf7970a.txt
+++ b/Documentation/devicetree/bindings/net/nfc/trf7970a.txt
@@ -21,9 +21,9 @@ Optional SoC Specific Properties:
- t5t-rmb-extra-byte-quirk: Specify that the trf7970a has the erratum
where an extra byte is returned by Read Multiple Block commands issued
to Type 5 tags.
+- vdd-io-supply: Regulator specifying voltage for vdd-io
- clock-frequency: Set to specify that the input frequency to the trf7970a is 13560000Hz or 27120000Hz
-
Example (for ARM-based BeagleBone with TRF7970A on SPI1):
&spi1 {
@@ -41,11 +41,11 @@ Example (for ARM-based BeagleBone with TRF7970A on SPI1):
<&gpio2 5 GPIO_ACTIVE_LOW>;
vin-supply = <&ldo3_reg>;
vin-voltage-override = <5000000>;
+ vdd-io-supply = <&ldo2_reg>;
autosuspend-delay = <30000>;
irq-status-read-quirk;
en2-rf-quirk;
t5t-rmb-extra-byte-quirk;
- vdd_io_1v8;
clock-frequency = <27120000>;
status = "okay";
};
diff --git a/drivers/nfc/trf7970a.c b/drivers/nfc/trf7970a.c
index c9cb278..94c31f8 100644
--- a/drivers/nfc/trf7970a.c
+++ b/drivers/nfc/trf7970a.c
@@ -444,6 +444,7 @@ struct trf7970a {
u8 iso_ctrl_tech;
u8 modulator_sys_clk_ctrl;
u8 special_fcn_reg1;
+ u8 io_ctrl;
unsigned int guard_time;
int technology;
int framing;
@@ -1051,6 +1052,11 @@ static int trf7970a_init(struct trf7970a *trf)
if (ret)
goto err_out;
+ ret = trf7970a_write(trf, TRF7970A_REG_IO_CTRL,
+ trf->io_ctrl | TRF7970A_REG_IO_CTRL_VRS(0x1));
+ if (ret)
+ goto err_out;
+
ret = trf7970a_write(trf, TRF7970A_NFC_TARGET_LEVEL, 0);
if (ret)
goto err_out;
@@ -1767,7 +1773,7 @@ static int _trf7970a_tg_listen(struct nfc_digital_dev *ddev, u16 timeout,
goto out_err;
ret = trf7970a_write(trf, TRF7970A_REG_IO_CTRL,
- TRF7970A_REG_IO_CTRL_VRS(0x1));
+ trf->io_ctrl | TRF7970A_REG_IO_CTRL_VRS(0x1));
if (ret)
goto out_err;
@@ -2062,6 +2068,7 @@ static int trf7970a_probe(struct spi_device *spi)
return ret;
}
+
of_property_read_u32(np, "clock-frequency", &clk_freq);
if ((clk_freq != TRF7970A_27MHZ_CLOCK_FREQUENCY) ||
(clk_freq != TRF7970A_27MHZ_CLOCK_FREQUENCY)) {
@@ -2105,6 +2112,25 @@ static int trf7970a_probe(struct spi_device *spi)
if (uvolts > 4000000)
trf->chip_status_ctrl = TRF7970A_CHIP_STATUS_VRS5_3;
+ trf->regulator = devm_regulator_get(&spi->dev, "vdd-io");
+ if (IS_ERR(trf->regulator)) {
+ ret = PTR_ERR(trf->regulator);
+ dev_err(trf->dev, "Can't get VDD_IO regulator: %d\n", ret);
+ goto err_destroy_lock;
+ }
+
+ ret = regulator_enable(trf->regulator);
+ if (ret) {
+ dev_err(trf->dev, "Can't enable VDD_IO: %d\n", ret);
+ goto err_destroy_lock;
+ }
+
+
+ if (regulator_get_voltage(trf->regulator) == 1800000) {
+ trf->io_ctrl = TRF7970A_REG_IO_CTRL_IO_LOW;
+ dev_dbg(trf->dev, "trf7970a config vdd_io to 1.8V\n");
+ }
+
trf->ddev = nfc_digital_allocate_device(&trf7970a_nfc_ops,
TRF7970A_SUPPORTED_PROTOCOLS,
NFC_DIGITAL_DRV_CAPS_IN_CRC |
--
Signed-off-by: Geoff Lansberry <geoff-R+k406RtEhcAvxtiuMwx3w@public.gmane.org>
--
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/3] NFC: trf7970a: Add device tree option of 1.8 Volt IO voltage
From: Geoff Lansberry @ 2016-12-20 16:10 UTC (permalink / raw)
To: linux-wireless
Cc: lauro.venancio, aloisio.almeida, sameo, robh+dt, mark.rutland,
netdev, devicetree, linux-kernel, mgreer, justin, Geoff Lansberry
In-Reply-To: <1482250250-4192-1-git-send-email-glansberry@gmail.com>
From: Geoff Lansberry <geoff@kuvee.com>
The TRF7970A has configuration options for supporting hardware designs
with 1.8 Volt or 3.3 Volt IO. This commit adds a device tree option,
using a fixed regulator binding, for setting the io voltage to match
the hardware configuration. If no option is supplied it defaults to
3.3 volt configuration.
---
.../devicetree/bindings/net/nfc/trf7970a.txt | 4 ++--
drivers/nfc/trf7970a.c | 28 +++++++++++++++++++++-
2 files changed, 29 insertions(+), 3 deletions(-)
diff --git a/Documentation/devicetree/bindings/net/nfc/trf7970a.txt b/Documentation/devicetree/bindings/net/nfc/trf7970a.txt
index e262ac1..b5777d8 100644
--- a/Documentation/devicetree/bindings/net/nfc/trf7970a.txt
+++ b/Documentation/devicetree/bindings/net/nfc/trf7970a.txt
@@ -21,9 +21,9 @@ Optional SoC Specific Properties:
- t5t-rmb-extra-byte-quirk: Specify that the trf7970a has the erratum
where an extra byte is returned by Read Multiple Block commands issued
to Type 5 tags.
+- vdd-io-supply: Regulator specifying voltage for vdd-io
- clock-frequency: Set to specify that the input frequency to the trf7970a is 13560000Hz or 27120000Hz
-
Example (for ARM-based BeagleBone with TRF7970A on SPI1):
&spi1 {
@@ -41,11 +41,11 @@ Example (for ARM-based BeagleBone with TRF7970A on SPI1):
<&gpio2 5 GPIO_ACTIVE_LOW>;
vin-supply = <&ldo3_reg>;
vin-voltage-override = <5000000>;
+ vdd-io-supply = <&ldo2_reg>;
autosuspend-delay = <30000>;
irq-status-read-quirk;
en2-rf-quirk;
t5t-rmb-extra-byte-quirk;
- vdd_io_1v8;
clock-frequency = <27120000>;
status = "okay";
};
diff --git a/drivers/nfc/trf7970a.c b/drivers/nfc/trf7970a.c
index 4e051e9..8a88195 100644
--- a/drivers/nfc/trf7970a.c
+++ b/drivers/nfc/trf7970a.c
@@ -444,6 +444,7 @@ struct trf7970a {
u8 iso_ctrl_tech;
u8 modulator_sys_clk_ctrl;
u8 special_fcn_reg1;
+ u8 io_ctrl;
unsigned int guard_time;
int technology;
int framing;
@@ -1051,6 +1052,11 @@ static int trf7970a_init(struct trf7970a *trf)
if (ret)
goto err_out;
+ ret = trf7970a_write(trf, TRF7970A_REG_IO_CTRL,
+ trf->io_ctrl | TRF7970A_REG_IO_CTRL_VRS(0x1));
+ if (ret)
+ goto err_out;
+
ret = trf7970a_write(trf, TRF7970A_NFC_TARGET_LEVEL, 0);
if (ret)
goto err_out;
@@ -1767,7 +1773,7 @@ static int _trf7970a_tg_listen(struct nfc_digital_dev *ddev, u16 timeout,
goto out_err;
ret = trf7970a_write(trf, TRF7970A_REG_IO_CTRL,
- TRF7970A_REG_IO_CTRL_VRS(0x1));
+ trf->io_ctrl | TRF7970A_REG_IO_CTRL_VRS(0x1));
if (ret)
goto out_err;
@@ -2062,6 +2068,7 @@ static int trf7970a_probe(struct spi_device *spi)
return ret;
}
+
of_property_read_u32(np, "clock-frequency", &clk_freq);
if ((clk_freq != TRF7970A_27MHZ_CLOCK_FREQUENCY) ||
(clk_freq != TRF7970A_27MHZ_CLOCK_FREQUENCY)) {
@@ -2105,6 +2112,25 @@ static int trf7970a_probe(struct spi_device *spi)
if (uvolts > 4000000)
trf->chip_status_ctrl = TRF7970A_CHIP_STATUS_VRS5_3;
+ trf->regulator = devm_regulator_get(&spi->dev, "vdd-io");
+ if (IS_ERR(trf->regulator)) {
+ ret = PTR_ERR(trf->regulator);
+ dev_err(trf->dev, "Can't get VDD_IO regulator: %d\n", ret);
+ goto err_destroy_lock;
+ }
+
+ ret = regulator_enable(trf->regulator);
+ if (ret) {
+ dev_err(trf->dev, "Can't enable VDD_IO: %d\n", ret);
+ goto err_destroy_lock;
+ }
+
+
+ if (regulator_get_voltage(trf->regulator) == 1800000) {
+ trf->io_ctrl = TRF7970A_REG_IO_CTRL_IO_LOW;
+ dev_dbg(trf->dev, "trf7970a config vdd_io to 1.8V\n");
+ }
+
trf->ddev = nfc_digital_allocate_device(&trf7970a_nfc_ops,
TRF7970A_SUPPORTED_PROTOCOLS,
NFC_DIGITAL_DRV_CAPS_IN_CRC |
--
Signed-off-by: Geoff Lansberry <geoff@kuvee.com>
^ permalink raw reply related
* [PATCH 2/3] nfc: trf7970a: Prevent repeated polling from crashing the kernel
From: Geoff Lansberry @ 2016-12-20 16:10 UTC (permalink / raw)
To: linux-wireless
Cc: lauro.venancio, aloisio.almeida, sameo, robh+dt, mark.rutland,
netdev, devicetree, linux-kernel, mgreer, justin, Jaret Cantu,
Geoff Lansberry
In-Reply-To: <1482250250-4192-1-git-send-email-glansberry@gmail.com>
From: Jaret Cantu <jaret.cantu@timesys.com>
Repeated polling attempts cause a NULL dereference error to occur.
This is because the state of the trf7970a is currently reading but
another request has been made to send a command before it has finished.
The solution is to properly kill the waiting reading (workqueue)
before failing on the send.
---
drivers/nfc/trf7970a.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/nfc/trf7970a.c b/drivers/nfc/trf7970a.c
index 94c31f8..e9e93ea 100644
--- a/drivers/nfc/trf7970a.c
+++ b/drivers/nfc/trf7970a.c
@@ -1496,6 +1496,10 @@ static int trf7970a_send_cmd(struct nfc_digital_dev *ddev,
(trf->state != TRF7970A_ST_IDLE_RX_BLOCKED)) {
dev_err(trf->dev, "%s - Bogus state: %d\n", __func__,
trf->state);
+ if (trf->state == TRF7970A_ST_WAIT_FOR_RX_DATA ||
+ trf->state == TRF7970A_ST_WAIT_FOR_RX_DATA_CONT)
+ trf->ignore_timeout =
+ !cancel_delayed_work(&trf->timeout_work);
ret = -EIO;
goto out_err;
}
--
Signed-off-by: Geoff Lansberry <geoff@kuvee.com>
^ permalink raw reply related
* [PATCH 3/3] mod of frequency
From: Geoff Lansberry @ 2016-12-20 16:10 UTC (permalink / raw)
To: linux-wireless
Cc: lauro.venancio, aloisio.almeida, sameo, robh+dt, mark.rutland,
netdev, devicetree, linux-kernel, mgreer, justin, Geoff Lansberry,
Geoff Lansberry
In-Reply-To: <1482250250-4192-1-git-send-email-glansberry@gmail.com>
---
drivers/nfc/trf7970a.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/nfc/trf7970a.c b/drivers/nfc/trf7970a.c
index e9e93ea..5916737 100644
--- a/drivers/nfc/trf7970a.c
+++ b/drivers/nfc/trf7970a.c
@@ -2076,10 +2076,10 @@ static int trf7970a_probe(struct spi_device *spi)
of_property_read_u32(np, "clock-frequency", &clk_freq);
if ((clk_freq != TRF7970A_27MHZ_CLOCK_FREQUENCY) ||
(clk_freq != TRF7970A_27MHZ_CLOCK_FREQUENCY)) {
- dev_err(trf->dev,
- "clock-frequency (%u Hz) unsupported\n",
- clk_freq);
- return -EINVAL;
+ dev_err(trf->dev,
+ "clock-frequency (%u Hz) unsupported\n",
+ clk_freq);
+ return -EINVAL;
}
if (of_property_read_bool(np, "en2-rf-quirk"))
--
Signed-off-by: Geoff Lansberry <geoff@kuvee.com>
^ permalink raw reply related
* [PATCH 3/3] nfc: trf7970a: Prevent repeated polling from crashing the kernel
From: Geoff Lansberry @ 2016-12-20 16:10 UTC (permalink / raw)
To: linux-wireless-u79uwXL29TY76Z2rM5mHXA
Cc: lauro.venancio-430g2QfJUUCGglJvpFV4uA,
aloisio.almeida-430g2QfJUUCGglJvpFV4uA,
sameo-VuQAYsv1563Yd54FQh9/CA, robh+dt-DgEjT+Ai2ygdnm+yROfE0A,
mark.rutland-5wv7dgnIgG8, netdev-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
mgreer-luAo+O/VEmrlveNOaEYElw, justin-R+k406RtEhcAvxtiuMwx3w,
Jaret Cantu, Geoff Lansberry
In-Reply-To: <1482250250-4192-1-git-send-email-glansberry-Re5JQEeQqe8AvxtiuMwx3w@public.gmane.org>
From: Jaret Cantu <jaret.cantu-jEh4hwF5bVhBDgjK7y7TUQ@public.gmane.org>
Repeated polling attempts cause a NULL dereference error to occur.
This is because the state of the trf7970a is currently reading but
another request has been made to send a command before it has finished.
The solution is to properly kill the waiting reading (workqueue)
before failing on the send.
---
drivers/nfc/trf7970a.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/nfc/trf7970a.c b/drivers/nfc/trf7970a.c
index 8a88195..5916737 100644
--- a/drivers/nfc/trf7970a.c
+++ b/drivers/nfc/trf7970a.c
@@ -1496,6 +1496,10 @@ static int trf7970a_send_cmd(struct nfc_digital_dev *ddev,
(trf->state != TRF7970A_ST_IDLE_RX_BLOCKED)) {
dev_err(trf->dev, "%s - Bogus state: %d\n", __func__,
trf->state);
+ if (trf->state == TRF7970A_ST_WAIT_FOR_RX_DATA ||
+ trf->state == TRF7970A_ST_WAIT_FOR_RX_DATA_CONT)
+ trf->ignore_timeout =
+ !cancel_delayed_work(&trf->timeout_work);
ret = -EIO;
goto out_err;
}
--
Signed-off-by: Geoff Lansberry <geoff-R+k406RtEhcAvxtiuMwx3w@public.gmane.org>
^ permalink raw reply related
* [PATCH 4/4] mod of frequency
From: Geoff Lansberry @ 2016-12-20 16:10 UTC (permalink / raw)
To: linux-wireless
Cc: lauro.venancio, aloisio.almeida, sameo, robh+dt, mark.rutland,
netdev, devicetree, linux-kernel, mgreer, justin, Geoff Lansberry,
Geoff Lansberry
In-Reply-To: <1482250250-4192-1-git-send-email-glansberry@gmail.com>
---
drivers/nfc/trf7970a.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)
diff --git a/drivers/nfc/trf7970a.c b/drivers/nfc/trf7970a.c
index e9e93ea..5916737 100644
--- a/drivers/nfc/trf7970a.c
+++ b/drivers/nfc/trf7970a.c
@@ -2076,10 +2076,10 @@ static int trf7970a_probe(struct spi_device *spi)
of_property_read_u32(np, "clock-frequency", &clk_freq);
if ((clk_freq != TRF7970A_27MHZ_CLOCK_FREQUENCY) ||
(clk_freq != TRF7970A_27MHZ_CLOCK_FREQUENCY)) {
- dev_err(trf->dev,
- "clock-frequency (%u Hz) unsupported\n",
- clk_freq);
- return -EINVAL;
+ dev_err(trf->dev,
+ "clock-frequency (%u Hz) unsupported\n",
+ clk_freq);
+ return -EINVAL;
}
if (of_property_read_bool(np, "en2-rf-quirk"))
--
Signed-off-by: Geoff Lansberry <geoff@kuvee.com>
^ permalink raw reply related
* Re: [PATCH 2/3] NFC: trf7970a: Add device tree option of 1.8 Volt IO voltage
From: Geoff Lansberry @ 2016-12-20 16:13 UTC (permalink / raw)
To: Rob Herring
Cc: linux-wireless, Lauro Ramos Venancio, Aloisio Almeida Jr,
Samuel Ortiz, mark.rutland-5wv7dgnIgG8,
netdev-u79uwXL29TY76Z2rM5mHXA, devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA, Mark Greer, Justin Bronder
In-Reply-To: <20161219223504.ttwayzpfvdumgouu@rob-hp-laptop>
On Mon, Dec 19, 2016 at 5:35 PM, Rob Herring <robh-DgEjT+Ai2ygdnm+yROfE0A@public.gmane.org> wrote:
> On Thu, Dec 15, 2016 at 05:30:43PM -0500, Geoff Lansberry wrote:
>> From: Geoff Lansberry <geoff-R+k406RtEhcAvxtiuMwx3w@public.gmane.org>
>>
>> ---
>> Documentation/devicetree/bindings/net/nfc/trf7970a.txt | 2 ++
>> drivers/nfc/trf7970a.c | 13 ++++++++++++-
>> 2 files changed, 14 insertions(+), 1 deletion(-)
>>
>> diff --git a/Documentation/devicetree/bindings/net/nfc/trf7970a.txt b/Documentation/devicetree/bindings/net/nfc/trf7970a.txt
>> index 9dda879..208f045 100644
>> --- a/Documentation/devicetree/bindings/net/nfc/trf7970a.txt
>> +++ b/Documentation/devicetree/bindings/net/nfc/trf7970a.txt
>> @@ -21,6 +21,7 @@ Optional SoC Specific Properties:
>> - t5t-rmb-extra-byte-quirk: Specify that the trf7970a has the erratum
>> where an extra byte is returned by Read Multiple Block commands issued
>> to Type 5 tags.
>> +- vdd_io_1v8: Set to specify that the trf7970a io voltage should be set to 1.8V
>
> Use the regulator binding and provide a fixed 1.8V supply.
>
>> - crystal_27mhz: Set to specify that the input frequency to the trf7970a is 27.12MHz
>>
>>
>> @@ -45,6 +46,7 @@ Example (for ARM-based BeagleBone with TRF7970A on SPI1):
>> irq-status-read-quirk;
>> en2-rf-quirk;
>> t5t-rmb-extra-byte-quirk;
>> + vdd_io_1v8;
>> crystal_27mhz;
>> status = "okay";
>> };
Rob - using the regulator binding is new to me, but I've given it a
shot and just sent you another set of patches for your inspection.
Please let me know if this is what you had in mind.
Geoff
^ permalink raw reply
* [PATCH 1/3] NFC: trf7970a: add device tree option for 27MHz clock
From: Geoff Lansberry @ 2016-12-20 16:16 UTC (permalink / raw)
To: linux-wireless
Cc: lauro.venancio, aloisio.almeida, sameo, robh+dt, mark.rutland,
netdev, devicetree, linux-kernel, mgreer, justin, Geoff Lansberry
From: Geoff Lansberry <geoff@kuvee.com>
The TRF7970A has configuration options to support hardware designs
which use a 27.12MHz clock. This commit adds a device tree option
'clock-frequency' to support configuring the this chip for default
13.56MHz clock or the optional 27.12MHz clock.
---
.../devicetree/bindings/net/nfc/trf7970a.txt | 4 ++
drivers/nfc/trf7970a.c | 50 +++++++++++++++++-----
2 files changed, 43 insertions(+), 11 deletions(-)
diff --git a/Documentation/devicetree/bindings/net/nfc/trf7970a.txt b/Documentation/devicetree/bindings/net/nfc/trf7970a.txt
index 32b35a0..e262ac1 100644
--- a/Documentation/devicetree/bindings/net/nfc/trf7970a.txt
+++ b/Documentation/devicetree/bindings/net/nfc/trf7970a.txt
@@ -21,6 +21,8 @@ Optional SoC Specific Properties:
- t5t-rmb-extra-byte-quirk: Specify that the trf7970a has the erratum
where an extra byte is returned by Read Multiple Block commands issued
to Type 5 tags.
+- clock-frequency: Set to specify that the input frequency to the trf7970a is 13560000Hz or 27120000Hz
+
Example (for ARM-based BeagleBone with TRF7970A on SPI1):
@@ -43,6 +45,8 @@ Example (for ARM-based BeagleBone with TRF7970A on SPI1):
irq-status-read-quirk;
en2-rf-quirk;
t5t-rmb-extra-byte-quirk;
+ vdd_io_1v8;
+ clock-frequency = <27120000>;
status = "okay";
};
};
diff --git a/drivers/nfc/trf7970a.c b/drivers/nfc/trf7970a.c
index 26c9dbb..4e051e9 100644
--- a/drivers/nfc/trf7970a.c
+++ b/drivers/nfc/trf7970a.c
@@ -124,6 +124,9 @@
NFC_PROTO_ISO15693_MASK | NFC_PROTO_NFC_DEP_MASK)
#define TRF7970A_AUTOSUSPEND_DELAY 30000 /* 30 seconds */
+#define TRF7970A_13MHZ_CLOCK_FREQUENCY 13560000
+#define TRF7970A_27MHZ_CLOCK_FREQUENCY 27120000
+
#define TRF7970A_RX_SKB_ALLOC_SIZE 256
@@ -1056,12 +1059,11 @@ static int trf7970a_init(struct trf7970a *trf)
trf->chip_status_ctrl &= ~TRF7970A_CHIP_STATUS_RF_ON;
- ret = trf7970a_write(trf, TRF7970A_MODULATOR_SYS_CLK_CTRL, 0);
+ ret = trf7970a_write(trf, TRF7970A_MODULATOR_SYS_CLK_CTRL,
+ trf->modulator_sys_clk_ctrl);
if (ret)
goto err_out;
- trf->modulator_sys_clk_ctrl = 0;
-
ret = trf7970a_write(trf, TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS,
TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS_WLH_96 |
TRF7970A_ADJUTABLE_FIFO_IRQ_LEVELS_WLL_32);
@@ -1181,27 +1183,37 @@ static int trf7970a_in_config_rf_tech(struct trf7970a *trf, int tech)
switch (tech) {
case NFC_DIGITAL_RF_TECH_106A:
trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_14443A_106;
- trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_OOK;
+ trf->modulator_sys_clk_ctrl =
+ (trf->modulator_sys_clk_ctrl & 0xF8) |
+ TRF7970A_MODULATOR_DEPTH_OOK;
trf->guard_time = TRF7970A_GUARD_TIME_NFCA;
break;
case NFC_DIGITAL_RF_TECH_106B:
trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_14443B_106;
- trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_ASK10;
+ trf->modulator_sys_clk_ctrl =
+ (trf->modulator_sys_clk_ctrl & 0xF8) |
+ TRF7970A_MODULATOR_DEPTH_ASK10;
trf->guard_time = TRF7970A_GUARD_TIME_NFCB;
break;
case NFC_DIGITAL_RF_TECH_212F:
trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_FELICA_212;
- trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_ASK10;
+ trf->modulator_sys_clk_ctrl =
+ (trf->modulator_sys_clk_ctrl & 0xF8) |
+ TRF7970A_MODULATOR_DEPTH_ASK10;
trf->guard_time = TRF7970A_GUARD_TIME_NFCF;
break;
case NFC_DIGITAL_RF_TECH_424F:
trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_FELICA_424;
- trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_ASK10;
+ trf->modulator_sys_clk_ctrl =
+ (trf->modulator_sys_clk_ctrl & 0xF8) |
+ TRF7970A_MODULATOR_DEPTH_ASK10;
trf->guard_time = TRF7970A_GUARD_TIME_NFCF;
break;
case NFC_DIGITAL_RF_TECH_ISO15693:
trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_15693_SGL_1OF4_2648;
- trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_OOK;
+ trf->modulator_sys_clk_ctrl =
+ (trf->modulator_sys_clk_ctrl & 0xF8) |
+ TRF7970A_MODULATOR_DEPTH_OOK;
trf->guard_time = TRF7970A_GUARD_TIME_15693;
break;
default:
@@ -1571,17 +1583,23 @@ static int trf7970a_tg_config_rf_tech(struct trf7970a *trf, int tech)
trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_NFC_NFC_CE_MODE |
TRF7970A_ISO_CTRL_NFC_CE |
TRF7970A_ISO_CTRL_NFC_CE_14443A;
- trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_OOK;
+ trf->modulator_sys_clk_ctrl =
+ (trf->modulator_sys_clk_ctrl & 0xF8) |
+ TRF7970A_MODULATOR_DEPTH_OOK;
break;
case NFC_DIGITAL_RF_TECH_212F:
trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_NFC_NFC_CE_MODE |
TRF7970A_ISO_CTRL_NFC_NFCF_212;
- trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_ASK10;
+ trf->modulator_sys_clk_ctrl =
+ (trf->modulator_sys_clk_ctrl & 0xF8) |
+ TRF7970A_MODULATOR_DEPTH_ASK10;
break;
case NFC_DIGITAL_RF_TECH_424F:
trf->iso_ctrl_tech = TRF7970A_ISO_CTRL_NFC_NFC_CE_MODE |
TRF7970A_ISO_CTRL_NFC_NFCF_424;
- trf->modulator_sys_clk_ctrl = TRF7970A_MODULATOR_DEPTH_ASK10;
+ trf->modulator_sys_clk_ctrl =
+ (trf->modulator_sys_clk_ctrl & 0xF8) |
+ TRF7970A_MODULATOR_DEPTH_ASK10;
break;
default:
dev_dbg(trf->dev, "Unsupported rf technology: %d\n", tech);
@@ -1987,6 +2005,7 @@ static int trf7970a_probe(struct spi_device *spi)
struct device_node *np = spi->dev.of_node;
struct trf7970a *trf;
int uvolts, autosuspend_delay, ret;
+ u32 clk_freq = 13560000;
if (!np) {
dev_err(&spi->dev, "No Device Tree entry\n");
@@ -2043,6 +2062,15 @@ static int trf7970a_probe(struct spi_device *spi)
return ret;
}
+ of_property_read_u32(np, "clock-frequency", &clk_freq);
+ if ((clk_freq != TRF7970A_27MHZ_CLOCK_FREQUENCY) ||
+ (clk_freq != TRF7970A_27MHZ_CLOCK_FREQUENCY)) {
+ dev_err(trf->dev,
+ "clock-frequency (%u Hz) unsupported\n",
+ clk_freq);
+ return -EINVAL;
+ }
+
if (of_property_read_bool(np, "en2-rf-quirk"))
trf->quirks |= TRF7970A_QUIRK_EN2_MUST_STAY_LOW;
--
Signed-off-by: Geoff Lansberry <geoff@kuvee.com>
^ permalink raw reply related
* [PATCH 2/3] NFC: trf7970a: Add device tree option of 1.8 Volt IO voltage
From: Geoff Lansberry @ 2016-12-20 16:16 UTC (permalink / raw)
To: linux-wireless
Cc: lauro.venancio, aloisio.almeida, sameo, robh+dt, mark.rutland,
netdev, devicetree, linux-kernel, mgreer, justin, Geoff Lansberry
In-Reply-To: <1482250592-4268-1-git-send-email-glansberry@gmail.com>
From: Geoff Lansberry <geoff@kuvee.com>
The TRF7970A has configuration options for supporting hardware designs
with 1.8 Volt or 3.3 Volt IO. This commit adds a device tree option,
using a fixed regulator binding, for setting the io voltage to match
the hardware configuration. If no option is supplied it defaults to
3.3 volt configuration.
---
.../devicetree/bindings/net/nfc/trf7970a.txt | 4 ++--
drivers/nfc/trf7970a.c | 28 +++++++++++++++++++++-
2 files changed, 29 insertions(+), 3 deletions(-)
diff --git a/Documentation/devicetree/bindings/net/nfc/trf7970a.txt b/Documentation/devicetree/bindings/net/nfc/trf7970a.txt
index e262ac1..b5777d8 100644
--- a/Documentation/devicetree/bindings/net/nfc/trf7970a.txt
+++ b/Documentation/devicetree/bindings/net/nfc/trf7970a.txt
@@ -21,9 +21,9 @@ Optional SoC Specific Properties:
- t5t-rmb-extra-byte-quirk: Specify that the trf7970a has the erratum
where an extra byte is returned by Read Multiple Block commands issued
to Type 5 tags.
+- vdd-io-supply: Regulator specifying voltage for vdd-io
- clock-frequency: Set to specify that the input frequency to the trf7970a is 13560000Hz or 27120000Hz
-
Example (for ARM-based BeagleBone with TRF7970A on SPI1):
&spi1 {
@@ -41,11 +41,11 @@ Example (for ARM-based BeagleBone with TRF7970A on SPI1):
<&gpio2 5 GPIO_ACTIVE_LOW>;
vin-supply = <&ldo3_reg>;
vin-voltage-override = <5000000>;
+ vdd-io-supply = <&ldo2_reg>;
autosuspend-delay = <30000>;
irq-status-read-quirk;
en2-rf-quirk;
t5t-rmb-extra-byte-quirk;
- vdd_io_1v8;
clock-frequency = <27120000>;
status = "okay";
};
diff --git a/drivers/nfc/trf7970a.c b/drivers/nfc/trf7970a.c
index 4e051e9..8a88195 100644
--- a/drivers/nfc/trf7970a.c
+++ b/drivers/nfc/trf7970a.c
@@ -444,6 +444,7 @@ struct trf7970a {
u8 iso_ctrl_tech;
u8 modulator_sys_clk_ctrl;
u8 special_fcn_reg1;
+ u8 io_ctrl;
unsigned int guard_time;
int technology;
int framing;
@@ -1051,6 +1052,11 @@ static int trf7970a_init(struct trf7970a *trf)
if (ret)
goto err_out;
+ ret = trf7970a_write(trf, TRF7970A_REG_IO_CTRL,
+ trf->io_ctrl | TRF7970A_REG_IO_CTRL_VRS(0x1));
+ if (ret)
+ goto err_out;
+
ret = trf7970a_write(trf, TRF7970A_NFC_TARGET_LEVEL, 0);
if (ret)
goto err_out;
@@ -1767,7 +1773,7 @@ static int _trf7970a_tg_listen(struct nfc_digital_dev *ddev, u16 timeout,
goto out_err;
ret = trf7970a_write(trf, TRF7970A_REG_IO_CTRL,
- TRF7970A_REG_IO_CTRL_VRS(0x1));
+ trf->io_ctrl | TRF7970A_REG_IO_CTRL_VRS(0x1));
if (ret)
goto out_err;
@@ -2062,6 +2068,7 @@ static int trf7970a_probe(struct spi_device *spi)
return ret;
}
+
of_property_read_u32(np, "clock-frequency", &clk_freq);
if ((clk_freq != TRF7970A_27MHZ_CLOCK_FREQUENCY) ||
(clk_freq != TRF7970A_27MHZ_CLOCK_FREQUENCY)) {
@@ -2105,6 +2112,25 @@ static int trf7970a_probe(struct spi_device *spi)
if (uvolts > 4000000)
trf->chip_status_ctrl = TRF7970A_CHIP_STATUS_VRS5_3;
+ trf->regulator = devm_regulator_get(&spi->dev, "vdd-io");
+ if (IS_ERR(trf->regulator)) {
+ ret = PTR_ERR(trf->regulator);
+ dev_err(trf->dev, "Can't get VDD_IO regulator: %d\n", ret);
+ goto err_destroy_lock;
+ }
+
+ ret = regulator_enable(trf->regulator);
+ if (ret) {
+ dev_err(trf->dev, "Can't enable VDD_IO: %d\n", ret);
+ goto err_destroy_lock;
+ }
+
+
+ if (regulator_get_voltage(trf->regulator) == 1800000) {
+ trf->io_ctrl = TRF7970A_REG_IO_CTRL_IO_LOW;
+ dev_dbg(trf->dev, "trf7970a config vdd_io to 1.8V\n");
+ }
+
trf->ddev = nfc_digital_allocate_device(&trf7970a_nfc_ops,
TRF7970A_SUPPORTED_PROTOCOLS,
NFC_DIGITAL_DRV_CAPS_IN_CRC |
--
Signed-off-by: Geoff Lansberry <geoff@kuvee.com>
^ permalink raw reply related
* [PATCH 3/3] nfc: trf7970a: Prevent repeated polling from crashing the kernel
From: Geoff Lansberry @ 2016-12-20 16:16 UTC (permalink / raw)
To: linux-wireless
Cc: lauro.venancio, aloisio.almeida, sameo, robh+dt, mark.rutland,
netdev, devicetree, linux-kernel, mgreer, justin, Jaret Cantu,
Geoff Lansberry
In-Reply-To: <1482250592-4268-1-git-send-email-glansberry@gmail.com>
From: Jaret Cantu <jaret.cantu@timesys.com>
Repeated polling attempts cause a NULL dereference error to occur.
This is because the state of the trf7970a is currently reading but
another request has been made to send a command before it has finished.
The solution is to properly kill the waiting reading (workqueue)
before failing on the send.
---
drivers/nfc/trf7970a.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/drivers/nfc/trf7970a.c b/drivers/nfc/trf7970a.c
index 8a88195..5916737 100644
--- a/drivers/nfc/trf7970a.c
+++ b/drivers/nfc/trf7970a.c
@@ -1496,6 +1496,10 @@ static int trf7970a_send_cmd(struct nfc_digital_dev *ddev,
(trf->state != TRF7970A_ST_IDLE_RX_BLOCKED)) {
dev_err(trf->dev, "%s - Bogus state: %d\n", __func__,
trf->state);
+ if (trf->state == TRF7970A_ST_WAIT_FOR_RX_DATA ||
+ trf->state == TRF7970A_ST_WAIT_FOR_RX_DATA_CONT)
+ trf->ignore_timeout =
+ !cancel_delayed_work(&trf->timeout_work);
ret = -EIO;
goto out_err;
}
--
Signed-off-by: Geoff Lansberry <geoff@kuvee.com>
^ permalink raw reply related
* Re: [PATCH v2 3/3] arm64: dts: marvell: Add ethernet switch definition for the ESPRESSObin
From: Andrew Lunn @ 2016-12-20 16:17 UTC (permalink / raw)
To: Romain Perier
Cc: Vivien Didelot, Florian Fainelli, Jason Cooper,
Sebastian Hesselbarth, Gregory Clement, netdev, devicetree,
Rob Herring, Ian Campbell, Pawel Moll, Mark Rutland, Kumar Gala,
linux-arm-kernel, Thomas Petazzoni, Nadav Haklai
In-Reply-To: <c27998fd-3807-5c99-382b-b8d0d0f06526@free-electrons.com>
> >>+ mdio {
> >>+ #address-cells = <1>;
> >>+ #size-cells = <0>;
> >>+ reg = <1>;
> >
> >what is this reg value for?
> >
> > Andrew
> >
>
> It was required to avoid a warning thrown by the mdio subsystem
Do you remember what the warning was?
This seems odd to me. I don't see why a reg is needed here.
Thanks
Andrew
^ 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