Netdev List
 help / color / mirror / Atom feed
* Re: [PATCH net-next RFC V1 5/5] net: mdio: Add a driver for InES time stamping IP core.
From: Richard Cochran @ 2018-03-24 17:12 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: netdev, devicetree, David Miller, Florian Fainelli, Mark Rutland,
	Miroslav Lichvar, Rob Herring, Willem de Bruijn
In-Reply-To: <20180321235007.GA28402@lunn.ch>

On Thu, Mar 22, 2018 at 12:50:07AM +0100, Andrew Lunn wrote:
> How clever is this device? Can it tell the difference between
> 1000Base-X and SGMII? Can it figure out that the MAC is repeating
> every bit 100 times and so has dropped to 10Mbits? Does it understand
> EEE? Does it need to know if RGMII or RGMII-ID is being used?

This device isn't configurable at run time for any of those AFAICT.
Those decisions are made when the IP core is synthesized as part of
the HW design.

> Can such a device really operation without the MAC being involved?  My
> feeling is it needs to understand how the MII bus is being used. It
> might also be that the device is less capable than the MAC, so you
> need to turn off some of the MAC features. I think you are going to
> need the MAC actively involved in this.

You are right in that this particular device *does* need to know the
link speed.  I have neglected that part for this RFC.  I'm looking for
a notification based method of informing the device of link speed
changes, but without hacking any MAC driver.

In general, we might see devices one day that care about things like
EEE for example, but let's cross that bridge when we come to it.  In
the case of EEE, when the user enables it via ethtool we can tell the
time stamping device directly without hacking the MAC driver.

Thanks,
Richard

^ permalink raw reply

* Re: [PATCH bpf] tools: bpftool: don't use hex numbers in JSON output
From: Alexei Starovoitov @ 2018-03-24 17:40 UTC (permalink / raw)
  To: Jakub Kicinski; +Cc: daniel, oss-drivers, netdev
In-Reply-To: <20180324024512.20477-1-jakub.kicinski@netronome.com>

On Fri, Mar 23, 2018 at 07:45:12PM -0700, Jakub Kicinski wrote:
> JSON does not accept hex numbers with 0x prefix.  Simply print
> as decimal numbers, JSON should be primarily machine-readable.
> 
> Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
> Reviewed-by: Quentin Monnet <quentin.monnet@netronome.com>
> Fixes: 831a0aafe5c3 ("tools: bpftool: add JSON output for `bpftool map *` commands")

Applied to bpf tree, thanks Jakub.

^ permalink raw reply

* Re: [patch net-next RFC 00/12] devlink: introduce port flavours and common phys_port_name generation
From: Jiri Pirko @ 2018-03-24 17:42 UTC (permalink / raw)
  To: Florian Fainelli
  Cc: Andrew Lunn, netdev, davem, idosch, jakub.kicinski, mlxsw,
	vivien.didelot, michael.chan, ganeshgr, saeedm, simon.horman,
	pieter.jansenvanvuuren, john.hurley, dirk.vandermerwe,
	alexander.h.duyck, ogerlitz, dsahern, vijaya.guvva,
	satananda.burla, raghu.vatsavayi, felix.manlunas, gospo,
	sathya.perla, vasundhara-v.volam, tariqt, eranbe,
	jeffrey.t.kirsher
In-Reply-To: <D017986F-35B3-4B33-B2FF-97103AA9964A@gmail.com>

Sat, Mar 24, 2018 at 06:07:27PM CET, f.fainelli@gmail.com wrote:
>On March 24, 2018 9:07:49 AM PDT, Jiri Pirko <jiri@resnulli.us> wrote:
>>Sat, Mar 24, 2018 at 03:35:09PM CET, f.fainelli@gmail.com wrote:
>>>On March 24, 2018 12:45:51 AM PDT, Jiri Pirko <jiri@resnulli.us>
>>wrote:
>>>>Fri, Mar 23, 2018 at 04:24:12PM CET, andrew@lunn.ch wrote:
>>>>>On Fri, Mar 23, 2018 at 03:59:35PM +0100, Jiri Pirko wrote:
>>>>>> Fri, Mar 23, 2018 at 02:43:57PM CET, andrew@lunn.ch wrote:
>>>>>> >> I tested this for mlxsw and nfp. I have no way to test this on
>>>>DSA hw,
>>>>>> >> I would really appretiate DSA guys to test this.
>>>>>> >
>>>>>> >Hi Jiri
>>>>>> >
>>>>>> >With the missing break added, i get:
>>>>>> >
>>>>>> >root@zii-devel-b:~# ./iproute2/devlink/devlink port 
>>>>>> >mdio_bus/0.1:00/0: type eth netdev lan0 flavour physical number 0
>>>>>> >mdio_bus/0.1:00/1: type eth netdev lan1 flavour physical number 1
>>>>>> >mdio_bus/0.1:00/2: type eth netdev lan2 flavour physical number 2
>>>>>> >mdio_bus/0.1:00/3: type notset
>>>>>> >mdio_bus/0.1:00/4: type notset
>>>>>> >mdio_bus/0.1:00/5: type notset flavour dsa number 5
>>>>>> >mdio_bus/0.1:00/6: type notset flavour cpu number 6
>>>>>> >mdio_bus/0.2:00/0: type eth netdev lan3 flavour physical number 0
>>>>>> >mdio_bus/0.2:00/1: type eth netdev lan4 flavour physical number 1
>>>>>> >mdio_bus/0.2:00/2: type eth netdev lan5 flavour physical number 2
>>>>>> >mdio_bus/0.2:00/3: type notset
>>>>>> >mdio_bus/0.2:00/4: type notset
>>>>>> >mdio_bus/0.2:00/5: type notset flavour dsa number 5
>>>>>> >mdio_bus/0.2:00/6: type notset flavour dsa number 6
>>>>>> >mdio_bus/0.4:00/0: type eth netdev lan6 flavour physical number 0
>>>>>> >mdio_bus/0.4:00/1: type eth netdev lan7 flavour physical number 1
>>>>>> >mdio_bus/0.4:00/2: type eth netdev lan8 flavour physical number 2
>>>>>> >mdio_bus/0.4:00/3: type eth netdev optical3 flavour physical
>>number
>>>>3
>>>>>> >mdio_bus/0.4:00/4: type eth netdev optical4 flavour physical
>>number
>>>>4
>>>>>> >mdio_bus/0.4:00/5: type notset
>>>>>> >mdio_bus/0.4:00/6: type notset
>>>>>> >mdio_bus/0.4:00/7: type notset
>>>>>> >mdio_bus/0.4:00/8: type notset
>>>>>> >mdio_bus/0.4:00/9: type notset flavour dsa number 9
>>>>>
>>>>>> That is basically front panel number for physical ports.
>>>>>
>>>>>You cannot make that assumption. As you can see here, we have 3
>>ports
>>>>>with the number 0.
>>>>>
>>>>>Look at clearfog, armada-388-clearfog.dts. port 0=lan5, port 1=lan4
>>>>>port 2=lan3, port 3=lan2, port 4=lan1, port 5=cpu, port 6=lan6.
>>>>>
>>>>>The hardware and mechanical engineer is free to wire switch ports to
>>>>>the front panel however they want. That is why we put the netdev
>>name
>>>>>in device tree.
>>>>
>>>>Got it. Hmm, so I think that the port number can be made optional and
>>>>when it is present, it would be used to generate phys_port_name. If
>>>>not, perhaps devlink port index could be used instead.
>>>>
>>>>So iiuc, you don't really need phys_port_name in dsa, as it provides
>>>>misleading names, right? Why is it implemented then?
>>>
>>>We do need phys_port_name because there are switch configuration
>>operations, e.g: ethtool::rxnfc which take a port number and queue
>>number as part of the action to redirect a packet for instance. There
>>is no way to obtain this physical port number other than either knowing
>>it and hard coding it (not great) or scanning the device tree and look
>>for the "reg" property value. phys_port_name gets you that and it is
>>easy for an application to scan /sys/class/net/ on startup to get to
>>know that (and other stuff as well).
>>
>>Hmm. That sounds like misuse of phys_port_name. The original purpose
>>was
>>to provide names as they are actually written on the front panel.
>
>Ok, if we look back at the history of the changes I had implemented ndo_phys_port_id() to return the port number initially, but this was wrong and reverted based on your feedback, and then ndo_phys_port_name() was implemented with your reviewed-by tag:
>
>https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/net/dsa/slave.c?id=3a543ef479868e36c95935de320608a7e41466ca
>https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/net/dsa/slave.c?id=592050b2541407d033da18226d3644644832d082
>https://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git/commit/net/dsa/slave.c?id=592050b2541407d033da18226d3644644832d082
>
>Now that this is reported through sysfs it unfortunately becomes ABI and we should not be breaking user applications relying on that and there is at least one I know of...
>
>What is an appropriate attribute to use to return the physical port number within a given switch?

I don't think there's one out there. I tried to add it in this patchset.

^ permalink raw reply

* Re: [PATCH bpf] nfp: bpf: fix check of program max insn count
From: Alexei Starovoitov @ 2018-03-24 17:44 UTC (permalink / raw)
  To: Jakub Kicinski; +Cc: daniel, oss-drivers, netdev
In-Reply-To: <20180324030013.26436-1-jakub.kicinski@netronome.com>

On Fri, Mar 23, 2018 at 08:00:13PM -0700, Jakub Kicinski wrote:
> NFP program allocation length is in bytes and NFP program length
> is in instructions, fix the comparison of the two.
> 
> Fixes: 9314c442d7dd ("nfp: bpf: move translation prepare to offload.c")
> Signed-off-by: Jakub Kicinski <jakub.kicinski@netronome.com>
> Reviewed-by: Jiong Wang <jiong.wang@netronome.com>

Applied to bpf tree, thanks Jakub.

^ permalink raw reply

* [iproute PATCH] ssfilter: Eliminate shift/reduce conflicts
From: Phil Sutter @ 2018-03-24 17:45 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev

The problematic bit was the 'expr: expr expr' rule. Fix this by making
'expr' token represent a single filter only and introduce a new token
'exprlist' to represent a combination of filters.

Signed-off-by: Phil Sutter <phil@nwl.cc>
---
 misc/ssfilter.y | 52 +++++++++++++++++++++++++++-------------------------
 1 file changed, 27 insertions(+), 25 deletions(-)

diff --git a/misc/ssfilter.y b/misc/ssfilter.y
index 4db3c95faa3cc..88d4229a9b241 100644
--- a/misc/ssfilter.y
+++ b/misc/ssfilter.y
@@ -42,7 +42,7 @@ static void yyerror(char *s)
 %nonassoc '!'
 
 %%
-applet: null expr
+applet: null exprlist
         {
                 *yy_ret = $2;
                 $$ = $2;
@@ -51,6 +51,32 @@ applet: null expr
         ;
 null:   /* NOTHING */ { $$ = NULL; }
         ;
+exprlist: expr
+        | '!' expr
+        {
+                $$ = alloc_node(SSF_NOT, $2);
+        }
+        | '(' exprlist ')'
+        {
+                $$ = $2;
+        }
+        | exprlist '|' expr
+        {
+                $$ = alloc_node(SSF_OR, $1);
+                $$->post = $3;
+        }
+        | exprlist '&' expr
+        {
+                $$ = alloc_node(SSF_AND, $1);
+                $$->post = $3;
+        }
+        | exprlist expr
+        {
+                $$ = alloc_node(SSF_AND, $1);
+                $$->post = $2;
+        }
+        ;
+
 expr:	DCOND HOSTCOND
         {
 		$$ = alloc_node(SSF_DCOND, $2);
@@ -128,30 +154,6 @@ expr:	DCOND HOSTCOND
         {
                 $$ = alloc_node(SSF_S_AUTO, NULL);
         }
-        | expr '|' expr
-        {
-                $$ = alloc_node(SSF_OR, $1);
-	        $$->post = $3;
-        }
-        | expr expr
-        {
-                $$ = alloc_node(SSF_AND, $1);
-	        $$->post = $2;
-        }
-        | expr '&' expr
-
-        {
-                $$ = alloc_node(SSF_AND, $1);
-	        $$->post = $3;
-        }
-        | '!' expr
-        {
-                $$ = alloc_node(SSF_NOT, $2);
-        }
-        | '(' expr ')'
-        {
-                $$ = $2;
-        }
 ;
 %%
 
-- 
2.16.1

^ permalink raw reply related

* [iproute PATCH 2/3] ss: Put filter DB parsing into a separate function
From: Phil Sutter @ 2018-03-24 18:18 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev
In-Reply-To: <20180324181811.22615-1-phil@nwl.cc>

Use a table for database name parsing. The tricky bit is to allow for
association of a (nearly) arbitrary number of DBs with each name.
Luckily the number is not fully arbitrary as there is an upper bound of
MAX_DB items. Since it is not possible to have a variable length
array inside a variable length array, use this knowledge to make the
inner array of fixed length. But since DB values start from zero, an
explicit end entry needs to be present as well, so the inner array has
to be MAX_DB + 1 in size.

Signed-off-by: Phil Sutter <phil@nwl.cc>
---
 misc/ss.c | 114 ++++++++++++++++++++++++++++++--------------------------------
 1 file changed, 56 insertions(+), 58 deletions(-)

diff --git a/misc/ss.c b/misc/ss.c
index 2044776ba310b..e6511014ba3f4 100644
--- a/misc/ss.c
+++ b/misc/ss.c
@@ -340,6 +340,61 @@ static void filter_db_set(struct filter *f, int db, bool enable)
 	do_default   = 0;
 }
 
+static int filter_db_parse(struct filter *f, const char *s)
+{
+	const struct {
+		const char *name;
+		int dbs[MAX_DB + 1];
+	} db_name_tbl[] = {
+#define ENTRY(name, ...) { #name, { __VA_ARGS__, MAX_DB }}
+		ENTRY(all, UDP_DB, DCCP_DB, TCP_DB, RAW_DB, \
+			   UNIX_ST_DB, UNIX_DG_DB, UNIX_SQ_DB, \
+			   PACKET_R_DB, PACKET_DG_DB, NETLINK_DB, \
+			   SCTP_DB, VSOCK_ST_DB, VSOCK_DG_DB),
+		ENTRY(inet, UDP_DB, DCCP_DB, TCP_DB, SCTP_DB, RAW_DB),
+		ENTRY(udp, UDP_DB),
+		ENTRY(dccp, DCCP_DB),
+		ENTRY(tcp, TCP_DB),
+		ENTRY(sctp, SCTP_DB),
+		ENTRY(raw, RAW_DB),
+		ENTRY(unix, UNIX_ST_DB, UNIX_DG_DB, UNIX_SQ_DB),
+		ENTRY(unix_stream, UNIX_ST_DB),
+		ENTRY(u_str, UNIX_ST_DB),	/* alias for unix_stream */
+		ENTRY(unix_dgram, UNIX_DG_DB),
+		ENTRY(u_dgr, UNIX_DG_DB),	/* alias for unix_dgram */
+		ENTRY(unix_seqpacket, UNIX_SQ_DB),
+		ENTRY(u_seq, UNIX_SQ_DB),	/* alias for unix_seqpacket */
+		ENTRY(packet, PACKET_R_DB, PACKET_DG_DB),
+		ENTRY(packet_raw, PACKET_R_DB),
+		ENTRY(p_raw, PACKET_R_DB),	/* alias for packet_raw */
+		ENTRY(packet_dgram, PACKET_DG_DB),
+		ENTRY(p_dgr, PACKET_DG_DB),	/* alias for packet_dgram */
+		ENTRY(netlink, NETLINK_DB),
+		ENTRY(vsock, VSOCK_ST_DB, VSOCK_DG_DB),
+		ENTRY(vsock_stream, VSOCK_ST_DB),
+		ENTRY(v_str, VSOCK_ST_DB),	/* alias for vsock_stream */
+		ENTRY(vsock_dgram, VSOCK_DG_DB),
+		ENTRY(v_dgr, VSOCK_DG_DB),	/* alias for vsock_dgram */
+#undef ENTRY
+	};
+	bool enable = true;
+	unsigned int i;
+	const int *dbp;
+
+	if (s[0] == '!') {
+		enable = false;
+		s++;
+	}
+	for (i = 0; i < ARRAY_SIZE(db_name_tbl); i++) {
+		if (strcmp(s, db_name_tbl[i].name))
+			continue;
+		for (dbp = db_name_tbl[i].dbs; *dbp != MAX_DB; dbp++)
+			filter_db_set(f, *dbp, enable);
+		return 0;
+	}
+	return -1;
+}
+
 static void filter_af_set(struct filter *f, int af)
 {
 	f->states	   |= default_afs[af].states;
@@ -4757,66 +4812,9 @@ int main(int argc, char *argv[])
 			}
 			p = p1 = optarg;
 			do {
-				bool enable = true;
-
 				if ((p1 = strchr(p, ',')) != NULL)
 					*p1 = 0;
-				if (p[0] == '!') {
-					enable = false;
-					p++;
-				}
-				if (strcmp(p, "all") == 0) {
-					filter_default_dbs(&current_filter, enable);
-				} else if (strcmp(p, "inet") == 0) {
-					filter_db_set(&current_filter, UDP_DB, enable);
-					filter_db_set(&current_filter, DCCP_DB, enable);
-					filter_db_set(&current_filter, TCP_DB, enable);
-					filter_db_set(&current_filter, SCTP_DB, enable);
-					filter_db_set(&current_filter, RAW_DB, enable);
-				} else if (strcmp(p, "udp") == 0) {
-					filter_db_set(&current_filter, UDP_DB, enable);
-				} else if (strcmp(p, "dccp") == 0) {
-					filter_db_set(&current_filter, DCCP_DB, enable);
-				} else if (strcmp(p, "tcp") == 0) {
-					filter_db_set(&current_filter, TCP_DB, enable);
-				} else if (strcmp(p, "sctp") == 0) {
-					filter_db_set(&current_filter, SCTP_DB, enable);
-				} else if (strcmp(p, "raw") == 0) {
-					filter_db_set(&current_filter, RAW_DB, enable);
-				} else if (strcmp(p, "unix") == 0) {
-					filter_db_set(&current_filter, UNIX_ST_DB, enable);
-					filter_db_set(&current_filter, UNIX_DG_DB, enable);
-					filter_db_set(&current_filter, UNIX_SQ_DB, enable);
-				} else if (strcasecmp(p, "unix_stream") == 0 ||
-					   strcmp(p, "u_str") == 0) {
-					filter_db_set(&current_filter, UNIX_ST_DB, enable);
-				} else if (strcasecmp(p, "unix_dgram") == 0 ||
-					   strcmp(p, "u_dgr") == 0) {
-					filter_db_set(&current_filter, UNIX_DG_DB, enable);
-				} else if (strcasecmp(p, "unix_seqpacket") == 0 ||
-					   strcmp(p, "u_seq") == 0) {
-					filter_db_set(&current_filter, UNIX_SQ_DB, enable);
-				} else if (strcmp(p, "packet") == 0) {
-					filter_db_set(&current_filter, PACKET_R_DB, enable);
-					filter_db_set(&current_filter, PACKET_DG_DB, enable);
-				} else if (strcmp(p, "packet_raw") == 0 ||
-					   strcmp(p, "p_raw") == 0) {
-					filter_db_set(&current_filter, PACKET_R_DB, enable);
-				} else if (strcmp(p, "packet_dgram") == 0 ||
-					   strcmp(p, "p_dgr") == 0) {
-					filter_db_set(&current_filter, PACKET_DG_DB, enable);
-				} else if (strcmp(p, "netlink") == 0) {
-					filter_db_set(&current_filter, NETLINK_DB, enable);
-				} else if (strcmp(p, "vsock") == 0) {
-					filter_db_set(&current_filter, VSOCK_ST_DB, enable);
-					filter_db_set(&current_filter, VSOCK_DG_DB, enable);
-				} else if (strcmp(p, "vsock_stream") == 0 ||
-					   strcmp(p, "v_str") == 0) {
-					filter_db_set(&current_filter, VSOCK_ST_DB, enable);
-				} else if (strcmp(p, "vsock_dgram") == 0 ||
-					   strcmp(p, "v_dgr") == 0) {
-					filter_db_set(&current_filter, VSOCK_DG_DB, enable);
-				} else {
+				if (filter_db_parse(&current_filter, p)) {
 					fprintf(stderr, "ss: \"%s\" is illegal socket table id\n", p);
 					usage();
 				}
-- 
2.16.1

^ permalink raw reply related

* [iproute PATCH 3/3] ss: Drop filter_default_dbs()
From: Phil Sutter @ 2018-03-24 18:18 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev
In-Reply-To: <20180324181811.22615-1-phil@nwl.cc>

Instead call filter_db_parse(..., "all"). This eliminates the duplicate
default DB definition.

Signed-off-by: Phil Sutter <phil@nwl.cc>
---
 misc/ss.c | 19 +------------------
 1 file changed, 1 insertion(+), 18 deletions(-)

diff --git a/misc/ss.c b/misc/ss.c
index e6511014ba3f4..ab2f07b9e5d4d 100644
--- a/misc/ss.c
+++ b/misc/ss.c
@@ -408,23 +408,6 @@ static int filter_af_get(struct filter *f, int af)
 	return !!(f->families & FAMILY_MASK(af));
 }
 
-static void filter_default_dbs(struct filter *f, bool enable)
-{
-	filter_db_set(f, UDP_DB, enable);
-	filter_db_set(f, DCCP_DB, enable);
-	filter_db_set(f, TCP_DB, enable);
-	filter_db_set(f, RAW_DB, enable);
-	filter_db_set(f, UNIX_ST_DB, enable);
-	filter_db_set(f, UNIX_DG_DB, enable);
-	filter_db_set(f, UNIX_SQ_DB, enable);
-	filter_db_set(f, PACKET_R_DB, enable);
-	filter_db_set(f, PACKET_DG_DB, enable);
-	filter_db_set(f, NETLINK_DB, enable);
-	filter_db_set(f, SCTP_DB, enable);
-	filter_db_set(f, VSOCK_ST_DB, enable);
-	filter_db_set(f, VSOCK_DG_DB, enable);
-}
-
 static void filter_states_set(struct filter *f, int states)
 {
 	if (states)
@@ -4906,7 +4889,7 @@ int main(int argc, char *argv[])
 
 	if (do_default) {
 		state_filter = state_filter ? state_filter : SS_CONN;
-		filter_default_dbs(&current_filter, true);
+		filter_db_parse(&current_filter, "all");
 	}
 
 	filter_states_set(&current_filter, state_filter);
-- 
2.16.1

^ permalink raw reply related

* [iproute PATCH 1/3] ss: Allow excluding a socket table from being queried
From: Phil Sutter @ 2018-03-24 18:18 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev
In-Reply-To: <20180324181811.22615-1-phil@nwl.cc>

The original problem was that a simple call to 'ss' leads to loading of
sctp_diag kernel module which might not be desired. While searching for
a workaround, it became clear how inconvenient it is to exclude a single
socket table from being queried.

This patch allows to prefix an item passed to '-A' parameter with an
exclamation mark to inverse its meaning.

Signed-off-by: Phil Sutter <phil@nwl.cc>
---
 man/man8/ss.8 |   8 ++++-
 misc/ss.c     | 108 ++++++++++++++++++++++++++++++++--------------------------
 2 files changed, 66 insertions(+), 50 deletions(-)

diff --git a/man/man8/ss.8 b/man/man8/ss.8
index 973afbe0b386b..28033d8f01dda 100644
--- a/man/man8/ss.8
+++ b/man/man8/ss.8
@@ -317,7 +317,10 @@ Currently the following families are supported: unix, inet, inet6, link, netlink
 List of socket tables to dump, separated by commas. The following identifiers
 are understood: all, inet, tcp, udp, raw, unix, packet, netlink, unix_dgram,
 unix_stream, unix_seqpacket, packet_raw, packet_dgram, dccp, sctp,
-vsock_stream, vsock_dgram.
+vsock_stream, vsock_dgram. Any item in the list may optionally be prefixed by
+an exclamation mark
+.RB ( ! )
+to exclude that socket table from being dumped.
 .TP
 .B \-D FILE, \-\-diag=FILE
 Do not display anything, just dump raw information about TCP sockets to FILE after applying filters. If FILE is - stdout is used.
@@ -380,6 +383,9 @@ Find all local processes connected to X server.
 .TP
 .B ss -o state fin-wait-1 '( sport = :http or sport = :https )' dst 193.233.7/24
 List all the tcp sockets in state FIN-WAIT-1 for our apache to network 193.233.7/24 and look at their timers.
+.TP
+.B ss -a -A 'all,!tcp'
+List sockets in all states from all socket tables but TCP.
 .SH SEE ALSO
 .BR ip (8),
 .br
diff --git a/misc/ss.c b/misc/ss.c
index e087bef739b0d..2044776ba310b 100644
--- a/misc/ss.c
+++ b/misc/ss.c
@@ -329,10 +329,14 @@ static const struct filter default_afs[AF_MAX] = {
 static int do_default = 1;
 static struct filter current_filter;
 
-static void filter_db_set(struct filter *f, int db)
+static void filter_db_set(struct filter *f, int db, bool enable)
 {
-	f->states   |= default_dbs[db].states;
-	f->dbs	    |= 1 << db;
+	if (enable) {
+		f->states   |= default_dbs[db].states;
+		f->dbs	    |= 1 << db;
+	} else {
+		f->dbs &= ~(1 << db);
+	}
 	do_default   = 0;
 }
 
@@ -349,21 +353,21 @@ static int filter_af_get(struct filter *f, int af)
 	return !!(f->families & FAMILY_MASK(af));
 }
 
-static void filter_default_dbs(struct filter *f)
+static void filter_default_dbs(struct filter *f, bool enable)
 {
-	filter_db_set(f, UDP_DB);
-	filter_db_set(f, DCCP_DB);
-	filter_db_set(f, TCP_DB);
-	filter_db_set(f, RAW_DB);
-	filter_db_set(f, UNIX_ST_DB);
-	filter_db_set(f, UNIX_DG_DB);
-	filter_db_set(f, UNIX_SQ_DB);
-	filter_db_set(f, PACKET_R_DB);
-	filter_db_set(f, PACKET_DG_DB);
-	filter_db_set(f, NETLINK_DB);
-	filter_db_set(f, SCTP_DB);
-	filter_db_set(f, VSOCK_ST_DB);
-	filter_db_set(f, VSOCK_DG_DB);
+	filter_db_set(f, UDP_DB, enable);
+	filter_db_set(f, DCCP_DB, enable);
+	filter_db_set(f, TCP_DB, enable);
+	filter_db_set(f, RAW_DB, enable);
+	filter_db_set(f, UNIX_ST_DB, enable);
+	filter_db_set(f, UNIX_DG_DB, enable);
+	filter_db_set(f, UNIX_SQ_DB, enable);
+	filter_db_set(f, PACKET_R_DB, enable);
+	filter_db_set(f, PACKET_DG_DB, enable);
+	filter_db_set(f, NETLINK_DB, enable);
+	filter_db_set(f, SCTP_DB, enable);
+	filter_db_set(f, VSOCK_ST_DB, enable);
+	filter_db_set(f, VSOCK_DG_DB, enable);
 }
 
 static void filter_states_set(struct filter *f, int states)
@@ -4684,19 +4688,19 @@ int main(int argc, char *argv[])
 			follow_events = 1;
 			break;
 		case 'd':
-			filter_db_set(&current_filter, DCCP_DB);
+			filter_db_set(&current_filter, DCCP_DB, true);
 			break;
 		case 't':
-			filter_db_set(&current_filter, TCP_DB);
+			filter_db_set(&current_filter, TCP_DB, true);
 			break;
 		case 'S':
-			filter_db_set(&current_filter, SCTP_DB);
+			filter_db_set(&current_filter, SCTP_DB, true);
 			break;
 		case 'u':
-			filter_db_set(&current_filter, UDP_DB);
+			filter_db_set(&current_filter, UDP_DB, true);
 			break;
 		case 'w':
-			filter_db_set(&current_filter, RAW_DB);
+			filter_db_set(&current_filter, RAW_DB, true);
 			break;
 		case 'x':
 			filter_af_set(&current_filter, AF_UNIX);
@@ -4753,59 +4757,65 @@ int main(int argc, char *argv[])
 			}
 			p = p1 = optarg;
 			do {
+				bool enable = true;
+
 				if ((p1 = strchr(p, ',')) != NULL)
 					*p1 = 0;
+				if (p[0] == '!') {
+					enable = false;
+					p++;
+				}
 				if (strcmp(p, "all") == 0) {
-					filter_default_dbs(&current_filter);
+					filter_default_dbs(&current_filter, enable);
 				} else if (strcmp(p, "inet") == 0) {
-					filter_db_set(&current_filter, UDP_DB);
-					filter_db_set(&current_filter, DCCP_DB);
-					filter_db_set(&current_filter, TCP_DB);
-					filter_db_set(&current_filter, SCTP_DB);
-					filter_db_set(&current_filter, RAW_DB);
+					filter_db_set(&current_filter, UDP_DB, enable);
+					filter_db_set(&current_filter, DCCP_DB, enable);
+					filter_db_set(&current_filter, TCP_DB, enable);
+					filter_db_set(&current_filter, SCTP_DB, enable);
+					filter_db_set(&current_filter, RAW_DB, enable);
 				} else if (strcmp(p, "udp") == 0) {
-					filter_db_set(&current_filter, UDP_DB);
+					filter_db_set(&current_filter, UDP_DB, enable);
 				} else if (strcmp(p, "dccp") == 0) {
-					filter_db_set(&current_filter, DCCP_DB);
+					filter_db_set(&current_filter, DCCP_DB, enable);
 				} else if (strcmp(p, "tcp") == 0) {
-					filter_db_set(&current_filter, TCP_DB);
+					filter_db_set(&current_filter, TCP_DB, enable);
 				} else if (strcmp(p, "sctp") == 0) {
-					filter_db_set(&current_filter, SCTP_DB);
+					filter_db_set(&current_filter, SCTP_DB, enable);
 				} else if (strcmp(p, "raw") == 0) {
-					filter_db_set(&current_filter, RAW_DB);
+					filter_db_set(&current_filter, RAW_DB, enable);
 				} else if (strcmp(p, "unix") == 0) {
-					filter_db_set(&current_filter, UNIX_ST_DB);
-					filter_db_set(&current_filter, UNIX_DG_DB);
-					filter_db_set(&current_filter, UNIX_SQ_DB);
+					filter_db_set(&current_filter, UNIX_ST_DB, enable);
+					filter_db_set(&current_filter, UNIX_DG_DB, enable);
+					filter_db_set(&current_filter, UNIX_SQ_DB, enable);
 				} else if (strcasecmp(p, "unix_stream") == 0 ||
 					   strcmp(p, "u_str") == 0) {
-					filter_db_set(&current_filter, UNIX_ST_DB);
+					filter_db_set(&current_filter, UNIX_ST_DB, enable);
 				} else if (strcasecmp(p, "unix_dgram") == 0 ||
 					   strcmp(p, "u_dgr") == 0) {
-					filter_db_set(&current_filter, UNIX_DG_DB);
+					filter_db_set(&current_filter, UNIX_DG_DB, enable);
 				} else if (strcasecmp(p, "unix_seqpacket") == 0 ||
 					   strcmp(p, "u_seq") == 0) {
-					filter_db_set(&current_filter, UNIX_SQ_DB);
+					filter_db_set(&current_filter, UNIX_SQ_DB, enable);
 				} else if (strcmp(p, "packet") == 0) {
-					filter_db_set(&current_filter, PACKET_R_DB);
-					filter_db_set(&current_filter, PACKET_DG_DB);
+					filter_db_set(&current_filter, PACKET_R_DB, enable);
+					filter_db_set(&current_filter, PACKET_DG_DB, enable);
 				} else if (strcmp(p, "packet_raw") == 0 ||
 					   strcmp(p, "p_raw") == 0) {
-					filter_db_set(&current_filter, PACKET_R_DB);
+					filter_db_set(&current_filter, PACKET_R_DB, enable);
 				} else if (strcmp(p, "packet_dgram") == 0 ||
 					   strcmp(p, "p_dgr") == 0) {
-					filter_db_set(&current_filter, PACKET_DG_DB);
+					filter_db_set(&current_filter, PACKET_DG_DB, enable);
 				} else if (strcmp(p, "netlink") == 0) {
-					filter_db_set(&current_filter, NETLINK_DB);
+					filter_db_set(&current_filter, NETLINK_DB, enable);
 				} else if (strcmp(p, "vsock") == 0) {
-					filter_db_set(&current_filter, VSOCK_ST_DB);
-					filter_db_set(&current_filter, VSOCK_DG_DB);
+					filter_db_set(&current_filter, VSOCK_ST_DB, enable);
+					filter_db_set(&current_filter, VSOCK_DG_DB, enable);
 				} else if (strcmp(p, "vsock_stream") == 0 ||
 					   strcmp(p, "v_str") == 0) {
-					filter_db_set(&current_filter, VSOCK_ST_DB);
+					filter_db_set(&current_filter, VSOCK_ST_DB, enable);
 				} else if (strcmp(p, "vsock_dgram") == 0 ||
 					   strcmp(p, "v_dgr") == 0) {
-					filter_db_set(&current_filter, VSOCK_DG_DB);
+					filter_db_set(&current_filter, VSOCK_DG_DB, enable);
 				} else {
 					fprintf(stderr, "ss: \"%s\" is illegal socket table id\n", p);
 					usage();
@@ -4898,7 +4908,7 @@ int main(int argc, char *argv[])
 
 	if (do_default) {
 		state_filter = state_filter ? state_filter : SS_CONN;
-		filter_default_dbs(&current_filter);
+		filter_default_dbs(&current_filter, true);
 	}
 
 	filter_states_set(&current_filter, state_filter);
-- 
2.16.1

^ permalink raw reply related

* [iproute PATCH 0/3] ss: Allow excluding a socket table from being queried
From: Phil Sutter @ 2018-03-24 18:18 UTC (permalink / raw)
  To: Stephen Hemminger; +Cc: netdev

The first patch in this series adds the new functionality, the remaining
two refactor the code a bit.

Phil Sutter (3):
  ss: Allow excluding a socket table from being queried
  ss: Put filter DB parsing into a separate function
  ss: Drop filter_default_dbs()

 man/man8/ss.8 |   8 +++-
 misc/ss.c     | 147 +++++++++++++++++++++++++++-------------------------------
 2 files changed, 76 insertions(+), 79 deletions(-)

-- 
2.16.1

^ permalink raw reply

* [PATCH bpf-next 0/2] bpf_verifier_log changes
From: Martin KaFai Lau @ 2018-03-24 18:44 UTC (permalink / raw)
  To: netdev; +Cc: Alexei Starovoitov, Daniel Borkmann, kernel-team

This patch set has some changes and clean-up works for
the bpf_verifier_log.  They are the prep works for the
BTF (BPF Type Format).

Martin KaFai Lau (2):
  bpf: Rename bpf_verifer_log
  bpf: Add bpf_verifier_vlog() and bpf_verifier_log_needed()

 include/linux/bpf_verifier.h | 13 ++++++++++---
 kernel/bpf/verifier.c        | 21 ++++++++++++---------
 2 files changed, 22 insertions(+), 12 deletions(-)

-- 
2.9.5

^ permalink raw reply

* [PATCH bpf-next 1/2] bpf: Rename bpf_verifer_log
From: Martin KaFai Lau @ 2018-03-24 18:44 UTC (permalink / raw)
  To: netdev; +Cc: Alexei Starovoitov, Daniel Borkmann, kernel-team
In-Reply-To: <20180324184423.3053682-1-kafai@fb.com>

bpf_verifer_log =>
bpf_verifier_log

Signed-off-by: Martin KaFai Lau <kafai@fb.com>
Acked-by: Alexei Starovoitov <ast@fb.com>
---
 include/linux/bpf_verifier.h | 6 +++---
 kernel/bpf/verifier.c        | 4 ++--
 2 files changed, 5 insertions(+), 5 deletions(-)

diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h
index 6b66cd1aa0b9..c30668414b22 100644
--- a/include/linux/bpf_verifier.h
+++ b/include/linux/bpf_verifier.h
@@ -153,7 +153,7 @@ struct bpf_insn_aux_data {
 
 #define BPF_VERIFIER_TMP_LOG_SIZE	1024
 
-struct bpf_verifer_log {
+struct bpf_verifier_log {
 	u32 level;
 	char kbuf[BPF_VERIFIER_TMP_LOG_SIZE];
 	char __user *ubuf;
@@ -161,7 +161,7 @@ struct bpf_verifer_log {
 	u32 len_total;
 };
 
-static inline bool bpf_verifier_log_full(const struct bpf_verifer_log *log)
+static inline bool bpf_verifier_log_full(const struct bpf_verifier_log *log)
 {
 	return log->len_used >= log->len_total - 1;
 }
@@ -185,7 +185,7 @@ struct bpf_verifier_env {
 	bool allow_ptr_leaks;
 	bool seen_direct_write;
 	struct bpf_insn_aux_data *insn_aux_data; /* array of per-insn state */
-	struct bpf_verifer_log log;
+	struct bpf_verifier_log log;
 	u32 subprog_starts[BPF_MAX_SUBPROGS];
 	/* computes the stack depth of each bpf function */
 	u16 subprog_stack_depth[BPF_MAX_SUBPROGS + 1];
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index e93a6e48641b..1e84e02ff733 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -171,7 +171,7 @@ static DEFINE_MUTEX(bpf_verifier_lock);
 static void log_write(struct bpf_verifier_env *env, const char *fmt,
 		      va_list args)
 {
-	struct bpf_verifer_log *log = &env->log;
+	struct bpf_verifier_log *log = &env->log;
 	unsigned int n;
 
 	if (!log->level || !log->ubuf || bpf_verifier_log_full(log))
@@ -5611,7 +5611,7 @@ static void free_states(struct bpf_verifier_env *env)
 int bpf_check(struct bpf_prog **prog, union bpf_attr *attr)
 {
 	struct bpf_verifier_env *env;
-	struct bpf_verifer_log *log;
+	struct bpf_verifier_log *log;
 	int ret = -EINVAL;
 
 	/* no program is valid */
-- 
2.9.5

^ permalink raw reply related

* [PATCH bpf-next 2/2] bpf: Add bpf_verifier_vlog() and bpf_verifier_log_needed()
From: Martin KaFai Lau @ 2018-03-24 18:44 UTC (permalink / raw)
  To: netdev; +Cc: Alexei Starovoitov, Daniel Borkmann, kernel-team
In-Reply-To: <20180324184423.3053682-1-kafai@fb.com>

The BTF (BPF Type Format) verifier needs to reuse the current
BPF verifier log.  Hence, it requires the following changes:

(1) Expose log_write() in verifier.c for other users.
    Its name is renamed to bpf_verifier_vlog().

(2) The BTF verifier also needs to check
'log->level && log->ubuf && !bpf_verifier_log_full(log);'
independently outside of the current log_write().  It is
because the BTF verifier will do one-check before
making multiple calls to btf_verifier_vlog to log
the details of a type.

Hence, this check is also re-factored to a new function
bpf_verifier_log_needed().  Since it is re-factored,
we can check it before va_start() in the current
bpf_verifier_log_write() and verbose().

Signed-off-by: Martin KaFai Lau <kafai@fb.com>
Acked-by: Alexei Starovoitov <ast@fb.com>
---
 include/linux/bpf_verifier.h |  7 +++++++
 kernel/bpf/verifier.c        | 19 +++++++++++--------
 2 files changed, 18 insertions(+), 8 deletions(-)

diff --git a/include/linux/bpf_verifier.h b/include/linux/bpf_verifier.h
index c30668414b22..7e61c395fddf 100644
--- a/include/linux/bpf_verifier.h
+++ b/include/linux/bpf_verifier.h
@@ -166,6 +166,11 @@ static inline bool bpf_verifier_log_full(const struct bpf_verifier_log *log)
 	return log->len_used >= log->len_total - 1;
 }
 
+static inline bool bpf_verifier_log_needed(const struct bpf_verifier_log *log)
+{
+	return log->level && log->ubuf && !bpf_verifier_log_full(log);
+}
+
 #define BPF_MAX_SUBPROGS 256
 
 /* single container for all structs
@@ -192,6 +197,8 @@ struct bpf_verifier_env {
 	u32 subprog_cnt;
 };
 
+void bpf_verifier_vlog(struct bpf_verifier_log *log, const char *fmt,
+		       va_list args);
 __printf(2, 3) void bpf_verifier_log_write(struct bpf_verifier_env *env,
 					   const char *fmt, ...);
 
diff --git a/kernel/bpf/verifier.c b/kernel/bpf/verifier.c
index 1e84e02ff733..8acd2207e412 100644
--- a/kernel/bpf/verifier.c
+++ b/kernel/bpf/verifier.c
@@ -168,15 +168,11 @@ struct bpf_call_arg_meta {
 
 static DEFINE_MUTEX(bpf_verifier_lock);
 
-static void log_write(struct bpf_verifier_env *env, const char *fmt,
-		      va_list args)
+void bpf_verifier_vlog(struct bpf_verifier_log *log, const char *fmt,
+		       va_list args)
 {
-	struct bpf_verifier_log *log = &env->log;
 	unsigned int n;
 
-	if (!log->level || !log->ubuf || bpf_verifier_log_full(log))
-		return;
-
 	n = vscnprintf(log->kbuf, BPF_VERIFIER_TMP_LOG_SIZE, fmt, args);
 
 	WARN_ONCE(n >= BPF_VERIFIER_TMP_LOG_SIZE - 1,
@@ -200,18 +196,25 @@ __printf(2, 3) void bpf_verifier_log_write(struct bpf_verifier_env *env,
 {
 	va_list args;
 
+	if (!bpf_verifier_log_needed(&env->log))
+		return;
+
 	va_start(args, fmt);
-	log_write(env, fmt, args);
+	bpf_verifier_vlog(&env->log, fmt, args);
 	va_end(args);
 }
 EXPORT_SYMBOL_GPL(bpf_verifier_log_write);
 
 __printf(2, 3) static void verbose(void *private_data, const char *fmt, ...)
 {
+	struct bpf_verifier_env *env = private_data;
 	va_list args;
 
+	if (!bpf_verifier_log_needed(&env->log))
+		return;
+
 	va_start(args, fmt);
-	log_write(private_data, fmt, args);
+	bpf_verifier_vlog(&env->log, fmt, args);
 	va_end(args);
 }
 
-- 
2.9.5

^ permalink raw reply related

* Re: [PATCH net-next RFC V1 5/5] net: mdio: Add a driver for InES time stamping IP core.
From: Andrew Lunn @ 2018-03-24 18:48 UTC (permalink / raw)
  To: Richard Cochran
  Cc: netdev, devicetree, David Miller, Florian Fainelli, Mark Rutland,
	Miroslav Lichvar, Rob Herring, Willem de Bruijn
In-Reply-To: <20180324171219.vh6wcxbem3hyhkuu@localhost>

On Sat, Mar 24, 2018 at 10:12:19AM -0700, Richard Cochran wrote:
> On Thu, Mar 22, 2018 at 12:50:07AM +0100, Andrew Lunn wrote:
> > How clever is this device? Can it tell the difference between
> > 1000Base-X and SGMII? Can it figure out that the MAC is repeating
> > every bit 100 times and so has dropped to 10Mbits? Does it understand
> > EEE? Does it need to know if RGMII or RGMII-ID is being used?
> 
> This device isn't configurable at run time for any of those AFAICT.
> Those decisions are made when the IP core is synthesized as part of
> the HW design.

Hi Richard

Should we be designing an API for this specific device, or should we
think of the general case?

The general case would be a device which passes through MII signals,
and has some sort of control interface.

The control interface could be MMIO as here, MDIO, I2C, SPI, etc.

The MII interfaces could be MII, RMII, GMII, RGMII, SGMII, QSGMII,
XGMII, etc. Generally, a device which can do GMII can also do RGMII,
etc.

The device probably needs to know about the MII bus. If it is
synthesized as part of the hardware design, it might be able to get
this information directly from the MAC IP core. An external device
probably needs to be told. Especially when it comes to RGII, where the
clocking is 'interesting'.

As you already said, you need to know link speed. Do we want to be
able to restrict the MAC to specific link speeds? The Marvell MACs can
do a 2.5Gbps SGMII, by speeding up the clock. I can image a PTP device
not supporting this, the MII breaks, but PHY looks happy. To limit
this cleanly, you at least need to mask out the unsupported auto-neg
offered speeds.

With EEE there is probably two cases:

1) The PTP device understands it, but needs to be told it has been enabled.
2) The PTP device breaks when EEE is enabled, so EEE needs to be disabled.

To me, 1) seems pretty unlikely. But 2) is possible. Disabling EEE
again means changing the auto-neg parameters, so that EEE is not
offered.

As far as i can see, you have three basic problems:

1) How do you associate the PTP device to the netdev?
2) How do you get the information you need to configure the PTP device
3) How do you limit the MAC/PHY to what the PTP device can do.

For 1) you need some sort of phandle, either in the MAC, or the PHY
section of device tree. There is currently no generic code for
handling MAC OF nodes. phylib however does do all the generic work for
PHY nodes in DT.

2) you can get some of the information you need via notifiers. e.g,
NETDEV_CHANGE tells you something has happen, up/down, etc. But i'm
not sure it is 100% reliable. A PHY might be able to do 1G->100M
without going down and back up again, so you don't get a NETDEV_CHANGE
event. There is no notification of how the MII bus is being used.  So
i think notifiers is probably not the best bet.

phylib does have all this information. It is phylib that calls the MAC
with link speed information. When the MAC connects to the PHY, it
passes the MII mode, and when the PHY requests the MII mode changes,
phylib knows. The MAC has to call phy_init_eee() to see if the PHY is
EEE capable. phylib also tells the MAC what speeds the PHY is capable
off, so it is in the position to mask out speeds the PTP device does
not support, etc.

So i really think you need to cleanly integrate into phylib and
phylink.

	Andrew

^ permalink raw reply

* Re: [PATCH] of_net: Implement of_get_nvmem_mac_address helper
From: Andrew Lunn @ 2018-03-24 18:53 UTC (permalink / raw)
  To: Mike Looijmans
  Cc: Florian Fainelli, netdev, linux-kernel, devicetree, robh+dt,
	frowand.list
In-Reply-To: <cb12ea29-a7b0-cf66-7f5a-c09d36f443f0@topic.nl>

> A quick survey for the of_get_mac_address users learns that most of them do
> a memcpy (or similar) right after it, so for these drivers the
> "of_get_nvmem_mac_address" style signature that performs the memcpy (or
> better, ether_addr_copy) is a better fit, e.g.:
> 
> int of_get_mac_address(struct device_node *np, void *addr)

Hi Mike

This is a nicer solution, but it is quite a lot of work, there are a
lot of users. Maybe Coccinelle can help?

    Andrew

^ permalink raw reply

* Re: [patch net-next RFC 00/12] devlink: introduce port flavours and common phys_port_name generation
From: Andrew Lunn @ 2018-03-24 19:00 UTC (permalink / raw)
  To: Jiri Pirko
  Cc: Florian Fainelli, netdev, davem, idosch, jakub.kicinski, mlxsw,
	vivien.didelot, michael.chan, ganeshgr, saeedm, simon.horman,
	pieter.jansenvanvuuren, john.hurley, dirk.vandermerwe,
	alexander.h.duyck, ogerlitz, dsahern, vijaya.guvva,
	satananda.burla, raghu.vatsavayi, felix.manlunas, gospo,
	sathya.perla, vasundhara-v.volam, tariqt, eranbe,
	jeffrey.t.kirsher
In-Reply-To: <20180324174248.GH1891@nanopsycho>

> >>>>>> >root@zii-devel-b:~# ./iproute2/devlink/devlink port 
> >>>>>> >mdio_bus/0.1:00/0: type eth netdev lan0 flavour physical number 0
> >>>>>> >mdio_bus/0.1:00/1: type eth netdev lan1 flavour physical number 1
> >>>>>> >mdio_bus/0.1:00/2: type eth netdev lan2 flavour physical number 2
> >>>>>> >mdio_bus/0.1:00/3: type notset
> >>>>>> >mdio_bus/0.1:00/4: type notset
> >>>>>> >mdio_bus/0.1:00/5: type notset flavour dsa number 5
> >>>>>> >mdio_bus/0.1:00/6: type notset flavour cpu number 6
> >>>>>> >mdio_bus/0.2:00/0: type eth netdev lan3 flavour physical number 0
> >>>>>> >mdio_bus/0.2:00/1: type eth netdev lan4 flavour physical number 1
> >>>>>> >mdio_bus/0.2:00/2: type eth netdev lan5 flavour physical number 2
> >>>>>> >mdio_bus/0.2:00/3: type notset
> >>>>>> >mdio_bus/0.2:00/4: type notset
> >>>>>> >mdio_bus/0.2:00/5: type notset flavour dsa number 5
> >>>>>> >mdio_bus/0.2:00/6: type notset flavour dsa number 6
> >>>>>> >mdio_bus/0.4:00/0: type eth netdev lan6 flavour physical number 0
> >>>>>> >mdio_bus/0.4:00/1: type eth netdev lan7 flavour physical number 1
> >>>>>> >mdio_bus/0.4:00/2: type eth netdev lan8 flavour physical number 2
> >>>>>> >mdio_bus/0.4:00/3: type eth netdev optical3 flavour physical

> >What is an appropriate attribute to use to return the physical port number within a given switch?
> 
> I don't think there's one out there. I tried to add it in this patchset.

Florian, do you need it to be unique per switch, or DSA cluster. The
current solution is clearly not unique across a cluster.

	Andrew

^ permalink raw reply

* Re: switchdev and dsa
From: Andrew Lunn @ 2018-03-24 19:02 UTC (permalink / raw)
  To: Ran Shalit; +Cc: netdev
In-Reply-To: <CAJ2oMhK8FU8hPL6L0B6-Rujz5TXNGXQm7tF9=OtWtMa4ZZX5Tg@mail.gmail.com>

On Sat, Mar 24, 2018 at 07:12:15PM +0300, Ran Shalit wrote:
> Hello,
> 
> I am new with switchdev and dsa.
> I would please like to ask if configuring a device tree/board file
> with a switch (for example marvell switch) will provide all ports
> behins the switch as valid interface (ethX) ports in userspace
> ifconfig command ?

Hi Ranran

Yes, that is the idea.

https://www.netdevconf.org/2.1/session.html?lunn_didelot_fainelli

	Andrew

^ permalink raw reply

* [PATCH 0/2] sh_eth: unify the SoC feature checks
From: Sergei Shtylyov @ 2018-03-24 20:04 UTC (permalink / raw)
  To: netdev; +Cc: linux-renesas-soc, linux-sh

Hello!

Here's a set of 5 patches against DaveM's 'net-next.git' repo.

The Ether driver sometimes uses the bit fields in 'struct sh_eth_cpu_data'
to check which Ether registers exist in a certain SoC and sometimes it uses
sh_eth_is_{gether|rz_fast_ether}() which basically compares 2 pointers (1 of
them being constant) -- the latter is definitely not a strongest feature of
the RISC CPUs (be it SH or ARM), so I decided to get rid of this type of
the feature checks in favour of the bit fields (I've also made use of a
32-bit value and method pointer where appropriate)...

[1/5] sh_eth: add sh_eth_cpu_data::soft_reset() method
[2/5] sh_eth: add sh_eth_cpu_data::edtrr_trns value
[3/5] sh_eth: add sh_eth_cpu_data::xdfar_rw flag
[4/5] sh_eth: add sh_eth_cpu_data::no_tx_cntr flag
[5/5] sh_eth: add sh_eth_cpu_data::cexcr flag

MBR, Sergei

^ permalink raw reply

* Re: [patch net-next RFC 00/12] devlink: introduce port flavours and common phys_port_name generation
From: Florian Fainelli @ 2018-03-24 20:05 UTC (permalink / raw)
  To: Andrew Lunn, Jiri Pirko
  Cc: netdev, davem, idosch, jakub.kicinski, mlxsw, vivien.didelot,
	michael.chan, ganeshgr, saeedm, simon.horman,
	pieter.jansenvanvuuren, john.hurley, dirk.vandermerwe,
	alexander.h.duyck, ogerlitz, dsahern, vijaya.guvva,
	satananda.burla, raghu.vatsavayi, felix.manlunas, gospo,
	sathya.perla, vasundhara-v.volam, tariqt, eranbe,
	jeffrey.t.kirsher
In-Reply-To: <20180324190032.GH31941@lunn.ch>



On 24/03/2018 12:00, Andrew Lunn wrote:
>>>>>>>>> root@zii-devel-b:~# ./iproute2/devlink/devlink port 
>>>>>>>>> mdio_bus/0.1:00/0: type eth netdev lan0 flavour physical number 0
>>>>>>>>> mdio_bus/0.1:00/1: type eth netdev lan1 flavour physical number 1
>>>>>>>>> mdio_bus/0.1:00/2: type eth netdev lan2 flavour physical number 2
>>>>>>>>> mdio_bus/0.1:00/3: type notset
>>>>>>>>> mdio_bus/0.1:00/4: type notset
>>>>>>>>> mdio_bus/0.1:00/5: type notset flavour dsa number 5
>>>>>>>>> mdio_bus/0.1:00/6: type notset flavour cpu number 6
>>>>>>>>> mdio_bus/0.2:00/0: type eth netdev lan3 flavour physical number 0
>>>>>>>>> mdio_bus/0.2:00/1: type eth netdev lan4 flavour physical number 1
>>>>>>>>> mdio_bus/0.2:00/2: type eth netdev lan5 flavour physical number 2
>>>>>>>>> mdio_bus/0.2:00/3: type notset
>>>>>>>>> mdio_bus/0.2:00/4: type notset
>>>>>>>>> mdio_bus/0.2:00/5: type notset flavour dsa number 5
>>>>>>>>> mdio_bus/0.2:00/6: type notset flavour dsa number 6
>>>>>>>>> mdio_bus/0.4:00/0: type eth netdev lan6 flavour physical number 0
>>>>>>>>> mdio_bus/0.4:00/1: type eth netdev lan7 flavour physical number 1
>>>>>>>>> mdio_bus/0.4:00/2: type eth netdev lan8 flavour physical number 2
>>>>>>>>> mdio_bus/0.4:00/3: type eth netdev optical3 flavour physical
> 
>>> What is an appropriate attribute to use to return the physical port number within a given switch?
>>
>> I don't think there's one out there. I tried to add it in this patchset.
> 
> Florian, do you need it to be unique per switch, or DSA cluster. The
> current solution is clearly not unique across a cluster.

It needs to be unique per switch, we have the switch identifier through
phys_switch_id for higher level "uniqueness".
-- 
Florian

^ permalink raw reply

* [PATCH 1/5] sh_eth: add sh_eth_cpu_data::soft_reset() method
From: Sergei Shtylyov @ 2018-03-24 20:07 UTC (permalink / raw)
  To: netdev; +Cc: linux-renesas-soc, linux-sh
In-Reply-To: <b3706a51-27a4-d78b-998d-9440637ac216@cogentembedded.com>

sh_eth_reset() performs a software reset which is implemented in a
completely different way for the GEther-like controllers vs the other
controllers due to a different layout of EDMR (and other factors) --
it therefore makes sense to convert this function to a mandatory
sh_eth_cpu_data::soft_reset() method and thus get rid of the runtime
controller type check via sh_eth_is_{gether|rz_fast_ether}().

Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>

---
 drivers/net/ethernet/renesas/sh_eth.c |  135 ++++++++++++++++++++--------------
 drivers/net/ethernet/renesas/sh_eth.h |    3 
 2 files changed, 83 insertions(+), 55 deletions(-)

Index: net-next/drivers/net/ethernet/renesas/sh_eth.c
===================================================================
--- net-next.orig/drivers/net/ethernet/renesas/sh_eth.c
+++ net-next/drivers/net/ethernet/renesas/sh_eth.c
@@ -501,6 +501,62 @@ static void sh_eth_chip_reset(struct net
 	mdelay(1);
 }
 
+static int sh_eth_soft_reset(struct net_device *ndev)
+{
+	sh_eth_modify(ndev, EDMR, EDMR_SRST_ETHER, EDMR_SRST_ETHER);
+	mdelay(3);
+	sh_eth_modify(ndev, EDMR, EDMR_SRST_ETHER, 0);
+
+	return 0;
+}
+
+static int sh_eth_check_soft_reset(struct net_device *ndev)
+{
+	int cnt;
+
+	for (cnt = 100; cnt > 0; cnt--) {
+		if (!(sh_eth_read(ndev, EDMR) & EDMR_SRST_GETHER))
+			return 0;
+		mdelay(1);
+	}
+
+	netdev_err(ndev, "Device reset failed\n");
+	return -ETIMEDOUT;
+}
+
+static int sh_eth_soft_reset_gether(struct net_device *ndev)
+{
+	struct sh_eth_private *mdp = netdev_priv(ndev);
+	int ret;
+
+	sh_eth_write(ndev, EDSR_ENALL, EDSR);
+	sh_eth_modify(ndev, EDMR, EDMR_SRST_GETHER, EDMR_SRST_GETHER);
+
+	ret = sh_eth_check_soft_reset(ndev);
+	if (ret)
+		return ret;
+
+	/* Table Init */
+	sh_eth_write(ndev, 0, TDLAR);
+	sh_eth_write(ndev, 0, TDFAR);
+	sh_eth_write(ndev, 0, TDFXR);
+	sh_eth_write(ndev, 0, TDFFR);
+	sh_eth_write(ndev, 0, RDLAR);
+	sh_eth_write(ndev, 0, RDFAR);
+	sh_eth_write(ndev, 0, RDFXR);
+	sh_eth_write(ndev, 0, RDFFR);
+
+	/* Reset HW CRC register */
+	if (mdp->cd->hw_checksum)
+		sh_eth_write(ndev, 0, CSMR);
+
+	/* Select MII mode */
+	if (mdp->cd->select_mii)
+		sh_eth_select_mii(ndev);
+
+	return ret;
+}
+
 static void sh_eth_set_rate_gether(struct net_device *ndev)
 {
 	struct sh_eth_private *mdp = netdev_priv(ndev);
@@ -521,6 +577,8 @@ static void sh_eth_set_rate_gether(struc
 #ifdef CONFIG_OF
 /* R7S72100 */
 static struct sh_eth_cpu_data r7s72100_data = {
+	.soft_reset	= sh_eth_soft_reset_gether,
+
 	.chip_reset	= sh_eth_chip_reset,
 	.set_duplex	= sh_eth_set_duplex,
 
@@ -565,6 +623,8 @@ static void sh_eth_chip_reset_r8a7740(st
 
 /* R8A7740 */
 static struct sh_eth_cpu_data r8a7740_data = {
+	.soft_reset	= sh_eth_soft_reset_gether,
+
 	.chip_reset	= sh_eth_chip_reset_r8a7740,
 	.set_duplex	= sh_eth_set_duplex,
 	.set_rate	= sh_eth_set_rate_gether,
@@ -620,6 +680,8 @@ static void sh_eth_set_rate_rcar(struct
 
 /* R-Car Gen1 */
 static struct sh_eth_cpu_data rcar_gen1_data = {
+	.soft_reset	= sh_eth_soft_reset,
+
 	.set_duplex	= sh_eth_set_duplex,
 	.set_rate	= sh_eth_set_rate_rcar,
 
@@ -647,6 +709,8 @@ static struct sh_eth_cpu_data rcar_gen1_
 
 /* R-Car Gen2 and RZ/G1 */
 static struct sh_eth_cpu_data rcar_gen2_data = {
+	.soft_reset	= sh_eth_soft_reset,
+
 	.set_duplex	= sh_eth_set_duplex,
 	.set_rate	= sh_eth_set_rate_rcar,
 
@@ -694,6 +758,8 @@ static void sh_eth_set_rate_sh7724(struc
 
 /* SH7724 */
 static struct sh_eth_cpu_data sh7724_data = {
+	.soft_reset	= sh_eth_soft_reset,
+
 	.set_duplex	= sh_eth_set_duplex,
 	.set_rate	= sh_eth_set_rate_sh7724,
 
@@ -736,6 +802,8 @@ static void sh_eth_set_rate_sh7757(struc
 
 /* SH7757 */
 static struct sh_eth_cpu_data sh7757_data = {
+	.soft_reset	= sh_eth_soft_reset,
+
 	.set_duplex	= sh_eth_set_duplex,
 	.set_rate	= sh_eth_set_rate_sh7757,
 
@@ -808,6 +876,8 @@ static void sh_eth_set_rate_giga(struct
 
 /* SH7757(GETHERC) */
 static struct sh_eth_cpu_data sh7757_data_giga = {
+	.soft_reset	= sh_eth_soft_reset_gether,
+
 	.chip_reset	= sh_eth_chip_reset_giga,
 	.set_duplex	= sh_eth_set_duplex,
 	.set_rate	= sh_eth_set_rate_giga,
@@ -847,6 +917,8 @@ static struct sh_eth_cpu_data sh7757_dat
 
 /* SH7734 */
 static struct sh_eth_cpu_data sh7734_data = {
+	.soft_reset	= sh_eth_soft_reset_gether,
+
 	.chip_reset	= sh_eth_chip_reset,
 	.set_duplex	= sh_eth_set_duplex,
 	.set_rate	= sh_eth_set_rate_gether,
@@ -883,6 +955,8 @@ static struct sh_eth_cpu_data sh7734_dat
 
 /* SH7763 */
 static struct sh_eth_cpu_data sh7763_data = {
+	.soft_reset	= sh_eth_soft_reset_gether,
+
 	.chip_reset	= sh_eth_chip_reset,
 	.set_duplex	= sh_eth_set_duplex,
 	.set_rate	= sh_eth_set_rate_gether,
@@ -917,6 +991,8 @@ static struct sh_eth_cpu_data sh7763_dat
 };
 
 static struct sh_eth_cpu_data sh7619_data = {
+	.soft_reset	= sh_eth_soft_reset,
+
 	.register_type	= SH_ETH_REG_FAST_SH3_SH2,
 
 	.eesipr_value	= EESIPR_RFCOFIP | EESIPR_ECIIP |
@@ -935,6 +1011,8 @@ static struct sh_eth_cpu_data sh7619_dat
 };
 
 static struct sh_eth_cpu_data sh771x_data = {
+	.soft_reset	= sh_eth_soft_reset,
+
 	.register_type	= SH_ETH_REG_FAST_SH3_SH2,
 
 	.eesipr_value	= EESIPR_RFCOFIP | EESIPR_ECIIP |
@@ -974,59 +1052,6 @@ static void sh_eth_set_default_cpu_data(
 		cd->trscer_err_mask = DEFAULT_TRSCER_ERR_MASK;
 }
 
-static int sh_eth_check_reset(struct net_device *ndev)
-{
-	int cnt;
-
-	for (cnt = 100; cnt > 0; cnt--) {
-		if (!(sh_eth_read(ndev, EDMR) & EDMR_SRST_GETHER))
-			return 0;
-		mdelay(1);
-	}
-
-	netdev_err(ndev, "Device reset failed\n");
-	return -ETIMEDOUT;
-}
-
-static int sh_eth_reset(struct net_device *ndev)
-{
-	struct sh_eth_private *mdp = netdev_priv(ndev);
-	int ret = 0;
-
-	if (sh_eth_is_gether(mdp) || sh_eth_is_rz_fast_ether(mdp)) {
-		sh_eth_write(ndev, EDSR_ENALL, EDSR);
-		sh_eth_modify(ndev, EDMR, EDMR_SRST_GETHER, EDMR_SRST_GETHER);
-
-		ret = sh_eth_check_reset(ndev);
-		if (ret)
-			return ret;
-
-		/* Table Init */
-		sh_eth_write(ndev, 0x0, TDLAR);
-		sh_eth_write(ndev, 0x0, TDFAR);
-		sh_eth_write(ndev, 0x0, TDFXR);
-		sh_eth_write(ndev, 0x0, TDFFR);
-		sh_eth_write(ndev, 0x0, RDLAR);
-		sh_eth_write(ndev, 0x0, RDFAR);
-		sh_eth_write(ndev, 0x0, RDFXR);
-		sh_eth_write(ndev, 0x0, RDFFR);
-
-		/* Reset HW CRC register */
-		if (mdp->cd->hw_checksum)
-			sh_eth_write(ndev, 0x0, CSMR);
-
-		/* Select MII mode */
-		if (mdp->cd->select_mii)
-			sh_eth_select_mii(ndev);
-	} else {
-		sh_eth_modify(ndev, EDMR, EDMR_SRST_ETHER, EDMR_SRST_ETHER);
-		mdelay(3);
-		sh_eth_modify(ndev, EDMR, EDMR_SRST_ETHER, 0);
-	}
-
-	return ret;
-}
-
 static void sh_eth_set_receive_align(struct sk_buff *skb)
 {
 	uintptr_t reserve = (uintptr_t)skb->data & (SH_ETH_RX_ALIGN - 1);
@@ -1362,7 +1387,7 @@ static int sh_eth_dev_init(struct net_de
 	int ret;
 
 	/* Soft Reset */
-	ret = sh_eth_reset(ndev);
+	ret = mdp->cd->soft_reset(ndev);
 	if (ret)
 		return ret;
 
@@ -1463,7 +1488,7 @@ static void sh_eth_dev_exit(struct net_d
 	 */
 	msleep(2); /* max frame time at 10 Mbps < 1250 us */
 	sh_eth_get_stats(ndev);
-	sh_eth_reset(ndev);
+	mdp->cd->soft_reset(ndev);
 
 	/* Set MAC address again */
 	update_mac_address(ndev);
Index: net-next/drivers/net/ethernet/renesas/sh_eth.h
===================================================================
--- net-next.orig/drivers/net/ethernet/renesas/sh_eth.h
+++ net-next/drivers/net/ethernet/renesas/sh_eth.h
@@ -469,6 +469,9 @@ struct sh_eth_rxdesc {
 
 /* This structure is used by each CPU dependency handling. */
 struct sh_eth_cpu_data {
+	/* mandatory functions */
+	int (*soft_reset)(struct net_device *ndev);
+
 	/* optional functions */
 	void (*chip_reset)(struct net_device *ndev);
 	void (*set_duplex)(struct net_device *ndev);

^ permalink raw reply

* [PATCH 2/5] sh_eth: add sh_eth_cpu_data::edtrr_trns value
From: Sergei Shtylyov @ 2018-03-24 20:08 UTC (permalink / raw)
  To: netdev; +Cc: linux-renesas-soc, linux-sh
In-Reply-To: <b3706a51-27a4-d78b-998d-9440637ac216@cogentembedded.com>

sh_eth_get_edtrr_trns() returns the value to be written to EDTRR in order
to start TX DMA -- this value is different between the GEther-like and
the other controllers. We can replace this function (and thus get rid of
the calls to sh_eth_is_{gether|rz_fast_ether}() by it) with a new field
'edtrr_trns' in the 'struct sh_eth_cpu_data'.

Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>

---
 drivers/net/ethernet/renesas/sh_eth.c |   27 +++++++++++++++------------
 drivers/net/ethernet/renesas/sh_eth.h |    1 +
 2 files changed, 16 insertions(+), 12 deletions(-)

Index: net-next/drivers/net/ethernet/renesas/sh_eth.c
===================================================================
--- net-next.orig/drivers/net/ethernet/renesas/sh_eth.c
+++ net-next/drivers/net/ethernet/renesas/sh_eth.c
@@ -584,6 +584,7 @@ static struct sh_eth_cpu_data r7s72100_d
 
 	.register_type	= SH_ETH_REG_FAST_RZ,
 
+	.edtrr_trns	= EDTRR_TRNS_GETHER,
 	.ecsr_value	= ECSR_ICD,
 	.ecsipr_value	= ECSIPR_ICDIP,
 	.eesipr_value	= EESIPR_TWB1IP | EESIPR_TWBIP | EESIPR_TC1IP |
@@ -631,6 +632,7 @@ static struct sh_eth_cpu_data r8a7740_da
 
 	.register_type	= SH_ETH_REG_GIGABIT,
 
+	.edtrr_trns	= EDTRR_TRNS_GETHER,
 	.ecsr_value	= ECSR_ICD | ECSR_MPD,
 	.ecsipr_value	= ECSIPR_LCHNGIP | ECSIPR_ICDIP | ECSIPR_MPDIP,
 	.eesipr_value	= EESIPR_RFCOFIP | EESIPR_ECIIP |
@@ -687,6 +689,7 @@ static struct sh_eth_cpu_data rcar_gen1_
 
 	.register_type	= SH_ETH_REG_FAST_RCAR,
 
+	.edtrr_trns	= EDTRR_TRNS_ETHER,
 	.ecsr_value	= ECSR_PSRTO | ECSR_LCHNG | ECSR_ICD,
 	.ecsipr_value	= ECSIPR_PSRTOIP | ECSIPR_LCHNGIP | ECSIPR_ICDIP,
 	.eesipr_value	= EESIPR_RFCOFIP | EESIPR_ADEIP | EESIPR_ECIIP |
@@ -716,6 +719,7 @@ static struct sh_eth_cpu_data rcar_gen2_
 
 	.register_type	= SH_ETH_REG_FAST_RCAR,
 
+	.edtrr_trns	= EDTRR_TRNS_ETHER,
 	.ecsr_value	= ECSR_PSRTO | ECSR_LCHNG | ECSR_ICD | ECSR_MPD,
 	.ecsipr_value	= ECSIPR_PSRTOIP | ECSIPR_LCHNGIP | ECSIPR_ICDIP |
 			  ECSIPR_MPDIP,
@@ -765,6 +769,7 @@ static struct sh_eth_cpu_data sh7724_dat
 
 	.register_type	= SH_ETH_REG_FAST_SH4,
 
+	.edtrr_trns	= EDTRR_TRNS_ETHER,
 	.ecsr_value	= ECSR_PSRTO | ECSR_LCHNG | ECSR_ICD,
 	.ecsipr_value	= ECSIPR_PSRTOIP | ECSIPR_LCHNGIP | ECSIPR_ICDIP,
 	.eesipr_value	= EESIPR_RFCOFIP | EESIPR_ADEIP | EESIPR_ECIIP |
@@ -809,6 +814,7 @@ static struct sh_eth_cpu_data sh7757_dat
 
 	.register_type	= SH_ETH_REG_FAST_SH4,
 
+	.edtrr_trns	= EDTRR_TRNS_ETHER,
 	.eesipr_value	= EESIPR_RFCOFIP | EESIPR_ECIIP |
 			  EESIPR_FTCIP | EESIPR_TDEIP | EESIPR_TFUFIP |
 			  EESIPR_FRIP | EESIPR_RDEIP | EESIPR_RFOFIP |
@@ -884,6 +890,7 @@ static struct sh_eth_cpu_data sh7757_dat
 
 	.register_type	= SH_ETH_REG_GIGABIT,
 
+	.edtrr_trns	= EDTRR_TRNS_GETHER,
 	.ecsr_value	= ECSR_ICD | ECSR_MPD,
 	.ecsipr_value	= ECSIPR_LCHNGIP | ECSIPR_ICDIP | ECSIPR_MPDIP,
 	.eesipr_value	= EESIPR_RFCOFIP | EESIPR_ECIIP |
@@ -925,6 +932,7 @@ static struct sh_eth_cpu_data sh7734_dat
 
 	.register_type	= SH_ETH_REG_GIGABIT,
 
+	.edtrr_trns	= EDTRR_TRNS_GETHER,
 	.ecsr_value	= ECSR_ICD | ECSR_MPD,
 	.ecsipr_value	= ECSIPR_LCHNGIP | ECSIPR_ICDIP | ECSIPR_MPDIP,
 	.eesipr_value	= EESIPR_RFCOFIP | EESIPR_ECIIP |
@@ -963,6 +971,7 @@ static struct sh_eth_cpu_data sh7763_dat
 
 	.register_type	= SH_ETH_REG_GIGABIT,
 
+	.edtrr_trns	= EDTRR_TRNS_GETHER,
 	.ecsr_value	= ECSR_ICD | ECSR_MPD,
 	.ecsipr_value	= ECSIPR_LCHNGIP | ECSIPR_ICDIP | ECSIPR_MPDIP,
 	.eesipr_value	= EESIPR_RFCOFIP | EESIPR_ECIIP |
@@ -995,6 +1004,7 @@ static struct sh_eth_cpu_data sh7619_dat
 
 	.register_type	= SH_ETH_REG_FAST_SH3_SH2,
 
+	.edtrr_trns	= EDTRR_TRNS_ETHER,
 	.eesipr_value	= EESIPR_RFCOFIP | EESIPR_ECIIP |
 			  EESIPR_FTCIP | EESIPR_TDEIP | EESIPR_TFUFIP |
 			  EESIPR_FRIP | EESIPR_RDEIP | EESIPR_RFOFIP |
@@ -1015,6 +1025,7 @@ static struct sh_eth_cpu_data sh771x_dat
 
 	.register_type	= SH_ETH_REG_FAST_SH3_SH2,
 
+	.edtrr_trns	= EDTRR_TRNS_ETHER,
 	.eesipr_value	= EESIPR_RFCOFIP | EESIPR_ECIIP |
 			  EESIPR_FTCIP | EESIPR_TDEIP | EESIPR_TFUFIP |
 			  EESIPR_FRIP | EESIPR_RDEIP | EESIPR_RFOFIP |
@@ -1094,14 +1105,6 @@ static void read_mac_address(struct net_
 	}
 }
 
-static u32 sh_eth_get_edtrr_trns(struct sh_eth_private *mdp)
-{
-	if (sh_eth_is_gether(mdp) || sh_eth_is_rz_fast_ether(mdp))
-		return EDTRR_TRNS_GETHER;
-	else
-		return EDTRR_TRNS_ETHER;
-}
-
 struct bb_info {
 	void (*set_gate)(void *addr);
 	struct mdiobb_ctrl ctrl;
@@ -1741,9 +1744,9 @@ static void sh_eth_error(struct net_devi
 		sh_eth_tx_free(ndev, true);
 
 		/* SH7712 BUG */
-		if (edtrr ^ sh_eth_get_edtrr_trns(mdp)) {
+		if (edtrr ^ mdp->cd->edtrr_trns) {
 			/* tx dma start */
-			sh_eth_write(ndev, sh_eth_get_edtrr_trns(mdp), EDTRR);
+			sh_eth_write(ndev, mdp->cd->edtrr_trns, EDTRR);
 		}
 		/* wakeup */
 		netif_wake_queue(ndev);
@@ -2502,8 +2505,8 @@ static int sh_eth_start_xmit(struct sk_b
 
 	mdp->cur_tx++;
 
-	if (!(sh_eth_read(ndev, EDTRR) & sh_eth_get_edtrr_trns(mdp)))
-		sh_eth_write(ndev, sh_eth_get_edtrr_trns(mdp), EDTRR);
+	if (!(sh_eth_read(ndev, EDTRR) & mdp->cd->edtrr_trns))
+		sh_eth_write(ndev, mdp->cd->edtrr_trns, EDTRR);
 
 	return NETDEV_TX_OK;
 }
Index: net-next/drivers/net/ethernet/renesas/sh_eth.h
===================================================================
--- net-next.orig/drivers/net/ethernet/renesas/sh_eth.h
+++ net-next/drivers/net/ethernet/renesas/sh_eth.h
@@ -479,6 +479,7 @@ struct sh_eth_cpu_data {
 
 	/* mandatory initialize value */
 	int register_type;
+	u32 edtrr_trns;
 	u32 eesipr_value;
 
 	/* optional initialize value */

^ permalink raw reply

* [PATCH 3/5] sh_eth: add sh_eth_cpu_data::xdfar_rw flag
From: Sergei Shtylyov @ 2018-03-24 20:09 UTC (permalink / raw)
  To: netdev; +Cc: linux-renesas-soc, linux-sh
In-Reply-To: <b3706a51-27a4-d78b-998d-9440637ac216@cogentembedded.com>

The GEther-like controllers have writeable RDFAR/TDFAR, on the others
they are read-only or just absent (on R-Car). Currently we are calling
sh_eth_is_{gether|rz_fast_ether}() in order to check if these registers
can be written to, however it would be simpler to check the new 'xdfar_rw'
bitfield in the 'struct sh_eth_cpu_data'...

Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>

---
 drivers/net/ethernet/renesas/sh_eth.c |   11 +++++++----
 drivers/net/ethernet/renesas/sh_eth.h |    1 +
 2 files changed, 8 insertions(+), 4 deletions(-)

Index: net-next/drivers/net/ethernet/renesas/sh_eth.c
===================================================================
--- net-next.orig/drivers/net/ethernet/renesas/sh_eth.c
+++ net-next/drivers/net/ethernet/renesas/sh_eth.c
@@ -611,6 +611,7 @@ static struct sh_eth_cpu_data r7s72100_d
 	.rpadir_value   = 2 << 16,
 	.no_trimd	= 1,
 	.no_ade		= 1,
+	.xdfar_rw	= 1,
 	.hw_checksum	= 1,
 	.tsu		= 1,
 };
@@ -659,6 +660,7 @@ static struct sh_eth_cpu_data r8a7740_da
 	.rpadir_value   = 2 << 16,
 	.no_trimd	= 1,
 	.no_ade		= 1,
+	.xdfar_rw	= 1,
 	.hw_checksum	= 1,
 	.tsu		= 1,
 	.select_mii	= 1,
@@ -918,6 +920,7 @@ static struct sh_eth_cpu_data sh7757_dat
 	.rpadir_value   = 2 << 16,
 	.no_trimd	= 1,
 	.no_ade		= 1,
+	.xdfar_rw	= 1,
 	.tsu		= 1,
 	.dual_port	= 1,
 };
@@ -955,6 +958,7 @@ static struct sh_eth_cpu_data sh7734_dat
 	.hw_swap	= 1,
 	.no_trimd	= 1,
 	.no_ade		= 1,
+	.xdfar_rw	= 1,
 	.tsu		= 1,
 	.hw_checksum	= 1,
 	.select_mii	= 1,
@@ -993,6 +997,7 @@ static struct sh_eth_cpu_data sh7763_dat
 	.hw_swap	= 1,
 	.no_trimd	= 1,
 	.no_ade		= 1,
+	.xdfar_rw	= 1,
 	.tsu		= 1,
 	.irq_flags	= IRQF_SHARED,
 	.magic		= 1,
@@ -1301,8 +1306,7 @@ static void sh_eth_ring_format(struct ne
 		/* Rx descriptor address set */
 		if (i == 0) {
 			sh_eth_write(ndev, mdp->rx_desc_dma, RDLAR);
-			if (sh_eth_is_gether(mdp) ||
-			    sh_eth_is_rz_fast_ether(mdp))
+			if (mdp->cd->xdfar_rw)
 				sh_eth_write(ndev, mdp->rx_desc_dma, RDFAR);
 		}
 	}
@@ -1324,8 +1328,7 @@ static void sh_eth_ring_format(struct ne
 		if (i == 0) {
 			/* Tx descriptor address set */
 			sh_eth_write(ndev, mdp->tx_desc_dma, TDLAR);
-			if (sh_eth_is_gether(mdp) ||
-			    sh_eth_is_rz_fast_ether(mdp))
+			if (mdp->cd->xdfar_rw)
 				sh_eth_write(ndev, mdp->tx_desc_dma, TDFAR);
 		}
 	}
Index: net-next/drivers/net/ethernet/renesas/sh_eth.h
===================================================================
--- net-next.orig/drivers/net/ethernet/renesas/sh_eth.h
+++ net-next/drivers/net/ethernet/renesas/sh_eth.h
@@ -508,6 +508,7 @@ struct sh_eth_cpu_data {
 	unsigned rpadir:1;	/* E-DMAC have RPADIR */
 	unsigned no_trimd:1;	/* E-DMAC DO NOT have TRIMD */
 	unsigned no_ade:1;	/* E-DMAC DO NOT have ADE bit in EESR */
+	unsigned xdfar_rw:1;	/* E-DMAC has writeable RDFAR/TDFAR */
 	unsigned hw_checksum:1;	/* E-DMAC has CSMR */
 	unsigned select_mii:1;	/* EtherC have RMII_MII (MII select register) */
 	unsigned rmiimode:1;	/* EtherC has RMIIMODE register */

^ permalink raw reply

* [PATCH 4/5] sh_eth: add sh_eth_cpu_data::no_tx_cntr flag
From: Sergei Shtylyov @ 2018-03-24 20:11 UTC (permalink / raw)
  To: netdev; +Cc: linux-renesas-soc, linux-sh
In-Reply-To: <b3706a51-27a4-d78b-998d-9440637ac216@cogentembedded.com>

RZ/A1H (R7S72100) Ether controller doesn't  seem to have the TX counter
registers like TROCR/CDCR/LCCR (or at least they are still undocumented
like some TSU registers), so we bail out of sh_eth_get_stats() early in
this case.  Currently we are calling sh_eth_is_rz_fast_ether() in order
to check for this, but it would be simpler to check the new 'no_tx_cntrs'
bitfield in the 'struct sh_eth_cpu_data'; then we'd be able  to remove
sh_eth_is_rz_fast_ether() as there would be no callers left...

Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>

---
 drivers/net/ethernet/renesas/sh_eth.c |    8 ++------
 drivers/net/ethernet/renesas/sh_eth.h |    1 +
 2 files changed, 3 insertions(+), 6 deletions(-)

Index: net-next/drivers/net/ethernet/renesas/sh_eth.c
===================================================================
--- net-next.orig/drivers/net/ethernet/renesas/sh_eth.c
+++ net-next/drivers/net/ethernet/renesas/sh_eth.c
@@ -455,11 +455,6 @@ static bool sh_eth_is_gether(struct sh_e
 	return mdp->reg_offset == sh_eth_offset_gigabit;
 }
 
-static bool sh_eth_is_rz_fast_ether(struct sh_eth_private *mdp)
-{
-	return mdp->reg_offset == sh_eth_offset_fast_rz;
-}
-
 static void sh_eth_select_mii(struct net_device *ndev)
 {
 	struct sh_eth_private *mdp = netdev_priv(ndev);
@@ -614,6 +609,7 @@ static struct sh_eth_cpu_data r7s72100_d
 	.xdfar_rw	= 1,
 	.hw_checksum	= 1,
 	.tsu		= 1,
+	.no_tx_cntrs	= 1,
 };
 
 static void sh_eth_chip_reset_r8a7740(struct net_device *ndev)
@@ -2534,7 +2530,7 @@ static struct net_device_stats *sh_eth_g
 {
 	struct sh_eth_private *mdp = netdev_priv(ndev);
 
-	if (sh_eth_is_rz_fast_ether(mdp))
+	if (mdp->cd->no_tx_cntrs)
 		return &ndev->stats;
 
 	if (!mdp->is_opened)
Index: net-next/drivers/net/ethernet/renesas/sh_eth.h
===================================================================
--- net-next.orig/drivers/net/ethernet/renesas/sh_eth.h
+++ net-next/drivers/net/ethernet/renesas/sh_eth.h
@@ -514,6 +514,7 @@ struct sh_eth_cpu_data {
 	unsigned rmiimode:1;	/* EtherC has RMIIMODE register */
 	unsigned rtrate:1;	/* EtherC has RTRATE register */
 	unsigned magic:1;	/* EtherC has ECMR.MPDE and ECSR.MPD */
+	unsigned no_tx_cntrs:1;	/* EtherC DOES NOT have TX error counters */
 	unsigned dual_port:1;	/* Dual EtherC/E-DMAC */
 };
 

^ permalink raw reply

* [PATCH 5/5] sh_eth: add sh_eth_cpu_data::cexcr flag
From: Sergei Shtylyov @ 2018-03-24 20:12 UTC (permalink / raw)
  To: netdev; +Cc: linux-renesas-soc, linux-sh
In-Reply-To: <b3706a51-27a4-d78b-998d-9440637ac216@cogentembedded.com>

GEther controllers have CERCR/CEECR instead of CNDCR on the others.
Currently we are calling sh_eth_is_gether() in order to check for this,
however it would be simpler  to check the new 'cexcr' bitfield in the
'struct sh_eth_cpu_data';  then we'd be able to remove sh_eth_is_gether()
as there would be no callers left...

Signed-off-by: Sergei Shtylyov <sergei.shtylyov@cogentembedded.com>

---
 drivers/net/ethernet/renesas/sh_eth.c |   11 +++++------
 drivers/net/ethernet/renesas/sh_eth.h |    1 +
 2 files changed, 6 insertions(+), 6 deletions(-)

Index: net-next/drivers/net/ethernet/renesas/sh_eth.c
===================================================================
--- net-next.orig/drivers/net/ethernet/renesas/sh_eth.c
+++ net-next/drivers/net/ethernet/renesas/sh_eth.c
@@ -450,11 +450,6 @@ static u32 sh_eth_tsu_read(struct sh_eth
 	return ioread32(mdp->tsu_addr + mdp->reg_offset[enum_index]);
 }
 
-static bool sh_eth_is_gether(struct sh_eth_private *mdp)
-{
-	return mdp->reg_offset == sh_eth_offset_gigabit;
-}
-
 static void sh_eth_select_mii(struct net_device *ndev)
 {
 	struct sh_eth_private *mdp = netdev_priv(ndev);
@@ -661,6 +656,7 @@ static struct sh_eth_cpu_data r8a7740_da
 	.tsu		= 1,
 	.select_mii	= 1,
 	.magic		= 1,
+	.cexcr		= 1,
 };
 
 /* There is CPU dependent code */
@@ -918,6 +914,7 @@ static struct sh_eth_cpu_data sh7757_dat
 	.no_ade		= 1,
 	.xdfar_rw	= 1,
 	.tsu		= 1,
+	.cexcr		= 1,
 	.dual_port	= 1,
 };
 
@@ -959,6 +956,7 @@ static struct sh_eth_cpu_data sh7734_dat
 	.hw_checksum	= 1,
 	.select_mii	= 1,
 	.magic		= 1,
+	.cexcr		= 1,
 };
 
 /* SH7763 */
@@ -997,6 +995,7 @@ static struct sh_eth_cpu_data sh7763_dat
 	.tsu		= 1,
 	.irq_flags	= IRQF_SHARED,
 	.magic		= 1,
+	.cexcr		= 1,
 	.dual_port	= 1,
 };
 
@@ -2540,7 +2539,7 @@ static struct net_device_stats *sh_eth_g
 	sh_eth_update_stat(ndev, &ndev->stats.collisions, CDCR);
 	sh_eth_update_stat(ndev, &ndev->stats.tx_carrier_errors, LCCR);
 
-	if (sh_eth_is_gether(mdp)) {
+	if (mdp->cd->cexcr) {
 		sh_eth_update_stat(ndev, &ndev->stats.tx_carrier_errors,
 				   CERCR);
 		sh_eth_update_stat(ndev, &ndev->stats.tx_carrier_errors,
Index: net-next/drivers/net/ethernet/renesas/sh_eth.h
===================================================================
--- net-next.orig/drivers/net/ethernet/renesas/sh_eth.h
+++ net-next/drivers/net/ethernet/renesas/sh_eth.h
@@ -515,6 +515,7 @@ struct sh_eth_cpu_data {
 	unsigned rtrate:1;	/* EtherC has RTRATE register */
 	unsigned magic:1;	/* EtherC has ECMR.MPDE and ECSR.MPD */
 	unsigned no_tx_cntrs:1;	/* EtherC DOES NOT have TX error counters */
+	unsigned cexcr:1;	/* EtherC has CERCR/CEECR */
 	unsigned dual_port:1;	/* Dual EtherC/E-DMAC */
 };
 

^ permalink raw reply

* [net PATCH] net: sched, fix OOO packets with pfifo_fast
From: John Fastabend @ 2018-03-24 20:13 UTC (permalink / raw)
  To: xiyou.wangcong, jiri, davem; +Cc: netdev

After the qdisc lock was dropped in pfifo_fast we allow multiple
enqueue threads and dequeue threads to run in parallel. On the
enqueue side the skb bit ooo_okay is used to ensure all related
skbs are enqueued in-order. On the dequeue side though there is
no similar logic. What we observe is with fewer queues than CPUs
it is possible to re-order packets when two instances of
__qdisc_run() are running in parallel. Each thread will dequeue
a skb and then whichever thread calls the ndo op first will
be sent on the wire. This doesn't typically happen because
qdisc_run() is usually triggered by the same core that did the
enqueue. However, drivers will trigger __netif_schedule()
when queues are transitioning from stopped to awake using the
netif_tx_wake_* APIs. When this happens netif_schedule() calls
qdisc_run() on the same CPU that did the netif_tx_wake_* which
is usually done in the interrupt completion context. This CPU
is selected with the irq affinity which is unrelated to the
enqueue operations.

To resolve this we add a RUNNING bit to the qdisc to ensure
only a single dequeue per qdisc is running. Enqueue and dequeue
operations can still run in parallel and also on multi queue
NICs we can still have a dequeue in-flight per qdisc, which
is typically per CPU.

Fixes: c5ad119fb6c0 ("net: sched: pfifo_fast use skb_array")
Reported-by: Jakob Unterwurzacher <jakob.unterwurzacher@theobroma-systems.com>
Signed-off-by: John Fastabend <john.fastabend@gmail.com>
---
 include/net/sch_generic.h |    1 +
 net/sched/sch_generic.c   |   13 ++++++++++---
 2 files changed, 11 insertions(+), 3 deletions(-)

diff --git a/include/net/sch_generic.h b/include/net/sch_generic.h
index 2092d33..8da3267 100644
--- a/include/net/sch_generic.h
+++ b/include/net/sch_generic.h
@@ -30,6 +30,7 @@ struct qdisc_rate_table {
 enum qdisc_state_t {
 	__QDISC_STATE_SCHED,
 	__QDISC_STATE_DEACTIVATED,
+	__QDISC_STATE_RUNNING,
 };
 
 struct qdisc_size_table {
diff --git a/net/sched/sch_generic.c b/net/sched/sch_generic.c
index 7e3fbe9..29a1b47 100644
--- a/net/sched/sch_generic.c
+++ b/net/sched/sch_generic.c
@@ -377,12 +377,17 @@ static inline bool qdisc_restart(struct Qdisc *q, int *packets)
 	struct netdev_queue *txq;
 	struct net_device *dev;
 	struct sk_buff *skb;
-	bool validate;
+	bool more, validate;
 
 	/* Dequeue packet */
+	if (test_and_set_bit(__QDISC_STATE_RUNNING, &q->state))
+		return false;
+
 	skb = dequeue_skb(q, &validate, packets);
-	if (unlikely(!skb))
+	if (unlikely(!skb)) {
+		clear_bit(__QDISC_STATE_RUNNING, &q->state);
 		return false;
+	}
 
 	if (!(q->flags & TCQ_F_NOLOCK))
 		root_lock = qdisc_lock(q);
@@ -390,7 +395,9 @@ static inline bool qdisc_restart(struct Qdisc *q, int *packets)
 	dev = qdisc_dev(q);
 	txq = skb_get_tx_queue(dev, skb);
 
-	return sch_direct_xmit(skb, q, dev, txq, root_lock, validate);
+	more = sch_direct_xmit(skb, q, dev, txq, root_lock, validate);
+	clear_bit(__QDISC_STATE_RUNNING, &q->state);
+	return more;
 }
 
 void __qdisc_run(struct Qdisc *q)

^ permalink raw reply related

* Re: [PATCH 0/2] sh_eth: unify the SoC feature checks
From: Sergei Shtylyov @ 2018-03-24 20:14 UTC (permalink / raw)
  To: netdev; +Cc: linux-renesas-soc, linux-sh
In-Reply-To: <b3706a51-27a4-d78b-998d-9440637ac216@cogentembedded.com>

Should have been 0/5 in the subject. Sorry. :-)

^ 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