* Re: rsi: fix memory leak on buf and usb_reg_buf
From: Kalle Valo @ 2017-12-07 13:26 UTC (permalink / raw)
To: Colin Ian King
Cc: Amitkumar Karwar, Prameela Rani Garnepudi, linux-wireless, netdev,
kernel-janitors, linux-kernel
In-Reply-To: <20171116173918.3030-1-colin.king@canonical.com>
Colin Ian King <colin.king@canonical.com> wrote:
> From: Colin Ian King <colin.king@canonical.com>
>
> In the cases where len is too long, the error return path fails to
> kfree allocated buffers buf and usb_reg_buf. The simplest fix is to
> perform the sanity check on len before the allocations to avoid having
> to do the kfree'ing in the first place.
>
> Detected by CoverityScan, CID#1452258,1452259 ("Resource Leak")
>
> Fixes: 59f73e2ae185 ("rsi: check length before USB read/write register")
> Signed-off-by: Colin Ian King <colin.king@canonical.com>
Patch applied to wireless-drivers-next.git, thanks.
c4ee30a280b1 wlcore, wl1251: fix spelling: "Couldnt" -> "Couldn't" and remove error on -ENOMEM
--
https://patchwork.kernel.org/patch/10061619/
https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
^ permalink raw reply
* [PATCH] netfilter: fix clusterip_net_exit build regression
From: Arnd Bergmann @ 2017-12-07 13:26 UTC (permalink / raw)
To: Pablo Neira Ayuso, Jozsef Kadlecsik, Florian Westphal,
David S. Miller, Alexey Kuznetsov, Hideaki YOSHIFUJI
Cc: Arnd Bergmann, Xin Long, Vasily Averin, netfilter-devel, coreteam,
netdev, linux-kernel
The added check produces a build error when CONFIG_PROC_FS is
disabled:
net/ipv4/netfilter/ipt_CLUSTERIP.c: In function 'clusterip_net_exit':
net/ipv4/netfilter/ipt_CLUSTERIP.c:822:28: error: 'cn' undeclared (first use in this function)
This moves the variable declaration out of the #ifdef to make it
available to the WARN_ON_ONCE().
Fixes: 613d0776d3fe ("netfilter: exit_net cleanup check added")
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
---
net/ipv4/netfilter/ipt_CLUSTERIP.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/net/ipv4/netfilter/ipt_CLUSTERIP.c b/net/ipv4/netfilter/ipt_CLUSTERIP.c
index e35b8d074f06..69060e3abe85 100644
--- a/net/ipv4/netfilter/ipt_CLUSTERIP.c
+++ b/net/ipv4/netfilter/ipt_CLUSTERIP.c
@@ -813,8 +813,8 @@ static int clusterip_net_init(struct net *net)
static void clusterip_net_exit(struct net *net)
{
-#ifdef CONFIG_PROC_FS
struct clusterip_net *cn = net_generic(net, clusterip_net_id);
+#ifdef CONFIG_PROC_FS
proc_remove(cn->procdir);
cn->procdir = NULL;
#endif
--
2.9.0
^ permalink raw reply related
* Re: [v1] brcmfmac: Avoid build error with make W=1
From: Kalle Valo @ 2017-12-07 13:49 UTC (permalink / raw)
To: Andy Shevchenko
Cc: Arend van Spriel, Franky Lin, Hante Meuleman, Chi-Hsien Lin,
Wright Feng, brcm80211-dev-list.pdl-dY08KVG/lbpWk0Htik3J/w,
brcm80211-dev-list-+wT8y+m8/X5BDgjK7y7TUQ,
linux-wireless-u79uwXL29TY76Z2rM5mHXA,
netdev-u79uwXL29TY76Z2rM5mHXA, Andy Shevchenko
In-Reply-To: <20171123155704.44878-1-andriy.shevchenko-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
Andy Shevchenko <andriy.shevchenko-VuQAYsv1563Yd54FQh9/CA@public.gmane.org> wrote:
> When I run make W=1 on gcc (Debian 7.2.0-16) 7.2.0 I got an error for
> the first run, all next ones are okay.
>
> CC [M] drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.o
> drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.c:2078: error: Cannot parse struct or union!
> scripts/Makefile.build:310: recipe for target 'drivers/net/wireless/broadcom/brcm80211/brcmfmac/sdio.o' failed
>
> Seems like something happened with W=1 and wrong kernel doc format.
> As a quick fix remove dubious /** in the code.
>
> Signed-off-by: Andy Shevchenko <andriy.shevchenko-VuQAYsv1563Yd54FQh9/CA@public.gmane.org>
> Acked-by: Arend van Spriel <arend.vanspriel-dY08KVG/lbpWk0Htik3J/w@public.gmane.org>
Patch applied to wireless-drivers.git, thanks.
51ef7925e106 brcmfmac: Avoid build error with make W=1
--
https://patchwork.kernel.org/patch/10073021/
https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
^ permalink raw reply
* [PATCH v5 net-next] net/tcp: trace all TCP/IP state transition with tcp_set_state tracepoint
From: Yafang Shao @ 2017-12-07 14:10 UTC (permalink / raw)
To: davem, songliubraving, marcelo.leitner
Cc: kuznet, yoshfuji, rostedt, bgregg, netdev, linux-kernel,
Yafang Shao
The TCP/IP transition from TCP_LISTEN to TCP_SYN_RECV and some other
transitions are not traced with tcp_set_state tracepoint.
In order to trace the whole tcp lifespans, two helpers are introduced,
void sk_set_state(struct sock *sk, int state);
void sk_state_store(struct sock *sk, int newstate);
When do TCP/IP state transition, we should use these two helpers or use
tcp_set_state() other than assigning a value to sk_state directly.
Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
Acked-by: Song Liu <songliubraving@fb.com>
Reviewed-by: Marcelo Ricardo Leitner <marcelo.leitner@gmail.com>
Signed-off-by: Yafang Shao <laoar.shao@gmail.com>
---
v4->v5: Trace only TCP sockets, whatever it is stream socket or raw socket.
v3->v4: Do not trace DCCP socket
v2->v3: Per suggestion from Marcelo Ricardo Leitner, inverting __
to sk_state_store.
---
include/net/sock.h | 8 ++++++--
net/core/sock.c | 15 +++++++++++++++
net/ipv4/inet_connection_sock.c | 5 +++--
net/ipv4/inet_hashtables.c | 2 +-
net/ipv4/tcp.c | 2 +-
5 files changed, 26 insertions(+), 6 deletions(-)
diff --git a/include/net/sock.h b/include/net/sock.h
index 79e1a2c..1cf7685 100644
--- a/include/net/sock.h
+++ b/include/net/sock.h
@@ -2349,18 +2349,22 @@ static inline int sk_state_load(const struct sock *sk)
}
/**
- * sk_state_store - update sk->sk_state
+ * __sk_state_store - update sk->sk_state
* @sk: socket pointer
* @newstate: new state
*
* Paired with sk_state_load(). Should be used in contexts where
* state change might impact lockless readers.
*/
-static inline void sk_state_store(struct sock *sk, int newstate)
+static inline void __sk_state_store(struct sock *sk, int newstate)
{
smp_store_release(&sk->sk_state, newstate);
}
+/* For tcp_set_state tracepoint */
+void sk_state_store(struct sock *sk, int newstate);
+void sk_set_state(struct sock *sk, int state);
+
void sock_enable_timestamp(struct sock *sk, int flag);
int sock_get_timestamp(struct sock *, struct timeval __user *);
int sock_get_timestampns(struct sock *, struct timespec __user *);
diff --git a/net/core/sock.c b/net/core/sock.c
index c0b5b2f..61841a2 100644
--- a/net/core/sock.c
+++ b/net/core/sock.c
@@ -138,6 +138,7 @@
#include <net/sock_reuseport.h>
#include <trace/events/sock.h>
+#include <trace/events/tcp.h>
#include <net/tcp.h>
#include <net/busy_poll.h>
@@ -2859,6 +2860,20 @@ int sock_get_timestampns(struct sock *sk, struct timespec __user *userstamp)
}
EXPORT_SYMBOL(sock_get_timestampns);
+void sk_state_store(struct sock *sk, int newstate)
+{
+ if (sk->sk_protocol == IPPROTO_TCP)
+ trace_tcp_set_state(sk, sk->sk_state, newstate);
+ __sk_state_store(sk, newstate);
+}
+
+void sk_set_state(struct sock *sk, int state)
+{
+ if (sk->sk_protocol == IPPROTO_TCP)
+ trace_tcp_set_state(sk, sk->sk_state, state);
+ sk->sk_state = state;
+}
+
void sock_enable_timestamp(struct sock *sk, int flag)
{
if (!sock_flag(sk, flag)) {
diff --git a/net/ipv4/inet_connection_sock.c b/net/ipv4/inet_connection_sock.c
index 4ca46dc..41f9c87 100644
--- a/net/ipv4/inet_connection_sock.c
+++ b/net/ipv4/inet_connection_sock.c
@@ -783,7 +783,7 @@ struct sock *inet_csk_clone_lock(const struct sock *sk,
if (newsk) {
struct inet_connection_sock *newicsk = inet_csk(newsk);
- newsk->sk_state = TCP_SYN_RECV;
+ sk_set_state(newsk, TCP_SYN_RECV);
newicsk->icsk_bind_hash = NULL;
inet_sk(newsk)->inet_dport = inet_rsk(req)->ir_rmt_port;
@@ -888,7 +888,8 @@ int inet_csk_listen_start(struct sock *sk, int backlog)
return 0;
}
- sk->sk_state = TCP_CLOSE;
+ sk_set_state(sk, TCP_CLOSE);
+
return err;
}
EXPORT_SYMBOL_GPL(inet_csk_listen_start);
diff --git a/net/ipv4/inet_hashtables.c b/net/ipv4/inet_hashtables.c
index f6f5810..5973693 100644
--- a/net/ipv4/inet_hashtables.c
+++ b/net/ipv4/inet_hashtables.c
@@ -544,7 +544,7 @@ bool inet_ehash_nolisten(struct sock *sk, struct sock *osk)
sock_prot_inuse_add(sock_net(sk), sk->sk_prot, 1);
} else {
percpu_counter_inc(sk->sk_prot->orphan_count);
- sk->sk_state = TCP_CLOSE;
+ sk_set_state(sk, TCP_CLOSE);
sock_set_flag(sk, SOCK_DEAD);
inet_csk_destroy_sock(sk);
}
diff --git a/net/ipv4/tcp.c b/net/ipv4/tcp.c
index 1803116..ac98dc6 100644
--- a/net/ipv4/tcp.c
+++ b/net/ipv4/tcp.c
@@ -2065,7 +2065,7 @@ void tcp_set_state(struct sock *sk, int state)
/* Change state AFTER socket is unhashed to avoid closed
* socket sitting in hash tables.
*/
- sk_state_store(sk, state);
+ __sk_state_store(sk, state);
#ifdef STATE_TRACE
SOCK_DEBUG(sk, "TCP sk=%p, State %s -> %s\n", sk, statename[oldstate], statename[state]);
--
1.8.3.1
^ permalink raw reply related
* Re: [PATCH v3] leds: trigger: Introduce a NETDEV trigger
From: Ben Whitten @ 2017-12-07 14:19 UTC (permalink / raw)
To: Philippe Ombredanne
Cc: rpurdie, Pavel Machek, Jacek Anaszewski, linux-leds, LKML, netdev
In-Reply-To: <CAOFm3uGxzg45ZGmE4GRwy=oiaNERtq7tYdG4VwgZc0xgvXG6Pg@mail.gmail.com>
Philippe,
On 7 December 2017 at 13:01, Philippe Ombredanne <pombredanne@nexb.com> wrote:
> Ben,
>
> On Thu, Dec 7, 2017 at 12:46 PM, Ben Whitten <ben.whitten@gmail.com> wrote:
>> From: Ben Whitten <ben.whitten@gmail.com>
>>
>> This commit introduces a NETDEV trigger for named device
>> activity. Available triggers are link, rx, and tx.
>>
>> Signed-off-by: Ben Whitten <ben.whitten@gmail.com>
> []
>> --- /dev/null
>> +++ b/drivers/leds/trigger/ledtrig-netdev.c
>> @@ -0,0 +1,503 @@
>> +/*
>> + * LED Kernel Netdev Trigger
>> + *
>> + * Toggles the LED to reflect the link and traffic state of a named net device
>> + *
>> + * Copyright 2017 Ben Whitten <ben.whitten@gmail.com>
>> + *
>> + * Copyright 2007 Oliver Jowett <oliver@opencloud.com>
>> + *
>> + * Derived from ledtrig-timer.c which is:
>> + * Copyright 2005-2006 Openedhand Ltd.
>> + * Author: Richard Purdie <rpurdie@openedhand.com>
>> + *
>> + * This program is free software; you can redistribute it and/or modify
>> + * it under the terms of the GNU General Public License version 2 as
>> + * published by the Free Software Foundation.
>> + *
>> + */
>
> Have you considered using the new SPDX id instead ? See Thomas doc
> patches and Greg and Linus comments on the topic
> Here this would likely come out this way (yes, using a C++ comment at the top):
>
>> +// SPDX-License-Identifier: GPL-2.0
>> +/*
>> + * LED Kernel Netdev Trigger
>> + *
>> + * Toggles the LED to reflect the link and traffic state of a named net device
>> + *
>> + * Copyright 2017 Ben Whitten <ben.whitten@gmail.com>
>> + *
>> + * Copyright 2007 Oliver Jowett <oliver@opencloud.com>
>> + *
>> + * Derived from ledtrig-timer.c which is:
>> + * Copyright 2005-2006 Openedhand Ltd.
>> + * Author: Richard Purdie <rpurdie@openedhand.com>
>> + *
>> + */
>
>
> This is cleaner and simpler, don't you think?
Much cleaner. Thank you for the suggestion, I was unaware of this.
Kind regards,
Ben Whitten
^ permalink raw reply
* RE: [crypto 6/8] chtls: TCB and Key program
From: Atul Gupta @ 2017-12-07 14:21 UTC (permalink / raw)
To: Stephan Mueller
Cc: herbert@gondor.apana.org.au, linux-crypto@vger.kernel.org,
netdev@vger.kernel.org, davem@davemloft.net, davejwatson@fb.com,
Ganesh GR, Harsh Jain
In-Reply-To: <2083625.RdNrO0bCEz@tauon.chronox.de>
-----Original Message-----
From: Stephan Mueller [mailto:smueller@chronox.de]
Sent: Tuesday, December 5, 2017 6:37 PM
To: Atul Gupta <atul.gupta@chelsio.com>
Cc: herbert@gondor.apana.org.au; linux-crypto@vger.kernel.org; netdev@vger.kernel.org; davem@davemloft.net; davejwatson@fb.com; Ganesh GR <ganeshgr@chelsio.com>; Harsh Jain <Harsh@chelsio.com>
Subject: Re: [crypto 6/8] chtls: TCB and Key program
Am Dienstag, 5. Dezember 2017, 12:40:29 CET schrieb Atul Gupta:
Hi Atul,
> program the tx and rx key on chip.
>
> Signed-off-by: Atul Gupta <mailto:atul.gupta@chelsio.com>
> ---
> drivers/crypto/chelsio/chtls/chtls_hw.c | 394
> ++++++++++++++++++++++++++++++++ 1 file changed, 394 insertions(+)
> create mode 100644 drivers/crypto/chelsio/chtls/chtls_hw.c
>
> diff --git a/drivers/crypto/chelsio/chtls/chtls_hw.c
> b/drivers/crypto/chelsio/chtls/chtls_hw.c new file mode 100644 index
> 0000000..5e65aa2
> --- /dev/null
> +++ b/drivers/crypto/chelsio/chtls/chtls_hw.c
> @@ -0,0 +1,394 @@
> +/*
> + * Copyright (c) 2017 Chelsio Communications, Inc.
> + *
> + * This program is free software; you can redistribute it and/or
> +modify
> + * it under the terms of the GNU General Public License version 2 as
> + * published by the Free Software Foundation.
> + *
> + * Written by: Atul Gupta (mailto:atul.gupta@chelsio.com) */
> +
> +#include <linux/module.h>
> +#include <linux/list.h>
> +#include <linux/workqueue.h>
> +#include <linux/skbuff.h>
> +#include <linux/timer.h>
> +#include <linux/notifier.h>
> +#include <linux/inetdevice.h>
> +#include <linux/ip.h>
> +#include <linux/tcp.h>
> +#include <linux/tls.h>
> +#include <net/tls.h>
> +
> +#include "chtls.h"
> +#include "chtls_cm.h"
> +
> +static void __set_tcb_field_direct(struct chtls_sock *csk,
> + struct cpl_set_tcb_field *req, u16 word,
> + u64 mask, u64 val, u8 cookie, int no_reply) {
> + struct ulptx_idata *sc;
> +
> + INIT_TP_WR_CPL(req, CPL_SET_TCB_FIELD, csk->tid);
> + req->wr.wr_mid |= htonl(FW_WR_FLOWID_V(csk->tid));
> + req->reply_ctrl = htons(NO_REPLY_V(no_reply) |
> + QUEUENO_V(csk->rss_qid));
> + req->word_cookie = htons(TCB_WORD(word) | TCB_COOKIE_V(cookie));
> + req->mask = cpu_to_be64(mask);
> + req->val = cpu_to_be64(val);
> + sc = (struct ulptx_idata *)(req + 1);
> + sc->cmd_more = htonl(ULPTX_CMD_V(ULP_TX_SC_NOOP));
> + sc->len = htonl(0);
> +}
> +
> +void __set_tcb_field(struct sock *sk, struct sk_buff *skb, u16 word,
> + u64 mask, u64 val, u8 cookie, int no_reply) {
> + struct chtls_sock *csk = rcu_dereference_sk_user_data(sk);
> + struct cpl_set_tcb_field *req;
> + struct ulptx_idata *sc;
> + unsigned int wrlen = roundup(sizeof(*req) + sizeof(*sc), 16);
> +
> + req = (struct cpl_set_tcb_field *)__skb_put(skb, wrlen);
> + __set_tcb_field_direct(csk, req, word, mask, val, cookie, no_reply);
> + set_wr_txq(skb, CPL_PRIORITY_CONTROL, csk->port_id); }
> +
> +static int chtls_set_tcb_field(struct sock *sk, u16 word, u64 mask,
> +u64
> val) +{
> + struct chtls_sock *csk = rcu_dereference_sk_user_data(sk);
> + struct sk_buff *skb;
> + struct cpl_set_tcb_field *req;
> + struct ulptx_idata *sc;
> + unsigned int wrlen = roundup(sizeof(*req) + sizeof(*sc), 16);
> + unsigned int credits_needed = DIV_ROUND_UP(wrlen, 16);
> +
> + skb = alloc_skb(wrlen, GFP_ATOMIC);
> + if (!skb)
> + return -ENOMEM;
> +
> + __set_tcb_field(sk, skb, word, mask, val, 0, 1);
> + set_queue(skb, (csk->txq_idx << 1) | CPL_PRIORITY_DATA, sk);
> + csk->wr_credits -= credits_needed;
> + csk->wr_unacked += credits_needed;
> + enqueue_wr(csk, skb);
> + cxgb4_ofld_send(csk->egress_dev, skb);
> + return 0;
> +}
> +
> +/*
> + * Set one of the t_flags bits in the TCB.
> + */
> +int chtls_set_tcb_tflag(struct sock *sk, unsigned int bit_pos, int
> +val) {
> + return chtls_set_tcb_field(sk, 1, 1ULL << bit_pos,
> + val << bit_pos);
> +}
> +
> +static int chtls_set_tcb_keyid(struct sock *sk, int keyid) {
> + return chtls_set_tcb_field(sk, 31, 0xFFFFFFFFULL, keyid); }
> +
> +static int chtls_set_tcb_seqno(struct sock *sk) {
> + return chtls_set_tcb_field(sk, 28, ~0ULL, 0); }
> +
> +static int chtls_set_tcb_quiesce(struct sock *sk, int val) {
> + return chtls_set_tcb_field(sk, 1, (1ULL << TF_RX_QUIESCE_S),
> + TF_RX_QUIESCE_V(val));
> +}
> +
> +static void *chtls_alloc_mem(unsigned long size) {
> + void *p = kmalloc(size, GFP_KERNEL);
> +
> + if (!p)
> + p = vmalloc(size);
> + if (p)
> + memset(p, 0, size);
> + return p;
> +}
> +
> +static void chtls_free_mem(void *addr) {
> + unsigned long p = (unsigned long)addr;
> +
> + if (p >= VMALLOC_START && p < VMALLOC_END)
> + vfree(addr);
> + else
> + kfree(addr);
> +}
> +
> +/* TLS Key bitmap processing */
> +int chtls_init_kmap(struct chtls_dev *cdev, struct cxgb4_lld_info
> +*lldi) {
> + unsigned int num_key_ctx, bsize;
> +
> + num_key_ctx = (lldi->vr->key.size / TLS_KEY_CONTEXT_SZ);
> + bsize = BITS_TO_LONGS(num_key_ctx);
> +
> + cdev->kmap.size = num_key_ctx;
> + cdev->kmap.available = bsize;
> + cdev->kmap.addr = chtls_alloc_mem(sizeof(*cdev->kmap.addr) *
> + bsize);
> + if (!cdev->kmap.addr)
> + return -1;
> +
> + cdev->kmap.start = lldi->vr->key.start;
> + spin_lock_init(&cdev->kmap.lock);
> + return 0;
> +}
> +
> +void chtls_free_kmap(struct chtls_dev *cdev) {
> + if (cdev->kmap.addr)
> + chtls_free_mem(cdev->kmap.addr);
> +}
> +
> +static int get_new_keyid(struct chtls_sock *csk, u32 optname) {
> + struct chtls_dev *cdev = csk->cdev;
> + struct chtls_hws *hws = &csk->tlshws;
> + struct net_device *dev = csk->egress_dev;
> + struct adapter *adap = netdev2adap(dev);
> + int keyid;
> +
> + spin_lock_bh(&cdev->kmap.lock);
> + keyid = find_first_zero_bit(cdev->kmap.addr, cdev->kmap.size);
> + if (keyid < cdev->kmap.size) {
> + __set_bit(keyid, cdev->kmap.addr);
> + if (optname == TLS_RX)
> + hws->rxkey = keyid;
> + else
> + hws->txkey = keyid;
> + atomic_inc(&adap->chcr_stats.tls_key);
> + } else {
> + keyid = -1;
> + }
> + spin_unlock_bh(&cdev->kmap.lock);
> + pr_info("keyid:%d\n", keyid);
> + return keyid;
> +}
> +
> +void free_tls_keyid(struct sock *sk)
> +{
> + struct chtls_sock *csk = rcu_dereference_sk_user_data(sk);
> + struct chtls_dev *cdev = csk->cdev;
> + struct chtls_hws *hws = &csk->tlshws;
> + struct net_device *dev = csk->egress_dev;
> + struct adapter *adap = netdev2adap(dev);
> +
> + if (!cdev->kmap.addr)
> + return;
> +
> + spin_lock_bh(&cdev->kmap.lock);
> + if (hws->rxkey >= 0) {
> + __clear_bit(hws->rxkey, cdev->kmap.addr);
> + atomic_dec(&adap->chcr_stats.tls_key);
> + hws->rxkey = -1;
> + }
> + if (hws->txkey >= 0) {
> + __clear_bit(hws->txkey, cdev->kmap.addr);
> + atomic_dec(&adap->chcr_stats.tls_key);
> + hws->txkey = -1;
> + }
> + spin_unlock_bh(&cdev->kmap.lock);
> +}
> +
> +static unsigned int keyid_to_addr(int start_addr, int keyid) {
> + return ((start_addr + (keyid * TLS_KEY_CONTEXT_SZ)) >> 5); }
> +
> +static void chtls_rxkey_ivauth(struct _key_ctx *kctx) {
> + kctx->iv_to_auth = cpu_to_be64(KEYCTX_TX_WR_IV_V(6ULL) |
> + KEYCTX_TX_WR_AAD_V(1ULL) |
> + KEYCTX_TX_WR_AADST_V(5ULL) |
> + KEYCTX_TX_WR_CIPHER_V(14ULL) |
> + KEYCTX_TX_WR_CIPHERST_V(0ULL) |
> + KEYCTX_TX_WR_AUTH_V(14ULL) |
> + KEYCTX_TX_WR_AUTHST_V(16ULL) |
> + KEYCTX_TX_WR_AUTHIN_V(16ULL));
> +}
> +
> +static int chtls_key_info(struct chtls_sock *csk,
> + struct _key_ctx *kctx,
> + void *c_info, u32 keylen, u32 optname) {
> + struct crypto_cipher *cipher;
> + struct tls12_crypto_info_aes_gcm_128 *gcm_ctx =
> + (struct tls12_crypto_info_aes_gcm_128 *)
> + &csk->tlshws.crypto_info;
> + unsigned char ghash_h[AEAD_H_SIZE];
> + unsigned char key[CHCR_KEYCTX_CIPHER_KEY_SIZE_256];
> + int ck_size, key_ctx_size;
> + int ret;
> +
> + key_ctx_size = sizeof(struct _key_ctx) +
> + roundup(keylen, 16) + AEAD_H_SIZE;
> +
> + if (keylen == AES_KEYSIZE_128) {
> + ck_size = CHCR_KEYCTX_CIPHER_KEY_SIZE_128;
> + } else if (keylen == AES_KEYSIZE_192) {
> + ck_size = CHCR_KEYCTX_CIPHER_KEY_SIZE_192;
> + } else if (keylen == AES_KEYSIZE_256) {
> + ck_size = CHCR_KEYCTX_CIPHER_KEY_SIZE_256;
> + } else {
> + pr_err("GCM: Invalid key length %d\n", keylen);
> + return -EINVAL;
> + }
> + memcpy(key, gcm_ctx->key, keylen);
> +
> + /* Calculate the H = CIPH(K, 0 repeated 16 times).
> + * It will go in key context
> + */
> + cipher = crypto_alloc_cipher("aes-generic", 0, 0);
Why not "aes"?
[Atul] AES is also fine, will make the change in v2
> + if (IS_ERR(cipher)) {
> + ret = -ENOMEM;
> + goto out;
> + }
> +
> + ret = crypto_cipher_setkey(cipher, key, keylen);
> + if (ret)
> + goto out1;
> +
> + memset(ghash_h, 0, AEAD_H_SIZE);
> + crypto_cipher_encrypt_one(cipher, ghash_h, ghash_h);
> + csk->tlshws.keylen = key_ctx_size;
> +
> + /* Copy the Key context */
> + if (optname == TLS_RX) {
> + int key_ctx;
> +
> + key_ctx = ((key_ctx_size >> 4) << 3);
> + kctx->ctx_hdr = FILL_KEY_CRX_HDR(ck_size,
> + CHCR_KEYCTX_MAC_KEY_SIZE_128,
> + 0, 0, key_ctx);
> + chtls_rxkey_ivauth(kctx);
> + } else {
> + kctx->ctx_hdr = FILL_KEY_CTX_HDR(ck_size,
> + CHCR_KEYCTX_MAC_KEY_SIZE_128,
> + 0, 0, key_ctx_size >> 4);
> + }
> +
> + memcpy(kctx->salt, gcm_ctx->salt, TLS_CIPHER_AES_GCM_128_SALT_SIZE);
> + memcpy(kctx->key, gcm_ctx->key, keylen);
> + memcpy(kctx->key + keylen, ghash_h, AEAD_H_SIZE);
> +
> +out1:
> + crypto_free_cipher(cipher);
> +out:
> + return ret;
memzero_explicit(key)?
[Atul] may not be required as entire info of size keylen and AEAD_H_SIZE is copied onto kctx->key. Key data is received from user, while ghash is memset and locally generated
> +}
> +
> +static void chtls_set_scmd(struct chtls_sock *csk) {
> + struct chtls_hws *hws = &csk->tlshws;
> +
> + hws->scmd.seqno_numivs =
> + SCMD_SEQ_NO_CTRL_V(3) |
> + SCMD_PROTO_VERSION_V(0) |
> + SCMD_ENC_DEC_CTRL_V(0) |
> + SCMD_CIPH_AUTH_SEQ_CTRL_V(1) |
> + SCMD_CIPH_MODE_V(2) |
> + SCMD_AUTH_MODE_V(4) |
> + SCMD_HMAC_CTRL_V(0) |
> + SCMD_IV_SIZE_V(4) |
> + SCMD_NUM_IVS_V(1);
> +
> + hws->scmd.ivgen_hdrlen =
> + SCMD_IV_GEN_CTRL_V(1) |
> + SCMD_KEY_CTX_INLINE_V(0) |
> + SCMD_TLS_FRAG_ENABLE_V(1);
> +}
> +
> +int chtls_setkey(struct chtls_sock *csk, void *c_info,
> + u32 keylen, u32 optname)
The current structure of the patch set will break bisect because chtls_setkey is needed in the earlier patch 3. I think this applies to patch 7 as well.
[Atul] Will take care in v2
> +{
> + struct sock *sk = csk->sk;
> + struct chtls_dev *cdev = csk->cdev;
> + struct tls_key_req *kwr;
> + struct _key_ctx *kctx;
> + struct sk_buff *skb;
> + int wrlen, klen, len;
> + int keyid;
> + int ret = 0;
> +
> + klen = roundup((keylen + AEAD_H_SIZE) + sizeof(*kctx), 32);
> + wrlen = roundup(sizeof(*kwr), 16);
> + len = klen + wrlen;
> +
> + /* Flush out-standing data before new key takes effect */
> + if (optname == TLS_TX) {
> + lock_sock(sk);
> + if (skb_queue_len(&csk->txq))
> + chtls_push_frames(csk, 0);
> + release_sock(sk);
> + }
> +
> + keyid = get_new_keyid(csk, optname);
> + if (keyid < 0)
> + return -ENOSPC;
> +
> + skb = alloc_skb(len, GFP_KERNEL);
> + if (!skb)
> + return -ENOMEM;
> +
> + kwr = (struct tls_key_req *)__skb_put_zero(skb, len);
> + kwr->wr.op_to_compl =
> + cpu_to_be32(FW_WR_OP_V(FW_ULPTX_WR) | FW_WR_COMPL_F |
> + FW_WR_ATOMIC_V(1U));
> + kwr->wr.flowid_len16 =
> + cpu_to_be32(FW_WR_LEN16_V(DIV_ROUND_UP(len, 16) |
> + FW_WR_FLOWID_V(csk->tid)));
> + kwr->wr.protocol = 0;
> + kwr->wr.mfs = htons(TLS_MFS);
> + kwr->wr.reneg_to_write_rx = optname;
> +
> + /* ulptx command */
> + kwr->req.cmd = cpu_to_be32(ULPTX_CMD_V(ULP_TX_MEM_WRITE) |
> + T5_ULP_MEMIO_ORDER_V(1) |
> + T5_ULP_MEMIO_IMM_V(1));
> + kwr->req.len16 = cpu_to_be32((csk->tid << 8) |
> + DIV_ROUND_UP(len - sizeof(kwr->wr), 16));
> + kwr->req.dlen = cpu_to_be32(ULP_MEMIO_DATA_LEN_V(klen >> 5));
> + kwr->req.lock_addr = cpu_to_be32(ULP_MEMIO_ADDR_V(keyid_to_addr
> + (cdev->kmap.start, keyid)));
> +
> + /* sub command */
> + kwr->sc_imm.cmd_more = cpu_to_be32(ULPTX_CMD_V(ULP_TX_SC_IMM));
> + kwr->sc_imm.len = cpu_to_be32(klen);
> +
> + /* key info */
> + kctx = (struct _key_ctx *)(kwr + 1);
> + ret = chtls_key_info(csk, kctx, c_info, keylen, optname);
> +
> + csk->wr_credits -= DIV_ROUND_UP(len, 16);
> + csk->wr_unacked += DIV_ROUND_UP(len, 16);
> + enqueue_wr(csk, skb);
> + cxgb4_ofld_send(csk->egress_dev, skb);
> +
> + chtls_set_scmd(csk);
> + /* Clear quiesce for Rx key */
> + if (optname == TLS_RX) {
> + chtls_set_tcb_keyid(sk, keyid);
> + chtls_set_tcb_field(sk, 0,
> + TCB_ULP_RAW_V(TCB_ULP_RAW_M),
> + TCB_ULP_RAW_V((TF_TLS_KEY_SIZE_V(1) |
> + TF_TLS_CONTROL_V(1) |
> + TF_TLS_ACTIVE_V(1) |
> + TF_TLS_ENABLE_V(1))));
> + chtls_set_tcb_seqno(sk);
> + chtls_set_tcb_quiesce(sk, 0);
> + csk->tlshws.rxkey = keyid;
> + } else {
> + csk->tlshws.tx_seq_no = 0;
> + csk->tlshws.txkey = keyid;
> + }
> +
> + return ret;
As far as I see, the key is part of the skb (via kctx). This skb is released after being processed. The release calls kfree_skb which does not zeroize the key. Wouldn't it make sense to clear the memory of the key when the skb is released?
[Atul] we should perhaps memset the info received from user so that driver has no info on key once its written on chip memory.
memset(gcm_ctx->key, 0, keylen);
> +}
Ciao
Stephan
^ permalink raw reply
* Re: ath10k: use 64-bit crash dump timestamps
From: Kalle Valo @ 2017-12-07 14:23 UTC (permalink / raw)
To: Arnd Bergmann
Cc: y2038, Arnd Bergmann, Waldemar Rymarkiewicz, Erik Stromdahl,
Mohammed Shafi Shajakhan, Sarada Prasanna Garnayak,
Venkateswara Naralasetty, Marcin Rokicki, ath10k, linux-wireless,
netdev, linux-kernel
In-Reply-To: <20171127115113.2831506-1-arnd@arndb.de>
Arnd Bergmann <arnd@arndb.de> wrote:
> The dump format uses 64-bit timestamps already, but calling
> getnstimeofday() only returns a 32-bit number on 32-bit architectures,
> so that will overflow in y2038.
>
> This changes it to use ktime_get_real_ts64() instead.
>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
Patch applied to ath-next branch of ath.git, thanks.
dafa42036012 ath10k: use 64-bit crash dump timestamps
--
https://patchwork.kernel.org/patch/10076697/
https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
^ permalink raw reply
* [PATCH net-next v2 0/8] phy: net: meson-gxl: clean-up and improvements
From: Jerome Brunet @ 2017-12-07 14:27 UTC (permalink / raw)
To: Andrew Lunn, Florian Fainelli
Cc: Kevin Hilman, linux-kernel, netdev, linux-amlogic,
linux-arm-kernel, Jerome Brunet
The patchset is a v2 of the previous single clean-up patch [0] which was
part of larger series. I initially to send these patches separately but
adding helper function without using them did not make much sense after
all. So, here is the complete patchset.
This patchset add defines for the control registers and helpers to access
the banked registers. The goal being to make it easier to understand what
the driver actually does.
Then there is fix for the incorrect sampling of the MII LPA register which
is often breaking the auto-negotiation with this PHY. More details on this
in the related patch
CONFIG_A6 settings is removed since this statement was without effect
Finally interrupt support is added, speeding things up a little
This series has been tested on the libretech-cc and khadas VIM
Jerome Brunet (8):
net: phy: meson-gxl: check phy_write return value
net: phy: meson-gxl: define control registers
net: phy: meson-gxl: add read and write helpers for bank registers
net: phy: meson-gxl: use genphy_config_init
net: phy: meson-gxl: detect LPA corruption
net: phy: meson-gxl: leave CONFIG_A6 untouched
net: phy: meson-gxl: add interrupt support
net: phy: meson-gxl: join the authors
drivers/net/phy/meson-gxl.c | 215 ++++++++++++++++++++++++++++++++++++++++----
1 file changed, 197 insertions(+), 18 deletions(-)
--
2.14.3
^ permalink raw reply
* [PATCH net-next v2 1/8] net: phy: meson-gxl: check phy_write return value
From: Jerome Brunet @ 2017-12-07 14:27 UTC (permalink / raw)
To: Andrew Lunn, Florian Fainelli
Cc: Jerome Brunet, Kevin Hilman, netdev, linux-arm-kernel,
linux-amlogic, linux-kernel
In-Reply-To: <20171207142715.32578-1-jbrunet@baylibre.com>
Always check phy_write return values. Better to be safe than sorry
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
drivers/net/phy/meson-gxl.c | 50 ++++++++++++++++++++++++++++++++++-----------
1 file changed, 38 insertions(+), 12 deletions(-)
diff --git a/drivers/net/phy/meson-gxl.c b/drivers/net/phy/meson-gxl.c
index 1ea69b7585d9..7ddb709f69fc 100644
--- a/drivers/net/phy/meson-gxl.c
+++ b/drivers/net/phy/meson-gxl.c
@@ -25,27 +25,53 @@
static int meson_gxl_config_init(struct phy_device *phydev)
{
+ int ret;
+
/* Enable Analog and DSP register Bank access by */
- phy_write(phydev, 0x14, 0x0000);
- phy_write(phydev, 0x14, 0x0400);
- phy_write(phydev, 0x14, 0x0000);
- phy_write(phydev, 0x14, 0x0400);
+ ret = phy_write(phydev, 0x14, 0x0000);
+ if (ret)
+ return ret;
+ ret = phy_write(phydev, 0x14, 0x0400);
+ if (ret)
+ return ret;
+ ret = phy_write(phydev, 0x14, 0x0000);
+ if (ret)
+ return ret;
+ ret = phy_write(phydev, 0x14, 0x0400);
+ if (ret)
+ return ret;
/* Write Analog register 23 */
- phy_write(phydev, 0x17, 0x8E0D);
- phy_write(phydev, 0x14, 0x4417);
+ ret = phy_write(phydev, 0x17, 0x8E0D);
+ if (ret)
+ return ret;
+ ret = phy_write(phydev, 0x14, 0x4417);
+ if (ret)
+ return ret;
/* Enable fractional PLL */
- phy_write(phydev, 0x17, 0x0005);
- phy_write(phydev, 0x14, 0x5C1B);
+ ret = phy_write(phydev, 0x17, 0x0005);
+ if (ret)
+ return ret;
+ ret = phy_write(phydev, 0x14, 0x5C1B);
+ if (ret)
+ return ret;
/* Program fraction FR_PLL_DIV1 */
- phy_write(phydev, 0x17, 0x029A);
- phy_write(phydev, 0x14, 0x5C1D);
+ ret = phy_write(phydev, 0x17, 0x029A);
+ if (ret)
+ return ret;
+ ret = phy_write(phydev, 0x14, 0x5C1D);
+ if (ret)
+ return ret;
/* Program fraction FR_PLL_DIV1 */
- phy_write(phydev, 0x17, 0xAAAA);
- phy_write(phydev, 0x14, 0x5C1C);
+ ret = phy_write(phydev, 0x17, 0xAAAA);
+ if (ret)
+ return ret;
+ ret = phy_write(phydev, 0x14, 0x5C1C);
+ if (ret)
+ return ret;
return 0;
}
--
2.14.3
^ permalink raw reply related
* [PATCH net-next v2 2/8] net: phy: meson-gxl: define control registers
From: Jerome Brunet @ 2017-12-07 14:27 UTC (permalink / raw)
To: Andrew Lunn, Florian Fainelli
Cc: Jerome Brunet, Kevin Hilman, netdev, linux-arm-kernel,
linux-amlogic, linux-kernel, Neil Armstrong
In-Reply-To: <20171207142715.32578-1-jbrunet@baylibre.com>
Define registers and bits in meson-gxl PHY driver to make a bit
more human friendly. No functional change.
Signed-off-by: Neil Armstrong <narmstrong@baylibre.com>
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
drivers/net/phy/meson-gxl.c | 64 ++++++++++++++++++++++++++++++++++++---------
1 file changed, 51 insertions(+), 13 deletions(-)
diff --git a/drivers/net/phy/meson-gxl.c b/drivers/net/phy/meson-gxl.c
index 7ddb709f69fc..d82aa8cea401 100644
--- a/drivers/net/phy/meson-gxl.c
+++ b/drivers/net/phy/meson-gxl.c
@@ -22,54 +22,92 @@
#include <linux/ethtool.h>
#include <linux/phy.h>
#include <linux/netdevice.h>
+#include <linux/bitfield.h>
+
+#define TSTCNTL 20
+#define TSTCNTL_READ BIT(15)
+#define TSTCNTL_WRITE BIT(14)
+#define TSTCNTL_REG_BANK_SEL GENMASK(12, 11)
+#define TSTCNTL_TEST_MODE BIT(10)
+#define TSTCNTL_READ_ADDRESS GENMASK(9, 5)
+#define TSTCNTL_WRITE_ADDRESS GENMASK(4, 0)
+#define TSTREAD1 21
+#define TSTWRITE 23
+
+#define BANK_ANALOG_DSP 0
+#define BANK_BIST 3
+
+/* Analog/DSP Registers */
+#define A6_CONFIG_REG 0x17
+
+/* BIST Registers */
+#define FR_PLL_CONTROL 0x1b
+#define FR_PLL_DIV0 0x1c
+#define FR_PLL_DIV1 0x1d
static int meson_gxl_config_init(struct phy_device *phydev)
{
int ret;
/* Enable Analog and DSP register Bank access by */
- ret = phy_write(phydev, 0x14, 0x0000);
+ ret = phy_write(phydev, TSTCNTL, 0);
if (ret)
return ret;
- ret = phy_write(phydev, 0x14, 0x0400);
+ ret = phy_write(phydev, TSTCNTL, TSTCNTL_TEST_MODE);
if (ret)
return ret;
- ret = phy_write(phydev, 0x14, 0x0000);
+ ret = phy_write(phydev, TSTCNTL, 0);
if (ret)
return ret;
- ret = phy_write(phydev, 0x14, 0x0400);
+ ret = phy_write(phydev, TSTCNTL, TSTCNTL_TEST_MODE);
if (ret)
return ret;
- /* Write Analog register 23 */
- ret = phy_write(phydev, 0x17, 0x8E0D);
+ /* Write CONFIG_A6*/
+ ret = phy_write(phydev, TSTWRITE, 0x8e0d)
if (ret)
return ret;
- ret = phy_write(phydev, 0x14, 0x4417);
+ ret = phy_write(phydev, TSTCNTL,
+ TSTCNTL_WRITE
+ | FIELD_PREP(TSTCNTL_REG_BANK_SEL, BANK_ANALOG_DSP)
+ | TSTCNTL_TEST_MODE
+ | FIELD_PREP(TSTCNTL_WRITE_ADDRESS, A6_CONFIG_REG));
if (ret)
return ret;
/* Enable fractional PLL */
- ret = phy_write(phydev, 0x17, 0x0005);
+ ret = phy_write(phydev, TSTWRITE, 0x0005);
if (ret)
return ret;
- ret = phy_write(phydev, 0x14, 0x5C1B);
+ ret = phy_write(phydev, TSTCNTL,
+ TSTCNTL_WRITE
+ | FIELD_PREP(TSTCNTL_REG_BANK_SEL, BANK_BIST)
+ | TSTCNTL_TEST_MODE
+ | FIELD_PREP(TSTCNTL_WRITE_ADDRESS, FR_PLL_CONTROL));
if (ret)
return ret;
/* Program fraction FR_PLL_DIV1 */
- ret = phy_write(phydev, 0x17, 0x029A);
+ ret = phy_write(phydev, TSTWRITE, 0x029a);
if (ret)
return ret;
- ret = phy_write(phydev, 0x14, 0x5C1D);
+ ret = phy_write(phydev, TSTCNTL,
+ TSTCNTL_WRITE
+ | FIELD_PREP(TSTCNTL_REG_BANK_SEL, BANK_BIST)
+ | TSTCNTL_TEST_MODE
+ | FIELD_PREP(TSTCNTL_WRITE_ADDRESS, FR_PLL_DIV1));
if (ret)
return ret;
/* Program fraction FR_PLL_DIV1 */
- ret = phy_write(phydev, 0x17, 0xAAAA);
+ ret = phy_write(phydev, TSTWRITE, 0xaaaa);
if (ret)
return ret;
- ret = phy_write(phydev, 0x14, 0x5C1C);
+ ret = phy_write(phydev, TSTCNTL,
+ TSTCNTL_WRITE
+ | FIELD_PREP(TSTCNTL_REG_BANK_SEL, BANK_BIST)
+ | TSTCNTL_TEST_MODE
+ | FIELD_PREP(TSTCNTL_WRITE_ADDRESS, FR_PLL_DIV0));
if (ret)
return ret;
--
2.14.3
^ permalink raw reply related
* [PATCH net-next v2 3/8] net: phy: meson-gxl: add read and write helpers for bank registers
From: Jerome Brunet @ 2017-12-07 14:27 UTC (permalink / raw)
To: Andrew Lunn, Florian Fainelli
Cc: Jerome Brunet, Kevin Hilman, netdev, linux-arm-kernel,
linux-amlogic, linux-kernel
In-Reply-To: <20171207142715.32578-1-jbrunet@baylibre.com>
Add read and write helpers to manipulate banked registers on this PHY
This helps clarify the settings applied to these registers in the init
function and upcoming changes.
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
drivers/net/phy/meson-gxl.c | 103 ++++++++++++++++++++++++++++----------------
1 file changed, 67 insertions(+), 36 deletions(-)
diff --git a/drivers/net/phy/meson-gxl.c b/drivers/net/phy/meson-gxl.c
index d82aa8cea401..05054770aefb 100644
--- a/drivers/net/phy/meson-gxl.c
+++ b/drivers/net/phy/meson-gxl.c
@@ -45,11 +45,13 @@
#define FR_PLL_DIV0 0x1c
#define FR_PLL_DIV1 0x1d
-static int meson_gxl_config_init(struct phy_device *phydev)
+static int meson_gxl_open_banks(struct phy_device *phydev)
{
int ret;
- /* Enable Analog and DSP register Bank access by */
+ /* Enable Analog and DSP register Bank access by
+ * toggling TSTCNTL_TEST_MODE bit in the TSTCNTL register
+ */
ret = phy_write(phydev, TSTCNTL, 0);
if (ret)
return ret;
@@ -59,55 +61,84 @@ static int meson_gxl_config_init(struct phy_device *phydev)
ret = phy_write(phydev, TSTCNTL, 0);
if (ret)
return ret;
- ret = phy_write(phydev, TSTCNTL, TSTCNTL_TEST_MODE);
- if (ret)
- return ret;
+ return phy_write(phydev, TSTCNTL, TSTCNTL_TEST_MODE);
+}
- /* Write CONFIG_A6*/
- ret = phy_write(phydev, TSTWRITE, 0x8e0d)
+static void meson_gxl_close_banks(struct phy_device *phydev)
+{
+ phy_write(phydev, TSTCNTL, 0);
+}
+
+static int meson_gxl_read_reg(struct phy_device *phydev,
+ unsigned int bank, unsigned int reg)
+{
+ int ret;
+
+ ret = meson_gxl_open_banks(phydev);
if (ret)
- return ret;
- ret = phy_write(phydev, TSTCNTL,
- TSTCNTL_WRITE
- | FIELD_PREP(TSTCNTL_REG_BANK_SEL, BANK_ANALOG_DSP)
- | TSTCNTL_TEST_MODE
- | FIELD_PREP(TSTCNTL_WRITE_ADDRESS, A6_CONFIG_REG));
+ goto out;
+
+ ret = phy_write(phydev, TSTCNTL, TSTCNTL_READ |
+ FIELD_PREP(TSTCNTL_REG_BANK_SEL, bank) |
+ TSTCNTL_TEST_MODE |
+ FIELD_PREP(TSTCNTL_READ_ADDRESS, reg));
if (ret)
- return ret;
+ goto out;
- /* Enable fractional PLL */
- ret = phy_write(phydev, TSTWRITE, 0x0005);
+ ret = phy_read(phydev, TSTREAD1);
+out:
+ /* Close the bank access on our way out */
+ meson_gxl_close_banks(phydev);
+ return ret;
+}
+
+static int meson_gxl_write_reg(struct phy_device *phydev,
+ unsigned int bank, unsigned int reg,
+ uint16_t value)
+{
+ int ret;
+
+ ret = meson_gxl_open_banks(phydev);
if (ret)
- return ret;
- ret = phy_write(phydev, TSTCNTL,
- TSTCNTL_WRITE
- | FIELD_PREP(TSTCNTL_REG_BANK_SEL, BANK_BIST)
- | TSTCNTL_TEST_MODE
- | FIELD_PREP(TSTCNTL_WRITE_ADDRESS, FR_PLL_CONTROL));
+ goto out;
+
+ ret = phy_write(phydev, TSTWRITE, value);
if (ret)
- return ret;
+ goto out;
- /* Program fraction FR_PLL_DIV1 */
- ret = phy_write(phydev, TSTWRITE, 0x029a);
+ ret = phy_write(phydev, TSTCNTL, TSTCNTL_WRITE |
+ FIELD_PREP(TSTCNTL_REG_BANK_SEL, bank) |
+ TSTCNTL_TEST_MODE |
+ FIELD_PREP(TSTCNTL_WRITE_ADDRESS, reg));
+
+out:
+ /* Close the bank access on our way out */
+ meson_gxl_close_banks(phydev);
+ return ret;
+}
+
+static int meson_gxl_config_init(struct phy_device *phydev)
+{
+ int ret;
+
+ /* Write CONFIG_A6*/
+ ret = meson_gxl_write_reg(phydev, BANK_ANALOG_DSP, A6_CONFIG_REG,
+ 0x8e0d);
if (ret)
return ret;
- ret = phy_write(phydev, TSTCNTL,
- TSTCNTL_WRITE
- | FIELD_PREP(TSTCNTL_REG_BANK_SEL, BANK_BIST)
- | TSTCNTL_TEST_MODE
- | FIELD_PREP(TSTCNTL_WRITE_ADDRESS, FR_PLL_DIV1));
+
+ /* Enable fractional PLL */
+ ret = meson_gxl_write_reg(phydev, BANK_BIST, FR_PLL_CONTROL, 0x5);
if (ret)
return ret;
/* Program fraction FR_PLL_DIV1 */
- ret = phy_write(phydev, TSTWRITE, 0xaaaa);
+ ret = meson_gxl_write_reg(phydev, BANK_BIST, FR_PLL_DIV1, 0x029a);
if (ret)
return ret;
- ret = phy_write(phydev, TSTCNTL,
- TSTCNTL_WRITE
- | FIELD_PREP(TSTCNTL_REG_BANK_SEL, BANK_BIST)
- | TSTCNTL_TEST_MODE
- | FIELD_PREP(TSTCNTL_WRITE_ADDRESS, FR_PLL_DIV0));
+
+ /* Program fraction FR_PLL_DIV1 */
+ ret = meson_gxl_write_reg(phydev, BANK_BIST, FR_PLL_DIV0, 0xaaaa);
if (ret)
return ret;
--
2.14.3
^ permalink raw reply related
* [PATCH net-next v2 4/8] net: phy: meson-gxl: use genphy_config_init
From: Jerome Brunet @ 2017-12-07 14:27 UTC (permalink / raw)
To: Andrew Lunn, Florian Fainelli
Cc: Kevin Hilman, linux-kernel, netdev, linux-amlogic,
linux-arm-kernel, Jerome Brunet
In-Reply-To: <20171207142715.32578-1-jbrunet@baylibre.com>
Use the generic init function to populate some of the phydev
structure fields
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
drivers/net/phy/meson-gxl.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/phy/meson-gxl.c b/drivers/net/phy/meson-gxl.c
index 05054770aefb..2e8c40df33c2 100644
--- a/drivers/net/phy/meson-gxl.c
+++ b/drivers/net/phy/meson-gxl.c
@@ -142,7 +142,7 @@ static int meson_gxl_config_init(struct phy_device *phydev)
if (ret)
return ret;
- return 0;
+ return genphy_config_init(phydev);
}
static struct phy_driver meson_gxl_phy[] = {
--
2.14.3
^ permalink raw reply related
* [PATCH net-next v2 5/8] net: phy: meson-gxl: detect LPA corruption
From: Jerome Brunet @ 2017-12-07 14:27 UTC (permalink / raw)
To: Andrew Lunn, Florian Fainelli
Cc: Jerome Brunet, Kevin Hilman, netdev, linux-arm-kernel,
linux-amlogic, linux-kernel
In-Reply-To: <20171207142715.32578-1-jbrunet@baylibre.com>
The purpose of this change is to fix the incorrect detection of the link
partner (LP) advertised capabilities which sometimes happens with this PHY
(roughly 1 time in a dozen)
This issue may cause the link to be negotiated at 10Mbps/Full or
10Mbps/Half when 100MBps/Full is actually possible. In some case, the link
is even completely broken and no communication is possible.
To detect the corruption, we must look for a magic undocumented bit in the
WOL bank (hint given by the SoC vendor kernel) but this is not enough to
cover all cases. We also have to look at the LPA ack. If the LP supports
Aneg but did not ack our base code when aneg is completed, we assume
something went wrong.
The detection of a corrupted LPA triggers a restart of the aneg process.
This solves the problem but may take up to 6 retries to complete.
Fixes: 7334b3e47aee ("net: phy: Add Meson GXL Internal PHY driver")
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
I suppose this patch probably seems a bit hacky, especially the part
about the link partner acknowledge. I'm trying to figure out if the
value in MII_LPA makes sense but I don't have such a deep knowledge
of the ethernet spec.
To me, it does not makes sense for the LP to support ANEG (Bit 1 in
MII_EXPENSION), the aneg to have successfully complete and, at the
same time, LP does not ACK our base code word, which we should have
sent during this aneg.
If you think this may have unintended consequences or if you have
an idea to this differently, feel free to let me know.
drivers/net/phy/meson-gxl.c | 59 ++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 58 insertions(+), 1 deletion(-)
diff --git a/drivers/net/phy/meson-gxl.c b/drivers/net/phy/meson-gxl.c
index 2e8c40df33c2..726e0eeed475 100644
--- a/drivers/net/phy/meson-gxl.c
+++ b/drivers/net/phy/meson-gxl.c
@@ -35,11 +35,16 @@
#define TSTWRITE 23
#define BANK_ANALOG_DSP 0
+#define BANK_WOL 1
#define BANK_BIST 3
/* Analog/DSP Registers */
#define A6_CONFIG_REG 0x17
+/* WOL Registers */
+#define LPI_STATUS 0xc
+#define LPI_STATUS_RSV12 BIT(12)
+
/* BIST Registers */
#define FR_PLL_CONTROL 0x1b
#define FR_PLL_DIV0 0x1c
@@ -145,6 +150,58 @@ static int meson_gxl_config_init(struct phy_device *phydev)
return genphy_config_init(phydev);
}
+/* This specific function is provided to cope with the possible failures of
+ * this phy during aneg process. When aneg fails, the PHY reports that aneg
+ * is done but the value found in MII_LPA is wrong:
+ * - Early failures: MII_LPA is just 0x0001. if MII_EXPANSION reports that
+ * the link partner (LP) supports aneg but the LP never acked our base
+ * code word, it is likely that we never sent it to begin with.
+ * - Late failures: MII_LPA is filled with a value which seems to make sense
+ * but it actually is not what the LP is advertising. It seems that we
+ * can detect this using a magic bit in the WOL bank (reg 12 - bit 12).
+ * If this particular bit is not set when aneg is reported being done,
+ * it means MII_LPA is likely to be wrong.
+ *
+ * In both case, forcing a restart of the aneg process solve the problem.
+ * When this failure happens, the first retry is usually successful but,
+ * in some cases, it may take up to 6 retries to get a decent result
+ */
+int meson_gxl_read_status(struct phy_device *phydev)
+{
+ int ret, wol, lpa, exp;
+
+ if (phydev->autoneg == AUTONEG_ENABLE) {
+ ret = genphy_aneg_done(phydev);
+ if (ret < 0)
+ return ret;
+ else if (!ret)
+ goto read_status_continue;
+
+ /* Aneg is done, let's check everything is fine */
+ wol = meson_gxl_read_reg(phydev, BANK_WOL, LPI_STATUS);
+ if (wol < 0)
+ return wol;
+
+ lpa = phy_read(phydev, MII_LPA);
+ if (lpa < 0)
+ return lpa;
+
+ exp = phy_read(phydev, MII_EXPANSION);
+ if (exp < 0)
+ return exp;
+
+ if (!(wol & LPI_STATUS_RSV12) ||
+ ((exp & EXPANSION_NWAY) && !(lpa & LPA_LPACK))) {
+ /* Looks like aneg failed after all */
+ phydev_dbg(phydev, "LPA corruption - aneg restart\n");
+ return genphy_restart_aneg(phydev);
+ }
+ }
+
+read_status_continue:
+ return genphy_read_status(phydev);
+}
+
static struct phy_driver meson_gxl_phy[] = {
{
.phy_id = 0x01814400,
@@ -155,7 +212,7 @@ static struct phy_driver meson_gxl_phy[] = {
.config_init = meson_gxl_config_init,
.config_aneg = genphy_config_aneg,
.aneg_done = genphy_aneg_done,
- .read_status = genphy_read_status,
+ .read_status = meson_gxl_read_status,
.suspend = genphy_suspend,
.resume = genphy_resume,
},
--
2.14.3
^ permalink raw reply related
* [PATCH net-next v2 6/8] net: phy: meson-gxl: leave CONFIG_A6 untouched
From: Jerome Brunet @ 2017-12-07 14:27 UTC (permalink / raw)
To: Andrew Lunn, Florian Fainelli
Cc: Jerome Brunet, Kevin Hilman, netdev, linux-arm-kernel,
linux-amlogic, linux-kernel
In-Reply-To: <20171207142715.32578-1-jbrunet@baylibre.com>
The PHY performs just as well when left in its default configuration and
it makes senses because this poke gets reset just after init.
According to the documentation, all registers in the Analog/DSP bank are
reset when there is a mode switch from 10BT to 100BT.
In the end, we have used the default configuration so far and there is no
reason to change now. Remove CONFIG_A6 poke to make this clear.
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
Out of curiosity, I tried to re-apply the ANALOG/DSP settings on speed
changes (patch available here [0] if someone wants to try) but I did
not notice any change as a result. In the end, I thought it was safer
to keep on using the ANALOG settings we have been actually using so far,
everybody seems to be happy with them
[0]: https://github.com/jeromebrunet/linux/commit/b594288e629a61574e76112497474fd3cf46c781
drivers/net/phy/meson-gxl.c | 9 ---------
1 file changed, 9 deletions(-)
diff --git a/drivers/net/phy/meson-gxl.c b/drivers/net/phy/meson-gxl.c
index 726e0eeed475..5325940fe899 100644
--- a/drivers/net/phy/meson-gxl.c
+++ b/drivers/net/phy/meson-gxl.c
@@ -38,9 +38,6 @@
#define BANK_WOL 1
#define BANK_BIST 3
-/* Analog/DSP Registers */
-#define A6_CONFIG_REG 0x17
-
/* WOL Registers */
#define LPI_STATUS 0xc
#define LPI_STATUS_RSV12 BIT(12)
@@ -126,12 +123,6 @@ static int meson_gxl_config_init(struct phy_device *phydev)
{
int ret;
- /* Write CONFIG_A6*/
- ret = meson_gxl_write_reg(phydev, BANK_ANALOG_DSP, A6_CONFIG_REG,
- 0x8e0d);
- if (ret)
- return ret;
-
/* Enable fractional PLL */
ret = meson_gxl_write_reg(phydev, BANK_BIST, FR_PLL_CONTROL, 0x5);
if (ret)
--
2.14.3
^ permalink raw reply related
* [PATCH net-next v2 7/8] net: phy: meson-gxl: add interrupt support
From: Jerome Brunet @ 2017-12-07 14:27 UTC (permalink / raw)
To: Andrew Lunn, Florian Fainelli
Cc: Jerome Brunet, Kevin Hilman, netdev, linux-arm-kernel,
linux-amlogic, linux-kernel
In-Reply-To: <20171207142715.32578-1-jbrunet@baylibre.com>
Enable interrupt support in meson-gxl PHY driver
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
drivers/net/phy/meson-gxl.c | 37 ++++++++++++++++++++++++++++++++++++-
1 file changed, 36 insertions(+), 1 deletion(-)
diff --git a/drivers/net/phy/meson-gxl.c b/drivers/net/phy/meson-gxl.c
index 5325940fe899..861b021b9758 100644
--- a/drivers/net/phy/meson-gxl.c
+++ b/drivers/net/phy/meson-gxl.c
@@ -33,6 +33,14 @@
#define TSTCNTL_WRITE_ADDRESS GENMASK(4, 0)
#define TSTREAD1 21
#define TSTWRITE 23
+#define INTSRC_FLAG 29
+#define INTSRC_ANEG_PR BIT(1)
+#define INTSRC_PARALLEL_FAULT BIT(2)
+#define INTSRC_ANEG_LP_ACK BIT(3)
+#define INTSRC_LINK_DOWN BIT(4)
+#define INTSRC_REMOTE_FAULT BIT(5)
+#define INTSRC_ANEG_COMPLETE BIT(6)
+#define INTSRC_MASK 30
#define BANK_ANALOG_DSP 0
#define BANK_WOL 1
@@ -193,17 +201,44 @@ int meson_gxl_read_status(struct phy_device *phydev)
return genphy_read_status(phydev);
}
+static int meson_gxl_ack_interrupt(struct phy_device *phydev)
+{
+ int ret = phy_read(phydev, INTSRC_FLAG);
+
+ return ret < 0 ? ret : 0;
+}
+
+static int meson_gxl_config_intr(struct phy_device *phydev)
+{
+ u16 val;
+
+ if (phydev->interrupts == PHY_INTERRUPT_ENABLED) {
+ val = INTSRC_ANEG_PR
+ | INTSRC_PARALLEL_FAULT
+ | INTSRC_ANEG_LP_ACK
+ | INTSRC_LINK_DOWN
+ | INTSRC_REMOTE_FAULT
+ | INTSRC_ANEG_COMPLETE;
+ } else {
+ val = 0;
+ }
+
+ return phy_write(phydev, INTSRC_MASK, val);
+}
+
static struct phy_driver meson_gxl_phy[] = {
{
.phy_id = 0x01814400,
.phy_id_mask = 0xfffffff0,
.name = "Meson GXL Internal PHY",
.features = PHY_BASIC_FEATURES,
- .flags = PHY_IS_INTERNAL,
+ .flags = PHY_IS_INTERNAL | PHY_HAS_INTERRUPT,
.config_init = meson_gxl_config_init,
.config_aneg = genphy_config_aneg,
.aneg_done = genphy_aneg_done,
.read_status = meson_gxl_read_status,
+ .ack_interrupt = meson_gxl_ack_interrupt,
+ .config_intr = meson_gxl_config_intr,
.suspend = genphy_suspend,
.resume = genphy_resume,
},
--
2.14.3
^ permalink raw reply related
* [PATCH net-next v2 8/8] net: phy: meson-gxl: join the authors
From: Jerome Brunet @ 2017-12-07 14:27 UTC (permalink / raw)
To: Andrew Lunn, Florian Fainelli
Cc: Jerome Brunet, Kevin Hilman, netdev, linux-arm-kernel,
linux-amlogic, linux-kernel
In-Reply-To: <20171207142715.32578-1-jbrunet@baylibre.com>
Following previous changes, join the other authors of this driver and
take the blame with them
Signed-off-by: Jerome Brunet <jbrunet@baylibre.com>
---
drivers/net/phy/meson-gxl.c | 1 +
1 file changed, 1 insertion(+)
diff --git a/drivers/net/phy/meson-gxl.c b/drivers/net/phy/meson-gxl.c
index 861b021b9758..4cd5b2622ae1 100644
--- a/drivers/net/phy/meson-gxl.c
+++ b/drivers/net/phy/meson-gxl.c
@@ -256,4 +256,5 @@ MODULE_DEVICE_TABLE(mdio, meson_gxl_tbl);
MODULE_DESCRIPTION("Amlogic Meson GXL Internal PHY driver");
MODULE_AUTHOR("Baoqi wang");
MODULE_AUTHOR("Neil Armstrong <narmstrong@baylibre.com>");
+MODULE_AUTHOR("Jerome Brunet <jbrunet@baylibre.com>");
MODULE_LICENSE("GPL");
--
2.14.3
^ permalink raw reply related
* Re: [PATCH v4 6/8] staging: octeon: Remove USE_ASYNC_IOBDMA macro.
From: Greg Kroah-Hartman @ 2017-12-07 14:28 UTC (permalink / raw)
To: David Daney
Cc: Mark Rutland, linux-mips, devel, devicetree, netdev, linux-kernel,
ralf, Rob Herring, Andrew Lunn, Steven J. Hill, Florian Fainelli,
James Hogan, David S. Miller
In-Reply-To: <20171129005540.28829-7-david.daney@cavium.com>
On Tue, Nov 28, 2017 at 04:55:38PM -0800, David Daney wrote:
> Previous patch sets USE_ASYNC_IOBDMA to 1 unconditionally. Remove
> USE_ASYNC_IOBDMA from all if statements. Remove dead code caused by
> the change.
>
> Signed-off-by: David Daney <david.daney@cavium.com>
Acked-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
^ permalink raw reply
* Re: [PATCH 1/3] ath9k: remove stray backslash in Makefile
From: Kalle Valo @ 2017-12-07 14:30 UTC (permalink / raw)
To: Jakub Kicinski
Cc: Matthias Schiffer, ath9k-devel, ath10k@lists.infradead.org,
linux-wireless@vger.kernel.org, netdev@vger.kernel.org,
linux-kernel@vger.kernel.org, nbd@nbd.name
In-Reply-To: <20171127193516.682827ea@cakuba.netronome.com>
Jakub Kicinski <kubakici@wp.pl> writes:
> On Mon, 27 Nov 2017 18:56:21 +0100, Matthias Schiffer wrote:
>> Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
>> ---
>> drivers/net/wireless/ath/ath9k/Makefile | 2 +-
>> 1 file changed, 1 insertion(+), 1 deletion(-)
>>
>> diff --git a/drivers/net/wireless/ath/ath9k/Makefile b/drivers/net/wireless/ath/ath9k/Makefile
>> index 36a40ffdce15..90e4a341076c 100644
>> --- a/drivers/net/wireless/ath/ath9k/Makefile
>> +++ b/drivers/net/wireless/ath/ath9k/Makefile
>> @@ -59,7 +59,7 @@ obj-$(CONFIG_ATH9K_HW) += ath9k_hw.o
>> obj-$(CONFIG_ATH9K_COMMON) += ath9k_common.o
>> ath9k_common-y:= common.o \
>> common-init.o \
>> - common-beacon.o \
>> + common-beacon.o
>>
>
> It's not necessarily stray, there is nothing on the next line so it's
> OK, and if you add \ at the end of all lines, you don't have to touch
> the last line every time you add/remove something. Sort of like
> putting a , after last enum value.
I agree with Jakub, I think the backslash is there on purpose so I
dropped this patch.
--
Kalle Valo
^ permalink raw reply
* Re: [2/3] ath9k: move spectral scan support under a separate config symbol
From: Kalle Valo @ 2017-12-07 14:32 UTC (permalink / raw)
To: Matthias Schiffer
Cc: ath9k-devel, ath10k, linux-wireless, netdev, linux-kernel, nbd
In-Reply-To: <1c982c915065a9b5ed3232eedb567f589eca261b.1511804622.git.mschiffer@universe-factory.net>
Matthias Schiffer <mschiffer@universe-factory.net> wrote:
> At the moment, spectral scan support, and with it RELAY, is always enabled
> with ATH9K[_HTC]_DEBUGFS. Spectral scan support is currently the only user
> of RELAY in ath9k, and it unconditionally reserves a relay channel.
>
> Having debugfs support in ath9k is often useful even on very small embedded
> routers, where we'd rather like to avoid the code size and RAM usage of the
> relay support.
>
> Signed-off-by: Matthias Schiffer <mschiffer@universe-factory.net>
> Signed-off-by: Kalle Valo <kvalo@qca.qualcomm.com>
2 patches applied to ath-next branch of ath.git, thanks.
9df7ddc3ed25 ath9k: move spectral scan support under a separate config symbol
42e01cb9cb10 ath10k: move spectral scan support under a separate config symbol
--
https://patchwork.kernel.org/patch/10077735/
https://wireless.wiki.kernel.org/en/developers/documentation/submittingpatches
^ permalink raw reply
* Re: [crypto 6/8] chtls: TCB and Key program
From: Stephan Mueller @ 2017-12-07 14:42 UTC (permalink / raw)
To: Atul Gupta
Cc: herbert@gondor.apana.org.au, linux-crypto@vger.kernel.org,
netdev@vger.kernel.org, davem@davemloft.net, davejwatson@fb.com,
Ganesh GR, Harsh Jain
In-Reply-To: <MWHPR1201MB02382E04C3603A5B5F531CB897330@MWHPR1201MB0238.namprd12.prod.outlook.com>
Am Donnerstag, 7. Dezember 2017, 15:21:03 CET schrieb Atul Gupta:
Hi Atul,
>
> memzero_explicit(key)?
> [Atul] may not be required as entire info of size keylen and AEAD_H_SIZE is
> copied onto kctx->key. Key data is received from user, while ghash is
> memset and locally generated
Sure, but wouldn't it make sense to zap all instances where key material was
stored?
>
> As far as I see, the key is part of the skb (via kctx). This skb is released
> after being processed. The release calls kfree_skb which does not zeroize
> the key. Wouldn't it make sense to clear the memory of the key when the skb
> is released? [Atul] we should perhaps memset the info received from user so
> that driver has no info on key once its written on chip memory.
> memset(gcm_ctx->key, 0, keylen);
Are you saying that the skb (via kctx) above does not obtain a copy of the
key? If not, what is done in chtls_key_info?
Ciao
Stephan
^ permalink raw reply
* [PATCH net-next v4 0/4] net: fec: fix refclk enable for SMSC LAN8710/20
From: Richard Leitner @ 2017-12-07 14:43 UTC (permalink / raw)
To: robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
fugang.duan-3arQi8VN3Tc, andrew-g2DYL2Zd6BY,
f.fainelli-Re5JQEeQqe8AvxtiuMwx3w,
frowand.list-Re5JQEeQqe8AvxtiuMwx3w
Cc: davem-fT/PcQaiUtIeIZ0/mPfg9Q,
geert+renesas-gXvu3+zWzMSzQB+pC5nmwQ,
sergei.shtylyov-M4DtvfQ/ZS1MRgGoP+s0PdBPR1lH4CV8,
baruch-NswTu9S1W3P6gbPvEgmw2w, david.wu-TNX95d0MmH7DzftRWevZcw,
lukma-ynQEQJNshbs, netdev-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
richard.leitner-WcANXNA0UjBBDgjK7y7TUQ
From: Richard Leitner <richard.leitner-WcANXNA0UjBBDgjK7y7TUQ@public.gmane.org>
This patch series fixes the use of the SMSC LAN8710/20 with a Freescale ETH
when the refclk is generated by the FSL.
This patchset depends on the "phylib: Add device reset GPIO support" patch
submitted by Geert Uytterhoeven/Sergei Shtylyov, which was merged to
net-next as commit bafbdd527d56 ("phylib: Add device reset GPIO support").
Changes v4:
- simplify dts parsing
- simplify reset delay evaluation and execution
- fec: ensure to only reset once during fec_enet_open()
- remove dependency notes from commit message
- add reviews and acks
Changes v3:
- use phylib to hard-reset the PHY
- implement reset delays in phylib
- add new phylib API & flag (PHY_RST_AFTER_CLK_EN) to determine if
a PHY is affected
Changes v2:
- simplify and fix fec_reset_phy function to support multiple calls
- include: linux: phy: harmonize phy_id{,_mask} type
- reset the phy instead of not turning the clock on and off
(which would have caused a power consumption regression)
Richard Leitner (4):
phylib: Add device reset delay support
phylib: add reset after clk enable support
net: phy: smsc: LAN8710/20: add PHY_RST_AFTER_CLK_EN flag
net: fec: add phy_reset_after_clk_enable() support
Documentation/devicetree/bindings/net/phy.txt | 10 ++++++++++
drivers/net/ethernet/freescale/fec_main.c | 20 ++++++++++++++++++++
drivers/net/phy/mdio_device.c | 13 +++++++++++--
drivers/net/phy/phy_device.c | 24 ++++++++++++++++++++++++
drivers/net/phy/smsc.c | 2 +-
drivers/of/of_mdio.c | 4 ++++
include/linux/mdio.h | 2 ++
include/linux/phy.h | 2 ++
8 files changed, 74 insertions(+), 3 deletions(-)
--
2.11.0
--
To unsubscribe from this list: send the line "unsubscribe devicetree" in
the body of a message to majordomo-u79uwXL29TY76Z2rM5mHXA@public.gmane.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
^ permalink raw reply
* [PATCH net-next v4 1/4] phylib: Add device reset delay support
From: Richard Leitner @ 2017-12-07 14:43 UTC (permalink / raw)
To: robh+dt, mark.rutland, fugang.duan, andrew, f.fainelli,
frowand.list
Cc: davem, geert+renesas, sergei.shtylyov, baruch, david.wu, lukma,
netdev, devicetree, linux-kernel, richard.leitner
In-Reply-To: <20171207144358.3351-1-dev@g0hl1n.net>
From: Richard Leitner <richard.leitner@skidata.com>
Some PHYs need a minimum time after the reset gpio was asserted and/or
deasserted. To ensure we meet these timing requirements add two new
optional devicetree parameters for the phy: reset-delay-us and
reset-post-delay-us.
Signed-off-by: Richard Leitner <richard.leitner@skidata.com>
Reviewed-by: Geert Uytterhoeven <geert+renesas@glider.be>
---
Documentation/devicetree/bindings/net/phy.txt | 10 ++++++++++
drivers/net/phy/mdio_device.c | 13 +++++++++++--
drivers/of/of_mdio.c | 4 ++++
include/linux/mdio.h | 2 ++
4 files changed, 27 insertions(+), 2 deletions(-)
diff --git a/Documentation/devicetree/bindings/net/phy.txt b/Documentation/devicetree/bindings/net/phy.txt
index c05479f5ac7c..72860ce7f610 100644
--- a/Documentation/devicetree/bindings/net/phy.txt
+++ b/Documentation/devicetree/bindings/net/phy.txt
@@ -55,6 +55,12 @@ Optional Properties:
- reset-gpios: The GPIO phandle and specifier for the PHY reset signal.
+- reset-delay-us: Delay after the reset was asserted in microseconds.
+ If this property is missing the delay will be skipped.
+
+- reset-post-delay-us: Delay after the reset was deasserted in microseconds.
+ If this property is missing the delay will be skipped.
+
Example:
ethernet-phy@0 {
@@ -62,4 +68,8 @@ ethernet-phy@0 {
interrupt-parent = <&PIC>;
interrupts = <35 IRQ_TYPE_EDGE_RISING>;
reg = <0>;
+
+ reset-gpios = <&gpio1 4 GPIO_ACTIVE_LOW>;
+ reset-delay-us = <1000>;
+ reset-post-delay-us = <2000>;
};
diff --git a/drivers/net/phy/mdio_device.c b/drivers/net/phy/mdio_device.c
index 75d97dd9fb28..0423280c88fe 100644
--- a/drivers/net/phy/mdio_device.c
+++ b/drivers/net/phy/mdio_device.c
@@ -24,6 +24,7 @@
#include <linux/slab.h>
#include <linux/string.h>
#include <linux/unistd.h>
+#include <linux/delay.h>
void mdio_device_free(struct mdio_device *mdiodev)
{
@@ -118,8 +119,16 @@ EXPORT_SYMBOL(mdio_device_remove);
void mdio_device_reset(struct mdio_device *mdiodev, int value)
{
- if (mdiodev->reset)
- gpiod_set_value(mdiodev->reset, value);
+ unsigned int d;
+
+ if (!mdiodev->reset)
+ return;
+
+ gpiod_set_value(mdiodev->reset, value);
+
+ d = value ? mdiodev->reset_delay : mdiodev->reset_post_delay;
+ if (d)
+ usleep_range(d, d + min_t(unsigned int, d / 10, 100));
}
EXPORT_SYMBOL(mdio_device_reset);
diff --git a/drivers/of/of_mdio.c b/drivers/of/of_mdio.c
index 98258583abb0..7c8767176315 100644
--- a/drivers/of/of_mdio.c
+++ b/drivers/of/of_mdio.c
@@ -77,6 +77,10 @@ static int of_mdiobus_register_phy(struct mii_bus *mdio,
if (of_property_read_bool(child, "broken-turn-around"))
mdio->phy_ignore_ta_mask |= 1 << addr;
+ of_property_read_u32(child, "reset-delay-us", &phy->mdio.reset_delay);
+ of_property_read_u32(child, "reset-post-delay-us",
+ &phy->mdio.reset_post_delay);
+
/* Associate the OF node with the device structure so it
* can be looked up later */
of_node_get(child);
diff --git a/include/linux/mdio.h b/include/linux/mdio.h
index 92d4e55ffe67..e37c21d8eb19 100644
--- a/include/linux/mdio.h
+++ b/include/linux/mdio.h
@@ -41,6 +41,8 @@ struct mdio_device {
int addr;
int flags;
struct gpio_desc *reset;
+ unsigned int reset_delay;
+ unsigned int reset_post_delay;
};
#define to_mdio_device(d) container_of(d, struct mdio_device, dev)
--
2.11.0
^ permalink raw reply related
* [PATCH net-next v4 2/4] phylib: add reset after clk enable support
From: Richard Leitner @ 2017-12-07 14:43 UTC (permalink / raw)
To: robh+dt, mark.rutland, fugang.duan, andrew, f.fainelli,
frowand.list
Cc: davem, geert+renesas, sergei.shtylyov, baruch, david.wu, lukma,
netdev, devicetree, linux-kernel, richard.leitner
In-Reply-To: <20171207144358.3351-1-dev@g0hl1n.net>
From: Richard Leitner <richard.leitner@skidata.com>
Some PHYs need the refclk to be a continuous clock. Therefore they don't
allow turning it off and on again during operation. Nonetheless such a
clock switching is performed by some ETH drivers (namely FEC [1]) for
power saving reasons. An example for an affected PHY is the
SMSC/Microchip LAN8720 in "REF_CLK In Mode".
In order to provide a uniform method to overcome this problem this patch
adds a new phy_driver flag (PHY_RST_AFTER_CLK_EN) and corresponding
function phy_reset_after_clk_enable() to the phylib. These should be
used to trigger reset of the PHY after the refclk is switched on again.
[1] commit e8fcfcd5684a ("net: fec: optimize the clock management to save power")
Signed-off-by: Richard Leitner <richard.leitner@skidata.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
---
drivers/net/phy/phy_device.c | 24 ++++++++++++++++++++++++
include/linux/phy.h | 2 ++
2 files changed, 26 insertions(+)
diff --git a/drivers/net/phy/phy_device.c b/drivers/net/phy/phy_device.c
index 1de5e242b8b4..462c17ed87b8 100644
--- a/drivers/net/phy/phy_device.c
+++ b/drivers/net/phy/phy_device.c
@@ -1218,6 +1218,30 @@ int phy_loopback(struct phy_device *phydev, bool enable)
}
EXPORT_SYMBOL(phy_loopback);
+/**
+ * phy_reset_after_clk_enable - perform a PHY reset if needed
+ * @phydev: target phy_device struct
+ *
+ * Description: Some PHYs are known to need a reset after their refclk was
+ * enabled. This function evaluates the flags and perform the reset if it's
+ * needed. Returns < 0 on error, 0 if the phy wasn't reset and 1 if the phy
+ * was reset.
+ */
+int phy_reset_after_clk_enable(struct phy_device *phydev)
+{
+ if (!phydev || !phydev->drv)
+ return -ENODEV;
+
+ if (phydev->drv->flags & PHY_RST_AFTER_CLK_EN) {
+ phy_device_reset(phydev, 1);
+ phy_device_reset(phydev, 0);
+ return 1;
+ }
+
+ return 0;
+}
+EXPORT_SYMBOL(phy_reset_after_clk_enable);
+
/* Generic PHY support and helper functions */
/**
diff --git a/include/linux/phy.h b/include/linux/phy.h
index d3037e2ffbc4..c4b4715caa21 100644
--- a/include/linux/phy.h
+++ b/include/linux/phy.h
@@ -59,6 +59,7 @@
#define PHY_HAS_INTERRUPT 0x00000001
#define PHY_IS_INTERNAL 0x00000002
+#define PHY_RST_AFTER_CLK_EN 0x00000004
#define MDIO_DEVICE_IS_PHY 0x80000000
/* Interface Mode definitions */
@@ -853,6 +854,7 @@ int phy_aneg_done(struct phy_device *phydev);
int phy_stop_interrupts(struct phy_device *phydev);
int phy_restart_aneg(struct phy_device *phydev);
+int phy_reset_after_clk_enable(struct phy_device *phydev);
static inline void phy_device_reset(struct phy_device *phydev, int value)
{
--
2.11.0
^ permalink raw reply related
* [PATCH net-next v4 4/4] net: fec: add phy_reset_after_clk_enable() support
From: Richard Leitner @ 2017-12-07 14:43 UTC (permalink / raw)
To: robh+dt-DgEjT+Ai2ygdnm+yROfE0A, mark.rutland-5wv7dgnIgG8,
fugang.duan-3arQi8VN3Tc, andrew-g2DYL2Zd6BY,
f.fainelli-Re5JQEeQqe8AvxtiuMwx3w,
frowand.list-Re5JQEeQqe8AvxtiuMwx3w
Cc: davem-fT/PcQaiUtIeIZ0/mPfg9Q,
geert+renesas-gXvu3+zWzMSzQB+pC5nmwQ,
sergei.shtylyov-M4DtvfQ/ZS1MRgGoP+s0PdBPR1lH4CV8,
baruch-NswTu9S1W3P6gbPvEgmw2w, david.wu-TNX95d0MmH7DzftRWevZcw,
lukma-ynQEQJNshbs, netdev-u79uwXL29TY76Z2rM5mHXA,
devicetree-u79uwXL29TY76Z2rM5mHXA,
linux-kernel-u79uwXL29TY76Z2rM5mHXA,
richard.leitner-WcANXNA0UjBBDgjK7y7TUQ
In-Reply-To: <20171207144358.3351-1-dev-M/VWbR8SM2SsTnJN9+BGXg@public.gmane.org>
From: Richard Leitner <richard.leitner-WcANXNA0UjBBDgjK7y7TUQ@public.gmane.org>
Some PHYs (for example the SMSC LAN8710/LAN8720) doesn't allow turning
the refclk on and off again during operation (according to their
datasheet). Nonetheless exactly this behaviour was introduced for power
saving reasons by commit e8fcfcd5684a ("net: fec: optimize the clock management to save power").
Therefore add support for the phy_reset_after_clk_enable function from
phylib to mitigate this issue.
Generally speaking this issue is only relevant if the ref clk for the
PHY is generated by the SoC and therefore the PHY is configured to
"REF_CLK In Mode". In our specific case (PCB) this problem does occur at
about every 10th to 50th POR of an LAN8710 connected to an i.MX6SOLO
SoC. The typical symptom of this problem is a "swinging" ethernet link.
Similar issues were reported by users of the NXP forum:
https://community.nxp.com/thread/389902
https://community.nxp.com/message/309354
With this patch applied the issue didn't occur for at least a few
hundret PORs of our board.
Fixes: e8fcfcd5684a ("net: fec: optimize the clock management to save power")
Signed-off-by: Richard Leitner <richard.leitner-WcANXNA0UjBBDgjK7y7TUQ@public.gmane.org>
---
drivers/net/ethernet/freescale/fec_main.c | 20 ++++++++++++++++++++
1 file changed, 20 insertions(+)
diff --git a/drivers/net/ethernet/freescale/fec_main.c b/drivers/net/ethernet/freescale/fec_main.c
index 610573855213..2d1b06579c1a 100644
--- a/drivers/net/ethernet/freescale/fec_main.c
+++ b/drivers/net/ethernet/freescale/fec_main.c
@@ -1862,6 +1862,8 @@ static int fec_enet_clk_enable(struct net_device *ndev, bool enable)
ret = clk_prepare_enable(fep->clk_ref);
if (ret)
goto failed_clk_ref;
+
+ phy_reset_after_clk_enable(ndev->phydev);
} else {
clk_disable_unprepare(fep->clk_ahb);
clk_disable_unprepare(fep->clk_enet_out);
@@ -2834,6 +2836,7 @@ fec_enet_open(struct net_device *ndev)
{
struct fec_enet_private *fep = netdev_priv(ndev);
int ret;
+ bool reset_again;
ret = pm_runtime_get_sync(&fep->pdev->dev);
if (ret < 0)
@@ -2844,6 +2847,17 @@ fec_enet_open(struct net_device *ndev)
if (ret)
goto clk_enable;
+ /* During the first fec_enet_open call the PHY isn't probed at this
+ * point. Therefore the phy_reset_after_clk_enable() call within
+ * fec_enet_clk_enable() fails. As we need this reset in order to be
+ * sure the PHY is working correctly we check if we need to reset again
+ * later when the PHY is probed
+ */
+ if (ndev->phydev && ndev->phydev->drv)
+ reset_again = false;
+ else
+ reset_again = true;
+
/* I should reset the ring buffers here, but I don't yet know
* a simple way to do that.
*/
@@ -2860,6 +2874,12 @@ fec_enet_open(struct net_device *ndev)
if (ret)
goto err_enet_mii_probe;
+ /* Call phy_reset_after_clk_enable() again if it failed during
+ * phy_reset_after_clk_enable() before because the PHY wasn't probed.
+ */
+ if (reset_again)
+ phy_reset_after_clk_enable(ndev->phydev);
+
if (fep->quirks & FEC_QUIRK_ERR006687)
imx6q_cpuidle_fec_irqs_used();
--
2.11.0
--
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 net-next v4 3/4] net: phy: smsc: LAN8710/20: add PHY_RST_AFTER_CLK_EN flag
From: Richard Leitner @ 2017-12-07 14:43 UTC (permalink / raw)
To: robh+dt, mark.rutland, fugang.duan, andrew, f.fainelli,
frowand.list
Cc: davem, geert+renesas, sergei.shtylyov, baruch, david.wu, lukma,
netdev, devicetree, linux-kernel, richard.leitner
In-Reply-To: <20171207144358.3351-1-dev@g0hl1n.net>
From: Richard Leitner <richard.leitner@skidata.com>
The Microchip/SMSC LAN8710/LAN8720 PHYs need (according to their
datasheet [1]) a continuous REF_CLK when configured to "REF_CLK In Mode".
Therefore set the PHY_RST_AFTER_CLK_EN flag for those PHYs to let the
ETH driver reset them after the REF_CLK is enabled.
[1] http://ww1.microchip.com/downloads/en/DeviceDoc/00002165B.pdf
Signed-off-by: Richard Leitner <richard.leitner@skidata.com>
Reviewed-by: Andrew Lunn <andrew@lunn.ch>
---
drivers/net/phy/smsc.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/drivers/net/phy/smsc.c b/drivers/net/phy/smsc.c
index a1961ba87e2b..be399d645224 100644
--- a/drivers/net/phy/smsc.c
+++ b/drivers/net/phy/smsc.c
@@ -312,7 +312,7 @@ static struct phy_driver smsc_phy_driver[] = {
.name = "SMSC LAN8710/LAN8720",
.features = PHY_BASIC_FEATURES,
- .flags = PHY_HAS_INTERRUPT,
+ .flags = PHY_HAS_INTERRUPT | PHY_RST_AFTER_CLK_EN,
.probe = smsc_phy_probe,
--
2.11.0
^ permalink raw reply related
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox