Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH net-next v8 4/4] netvsc: refactor notifier/event handling code to use the failover framework
From: Samudrala, Sridhar @ 2018-04-27  0:30 UTC (permalink / raw)
  To: Michael S. Tsirkin, Stephen Hemminger
  Cc: davem, netdev, virtualization, virtio-dev, jesse.brandeburg,
	alexander.h.duyck, kubakici, jasowang, loseweigh, jiri,
	aaron.f.brown
In-Reply-To: <20180427024347-mutt-send-email-mst@kernel.org>


On 4/26/2018 5:09 PM, Michael S. Tsirkin wrote:
> On Thu, Apr 26, 2018 at 03:33:26PM -0700, Stephen Hemminger wrote:
>> On Thu, 26 Apr 2018 05:30:05 +0300
>> "Michael S. Tsirkin" <mst@redhat.com> wrote:
>>
>>> On Wed, Apr 25, 2018 at 05:08:37PM -0700, Stephen Hemminger wrote:
>>>> On Wed, 25 Apr 2018 16:59:28 -0700
>>>> Sridhar Samudrala <sridhar.samudrala@intel.com> wrote:
>>>>    
>>>>> Use the registration/notification framework supported by the generic
>>>>> failover infrastructure.
>>>>>
>>>>> Signed-off-by: Sridhar Samudrala <sridhar.samudrala@intel.com>
>>>> NAK unless you prove this works on legacy distributions and with DPDK 18.05
>>>> without modification.
>>> It looks like it should work. What kind of proof are you looking for?
>>>
>>
>> I tried this with working Ubuntu 17 on WS2016.
>> It boots if the failover driver is configured in (as module).
> Oh so by "unless you prove" you meant "unless you test"?
>
>> But if the configuration has:
>>
>> $ grep FAILOVER .config
>> # CONFIG_NET_FAILOVER is not set
>> CONFIG_MAY_USE_NET_FAILOVER=y
> So the new option works, what's broken is when it's *not* selected.
> Looks like a bug.

Yes.  Looks like i need to make NET_FAILOVER  to be enabled automatically when
VIRTIO_NET or HYPERV_NET are selected.

Thanks Stephen for confirming that it works when NET_FAILOVER is enabled.



>
>> The netvsc driver fails on boot with:
>>
>> [    0.826447] hv_vmbus: registering driver hv_netvsc
>> [    0.829616] scsi 0:0:0:0: Direct-Access     Msft     Virtual Disk     1.0  PQ: 0 ANSI: 5
>> [    0.836291] input: Microsoft Vmbus HID-compliant Mouse as /devices/0006:045E:0621.0001/input/input1
>> [    0.839139] hid-generic 0006:045E:0621.0001: input: <UNKNOWN> HID v0.01 Mouse [Microsoft Vmbus HID-compliant Mouse] on
>> [    0.964897] hv_vmbus: probe failed for device 849a776e-8120-4e4a-9a36-7e3d95ac75b3 (-95)
>> [    0.968039] hv_netvsc: probe of 849a776e-8120-4e4a-9a36-7e3d95ac75b3 failed with error -95
>> [    1.112877] hv_vmbus: probe failed for device 53557f8e-057d-425b-9265-01c0fd7e273e (-95)
>> [    1.116064] hv_netvsc: probe of 53557f8e-057d-425b-9265-01c0fd7e273e failed with error -95
>>
>> The system has two virtual networks. eth0 is on vswitch for management.
>> eth1 is on vswitch with SR-IOV for performance tests.
>>
>> You probably need to just put the failover part in net/core and select it.
>  From all drivers. Yes. And it does not need to be visible in the menu
> imho.
>
>
>> It is trivial to get an evaluation version of Windows Server 2016 and setup a Linux VM.
>> Please try it.
> I presume some kind of test was done here. Sridhar, do you think you
> could include some notes about testing of this patch? Or in case you
> only build-tested this part, it's a good idea to notice this after ---
> in the patch, or in the cover letter.

I only did compile and build test of netvsc. I don't have a hyperv setup to test it out.
Would appreciate if Stephen or someone who has this setup will test it out when i
submit the next revision with the config fixes.

>

^ permalink raw reply

* Re: [PATCH net-next 1/2 v2] netns: restrict uevents
From: Eric W. Biederman @ 2018-04-27  0:35 UTC (permalink / raw)
  To: Christian Brauner
  Cc: David Miller, netdev, linux-kernel, avagin, ktkhai, serge, gregkh
In-Reply-To: <20180426212744.GA30270@gmail.com>

Christian Brauner <christian.brauner@canonical.com> writes:

> On Thu, Apr 26, 2018 at 12:10:30PM -0500, Eric W. Biederman wrote:
>> Christian Brauner <christian.brauner@canonical.com> writes:
>> 
>> > On Thu, Apr 26, 2018 at 11:47:19AM -0500, Eric W. Biederman wrote:
>> >> Christian Brauner <christian.brauner@canonical.com> writes:
>> >> 
>> >> > On Tue, Apr 24, 2018 at 06:00:35PM -0500, Eric W. Biederman wrote:
>> >> >> Christian Brauner <christian.brauner@canonical.com> writes:
>> >> >> 
>> >> >> > On Wed, Apr 25, 2018, 00:41 Eric W. Biederman <ebiederm@xmission.com> wrote:
>> >> >> >
>> >> >> >  Bah. This code is obviously correct and probably wrong.
>> >> >> >
>> >> >> >  How do we deliver uevents for network devices that are outside of the
>> >> >> >  initial user namespace? The kernel still needs to deliver those.
>> >> >> >
>> >> >> >  The logic to figure out which network namespace a device needs to be
>> >> >> >  delivered to is is present in kobj_bcast_filter. That logic will almost
>> >> >> >  certainly need to be turned inside out. Sign not as easy as I would
>> >> >> >  have hoped.
>> >> >> >
>> >> >> > My first patch that we discussed put additional filtering logic into kobj_bcast_filter for that very reason. But I can move that logic
>> >> >> > out and come up with a new patch.
>> >> >> 
>> >> >> I may have mis-understood.
>> >> >> 
>> >> >> I heard and am still hearing additional filtering to reduce the places
>> >> >> the packet is delievered.
>> >> >> 
>> >> >> I am saying something needs to change to increase the number of places
>> >> >> the packet is delivered.
>> >> >> 
>> >> >> For the special class of devices that kobj_bcast_filter would apply to
>> >> >> those need to be delivered to netowrk namespaces  that are no longer on
>> >> >> uevent_sock_list.
>> >> >> 
>> >> >> So the code fundamentally needs to split into two paths.  Ordinary
>> >> >> devices that use uevent_sock_list.  Network devices that are just
>> >> >> delivered in their own network namespace.
>> >> >> 
>> >> >> netlink_broadcast_filtered gets to go away completely.
>> >> >
>> >> > The split *might* make sense but I think you're wrong about removing the
>> >> > kobj_bcast_filter. The current filter doesn't operate on the uevent
>> >> > socket in uevent_sock_list itself it rather operates on the sockets in
>> >> > mc_list. And if socket in mc_list can have a different network namespace
>> >> > then the uevent_socket itself then your way won't work. That's why my
>> >> > original patch added additional filtering in there. The way I see it we
>> >> > need something like:
>> >> 
>> >> We already filter the sockets in the mc_list by network namespace.
>> >
>> > Oh really? That's good to know. I haven't found where in the code this
>> > actually happens. I thought that when netlink_bind() is called anyone
>> > could register themselves in mc_list.
>> 
>> The code in af_netlink.c does:
>> > static void do_one_broadcast(struct sock *sk,
>> > 				    struct netlink_broadcast_data *p)
>> > {
>> > 	struct netlink_sock *nlk = nlk_sk(sk);
>> > 	int val;
>> > 
>> > 	if (p->exclude_sk == sk)
>> > 		return;
>> > 
>> > 	if (nlk->portid == p->portid || p->group - 1 >= nlk->ngroups ||
>> > 	    !test_bit(p->group - 1, nlk->groups))
>> > 		return;
>> > 
>> > 	if (!net_eq(sock_net(sk), p->net)) {
>>             ^^^^^^^^^^^^ Here
>> > 		if (!(nlk->flags & NETLINK_F_LISTEN_ALL_NSID))
>> > 			return;
>>                 ^^^^^^^^^^^ Here
>> > 
>> > 		if (!peernet_has_id(sock_net(sk), p->net))
>> > 			return;
>> > 
>> > 		if (!file_ns_capable(sk->sk_socket->file, p->net->user_ns,
>> > 				     CAP_NET_BROADCAST))
>> > 			return;
>> > 	}
>> 
>> Which if you are not a magic NETLINK_F_LISTEN_ALL_NSID socket filters
>> you out if you are the wrong network namespace.
>> 
>> 
>> >> When a packet is transmitted with netlink_broadcast it is only
>> >> transmitted within a single network namespace.
>> >> 
>> >> Even in the case of a NETLINK_F_LISTEN_ALL_NSID socket the skb is tagged
>> >> with it's source network namespace so no confusion will result, and the
>> >> permission checks have been done to make it safe. So you can safely
>> >> ignore that case.  Please ignore that case.  It only needs to be
>> >> considered if refactoring af_netlink.c
>> >> 
>> >> When I added netlink_broadcast_filtered I imagined that we would need
>> >> code that worked across network namespaces that worked for different
>> >> namespaces.   So it looked like we would need the level of granularity
>> >> that you can get with netlink_broadcast_filtered.  It turns out we don't
>> >> and that it was a case of over design.  As the only split we care about
>> >> is per network namespace there is no need for
>> >> netlink_broadcast_filtered.
>> >> 
>> >> > init_user_ns_broadcast_filtered(uevent_sock_list, kobj_bcast_filter);
>> >> > user_ns_broadcast_filtered(uevent_sock_list,kobj_bcast_filter);
>> >> >
>> >> > The question that remains is whether we can rely on the network
>> >> > namespace information we can gather from the kobject_ns_type_operations
>> >> > to decide where we want to broadcast that event to. So something
>> >> > *like*:
>> >> 
>> >> We can.  We already do.  That is what kobj_bcast_filter implements.
>> >> 
>> >> > 	ops = kobj_ns_ops(kobj);
>> >> > 	if (!ops && kobj->kset) {
>> >> > 		struct kobject *ksobj = &kobj->kset->kobj;
>> >> > 		if (ksobj->parent != NULL)
>> >> > 			ops = kobj_ns_ops(ksobj->parent);
>> >> > 	}
>> >> >
>> >> > 	if (ops && ops->netlink_ns && kobj->ktype->namespace)
>> >> > 		if (ops->type == KOBJ_NS_TYPE_NET)
>> >> > 			net = kobj->ktype->namespace(kobj);
>> >> 
>> >> Please note the only entry in the enumeration in the kobj_ns_type
>> >> enumeration other than KOBJ_NS_TYPE_NONE is KOBJ_NS_TYPE_NET.  So the
>> >> check for ops->type in this case is redundant.
>> >
>> > Yes, I know the reason for doing it explicitly is to block the case
>> > where kobjects get tagged with other namespaces. So we'd need to be
>> > vigilant should that ever happen but fine.
>> 
>> It is fine to keep the check.
>> 
>> I was intending to point out that it is much more likely that we remove
>> the enumeration and remove some of the extra abstraction, than another
>> namespace is implemented there.
>> 
>> >> That is something else that could be simplifed.  At the time it was the
>> >> necessary to get the sysfs changes merged.
>> >> 
>> >> > 	if (!net || net->user_ns == &init_user_ns)
>> >> > 		ret = init_user_ns_broadcast(env, action_string, devpath);
>> >> > 	else
>> >> > 		ret = user_ns_broadcast(net->uevent_sock->sk, env,
>> >> > 					action_string, devpath);
>> >> 
>> >> Almost.
>> >> 
>> >> 	if (!net)
>> >>         	kobject_uevent_net_broadcast(kobj, env, action_string,
>> >>         					dev_path);
>> >> 	else
>> >>         	netlink_broadcast(net->uevent_sock->sk, skb, 0, 1, GFP_KERNEL);
>> >> 
>> >> 
>> >> I am handwaving to get the skb in the netlink_broadcast case but that
>> >> should be enough for you to see what I am thinking.
>> >
>> > I have added a helper alloc_uevent_skb() that can be used in both cases.
>> >
>> > static struct sk_buff *alloc_uevent_skb(struct kobj_uevent_env *env,
>> > 					const char *action_string,
>> > 					const char *devpath)
>> > {
>> > 	struct sk_buff *skb = NULL;
>> > 	char *scratch;
>> > 	size_t len;
>> >
>> > 	/* allocate message with maximum possible size */
>> > 	len = strlen(action_string) + strlen(devpath) + 2;
>> > 	skb = alloc_skb(len + env->buflen, GFP_KERNEL);
>> > 	if (!skb)
>> > 		return NULL;
>> >
>> > 	/* add header */
>> > 	scratch = skb_put(skb, len);
>> > 	sprintf(scratch, "%s@%s", action_string, devpath);
>> >
>> > 	skb_put_data(skb, env->buf, env->buflen);
>> >
>> > 	NETLINK_CB(skb).dst_group = 1;
>> >
>> > 	return skb;
>> > }
>> >
>> >> 
>> >> My only concern with the above is that we almost certainly need to fix
>> >> the credentials on the skb so that userspace does not drop the packet
>
> I guess we simply want:
> 	if (user_ns != &init_user_ns) {
> 		NETLINK_CB(skb).creds.uid = (kuid_t)0;
> 		NETLINK_CB(skb).creds.gid = kgid_t)0;
> 	}

I believe the above is what we already have.

> instead of the more complicated and - imho wrong:
>
> 	if (user_ns != &init_user_ns) {
> 		/* fix credentials for udev running in user namespace */
> 		kuid_t uid = NETLINK_CB(skb).creds.uid;
> 		kgid_t gid = NETLINK_CB(skb).creds.gid;
> 		NETLINK_CB(skb).creds.uid = from_kuid_munged(user_ns, uid);
> 		NETLINK_CB(skb).creds.gid = from_kgid_munged(user_ns, gid);
> 	}

The above is most definitely wrong as we store kuids and kgids in
"NETLINK_CB(skb).creds".

I am pretty certain what we want is:
	kuid_t root_uid = make_kuid(net->user_ns, 0);
        kgid_g root_gid = make_kgid(net->user_ns, 0);
        if (!uid_valid(root_uid))
        	root_uid = GLOBAL_ROOT_UID;
	if (!gid_valid(root_gid))
        	root_gid = GLOBAL_ROOT_GID;
	NETLINK_CB(skb).creds.uid = root_uid;
        NETLINK_CB(skb).creds.gid = root_gid;

Let's be careful and only fix this for the networking uevents please.
We want the other onces to just go away.

The networking uevents we have to fix or they will be gone completely.

Eric

^ permalink raw reply

* pull-request: bpf-next 2018-04-27
From: Daniel Borkmann @ 2018-04-27  1:14 UTC (permalink / raw)
  To: davem; +Cc: daniel, ast, netdev

Hi David,

The following pull-request contains BPF updates for your *net-next* tree.

The main changes are:

1) Add extensive BPF helper description into include/uapi/linux/bpf.h
   and a new script bpf_helpers_doc.py which allows for generating a
   man page out of it. Thus, every helper in BPF now comes with proper
   function signature, detailed description and return code explanation,
   from Quentin.

2) Migrate the BPF collect metadata tunnel tests from BPF samples over
   to the BPF selftests and further extend them with v6 vxlan, geneve
   and ipip tests, simplify the ipip tests, improve documentation and
   convert to bpf_ntoh*() / bpf_hton*() api, from William.

3) Currently, helpers that expect ARG_PTR_TO_MAP_{KEY,VALUE} can only
   access stack and packet memory. Extend this to allow such helpers
   to also use map values, which enabled use cases where value from
   a first lookup can be directly used as a key for a second lookup,
   from Paul.

4) Add a new helper bpf_skb_get_xfrm_state() for tc BPF programs in
   order to retrieve XFRM state information containing SPI, peer
   address and reqid values, from Eyal.

5) Various optimizations in nfp driver's BPF JIT in order to turn ADD
   and SUB instructions with negative immediate into the opposite
   operation with a positive immediate such that nfp can better fit
   small immediates into instructions. Savings in instruction count
   up to 4% have been observed, from Jakub.

6) Add the BPF prog's gpl_compatible flag to struct bpf_prog_info
   and add support for dumping this through bpftool, from Jiri.

7) Move the BPF sockmap samples over into BPF selftests instead since
   sockmap was rather a series of tests than sample anyway and this way
   this can be run from automated bots, from John.

8) Follow-up fix for bpf_adjust_tail() helper in order to make it work
   with generic XDP, from Nikita.

9) Some follow-up cleanups to BTF, namely, removing unused defines from
   BTF uapi header and renaming 'name' struct btf_* members into name_off
   to make it more clear they are offsets into string section, from Martin.

10) Remove test_sock_addr from TEST_GEN_PROGS in BPF selftests since
    not run directly but invoked from test_sock_addr.sh, from Yonghong.

11) Remove redundant ret assignment in sample BPF loader, from Wang.

12) Add couple of missing files to BPF selftest's gitignore, from Anders.

Please consider pulling these changes from:

  git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git

There are two trivial merge conflicts while pulling:

  1) Remove samples/sockmap/Makefile since all sockmap tests have been
     moved to selftests.
  2) Add both hunks from tools/testing/selftests/bpf/.gitignore to the
     file since git should ignore all of them.

Thanks a lot!

----------------------------------------------------------------

The following changes since commit 48d7a07ba355c7056e66adcdd35379d12e48252b:

  hv_netvsc: select needed ucs2_string routine (2018-04-22 21:07:03 -0400)

are available in the git repository at:

  git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git 

for you to fetch changes up to c0885f61bbb6a89c35397d3a8fe49c35822cde81:

  samples, bpf: remove redundant ret assignment in bpf_load_program() (2018-04-27 00:47:06 +0200)

----------------------------------------------------------------
Anders Roxell (1):
      selftests: bpf: update .gitignore with missing file

Daniel Borkmann (6):
      Merge branch 'bpf-xfrm-states'
      Merge branch 'bpf-map-val-as-key'
      Merge branch 'bpf-sockmap-selftests'
      Merge branch 'bpf-optimize-neg-sums'
      Merge branch 'bpf-tunnel-metadata-selftests'
      Merge branch 'bpf-uapi-helper-doc'

Eyal Birger (2):
      bpf: add helper for getting xfrm states
      samples/bpf: extend test_tunnel_bpf.sh with xfrm state test

Jakub Kicinski (4):
      nfp: bpf: remove double space
      nfp: bpf: optimize add/sub of a negative constant
      nfp: bpf: tabularize generations of compare operations
      nfp: bpf: optimize comparisons to negative constants

Jiri Olsa (3):
      bpf: Add gpl_compatible flag to struct bpf_prog_info
      tools, bpf: Sync bpf.h uapi header
      tools, bpftool: Display license GPL compatible in prog show/list

John Fastabend (5):
      bpf: sockmap, code sockmap_test in C
      bpf: sockmap, add a set of tests to run by default
      bpf: sockmap, add selftests
      bpf: sockmap, remove samples program
      bpf: reduce runtime of test_sockmap tests

Martin KaFai Lau (1):
      bpf: btf: Clean up btf.h in uapi

Nikita V. Shirokov (2):
      bpf: fix virtio-net's length calc for XDP_PASS
      bpf: fix xdp_generic for bpf_adjust_tail usecase

Paul Chaignon (2):
      bpf: allow map helpers access to map values directly
      tools/bpf: add verifier tests for accesses to map values

Quentin Monnet (10):
      bpf: add script and prepare bpf.h for new helpers documentation
      bpf: add documentation for eBPF helpers (01-11)
      bpf: add documentation for eBPF helpers (12-22)
      bpf: add documentation for eBPF helpers (23-32)
      bpf: add documentation for eBPF helpers (33-41)
      bpf: add documentation for eBPF helpers (42-50)
      bpf: add documentation for eBPF helpers (51-57)
      bpf: add documentation for eBPF helpers (58-64)
      bpf: add documentation for eBPF helpers (65-66)
      bpf: update bpf.h uapi header for tools

Wang Sheng-Hui (1):
      samples, bpf: remove redundant ret assignment in bpf_load_program()

William Tu (2):
      selftests/bpf: bpf tunnel test.
      samples/bpf: remove the bpf tunnel testsuite.

Yonghong Song (1):
      tools/bpf: remove test_sock_addr from TEST_GEN_PROGS

 drivers/net/ethernet/netronome/nfp/bpf/jit.c       |  231 +--
 drivers/net/ethernet/netronome/nfp/bpf/main.h      |    6 +-
 drivers/net/virtio_net.c                           |    2 +-
 include/uapi/linux/bpf.h                           | 1784 ++++++++++++++-----
 include/uapi/linux/btf.h                           |    8 +-
 kernel/bpf/btf.c                                   |   20 +-
 kernel/bpf/syscall.c                               |    1 +
 kernel/bpf/verifier.c                              |   24 +-
 net/core/dev.c                                     |    4 +-
 net/core/filter.c                                  |   48 +
 samples/bpf/Makefile                               |    1 -
 samples/bpf/bpf_load.c                             |    2 -
 samples/bpf/test_tunnel_bpf.sh                     |  319 ----
 samples/sockmap/Makefile                           |   75 -
 samples/sockmap/sockmap_test.sh                    |  488 ------
 scripts/bpf_helpers_doc.py                         |  421 +++++
 tools/bpf/bpftool/Documentation/bpftool-prog.rst   |    3 +-
 tools/bpf/bpftool/prog.c                           |    3 +
 tools/include/uapi/linux/bpf.h                     | 1785 +++++++++++++++-----
 tools/include/uapi/linux/btf.h                     |    8 +-
 tools/include/uapi/linux/if_link.h                 |   39 +
 tools/lib/bpf/btf.c                                |    2 +-
 tools/lib/bpf/libbpf.c                             |    4 +-
 tools/lib/bpf/libbpf.h                             |    2 +
 tools/testing/selftests/bpf/.gitignore             |    1 +
 tools/testing/selftests/bpf/Makefile               |   10 +-
 tools/testing/selftests/bpf/bpf_helpers.h          |    4 +-
 .../testing/selftests/bpf/test_sockmap.c           |  880 ++++++++--
 .../testing/selftests/bpf/test_sockmap_kern.c      |   35 +-
 tools/testing/selftests/bpf/test_tunnel.sh         |  729 ++++++++
 .../testing/selftests/bpf/test_tunnel_kern.c       |  263 ++-
 tools/testing/selftests/bpf/test_verifier.c        |  266 +++
 32 files changed, 5400 insertions(+), 2068 deletions(-)
 delete mode 100755 samples/bpf/test_tunnel_bpf.sh
 delete mode 100644 samples/sockmap/Makefile
 delete mode 100755 samples/sockmap/sockmap_test.sh
 create mode 100755 scripts/bpf_helpers_doc.py
 rename samples/sockmap/sockmap_user.c => tools/testing/selftests/bpf/test_sockmap.c (57%)
 rename samples/sockmap/sockmap_kern.c => tools/testing/selftests/bpf/test_sockmap_kern.c (91%)
 create mode 100755 tools/testing/selftests/bpf/test_tunnel.sh
 rename samples/bpf/tcbpf2_kern.c => tools/testing/selftests/bpf/test_tunnel_kern.c (68%)

^ permalink raw reply

* Re: pull-request: bpf-next 2018-04-27
From: David Miller @ 2018-04-27  1:20 UTC (permalink / raw)
  To: daniel; +Cc: ast, netdev
In-Reply-To: <20180427011442.6525-1-daniel@iogearbox.net>

From: Daniel Borkmann <daniel@iogearbox.net>
Date: Fri, 27 Apr 2018 03:14:42 +0200

> The following pull-request contains BPF updates for your *net-next* tree.
 ...
> Please consider pulling these changes from:
> 
>   git://git.kernel.org/pub/scm/linux/kernel/git/bpf/bpf-next.git

Pulled and build testing before pushing back out.

> There are two trivial merge conflicts while pulling:
> 
>   1) Remove samples/sockmap/Makefile since all sockmap tests have been
>      moved to selftests.
>   2) Add both hunks from tools/testing/selftests/bpf/.gitignore to the
>      file since git should ignore all of them.

Thanks for this.

^ permalink raw reply

* Re: [PATCH net-next v5 1/3] vmcore: add API to collect hardware dump in second kernel
From: Eric W. Biederman @ 2018-04-27  1:30 UTC (permalink / raw)
  To: Rahul Lakkireddy
  Cc: netdev, kexec, linux-fsdevel, linux-kernel, davem, viro, stephen,
	akpm, torvalds, ganeshgr, nirranjan, indranil
In-Reply-To: <1393d2fce1a2c2a0f78431845deae26bc28c16ef.1524329561.git.rahul.lakkireddy@chelsio.com>


While looking this over I found a bug in the way elf notes are being composed.

Rahul Lakkireddy <rahul.lakkireddy@chelsio.com> writes:
> diff --git a/fs/proc/vmcore.c b/fs/proc/vmcore.c
> index a45f0af22a60..7395462d2f86 100644
> --- a/fs/proc/vmcore.c
> +++ b/fs/proc/vmcore.c
> @@ -1145,6 +1150,132 @@ static int __init parse_crash_elf_headers(void)
>  	return 0;
>  }
>  
> +#ifdef CONFIG_PROC_VMCORE_DEVICE_DUMP
> +/**
> + * vmcoredd_get_note_size - Get size of the note that will be inserted at
> + * beginning of the dump's buffer.
> + * @name: Note's name
> + *
> + * Gets the overall size of the note that will be inserted at the beginning
> + * of the dump's buffer.  It also adds padding, if necessary to meet
> + * alignment requirements.
> + */
> +static inline size_t vmcoredd_get_note_size(const char *name)
> +{
> +	return CRASH_CORE_NOTE_HEAD_BYTES +
> +	       ALIGN(VMCOREDD_NOTE_NAME_BYTES + strlen(name), sizeof(Elf_Word));
> +}
> +
> +/**
> + * vmcoredd_write_note - Write note at the beginning of the dump's buffer
> + * @name: Dump's name
> + * @buf: Output buffer where the note is written
> + * @size: Size of the dump
> + *
> + * Fills beginning of the dump's data with elf note.
> + */
> +static void vmcoredd_write_note(const char *name, void *buf, size_t size)
> +{
> +	struct elf_note *note = (struct elf_note *)buf;
> +	Elf_Word *word = (Elf_Word *)note;
> +
> +	note->n_namesz = ALIGN(VMCOREDD_NOTE_NAME_BYTES + strlen(name),
> +			       sizeof(Elf_Word));
> +	note->n_descsz = size;
> +	note->n_type = NT_VMCOREDD;
> +	word += DIV_ROUND_UP(sizeof(*note), sizeof(Elf_Word));
> +	snprintf((char *)word, note->n_namesz, "%s_%s", VMCOREDD_NOTE_NAME,
> +		 name);

I hate to do this to you but as this is ABI I am going to pick on
this bit of code.

First namesz needs to include the '\0' of the name string.
Second you did not count the length of "_" namesz.
Third name needs to be a vendor identifier.  So "LINUX\0\0\0" in our case.

Which means the device name needs to be in the body of the note.
Perhaps just reserve 32 bytes for the device name?
Perhaps prefix the device name with a length?

The exact layout is whatever you want NT_VMCOREDD to mean.

> diff --git a/include/uapi/linux/elf.h b/include/uapi/linux/elf.h
> index e2535d6dcec7..4e12c423b9fe 100644
> --- a/include/uapi/linux/elf.h
> +++ b/include/uapi/linux/elf.h
> @@ -421,6 +421,7 @@ typedef struct elf64_shdr {
>  #define NT_ARM_SYSTEM_CALL	0x404	/* ARM system call number */
>  #define NT_ARM_SVE	0x405		/* ARM Scalable Vector Extension registers */
>  #define NT_ARC_V2	0x600		/* ARCv2 accumulator/extra registers */
> +#define NT_VMCOREDD	0x700		/* Vmcore Device Dump Note */
>  
>  /* Note header in a PT_NOTE section */
>  typedef struct elf32_note {


Eric

^ permalink raw reply

* Re: [PATCH net] bridge: check iface upper dev when setting master via ioctl
From: Hangbin Liu @ 2018-04-27  1:31 UTC (permalink / raw)
  To: Nikolay Aleksandrov; +Cc: netdev, Dmitry Vyukov, syzbot, David Miller
In-Reply-To: <c8108c6b-5276-4a49-01ae-a99795f04359@cumulusnetworks.com>

Hi Nikolay,

Thanks for the comments.
On Thu, Apr 26, 2018 at 05:22:46PM +0300, Nikolay Aleksandrov wrote:
> > Not all upper devs are masters. This can break some setups.

Ah, like vlan device.. So how about

+	if (netdev_master_upper_dev_get(dev))
 		return -EBUSY;

> > 
> > 
> 
> Also it's not really a bug, the device begins to get initialized but it
> will get removed at netdev_master_upper_dev_link() anyway if there's
> already a master. Why would it be better ?

> It's clearly wrong to try and enslave a device that already has a master
> via ioctl, rtnetlink already deals with that and the old ioctl interface
> will get an error, yes it will initialize some structs but they'll get
> freed later. This is common practice, check the bonding for example.

Bonding use netdev_is_rx_handler_busy(slave_dev) to check if the slave
already has a master, which is another solution.
> 
> If anything do the check in the ioctl interface (add_del_if) only and
> maybe target net-next, there's really no bug fix here. IMO it's not

What if someone do like

while true; do brctl addif br0 bond_slave &; done

I know this is stupid and almost no one will do that in real world.
But syzbot run some similar test and get warn from kobject_add_internal()
with -ENOMEM. That's why I think we should fix it before allocate any
resource.

What do you think?

[1] https://syzkaller.appspot.com/bug?id=3e0339080acd6a2a350a900bc6533b03f5498490

Thanks
Hangbin

^ permalink raw reply

* [PATCH net-next 0/3] net: dsa: mv88e6xxx: remove Global 2 setup
From: Vivien Didelot @ 2018-04-27  1:56 UTC (permalink / raw)
  To: netdev
  Cc: Andrew Lunn, Vivien Didelot, Florian Fainelli, David S. Miller,
	linux-kernel, kernel

Parts of the mv88e6xxx driver still write arbitrary registers of
different banks at setup time, which is misleading especially when
supporting multiple device models.

This patchset moves two features setup into the top lovel
mv88e6xxx_setup function and kills the old Global 2 register bank setup
function. It brings no functional changes.

Vivien Didelot (3):
  net: dsa: mv88e6xxx: move trunk setup
  net: dsa: mv88e6xxx: move device mapping setup
  net: dsa: mv88e6xxx: remove Global 2 setup

 drivers/net/dsa/mv88e6xxx/chip.c    | 47 ++++++++++++++++++----
 drivers/net/dsa/mv88e6xxx/global2.c | 62 ++++-------------------------
 drivers/net/dsa/mv88e6xxx/global2.h | 25 ++++++++----
 3 files changed, 65 insertions(+), 69 deletions(-)

-- 
2.17.0

^ permalink raw reply

* [PATCH net-next 1/3] net: dsa: mv88e6xxx: move trunk setup
From: Vivien Didelot @ 2018-04-27  1:56 UTC (permalink / raw)
  To: netdev
  Cc: Andrew Lunn, Vivien Didelot, Florian Fainelli, David S. Miller,
	linux-kernel, kernel
In-Reply-To: <20180427015646.24946-1-vivien.didelot@savoirfairelinux.com>

Move the trunking setup out of Global 2 specific setup into the top
level mv88e6xxx_setup function.

Note that the 88E6390 family calls this LAG instead of Trunk and
supports 32 possible ID routing vectors, with LAG ID bit 4 being placed
in Global 2 register 0x1D...

We don't need Trunk (or LAG) IDs for the moment, thus keep it simple.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
 drivers/net/dsa/mv88e6xxx/chip.c    | 13 +++++++++++++
 drivers/net/dsa/mv88e6xxx/global2.c |  7 +------
 drivers/net/dsa/mv88e6xxx/global2.h |  7 +++++++
 3 files changed, 21 insertions(+), 6 deletions(-)

diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 3d2091099f7f..379edaf79aca 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -1020,6 +1020,15 @@ static void mv88e6xxx_port_stp_state_set(struct dsa_switch *ds, int port,
 		dev_err(ds->dev, "p%d: failed to update state\n", port);
 }
 
+static int mv88e6xxx_trunk_setup(struct mv88e6xxx_chip *chip)
+{
+	/* Clear all trunk masks and mapping */
+	if (chip->info->global2_addr)
+		return mv88e6xxx_g2_trunk_clear(chip);
+
+	return 0;
+}
+
 static int mv88e6xxx_pot_setup(struct mv88e6xxx_chip *chip)
 {
 	if (chip->info->ops->pot_clear)
@@ -2233,6 +2242,10 @@ static int mv88e6xxx_setup(struct dsa_switch *ds)
 	if (err)
 		goto unlock;
 
+	err = mv88e6xxx_trunk_setup(chip);
+	if (err)
+		goto unlock;
+
 	/* Setup PTP Hardware Clock and timestamping */
 	if (chip->info->ptp_support) {
 		err = mv88e6xxx_ptp_setup(chip);
diff --git a/drivers/net/dsa/mv88e6xxx/global2.c b/drivers/net/dsa/mv88e6xxx/global2.c
index 0ce627fded48..3f24763aedc5 100644
--- a/drivers/net/dsa/mv88e6xxx/global2.c
+++ b/drivers/net/dsa/mv88e6xxx/global2.c
@@ -174,7 +174,7 @@ static int mv88e6xxx_g2_trunk_mapping_write(struct mv88e6xxx_chip *chip, int id,
 	return mv88e6xxx_g2_update(chip, MV88E6XXX_G2_TRUNK_MAPPING, val);
 }
 
-static int mv88e6xxx_g2_clear_trunk(struct mv88e6xxx_chip *chip)
+int mv88e6xxx_g2_trunk_clear(struct mv88e6xxx_chip *chip)
 {
 	const u16 port_mask = BIT(mv88e6xxx_num_ports(chip)) - 1;
 	int i, err;
@@ -1159,10 +1159,5 @@ int mv88e6xxx_g2_setup(struct mv88e6xxx_chip *chip)
 	if (err)
 		return err;
 
-	/* Clear all trunk masks and mapping. */
-	err = mv88e6xxx_g2_clear_trunk(chip);
-	if (err)
-		return err;
-
 	return 0;
 }
diff --git a/drivers/net/dsa/mv88e6xxx/global2.h b/drivers/net/dsa/mv88e6xxx/global2.h
index 520ec70d32e8..7bd4ab31a93e 100644
--- a/drivers/net/dsa/mv88e6xxx/global2.h
+++ b/drivers/net/dsa/mv88e6xxx/global2.h
@@ -327,6 +327,8 @@ int mv88e6352_g2_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip);
 
 int mv88e6xxx_g2_pot_clear(struct mv88e6xxx_chip *chip);
 
+int mv88e6xxx_g2_trunk_clear(struct mv88e6xxx_chip *chip);
+
 extern const struct mv88e6xxx_irq_ops mv88e6097_watchdog_ops;
 extern const struct mv88e6xxx_irq_ops mv88e6390_watchdog_ops;
 
@@ -495,6 +497,11 @@ static inline int mv88e6xxx_g2_scratch_gpio_set_smi(struct mv88e6xxx_chip *chip,
 	return -EOPNOTSUPP;
 }
 
+static inline int mv88e6xxx_g2_trunk_clear(struct mv88e6xxx_chip *chip)
+{
+	return -EOPNOTSUPP;
+}
+
 #endif /* CONFIG_NET_DSA_MV88E6XXX_GLOBAL2 */
 
 #endif /* _MV88E6XXX_GLOBAL2_H */
-- 
2.17.0

^ permalink raw reply related

* [PATCH net-next 2/3] net: dsa: mv88e6xxx: move device mapping setup
From: Vivien Didelot @ 2018-04-27  1:56 UTC (permalink / raw)
  To: netdev
  Cc: Andrew Lunn, Vivien Didelot, Florian Fainelli, David S. Miller,
	linux-kernel, kernel
In-Reply-To: <20180427015646.24946-1-vivien.didelot@savoirfairelinux.com>

Move the Device Mapping setup out of the specific Global 2 code,
into the top level device setup function.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
 drivers/net/dsa/mv88e6xxx/chip.c    | 27 +++++++++++++++++++++
 drivers/net/dsa/mv88e6xxx/global2.c | 37 +++++------------------------
 drivers/net/dsa/mv88e6xxx/global2.h | 12 +++++++++-
 3 files changed, 44 insertions(+), 32 deletions(-)

diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 379edaf79aca..0b7530452643 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -1020,6 +1020,29 @@ static void mv88e6xxx_port_stp_state_set(struct dsa_switch *ds, int port,
 		dev_err(ds->dev, "p%d: failed to update state\n", port);
 }
 
+static int mv88e6xxx_devmap_setup(struct mv88e6xxx_chip *chip)
+{
+	int target, port;
+	int err;
+
+	if (!chip->info->global2_addr)
+		return 0;
+
+	/* Initialize the routing port to the 32 possible target devices */
+	for (target = 0; target < 32; target++) {
+		port = 0x1f;
+		if (target < DSA_MAX_SWITCHES)
+			if (chip->ds->rtable[target] != DSA_RTABLE_NONE)
+				port = chip->ds->rtable[target];
+
+		err = mv88e6xxx_g2_device_mapping_write(chip, target, port);
+		if (err)
+			return err;
+	}
+
+	return 0;
+}
+
 static int mv88e6xxx_trunk_setup(struct mv88e6xxx_chip *chip)
 {
 	/* Clear all trunk masks and mapping */
@@ -2246,6 +2269,10 @@ static int mv88e6xxx_setup(struct dsa_switch *ds)
 	if (err)
 		goto unlock;
 
+	err = mv88e6xxx_devmap_setup(chip);
+	if (err)
+		goto unlock;
+
 	/* Setup PTP Hardware Clock and timestamping */
 	if (chip->info->ptp_support) {
 		err = mv88e6xxx_ptp_setup(chip);
diff --git a/drivers/net/dsa/mv88e6xxx/global2.c b/drivers/net/dsa/mv88e6xxx/global2.c
index 3f24763aedc5..96e74d8d500d 100644
--- a/drivers/net/dsa/mv88e6xxx/global2.c
+++ b/drivers/net/dsa/mv88e6xxx/global2.c
@@ -119,37 +119,17 @@ int mv88e6352_g2_mgmt_rsvd2cpu(struct mv88e6xxx_chip *chip)
 
 /* Offset 0x06: Device Mapping Table register */
 
-static int mv88e6xxx_g2_device_mapping_write(struct mv88e6xxx_chip *chip,
-					     int target, int port)
+int mv88e6xxx_g2_device_mapping_write(struct mv88e6xxx_chip *chip, int target,
+				      int port)
 {
-	u16 val = (target << 8) | (port & 0xf);
+	u16 val = (target << 8) | (port & 0x1f);
+	/* Modern chips use 5 bits to define a device mapping port,
+	 * but bit 4 is reserved on older chips, so it is safe to use.
+	 */
 
 	return mv88e6xxx_g2_update(chip, MV88E6XXX_G2_DEVICE_MAPPING, val);
 }
 
-static int mv88e6xxx_g2_set_device_mapping(struct mv88e6xxx_chip *chip)
-{
-	int target, port;
-	int err;
-
-	/* Initialize the routing port to the 32 possible target devices */
-	for (target = 0; target < 32; ++target) {
-		port = 0xf;
-
-		if (target < DSA_MAX_SWITCHES) {
-			port = chip->ds->rtable[target];
-			if (port == DSA_RTABLE_NONE)
-				port = 0xf;
-		}
-
-		err = mv88e6xxx_g2_device_mapping_write(chip, target, port);
-		if (err)
-			break;
-	}
-
-	return err;
-}
-
 /* Offset 0x07: Trunk Mask Table register */
 
 static int mv88e6xxx_g2_trunk_mask_write(struct mv88e6xxx_chip *chip, int num,
@@ -1154,10 +1134,5 @@ int mv88e6xxx_g2_setup(struct mv88e6xxx_chip *chip)
 	if (err)
 		return err;
 
-	/* Program the DSA routing table. */
-	err = mv88e6xxx_g2_set_device_mapping(chip);
-	if (err)
-		return err;
-
 	return 0;
 }
diff --git a/drivers/net/dsa/mv88e6xxx/global2.h b/drivers/net/dsa/mv88e6xxx/global2.h
index 7bd4ab31a93e..46913a289255 100644
--- a/drivers/net/dsa/mv88e6xxx/global2.h
+++ b/drivers/net/dsa/mv88e6xxx/global2.h
@@ -60,7 +60,8 @@
 #define MV88E6XXX_G2_DEVICE_MAPPING		0x06
 #define MV88E6XXX_G2_DEVICE_MAPPING_UPDATE	0x8000
 #define MV88E6XXX_G2_DEVICE_MAPPING_DEV_MASK	0x1f00
-#define MV88E6XXX_G2_DEVICE_MAPPING_PORT_MASK	0x000f
+#define MV88E6352_G2_DEVICE_MAPPING_PORT_MASK	0x000f
+#define MV88E6390_G2_DEVICE_MAPPING_PORT_MASK	0x001f
 
 /* Offset 0x07: Trunk Mask Table Register */
 #define MV88E6XXX_G2_TRUNK_MASK			0x07
@@ -329,6 +330,9 @@ int mv88e6xxx_g2_pot_clear(struct mv88e6xxx_chip *chip);
 
 int mv88e6xxx_g2_trunk_clear(struct mv88e6xxx_chip *chip);
 
+int mv88e6xxx_g2_device_mapping_write(struct mv88e6xxx_chip *chip, int target,
+				      int port);
+
 extern const struct mv88e6xxx_irq_ops mv88e6097_watchdog_ops;
 extern const struct mv88e6xxx_irq_ops mv88e6390_watchdog_ops;
 
@@ -502,6 +506,12 @@ static inline int mv88e6xxx_g2_trunk_clear(struct mv88e6xxx_chip *chip)
 	return -EOPNOTSUPP;
 }
 
+static inline int mv88e6xxx_g2_device_mapping_write(struct mv88e6xxx_chip *chip,
+						    int target, int port)
+{
+	return -EOPNOTSUPP;
+}
+
 #endif /* CONFIG_NET_DSA_MV88E6XXX_GLOBAL2 */
 
 #endif /* _MV88E6XXX_GLOBAL2_H */
-- 
2.17.0

^ permalink raw reply related

* [PATCH net-next 3/3] net: dsa: mv88e6xxx: remove Global 2 setup
From: Vivien Didelot @ 2018-04-27  1:56 UTC (permalink / raw)
  To: netdev
  Cc: Andrew Lunn, Vivien Didelot, Florian Fainelli, David S. Miller,
	linux-kernel, kernel
In-Reply-To: <20180427015646.24946-1-vivien.didelot@savoirfairelinux.com>

The remaining values written to the Switch Management Register in the
mv88e6xxx_g2_setup function are specific to 88E6352 and older, and are
the default values anyway.

Thus remove completely this function. The mv88e6xxx driver no more
contains setup code to access arbitrary Global 2 registers.

Signed-off-by: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
---
 drivers/net/dsa/mv88e6xxx/chip.c    |  7 -------
 drivers/net/dsa/mv88e6xxx/global2.c | 18 ------------------
 drivers/net/dsa/mv88e6xxx/global2.h |  6 ------
 3 files changed, 31 deletions(-)

diff --git a/drivers/net/dsa/mv88e6xxx/chip.c b/drivers/net/dsa/mv88e6xxx/chip.c
index 0b7530452643..5671fb78c252 100644
--- a/drivers/net/dsa/mv88e6xxx/chip.c
+++ b/drivers/net/dsa/mv88e6xxx/chip.c
@@ -2222,13 +2222,6 @@ static int mv88e6xxx_setup(struct dsa_switch *ds)
 	if (err)
 		goto unlock;
 
-	/* Setup Switch Global 2 Registers */
-	if (chip->info->global2_addr) {
-		err = mv88e6xxx_g2_setup(chip);
-		if (err)
-			goto unlock;
-	}
-
 	err = mv88e6xxx_irl_setup(chip);
 	if (err)
 		goto unlock;
diff --git a/drivers/net/dsa/mv88e6xxx/global2.c b/drivers/net/dsa/mv88e6xxx/global2.c
index 96e74d8d500d..e6d658181b27 100644
--- a/drivers/net/dsa/mv88e6xxx/global2.c
+++ b/drivers/net/dsa/mv88e6xxx/global2.c
@@ -1118,21 +1118,3 @@ void mv88e6xxx_g2_irq_mdio_free(struct mv88e6xxx_chip *chip,
 	for (phy = 0; phy < chip->info->num_internal_phys; phy++)
 		irq_dispose_mapping(bus->irq[phy]);
 }
-
-int mv88e6xxx_g2_setup(struct mv88e6xxx_chip *chip)
-{
-	u16 reg;
-	int err;
-
-	/* Ignore removed tag data on doubly tagged packets, disable
-	 * flow control messages, force flow control priority to the
-	 * highest, and send all special multicast frames to the CPU
-	 * port at the highest priority.
-	 */
-	reg = MV88E6XXX_G2_SWITCH_MGMT_FORCE_FLOW_CTL_PRI | (0x7 << 4);
-	err = mv88e6xxx_g2_write(chip, MV88E6XXX_G2_SWITCH_MGMT, reg);
-	if (err)
-		return err;
-
-	return 0;
-}
diff --git a/drivers/net/dsa/mv88e6xxx/global2.h b/drivers/net/dsa/mv88e6xxx/global2.h
index 46913a289255..37e8ce2c72a0 100644
--- a/drivers/net/dsa/mv88e6xxx/global2.h
+++ b/drivers/net/dsa/mv88e6xxx/global2.h
@@ -314,7 +314,6 @@ int mv88e6xxx_g2_pvt_write(struct mv88e6xxx_chip *chip, int src_dev,
 			   int src_port, u16 data);
 int mv88e6xxx_g2_misc_4_bit_port(struct mv88e6xxx_chip *chip);
 
-int mv88e6xxx_g2_setup(struct mv88e6xxx_chip *chip);
 int mv88e6xxx_g2_irq_setup(struct mv88e6xxx_chip *chip);
 void mv88e6xxx_g2_irq_free(struct mv88e6xxx_chip *chip);
 
@@ -447,11 +446,6 @@ static inline int mv88e6xxx_g2_misc_4_bit_port(struct mv88e6xxx_chip *chip)
 	return -EOPNOTSUPP;
 }
 
-static inline int mv88e6xxx_g2_setup(struct mv88e6xxx_chip *chip)
-{
-	return -EOPNOTSUPP;
-}
-
 static inline int mv88e6xxx_g2_irq_setup(struct mv88e6xxx_chip *chip)
 {
 	return -EOPNOTSUPP;
-- 
2.17.0

^ permalink raw reply related

* Greeting,
From: Ms Zeliha Omer Faruk @ 2018-04-27  2:29 UTC (permalink / raw)





Hello

   Greetings to you today i asked before but i did't get a response please
i know this might come to you as a surprise because you do not know me
personally i have a business proposal for you please reply for more
info.



Best Regards,

Esentepe Mahallesi Büyükdere
Caddesi Kristal Kule Binasi
No:215
 Sisli - Istanbul, Turkey

^ permalink raw reply

* Re: [PATCH 2/2] net: stmmac: dwmac-meson: extend phy mode setting
From: Yixun Lan @ 2018-04-27  3:09 UTC (permalink / raw)
  To: Jerome Brunet, David S. Miller, netdev
  Cc: yixun.lan, Kevin Hilman, Carlo Caione, Rob Herring,
	Martin Blumenstingl, linux-amlogic, linux-arm-kernel,
	linux-kernel
In-Reply-To: <1524732426.4026.84.camel@baylibre.com>

Hi Jerome
On 04/26/18 16:47, Jerome Brunet wrote:
> On Thu, 2018-04-26 at 16:05 +0000, Yixun Lan wrote:
>>   In the Meson-AXG SoC, the phy mode setting of PRG_ETH0 in the glue layer
>> is extended from bit[0] to bit[2:0].
>>   There is no problem if we configure it to the RGMII 1000M PHY mode,
>> since the register setting is coincidentally compatible with previous one,
>> but for the RMII 100M PHY mode, the configuration need to be changed to
>> value - b100.
>>   This patch was verified with a RTL8201F 100M ethernet PHY.
>>
>> Signed-off-by: Yixun Lan <yixun.lan@amlogic.com>
>> ---
>>  .../ethernet/stmicro/stmmac/dwmac-meson8b.c   | 95 ++++++++++++++++---
>>  1 file changed, 84 insertions(+), 11 deletions(-)
>>
>> diff --git a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
>> index 7cb794094a70..e3688b6dd87c 100644
>> --- a/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
>> +++ b/drivers/net/ethernet/stmicro/stmmac/dwmac-meson8b.c
>> @@ -18,6 +18,7 @@
>>  #include <linux/io.h>
>>  #include <linux/ioport.h>
>>  #include <linux/module.h>
>> +#include <linux/of_device.h>
>>  #include <linux/of_net.h>
>>  #include <linux/mfd/syscon.h>
>>  #include <linux/platform_device.h>
>> @@ -29,6 +30,10 @@
>>  
>>  #define PRG_ETH0_RGMII_MODE		BIT(0)
>>  
>> +#define PRG_ETH0_EXT_PHY_MODE_MASK	GENMASK(2, 0)
>> +#define PRG_ETH0_EXT_RGMII_MODE		1
>> +#define PRG_ETH0_EXT_RMII_MODE		4
>> +
>>  /* mux to choose between fclk_div2 (bit unset) and mpll2 (bit set) */
>>  #define PRG_ETH0_CLK_M250_SEL_SHIFT	4
>>  #define PRG_ETH0_CLK_M250_SEL_MASK	GENMASK(4, 4)
>> @@ -46,10 +51,16 @@
>>  #define PRG_ETH0_TX_AND_PHY_REF_CLK	BIT(12)
>>  
>>  #define MUX_CLK_NUM_PARENTS		2
>> +struct meson8b_dwmac_data {
>> +	bool ext_phy_mode;
>> +};
>>  
>>  struct meson8b_dwmac {
>>  	struct device		*dev;
>>  	void __iomem		*regs;
>> +
>> +	const struct meson8b_dwmac_data *data;
>> +
>>  	phy_interface_t		phy_mode;
>>  	struct clk		*rgmii_tx_clk;
>>  	u32			tx_delay_ns;
>> @@ -171,6 +182,46 @@ static int meson8b_init_rgmii_tx_clk(struct meson8b_dwmac *dwmac)
>>  	return 0;
>>  }
>>  
>> +static int meson8b_init_set_mode(struct meson8b_dwmac *dwmac)
>> +{
>> +	bool ext_phy_mode = dwmac->data->ext_phy_mode;
>> +
>> +	switch (dwmac->phy_mode) {
>> +	case PHY_INTERFACE_MODE_RGMII:
>> +	case PHY_INTERFACE_MODE_RGMII_RXID:
>> +	case PHY_INTERFACE_MODE_RGMII_ID:
>> +	case PHY_INTERFACE_MODE_RGMII_TXID:
>> +		/* enable RGMII mode */
>> +		if (ext_phy_mode)
> 
> Looks weird to have this if target at a specific SoC withing a function named
> after another SoC
> 
> Couldn't you make one function per soc type, and pass that function pointer in
> the match data ?
> 
sounds good, I can do this

>> +			meson8b_dwmac_mask_bits(dwmac, PRG_ETH0,
>> +						PRG_ETH0_EXT_PHY_MODE_MASK,
>> +						PRG_ETH0_EXT_RGMII_MODE);
>> +		else
>> +			meson8b_dwmac_mask_bits(dwmac, PRG_ETH0,
>> +						PRG_ETH0_RGMII_MODE,
>> +						PRG_ETH0_RGMII_MODE);
>> +
>> +		break;
>> +	case PHY_INTERFACE_MODE_RMII:
>> +		/* disable RGMII mode -> enables RMII mode */
>> +		if (ext_phy_mode)
>> +			meson8b_dwmac_mask_bits(dwmac, PRG_ETH0,
>> +						PRG_ETH0_EXT_PHY_MODE_MASK,
>> +						PRG_ETH0_EXT_RMII_MODE);
>> +		else
>> +			meson8b_dwmac_mask_bits(dwmac, PRG_ETH0,
>> +						PRG_ETH0_RGMII_MODE, 0);
>> +
>> +		break;
>> +	default:
>> +		dev_err(dwmac->dev, "fail to set phy-mode %s\n",
>> +			phy_modes(dwmac->phy_mode));
>> +		return -EINVAL;
>> +	}
>> +
>> +	return 0;
>> +}
>> +
>>  static int meson8b_init_prg_eth(struct meson8b_dwmac *dwmac)
>>  {
>>  	int ret;
>> @@ -188,10 +239,6 @@ static int meson8b_init_prg_eth(struct meson8b_dwmac *dwmac)
>>  
>>  	case PHY_INTERFACE_MODE_RGMII_ID:
>>  	case PHY_INTERFACE_MODE_RGMII_TXID:
>> -		/* enable RGMII mode */
>> -		meson8b_dwmac_mask_bits(dwmac, PRG_ETH0, PRG_ETH0_RGMII_MODE,
>> -					PRG_ETH0_RGMII_MODE);
>> -
>>  		/* only relevant for RMII mode -> disable in RGMII mode */
>>  		meson8b_dwmac_mask_bits(dwmac, PRG_ETH0,
>>  					PRG_ETH0_INVERTED_RMII_CLK, 0);
>> @@ -224,10 +271,6 @@ static int meson8b_init_prg_eth(struct meson8b_dwmac *dwmac)
>>  		break;
>>  
>>  	case PHY_INTERFACE_MODE_RMII:
>> -		/* disable RGMII mode -> enables RMII mode */
>> -		meson8b_dwmac_mask_bits(dwmac, PRG_ETH0, PRG_ETH0_RGMII_MODE,
>> -					0);
>> -
>>  		/* invert internal clk_rmii_i to generate 25/2.5 tx_rx_clk */
>>  		meson8b_dwmac_mask_bits(dwmac, PRG_ETH0,
>>  					PRG_ETH0_INVERTED_RMII_CLK,
>> @@ -274,6 +317,11 @@ static int meson8b_dwmac_probe(struct platform_device *pdev)
>>  		goto err_remove_config_dt;
>>  	}
>>  
>> +	dwmac->data = (const struct meson8b_dwmac_data *)
>> +		of_device_get_match_data(&pdev->dev);
>> +	if (!dwmac->data)
>> +		return -EINVAL;
>> +
>>  	res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
>>  	dwmac->regs = devm_ioremap_resource(&pdev->dev, res);
>>  	if (IS_ERR(dwmac->regs)) {
>> @@ -298,6 +346,10 @@ static int meson8b_dwmac_probe(struct platform_device *pdev)
>>  	if (ret)
>>  		goto err_remove_config_dt;
>>  
>> +	ret = meson8b_init_set_mode(dwmac);
>> +	if (ret)
>> +		goto err_remove_config_dt;
>> +
>>  	ret = meson8b_init_prg_eth(dwmac);
>>  	if (ret)
>>  		goto err_remove_config_dt;
>> @@ -316,10 +368,31 @@ static int meson8b_dwmac_probe(struct platform_device *pdev)
>>  	return ret;
>>  }
>>  
>> +static const struct meson8b_dwmac_data meson8b_dwmac_data = {
>> +	.ext_phy_mode = false,
>> +};
>> +
>> +static const struct meson8b_dwmac_data meson_axg_dwmac_data = {
>> +	.ext_phy_mode = true,
>> +};
>> +
>>  static const struct of_device_id meson8b_dwmac_match[] = {
>> -	{ .compatible = "amlogic,meson8b-dwmac" },
>> -	{ .compatible = "amlogic,meson8m2-dwmac" },
>> -	{ .compatible = "amlogic,meson-gxbb-dwmac" },
>> +	{
>> +		.compatible = "amlogic,meson8b-dwmac",
>> +		.data = &meson8b_dwmac_data,
>> +	},
>> +	{
>> +		.compatible = "amlogic,meson8m2-dwmac",
>> +		.data = &meson8b_dwmac_data,
>> +	},
>> +	{
>> +		.compatible = "amlogic,meson-gxbb-dwmac",
>> +		.data = &meson8b_dwmac_data,
>> +	},
>> +	{
>> +		.compatible = "amlogic,meson-axg-dwmac",
>> +		.data = &meson_axg_dwmac_data,
>> +	},
>>  	{ }
>>  };
>>  MODULE_DEVICE_TABLE(of, meson8b_dwmac_match);
> 
> .
> 

^ permalink raw reply

* Re: [PATCH] net: phy: marvell: clear wol event before setting it
From: Bhadram Varka @ 2018-04-27  3:52 UTC (permalink / raw)
  To: Andrew Lunn, Jisheng Zhang
  Cc: Florian Fainelli, David S. Miller, netdev, linux-kernel,
	Jingju Hou
In-Reply-To: <20180426124007.GC13467@lunn.ch>

Hi Andrew/Jisheng,

On 4/26/2018 6:10 PM, Andrew Lunn wrote:
>> hmm, so you want a "stick" WOL feature, I dunno whether Linux kernel
>> requires WOL should be "stick".
> I see two different cases:
>
> Suspend/resume: The WoL state in the kernel is probably kept across
> such a cycle. If so, you would expect another suspend/resume to also
> work, without needs to reconfigure it.
Trying this scenario (suspend/resume) from my side. In this case WoL 
should be enabled in the HW. For Marvell PHY to generate WoL interrupt 
we need to clear WoL status.
Above mentioned change required to make this happen. Please share your 
thoughts on this.
>
> Boot from powered off: If the interrupt just enables the power supply,
> it is possible to wake up after a shutdown. There is no state kept, so
> WoL will be disabled in the kernel. So WoL should also be disabled in
> the hardware.
>
>      Andrew

^ permalink raw reply

* Re: [RFC v3 0/5] virtio: support packed ring
From: Jason Wang @ 2018-04-27  3:56 UTC (permalink / raw)
  To: Tiwei Bie, mst, virtualization, linux-kernel, netdev; +Cc: wexu, jfreimann
In-Reply-To: <20180425051550.24342-1-tiwei.bie@intel.com>



On 2018年04月25日 13:15, Tiwei Bie wrote:
> Hello everyone,
>
> This RFC implements packed ring support in virtio driver.
>
> Some simple functional tests have been done with Jason's
> packed ring implementation in vhost:
>
> https://lkml.org/lkml/2018/4/23/12
>
> Both of ping and netperf worked as expected (with EVENT_IDX
> disabled). But there are below known issues:
>
> 1. Reloading the guest driver will break the Tx/Rx;

Will have a look at this issue.

> 2. Zeroing the flags when detaching a used desc will
>     break the guest -> host path.

I still think zeroing flags is unnecessary or even a bug. At host, I 
track last observed avail wrap counter and detect avail like (what is 
suggested in the example code in the spec):

static bool desc_is_avail(struct vhost_virtqueue *vq, __virtio16 flags)
{
        bool avail = flags & cpu_to_vhost16(vq, DESC_AVAIL);

        return avail == vq->avail_wrap_counter;
}

So zeroing wrap can not work with this obviously.

Thanks

>
> Some simple functional tests have also been done with
> Wei's packed ring implementation in QEMU:
>
> http://lists.nongnu.org/archive/html/qemu-devel/2018-04/msg00342.html
>
> Both of ping and netperf worked as expected (with EVENT_IDX
> disabled). Reloading the guest driver also worked as expected.
>
> TODO:
> - Refinements (for code and commit log) and bug fixes;
> - Discuss/fix/test EVENT_IDX support;
> - Test devices other than net;
>
> RFC v2 -> RFC v3:
> - Split into small patches (Jason);
> - Add helper virtqueue_use_indirect() (Jason);
> - Just set id for the last descriptor of a list (Jason);
> - Calculate the prev in virtqueue_add_packed() (Jason);
> - Fix/improve desc suppression code (Jason/MST);
> - Refine the code layout for XXX_split/packed and wrappers (MST);
> - Fix the comments and API in uapi (MST);
> - Remove the BUG_ON() for indirect (Jason);
> - Some other refinements and bug fixes;
>
> RFC v1 -> RFC v2:
> - Add indirect descriptor support - compile test only;
> - Add event suppression supprt - compile test only;
> - Move vring_packed_init() out of uapi (Jason, MST);
> - Merge two loops into one in virtqueue_add_packed() (Jason);
> - Split vring_unmap_one() for packed ring and split ring (Jason);
> - Avoid using '%' operator (Jason);
> - Rename free_head -> next_avail_idx (Jason);
> - Add comments for virtio_wmb() in virtqueue_add_packed() (Jason);
> - Some other refinements and bug fixes;
>
> Thanks!
>
> Tiwei Bie (5):
>    virtio: add packed ring definitions
>    virtio_ring: support creating packed ring
>    virtio_ring: add packed ring support
>    virtio_ring: add event idx support in packed ring
>    virtio_ring: enable packed ring
>
>   drivers/virtio/virtio_ring.c       | 1271 ++++++++++++++++++++++++++++--------
>   include/linux/virtio_ring.h        |    8 +-
>   include/uapi/linux/virtio_config.h |   12 +-
>   include/uapi/linux/virtio_ring.h   |   36 +
>   4 files changed, 1049 insertions(+), 278 deletions(-)
>

^ permalink raw reply

* Re: [RFC v3 0/5] virtio: support packed ring
From: Michael S. Tsirkin @ 2018-04-27  4:18 UTC (permalink / raw)
  To: Jason Wang
  Cc: Tiwei Bie, virtualization, linux-kernel, netdev, wexu, jfreimann
In-Reply-To: <5ad1ca01-1e5c-7105-f303-7e8d42f6a068@redhat.com>

On Fri, Apr 27, 2018 at 11:56:05AM +0800, Jason Wang wrote:
> 
> 
> On 2018年04月25日 13:15, Tiwei Bie wrote:
> > Hello everyone,
> > 
> > This RFC implements packed ring support in virtio driver.
> > 
> > Some simple functional tests have been done with Jason's
> > packed ring implementation in vhost:
> > 
> > https://lkml.org/lkml/2018/4/23/12
> > 
> > Both of ping and netperf worked as expected (with EVENT_IDX
> > disabled). But there are below known issues:
> > 
> > 1. Reloading the guest driver will break the Tx/Rx;
> 
> Will have a look at this issue.
> 
> > 2. Zeroing the flags when detaching a used desc will
> >     break the guest -> host path.
> 
> I still think zeroing flags is unnecessary or even a bug. At host, I track
> last observed avail wrap counter and detect avail like (what is suggested in
> the example code in the spec):
> 
> static bool desc_is_avail(struct vhost_virtqueue *vq, __virtio16 flags)
> {
>        bool avail = flags & cpu_to_vhost16(vq, DESC_AVAIL);
> 
>        return avail == vq->avail_wrap_counter;
> }
> 
> So zeroing wrap can not work with this obviously.
> 
> Thanks

I agree. I think what one should do is flip the available bit.

> > 
> > Some simple functional tests have also been done with
> > Wei's packed ring implementation in QEMU:
> > 
> > http://lists.nongnu.org/archive/html/qemu-devel/2018-04/msg00342.html
> > 
> > Both of ping and netperf worked as expected (with EVENT_IDX
> > disabled). Reloading the guest driver also worked as expected.
> > 
> > TODO:
> > - Refinements (for code and commit log) and bug fixes;
> > - Discuss/fix/test EVENT_IDX support;
> > - Test devices other than net;
> > 
> > RFC v2 -> RFC v3:
> > - Split into small patches (Jason);
> > - Add helper virtqueue_use_indirect() (Jason);
> > - Just set id for the last descriptor of a list (Jason);
> > - Calculate the prev in virtqueue_add_packed() (Jason);
> > - Fix/improve desc suppression code (Jason/MST);
> > - Refine the code layout for XXX_split/packed and wrappers (MST);
> > - Fix the comments and API in uapi (MST);
> > - Remove the BUG_ON() for indirect (Jason);
> > - Some other refinements and bug fixes;
> > 
> > RFC v1 -> RFC v2:
> > - Add indirect descriptor support - compile test only;
> > - Add event suppression supprt - compile test only;
> > - Move vring_packed_init() out of uapi (Jason, MST);
> > - Merge two loops into one in virtqueue_add_packed() (Jason);
> > - Split vring_unmap_one() for packed ring and split ring (Jason);
> > - Avoid using '%' operator (Jason);
> > - Rename free_head -> next_avail_idx (Jason);
> > - Add comments for virtio_wmb() in virtqueue_add_packed() (Jason);
> > - Some other refinements and bug fixes;
> > 
> > Thanks!
> > 
> > Tiwei Bie (5):
> >    virtio: add packed ring definitions
> >    virtio_ring: support creating packed ring
> >    virtio_ring: add packed ring support
> >    virtio_ring: add event idx support in packed ring
> >    virtio_ring: enable packed ring
> > 
> >   drivers/virtio/virtio_ring.c       | 1271 ++++++++++++++++++++++++++++--------
> >   include/linux/virtio_ring.h        |    8 +-
> >   include/uapi/linux/virtio_config.h |   12 +-
> >   include/uapi/linux/virtio_ring.h   |   36 +
> >   4 files changed, 1049 insertions(+), 278 deletions(-)
> > 

^ permalink raw reply

* [PATCH v3] net: qrtr: Expose tunneling endpoint to user space
From: Bjorn Andersson @ 2018-04-27  5:28 UTC (permalink / raw)
  To: David S. Miller, Chris Lew; +Cc: linux-kernel, netdev, linux-arm-msm

This implements a misc character device named "qrtr-tun" for the purpose
of allowing user space applications to implement endpoints in the qrtr
network.

This allows more advanced (and dynamic) testing of the qrtr code as well
as opens up the ability of tunneling qrtr over a network or USB link.

Signed-off-by: Bjorn Andersson <bjorn.andersson@linaro.org>
---

Changes since v2:
- Add support for read poll

Changes since v1:
- Dropped queue lock

 net/qrtr/Kconfig  |   7 +++
 net/qrtr/Makefile |   2 +
 net/qrtr/tun.c    | 161 ++++++++++++++++++++++++++++++++++++++++++++++++++++++
 3 files changed, 170 insertions(+)
 create mode 100644 net/qrtr/tun.c

diff --git a/net/qrtr/Kconfig b/net/qrtr/Kconfig
index 326fd97444f5..1944834d225c 100644
--- a/net/qrtr/Kconfig
+++ b/net/qrtr/Kconfig
@@ -21,4 +21,11 @@ config QRTR_SMD
 	  Say Y here to support SMD based ipcrouter channels.  SMD is the
 	  most common transport for IPC Router.
 
+config QRTR_TUN
+	tristate "TUN device for Qualcomm IPC Router"
+	---help---
+	  Say Y here to expose a character device that allows user space to
+	  implement endpoints of QRTR, for purpose of tunneling data to other
+	  hosts or testing purposes.
+
 endif # QRTR
diff --git a/net/qrtr/Makefile b/net/qrtr/Makefile
index ab09e40f7c74..be012bfd3e52 100644
--- a/net/qrtr/Makefile
+++ b/net/qrtr/Makefile
@@ -2,3 +2,5 @@ obj-$(CONFIG_QRTR) := qrtr.o
 
 obj-$(CONFIG_QRTR_SMD) += qrtr-smd.o
 qrtr-smd-y	:= smd.o
+obj-$(CONFIG_QRTR_TUN) += qrtr-tun.o
+qrtr-tun-y	:= tun.o
diff --git a/net/qrtr/tun.c b/net/qrtr/tun.c
new file mode 100644
index 000000000000..ccff1e544c21
--- /dev/null
+++ b/net/qrtr/tun.c
@@ -0,0 +1,161 @@
+// SPDX-License-Identifier: GPL-2.0
+/* Copyright (c) 2018, Linaro Ltd */
+
+#include <linux/miscdevice.h>
+#include <linux/module.h>
+#include <linux/poll.h>
+#include <linux/skbuff.h>
+#include <linux/uaccess.h>
+
+#include "qrtr.h"
+
+struct qrtr_tun {
+	struct qrtr_endpoint ep;
+
+	struct sk_buff_head queue;
+	wait_queue_head_t readq;
+};
+
+static int qrtr_tun_send(struct qrtr_endpoint *ep, struct sk_buff *skb)
+{
+	struct qrtr_tun *tun = container_of(ep, struct qrtr_tun, ep);
+
+	skb_queue_tail(&tun->queue, skb);
+
+	/* wake up any blocking processes, waiting for new data */
+	wake_up_interruptible(&tun->readq);
+
+	return 0;
+}
+
+static int qrtr_tun_open(struct inode *inode, struct file *filp)
+{
+	struct qrtr_tun *tun;
+
+	tun = kzalloc(sizeof(*tun), GFP_KERNEL);
+	if (!tun)
+		return -ENOMEM;
+
+	skb_queue_head_init(&tun->queue);
+	init_waitqueue_head(&tun->readq);
+
+	tun->ep.xmit = qrtr_tun_send;
+
+	filp->private_data = tun;
+
+	return qrtr_endpoint_register(&tun->ep, QRTR_EP_NID_AUTO);
+}
+
+static ssize_t qrtr_tun_read_iter(struct kiocb *iocb, struct iov_iter *to)
+{
+	struct file *filp = iocb->ki_filp;
+	struct qrtr_tun *tun = filp->private_data;
+	struct sk_buff *skb;
+	int count;
+
+	while (!(skb = skb_dequeue(&tun->queue))) {
+		if (filp->f_flags & O_NONBLOCK)
+			return -EAGAIN;
+
+		/* Wait until we get data or the endpoint goes away */
+		if (wait_event_interruptible(tun->readq,
+					     !skb_queue_empty(&tun->queue)))
+			return -ERESTARTSYS;
+	}
+
+	count = min_t(size_t, iov_iter_count(to), skb->len);
+	if (copy_to_iter(skb->data, count, to) != count)
+		count = -EFAULT;
+
+	kfree_skb(skb);
+
+	return count;
+}
+
+static ssize_t qrtr_tun_write_iter(struct kiocb *iocb, struct iov_iter *from)
+{
+	struct file *filp = iocb->ki_filp;
+	struct qrtr_tun *tun = filp->private_data;
+	size_t len = iov_iter_count(from);
+	ssize_t ret;
+	void *kbuf;
+
+	kbuf = kzalloc(len, GFP_KERNEL);
+	if (!kbuf)
+		return -ENOMEM;
+
+	if (!copy_from_iter_full(kbuf, len, from))
+		return -EFAULT;
+
+	ret = qrtr_endpoint_post(&tun->ep, kbuf, len);
+
+	return ret < 0 ? ret : len;
+}
+
+static __poll_t qrtr_tun_poll(struct file *filp, poll_table *wait)
+{
+	struct qrtr_tun *tun = filp->private_data;
+	__poll_t mask = 0;
+
+	poll_wait(filp, &tun->readq, wait);
+
+	if (!skb_queue_empty(&tun->queue))
+		mask |= EPOLLIN | EPOLLRDNORM;
+
+	return mask;
+}
+
+static int qrtr_tun_release(struct inode *inode, struct file *filp)
+{
+	struct qrtr_tun *tun = filp->private_data;
+	struct sk_buff *skb;
+
+	qrtr_endpoint_unregister(&tun->ep);
+
+	/* Discard all SKBs */
+	while (!skb_queue_empty(&tun->queue)) {
+		skb = skb_dequeue(&tun->queue);
+		kfree_skb(skb);
+	}
+
+	kfree(tun);
+
+	return 0;
+}
+
+static const struct file_operations qrtr_tun_ops = {
+	.owner = THIS_MODULE,
+	.open = qrtr_tun_open,
+	.poll = qrtr_tun_poll,
+	.read_iter = qrtr_tun_read_iter,
+	.write_iter = qrtr_tun_write_iter,
+	.release = qrtr_tun_release,
+};
+
+static struct miscdevice qrtr_tun_miscdev = {
+	MISC_DYNAMIC_MINOR,
+	"qrtr-tun",
+	&qrtr_tun_ops,
+};
+
+static int __init qrtr_tun_init(void)
+{
+	int ret;
+
+	ret = misc_register(&qrtr_tun_miscdev);
+	if (ret)
+		pr_err("failed to register Qualcomm IPC Router tun device\n");
+
+	return ret;
+}
+
+static void __exit qrtr_tun_exit(void)
+{
+	misc_deregister(&qrtr_tun_miscdev);
+}
+
+module_init(qrtr_tun_init);
+module_exit(qrtr_tun_exit);
+
+MODULE_DESCRIPTION("Qualcomm IPC Router TUN device");
+MODULE_LICENSE("GPL v2");
-- 
2.16.2

^ permalink raw reply related

* [PATCH v4 net-next 0/3] lan78xx updates along with Fixed phy Support
From: Raghuram Chary J @ 2018-04-27  6:00 UTC (permalink / raw)
  To: davem; +Cc: netdev, unglinuxdriver, woojung.huh, raghuramchary.jallipalli

These series of patches handle few modifications in driver
and adds support for fixed phy.

Raghuram Chary J (3):
  lan78xx: Lan7801 Support for Fixed PHY
  lan78xx: Remove DRIVER_VERSION for lan78xx driver
  lan78xx: Modify error messages

 drivers/net/usb/Kconfig   |   1 +
 drivers/net/usb/lan78xx.c | 106 ++++++++++++++++++++++++++++++++--------------
 2 files changed, 75 insertions(+), 32 deletions(-)

-- 
2.16.2

^ permalink raw reply

* [PATCH v4 net-next 1/3] lan78xx: Lan7801 Support for Fixed PHY
From: Raghuram Chary J @ 2018-04-27  6:00 UTC (permalink / raw)
  To: davem; +Cc: netdev, unglinuxdriver, woojung.huh, raghuramchary.jallipalli
In-Reply-To: <20180427060024.23989-1-raghuramchary.jallipalli@microchip.com>

Adding Fixed PHY support to the lan78xx driver.

Signed-off-by: Raghuram Chary J <raghuramchary.jallipalli@microchip.com>
---
v0->v1:
   * Remove driver version #define
   * Modify netdev_info to netdev_dbg
   * Move lan7801 specific to new routine and add switch case
   * Minor cleanup

v1->v2:
   * Removed fixedphy variable and used phy_is_pseudo_fixed_link() check.
v2->v3:
   * Revert driver version, debug statment changes for separate patch.
   * Modify lan7801 specific routine with return type struct phy_device.
v3->v4:
   * Modify lan7801 specific routine by removing phydev arg and get phydev.
---
 drivers/net/usb/Kconfig   |   1 +
 drivers/net/usb/lan78xx.c | 100 +++++++++++++++++++++++++++++++++-------------
 2 files changed, 73 insertions(+), 28 deletions(-)

diff --git a/drivers/net/usb/Kconfig b/drivers/net/usb/Kconfig
index f28bd74ac275..418b0904cecb 100644
--- a/drivers/net/usb/Kconfig
+++ b/drivers/net/usb/Kconfig
@@ -111,6 +111,7 @@ config USB_LAN78XX
 	select MII
 	select PHYLIB
 	select MICROCHIP_PHY
+	select FIXED_PHY
 	help
 	  This option adds support for Microchip LAN78XX based USB 2
 	  & USB 3 10/100/1000 Ethernet adapters.
diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c
index 0867f7275852..cb35cfa20ca0 100644
--- a/drivers/net/usb/lan78xx.c
+++ b/drivers/net/usb/lan78xx.c
@@ -36,7 +36,7 @@
 #include <linux/irq.h>
 #include <linux/irqchip/chained_irq.h>
 #include <linux/microchipphy.h>
-#include <linux/phy.h>
+#include <linux/phy_fixed.h>
 #include "lan78xx.h"
 
 #define DRIVER_AUTHOR	"WOOJUNG HUH <woojung.huh@microchip.com>"
@@ -2003,52 +2003,91 @@ static int ksz9031rnx_fixup(struct phy_device *phydev)
 	return 1;
 }
 
-static int lan78xx_phy_init(struct lan78xx_net *dev)
+static struct phy_device *lan7801_phy_init(struct lan78xx_net *dev)
 {
+	u32 buf;
 	int ret;
-	u32 mii_adv;
+	struct fixed_phy_status fphy_status = {
+		.link = 1,
+		.speed = SPEED_1000,
+		.duplex = DUPLEX_FULL,
+	};
 	struct phy_device *phydev;
 
 	phydev = phy_find_first(dev->mdiobus);
 	if (!phydev) {
-		netdev_err(dev->net, "no PHY found\n");
-		return -EIO;
-	}
-
-	if ((dev->chipid == ID_REV_CHIP_ID_7800_) ||
-	    (dev->chipid == ID_REV_CHIP_ID_7850_)) {
-		phydev->is_internal = true;
-		dev->interface = PHY_INTERFACE_MODE_GMII;
-
-	} else if (dev->chipid == ID_REV_CHIP_ID_7801_) {
+		netdev_dbg(dev->net, "PHY Not Found!! Registering Fixed PHY\n");
+		phydev = fixed_phy_register(PHY_POLL, &fphy_status, -1,
+					    NULL);
+		if (IS_ERR(phydev)) {
+			netdev_err(dev->net, "No PHY/fixed_PHY found\n");
+			return NULL;
+		}
+		netdev_dbg(dev->net, "Registered FIXED PHY\n");
+		dev->interface = PHY_INTERFACE_MODE_RGMII;
+		ret = lan78xx_write_reg(dev, MAC_RGMII_ID,
+					MAC_RGMII_ID_TXC_DELAY_EN_);
+		ret = lan78xx_write_reg(dev, RGMII_TX_BYP_DLL, 0x3D00);
+		ret = lan78xx_read_reg(dev, HW_CFG, &buf);
+		buf |= HW_CFG_CLK125_EN_;
+		buf |= HW_CFG_REFCLK25_EN_;
+		ret = lan78xx_write_reg(dev, HW_CFG, buf);
+	} else {
 		if (!phydev->drv) {
 			netdev_err(dev->net, "no PHY driver found\n");
-			return -EIO;
+			return NULL;
 		}
-
 		dev->interface = PHY_INTERFACE_MODE_RGMII;
-
 		/* external PHY fixup for KSZ9031RNX */
 		ret = phy_register_fixup_for_uid(PHY_KSZ9031RNX, 0xfffffff0,
 						 ksz9031rnx_fixup);
 		if (ret < 0) {
 			netdev_err(dev->net, "fail to register fixup\n");
-			return ret;
+			return NULL;
 		}
 		/* external PHY fixup for LAN8835 */
 		ret = phy_register_fixup_for_uid(PHY_LAN8835, 0xfffffff0,
 						 lan8835_fixup);
 		if (ret < 0) {
 			netdev_err(dev->net, "fail to register fixup\n");
-			return ret;
+			return NULL;
 		}
 		/* add more external PHY fixup here if needed */
 
 		phydev->is_internal = false;
-	} else {
-		netdev_err(dev->net, "unknown ID found\n");
-		ret = -EIO;
-		goto error;
+	}
+	return phydev;
+}
+
+static int lan78xx_phy_init(struct lan78xx_net *dev)
+{
+	int ret;
+	u32 mii_adv;
+	struct phy_device *phydev;
+
+	switch (dev->chipid) {
+	case ID_REV_CHIP_ID_7801_:
+		phydev = lan7801_phy_init(dev);
+		if (!phydev) {
+			netdev_err(dev->net, "lan7801: PHY Init Failed");
+			return -EIO;
+		}
+		break;
+
+	case ID_REV_CHIP_ID_7800_:
+	case ID_REV_CHIP_ID_7850_:
+		phydev = phy_find_first(dev->mdiobus);
+		if (!phydev) {
+			netdev_err(dev->net, "no PHY found\n");
+			return -EIO;
+		}
+		phydev->is_internal = true;
+		dev->interface = PHY_INTERFACE_MODE_GMII;
+		break;
+
+	default:
+		netdev_err(dev->net, "Unknown CHIP ID found\n");
+		return -EIO;
 	}
 
 	/* if phyirq is not set, use polling mode in phylib */
@@ -2067,6 +2106,12 @@ static int lan78xx_phy_init(struct lan78xx_net *dev)
 	if (ret) {
 		netdev_err(dev->net, "can't attach PHY to %s\n",
 			   dev->mdiobus->id);
+		if (dev->chipid == ID_REV_CHIP_ID_7801_) {
+			phy_unregister_fixup_for_uid(PHY_KSZ9031RNX,
+						     0xfffffff0);
+			phy_unregister_fixup_for_uid(PHY_LAN8835,
+						     0xfffffff0);
+		}
 		return -EIO;
 	}
 
@@ -2084,12 +2129,6 @@ static int lan78xx_phy_init(struct lan78xx_net *dev)
 	dev->fc_autoneg = phydev->autoneg;
 
 	return 0;
-
-error:
-	phy_unregister_fixup_for_uid(PHY_KSZ9031RNX, 0xfffffff0);
-	phy_unregister_fixup_for_uid(PHY_LAN8835, 0xfffffff0);
-
-	return ret;
 }
 
 static int lan78xx_set_rx_max_frame_length(struct lan78xx_net *dev, int size)
@@ -3487,6 +3526,7 @@ static void lan78xx_disconnect(struct usb_interface *intf)
 	struct lan78xx_net		*dev;
 	struct usb_device		*udev;
 	struct net_device		*net;
+	struct phy_device		*phydev;
 
 	dev = usb_get_intfdata(intf);
 	usb_set_intfdata(intf, NULL);
@@ -3495,12 +3535,16 @@ static void lan78xx_disconnect(struct usb_interface *intf)
 
 	udev = interface_to_usbdev(intf);
 	net = dev->net;
+	phydev = net->phydev;
 
 	phy_unregister_fixup_for_uid(PHY_KSZ9031RNX, 0xfffffff0);
 	phy_unregister_fixup_for_uid(PHY_LAN8835, 0xfffffff0);
 
 	phy_disconnect(net->phydev);
 
+	if (phy_is_pseudo_fixed_link(phydev))
+		fixed_phy_unregister(phydev);
+
 	unregister_netdev(net);
 
 	cancel_delayed_work_sync(&dev->wq);
-- 
2.16.2

^ permalink raw reply related

* [PATCH v4 net-next 2/3] lan78xx: Remove DRIVER_VERSION for lan78xx driver
From: Raghuram Chary J @ 2018-04-27  6:00 UTC (permalink / raw)
  To: davem; +Cc: netdev, unglinuxdriver, woojung.huh, raghuramchary.jallipalli
In-Reply-To: <20180427060024.23989-1-raghuramchary.jallipalli@microchip.com>

Remove driver version info from the lan78xx driver.

Signed-off-by: Raghuram Chary J <raghuramchary.jallipalli@microchip.com>
---
 drivers/net/usb/lan78xx.c | 2 --
 1 file changed, 2 deletions(-)

diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c
index cb35cfa20ca0..5da5f0e3cd21 100644
--- a/drivers/net/usb/lan78xx.c
+++ b/drivers/net/usb/lan78xx.c
@@ -42,7 +42,6 @@
 #define DRIVER_AUTHOR	"WOOJUNG HUH <woojung.huh@microchip.com>"
 #define DRIVER_DESC	"LAN78XX USB 3.0 Gigabit Ethernet Devices"
 #define DRIVER_NAME	"lan78xx"
-#define DRIVER_VERSION	"1.0.6"
 
 #define TX_TIMEOUT_JIFFIES		(5 * HZ)
 #define THROTTLE_JIFFIES		(HZ / 8)
@@ -1477,7 +1476,6 @@ static void lan78xx_get_drvinfo(struct net_device *net,
 	struct lan78xx_net *dev = netdev_priv(net);
 
 	strncpy(info->driver, DRIVER_NAME, sizeof(info->driver));
-	strncpy(info->version, DRIVER_VERSION, sizeof(info->version));
 	usb_make_path(dev->udev, info->bus_info, sizeof(info->bus_info));
 }
 
-- 
2.16.2

^ permalink raw reply related

* [PATCH v4 net-next 3/3] lan78xx: Modify error messages
From: Raghuram Chary J @ 2018-04-27  6:00 UTC (permalink / raw)
  To: davem; +Cc: netdev, unglinuxdriver, woojung.huh, raghuramchary.jallipalli
In-Reply-To: <20180427060024.23989-1-raghuramchary.jallipalli@microchip.com>

Modify the error messages when phy registration fails.

Signed-off-by: Raghuram Chary J <raghuramchary.jallipalli@microchip.com>
---
 drivers/net/usb/lan78xx.c | 4 ++--
 1 file changed, 2 insertions(+), 2 deletions(-)

diff --git a/drivers/net/usb/lan78xx.c b/drivers/net/usb/lan78xx.c
index 5da5f0e3cd21..525bb4bf1975 100644
--- a/drivers/net/usb/lan78xx.c
+++ b/drivers/net/usb/lan78xx.c
@@ -2040,14 +2040,14 @@ static struct phy_device *lan7801_phy_init(struct lan78xx_net *dev)
 		ret = phy_register_fixup_for_uid(PHY_KSZ9031RNX, 0xfffffff0,
 						 ksz9031rnx_fixup);
 		if (ret < 0) {
-			netdev_err(dev->net, "fail to register fixup\n");
+			netdev_err(dev->net, "fail to register fixup for PHY_KSZ9031RNX\n");
 			return NULL;
 		}
 		/* external PHY fixup for LAN8835 */
 		ret = phy_register_fixup_for_uid(PHY_LAN8835, 0xfffffff0,
 						 lan8835_fixup);
 		if (ret < 0) {
-			netdev_err(dev->net, "fail to register fixup\n");
+			netdev_err(dev->net, "fail to register fixup for PHY_LAN8835\n");
 			return NULL;
 		}
 		/* add more external PHY fixup here if needed */
-- 
2.16.2

^ permalink raw reply related

* Re: [RFC v3 0/5] virtio: support packed ring
From: Jason Wang @ 2018-04-27  6:17 UTC (permalink / raw)
  To: Michael S. Tsirkin
  Cc: Tiwei Bie, virtualization, linux-kernel, netdev, wexu, jfreimann
In-Reply-To: <20180427071725-mutt-send-email-mst@kernel.org>



On 2018年04月27日 12:18, Michael S. Tsirkin wrote:
> On Fri, Apr 27, 2018 at 11:56:05AM +0800, Jason Wang wrote:
>> On 2018年04月25日 13:15, Tiwei Bie wrote:
>>> Hello everyone,
>>>
>>> This RFC implements packed ring support in virtio driver.
>>>
>>> Some simple functional tests have been done with Jason's
>>> packed ring implementation in vhost:
>>>
>>> https://lkml.org/lkml/2018/4/23/12
>>>
>>> Both of ping and netperf worked as expected (with EVENT_IDX
>>> disabled). But there are below known issues:
>>>
>>> 1. Reloading the guest driver will break the Tx/Rx;
>> Will have a look at this issue.
>>
>>> 2. Zeroing the flags when detaching a used desc will
>>>      break the guest -> host path.
>> I still think zeroing flags is unnecessary or even a bug. At host, I track
>> last observed avail wrap counter and detect avail like (what is suggested in
>> the example code in the spec):
>>
>> static bool desc_is_avail(struct vhost_virtqueue *vq, __virtio16 flags)
>> {
>>         bool avail = flags & cpu_to_vhost16(vq, DESC_AVAIL);
>>
>>         return avail == vq->avail_wrap_counter;
>> }
>>
>> So zeroing wrap can not work with this obviously.
>>
>> Thanks
> I agree. I think what one should do is flip the available bit.
>

But is this flipping a must?

Thanks

^ permalink raw reply

* Re: [PATCH] mac80211_hwsim: fix a possible memory leak in hwsim_new_radio_nl()
From: YueHaibing @ 2018-04-27  6:28 UTC (permalink / raw)
  To: johannes-cdvu00un1VgdHxzADdlk8Q
  Cc: netdev-u79uwXL29TY76Z2rM5mHXA, kvalo-sgV2jX0FEOL9JmXXK+q4OQ,
	linux-wireless-u79uwXL29TY76Z2rM5mHXA,
	ben.hutchings-4yDnlxn2s6sWdaTGBSpHTA
In-Reply-To: <20180424030835.21776-1-yuehaibing-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>


cc  Ben Hutchings <ben.hutchings-4yDnlxn2s6sWdaTGBSpHTA@public.gmane.org>

On 2018/4/24 11:08, YueHaibing wrote:
> 'hwname' should be freed before leaving from the error handling cases,
> otherwise it will cause mem leak
> 
> Fixes: cb1a5bae5684 ("mac80211_hwsim: add permanent mac address option for new radios")
> Signed-off-by: YueHaibing <yuehaibing-hv44wF8Li93QT0dZR+AlfA@public.gmane.org>
> ---
>  drivers/net/wireless/mac80211_hwsim.c | 1 +
>  1 file changed, 1 insertion(+)
> 
> diff --git a/drivers/net/wireless/mac80211_hwsim.c b/drivers/net/wireless/mac80211_hwsim.c
> index 96d26cf..4a017a0 100644
> --- a/drivers/net/wireless/mac80211_hwsim.c
> +++ b/drivers/net/wireless/mac80211_hwsim.c
> @@ -3236,6 +3236,7 @@ static int hwsim_new_radio_nl(struct sk_buff *msg, struct genl_info *info)
>  			GENL_SET_ERR_MSG(info,"MAC is no valid source addr");
>  			NL_SET_BAD_ATTR(info->extack,
>  					info->attrs[HWSIM_ATTR_PERM_ADDR]);
> +			kfree(hwname);
>  			return -EINVAL;
>  		}
>  
> 

^ permalink raw reply

* Re: [PATCH 0/3] can: fix ndo_start_xmit()'s return type
From: Marc Kleine-Budde @ 2018-04-27  7:21 UTC (permalink / raw)
  To: Luc Van Oostenryck
  Cc: Wolfgang Grandegger, Maxime Ripard, Chen-Yu Tsai, Michal Simek,
	open list:CAN NETWORK DRIVERS, open list:NETWORKING DRIVERS,
	open list, moderated list:ARM/Allwinner sunXi SoC support
In-Reply-To: <20180426211339.30821-1-luc.vanoostenryck@gmail.com>


[-- Attachment #1.1: Type: text/plain, Size: 1004 bytes --]

On 04/26/2018 11:13 PM, Luc Van Oostenryck wrote:
> ndo_start_xmit() is defined as returing an 'netdev_tx_t'.
> However, several can drivers use 'int' as the return type
> of their start_xmit() method.
> This series contains the fix for all three of them.
> 
> Luc Van Oostenryck (3):
>   can: janz-ican3: fix ican3_xmit()'s return type
>   can: sun4i: fix sun4ican_start_xmit()'s return type
>   can: xilinx: fix xcan_start_xmit()'s return type
> 
>  drivers/net/can/janz-ican3.c | 2 +-
>  drivers/net/can/sun4i_can.c  | 2 +-
>  drivers/net/can/xilinx_can.c | 2 +-
>  3 files changed, 3 insertions(+), 3 deletions(-)

Applied all 3 to linux-can-next, added similar patch for the flexcan driver.

Tnx,
Marc

-- 
Pengutronix e.K.                  | Marc Kleine-Budde           |
Industrial Linux Solutions        | Phone: +49-231-2826-924     |
Vertretung West/Dortmund          | Fax:   +49-5121-206917-5555 |
Amtsgericht Hildesheim, HRA 2686  | http://www.pengutronix.de   |


[-- Attachment #2: OpenPGP digital signature --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

^ permalink raw reply

* Re: [PATCH] net: phy: marvell: clear wol event before setting it
From: Jisheng Zhang @ 2018-04-27  7:23 UTC (permalink / raw)
  To: Bhadram Varka
  Cc: Andrew Lunn, Florian Fainelli, David S. Miller, netdev,
	linux-kernel, Jingju Hou
In-Reply-To: <7b63b6f5-d93c-f2c8-c448-b81a8323c305@nvidia.com>

On Fri, 27 Apr 2018 09:22:34 +0530 Bhadram Varka wrote:

> Hi Andrew/Jisheng,
> 
> On 4/26/2018 6:10 PM, Andrew Lunn wrote:
> >> hmm, so you want a "stick" WOL feature, I dunno whether Linux kernel
> >> requires WOL should be "stick".  
> > I see two different cases:
> >
> > Suspend/resume: The WoL state in the kernel is probably kept across
> > such a cycle. If so, you would expect another suspend/resume to also
> > work, without needs to reconfigure it.  
> Trying this scenario (suspend/resume) from my side. In this case WoL 
> should be enabled in the HW. For Marvell PHY to generate WoL interrupt 
> we need to clear WoL status.
> Above mentioned change required to make this happen. Please share your 
> thoughts on this.

I'm fine with that patch. Maybe you could send out a patch?

Thanks

^ permalink raw reply

* Re: [PATCH] net: phy: marvell: clear wol event before setting it
From: Jisheng Zhang @ 2018-04-27  7:25 UTC (permalink / raw)
  To: Bhadram Varka
  Cc: Andrew Lunn, Florian Fainelli, David S. Miller, netdev,
	linux-kernel, Jingju Hou
In-Reply-To: <73e21c83-f78a-8b22-a421-f179ef6adef1@nvidia.com>

On Thu, 26 Apr 2018 12:39:59 +0530 Bhadram Varka wrote:

> >>>>>
> >>>>> diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
> >>>>> index c22e8e383247..b6abe1cbc84b 100644
> >>>>> --- a/drivers/net/phy/marvell.c
> >>>>> +++ b/drivers/net/phy/marvell.c
> >>>>> @@ -115,6 +115,9 @@
> >>>>>    /* WOL Event Interrupt Enable */
> >>>>>    #define MII_88E1318S_PHY_CSIER_WOL_EIE BIT(7)
> >>>>>    +/* Copper Specific Interrupt Status Register */
> >>>>> +#define MII_88E1318S_PHY_CSISR                0x13
> >>>>> +
> >>>>>    /* LED Timer Control Register */
> >>>>>    #define MII_88E1318S_PHY_LED_TCR            0x12
> >>>>>    #define MII_88E1318S_PHY_LED_TCR_FORCE_INT BIT(15)
> >>>>> @@ -1393,6 +1396,12 @@ static int m88e1318_set_wol(struct 
> >>>>> phy_device *phydev,
> >>>>>            if (err < 0)
> >>>>>                goto error;
> >>>>>    +        /* If WOL event happened once, the LED[2] interrupt pin
> >>>>> +         * will not be cleared unless reading the CSISR register.
> >>>>> +         * So clear the WOL event first before enabling it.
> >>>>> +         */
> >>>>> +        phy_read(phydev, MII_88E1318S_PHY_CSISR);
> >>>>> +  
> >>>> Hi Jisheng
> >>>>
> >>>> The problem with this is, you could be clearing a real interrupt, link
> >>>> down/up etc. If interrupts are in use, i think the normal interrupt
> >>>> handling will clear the WOL interrupt? So can you make this read
> >>>> conditional on !phy_interrupt_is_valid()?  
> >>> So this will clear WoL interrupt bit from Copper Interrupt status 
> >>> register.
> >>>
> >>> How about clearing WoL status (Page 17, register 17) for every WOL 
> >>> event ?
> >>>  
> >> This is already properly done by setting 
> >> MII_88E1318S_PHY_WOL_CTRL_CLEAR_WOL_STATUS
> >> in m88e1318_set_wol()  
> > This part of the code executes only when we enable WOL through ethtool 
> > (ethtool -s eth0 wol g)
> >
> > Lets say once WOL enabled through magic packet - HW generates WOL 
> > interrupt once magic packet received.
> > The problem that I see here is that for the next immediate magic 
> > packet I don't see WOL interrupt generated by the HW.
> > I need to explicitly clear WOL status for HW to generate WOL interrupt.  
> 
> With the below patch I see WOL event interrupt for every magic packet 
> that HW receives...
> 
> diff --git a/drivers/net/phy/marvell.c b/drivers/net/phy/marvell.c
> index ed8a67d..5d3d138 100644
> --- a/drivers/net/phy/marvell.c
> +++ b/drivers/net/phy/marvell.c
> @@ -55,6 +55,7 @@
> 
>   #define MII_M1011_IEVENT               0x13
>   #define MII_M1011_IEVENT_CLEAR         0x0000
> +#define MII_M1011_IEVENT_WOL_EVENT     BIT(7)
> 
>   #define MII_M1011_IMASK                        0x12
> - #define MII_M1011_IMASK_INIT           0x6400
> + #define MII_M1011_IMASK_INIT           0x6480
> 
> @@ -195,13 +196,40 @@ struct marvell_priv {
>          bool copper;
>   };
> 
> +static int marvell_clear_wol_status(struct phy_device *phydev)
> +{
> +       int err, temp, oldpage;
> +
> +       oldpage = phy_read(phydev, MII_MARVELL_PHY_PAGE);
> +       if (oldpage < 0)
> +               return oldpage;
> +
> +       err = phy_write(phydev, MII_MARVELL_PHY_PAGE,
> +                        MII_88E1318S_PHY_WOL_PAGE);
> +       if (err < 0)
> +               return err;
> +
> +       /*
> +        * Clear WOL status so that for next WOL event
> +        * interrupt will be generated by HW
> +        */
> +       temp = phy_read(phydev, MII_88E1318S_PHY_WOL_CTRL);
> +       temp |= MII_88E1318S_PHY_WOL_CTRL_CLEAR_WOL_STATUS;
> +       err = phy_write(phydev, MII_88E1318S_PHY_WOL_CTRL, temp);

is it better to reuse __phy_write()?

> +       if (err < 0)
> +               return err;
> +
> +
> +       phy_write(phydev, MII_MARVELL_PHY_PAGE, oldpage);
> +
> +       return 0;
> +}
> +
>   static int marvell_ack_interrupt(struct phy_device *phydev)
>   {
>          int err;
> 
>          /* Clear the interrupts by reading the reg */
>          err = phy_read(phydev, MII_M1011_IEVENT);
> -
>          if (err < 0)
>                  return err;
> 
> @@ -1454,12 +1482,18 @@ static int marvell_aneg_done(struct phy_device 
> *phydev)
> 
>   static int m88e1121_did_interrupt(struct phy_device *phydev)
>   {
> -       int imask;
> +       int imask, err;
> 
>          imask = phy_read(phydev, MII_M1011_IEVENT);
> 
> -       if (imask & MII_M1011_IMASK_INIT)
> +       if (imask & MII_M1011_IMASK_INIT) {
> +               if (imask & MII_M1011_IEVENT_WOL_EVENT) {
> +                       err = marvell_clear_wol_status(phydev);
> +                       if (err < 0)
> +                               return 0;
> +               }
>                  return 1;
> +       }
> 
>          return 0;
>   }

^ permalink raw reply


This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox