Netdev List
 help / color / mirror / Atom feed
* RE: [PATCH v1 net-next] net: phy: mdio_bus: make mdiobus_scan also cover PHY that only talks C45
From: Voon, Weifeng @ 2019-08-27 15:23 UTC (permalink / raw)
  To: Andrew Lunn, Florian Fainelli
  Cc: David S. Miller, Maxime Coquelin, netdev@vger.kernel.org,
	linux-kernel@vger.kernel.org, Jose Abreu, Heiner Kallweit,
	Ong, Boon Leong
In-Reply-To: <20190826185418.GG2168@lunn.ch>

> > > Make mdiobus_scan() to try harder to look for any PHY that only
> talks C45.
> > If you are not using Device Tree or ACPI, and you are letting the MDIO
> > bus be scanned, it sounds like there should be a way for you to
> > provide a hint as to which addresses should be scanned (that's
> > mii_bus::phy_mask) and possibly enhance that with a mask of possible
> > C45 devices?
> 
> Yes, i don't like this unconditional c45 scanning. A lot of MDIO bus
> drivers don't look for the MII_ADDR_C45. They are going to do a C22
> transfer, and maybe not mask out the MII_ADDR_C45 from reg, causing an
> invalid register write. Bad things can then happen.
> 
> With DT and ACPI, we have an explicit indication that C45 should be used,
> so we know on this platform C45 is safe to use. We need something
> similar when not using DT or ACPI.
> 
> 	  Andrew

Florian and Andrew,
The mdio c22 is using the start-of-frame ST=01 while mdio c45 is using ST=00
as identifier. So mdio c22 device will not response to mdio c45 protocol.
As in IEEE 802.1ae-2002 Annex 45A.3 mention that:
" Even though the Clause 45 MDIO frames using the ST=00 frame code
will also be driven on to the Clause 22 MII Management interface,
the Clause 22 PHYs will ignore the frames. "

Hence, I am not seeing any concern that the c45 scanning will mess up with 
c22 devices.

Weifeng 



^ permalink raw reply

* Re: [PATCH] ipv6: Not to probe neighbourless routes
From: Eric Dumazet @ 2019-08-27 15:22 UTC (permalink / raw)
  To: Yi Wang, davem
  Cc: kuznet, yoshfuji, netdev, linux-kernel, xue.zhihong, wang.liang82,
	Cheng Lin
In-Reply-To: <1566896907-5121-1-git-send-email-wang.yi59@zte.com.cn>



On 8/27/19 11:08 AM, Yi Wang wrote:
> From: Cheng Lin <cheng.lin130@zte.com.cn>
> 
> Originally, Router Reachability Probing require a neighbour entry
> existed. Commit 2152caea7196 ("ipv6: Do not depend on rt->n in
> rt6_probe().") removed the requirement for a neighbour entry. And
> commit f547fac624be ("ipv6: rate-limit probes for neighbourless
> routes") adds rate-limiting for neighbourless routes.
> 
> And, the Neighbor Discovery for IP version 6 (IPv6)(rfc4861) says,
> "
> 7.2.5.  Receipt of Neighbor Advertisements
> 
> When a valid Neighbor Advertisement is received (either solicited or
> unsolicited), the Neighbor Cache is searched for the target's entry.
> If no entry exists, the advertisement SHOULD be silently discarded.
> There is no need to create an entry if none exists, since the
> recipient has apparently not initiated any communication with the
> target.
> ".
> 
> In rt6_probe(), just a Neighbor Solicitation message are transmited.
> When receiving a Neighbor Advertisement, the node does nothing in a
> Neighborless condition.
> 
> Not sure it's needed to create a neighbor entry in Router
> Reachability Probing. And the Original way may be the right way.
> 
> This patch recover the requirement for a neighbour entry.
> 
> Signed-off-by: Cheng Lin <cheng.lin130@zte.com.cn>
> ---
>  include/net/ip6_fib.h | 5 -----
>  net/ipv6/route.c      | 5 +----
>  2 files changed, 1 insertion(+), 9 deletions(-)
> 
> diff --git a/include/net/ip6_fib.h b/include/net/ip6_fib.h
> index 4b5656c..8c2e022 100644
> --- a/include/net/ip6_fib.h
> +++ b/include/net/ip6_fib.h
> @@ -124,11 +124,6 @@ struct rt6_exception {
>  
>  struct fib6_nh {
>  	struct fib_nh_common	nh_common;
> -
> -#ifdef CONFIG_IPV6_ROUTER_PREF
> -	unsigned long		last_probe;
> -#endif
> -
>  	struct rt6_info * __percpu *rt6i_pcpu;
>  	struct rt6_exception_bucket __rcu *rt6i_exception_bucket;
>  };
> diff --git a/net/ipv6/route.c b/net/ipv6/route.c
> index fd059e0..c4bcffc 100644
> --- a/net/ipv6/route.c
> +++ b/net/ipv6/route.c
> @@ -639,12 +639,12 @@ static void rt6_probe(struct fib6_nh *fib6_nh)
>  	nh_gw = &fib6_nh->fib_nh_gw6;
>  	dev = fib6_nh->fib_nh_dev;
>  	rcu_read_lock_bh();
> -	idev = __in6_dev_get(dev);
>  	neigh = __ipv6_neigh_lookup_noref(dev, nh_gw);
>  	if (neigh) {
>  		if (neigh->nud_state & NUD_VALID)
>  			goto out;
>  
> +		idev = __in6_dev_get(dev);
>  		write_lock(&neigh->lock);
>  		if (!(neigh->nud_state & NUD_VALID) &&
>  		    time_after(jiffies,
> @@ -654,9 +654,6 @@ static void rt6_probe(struct fib6_nh *fib6_nh)
>  				__neigh_set_probe_once(neigh);
>  		}
>  		write_unlock(&neigh->lock);
> -	} else if (time_after(jiffies, fib6_nh->last_probe +
> -				       idev->cnf.rtr_probe_interval)) {
> -		work = kmalloc(sizeof(*work), GFP_ATOMIC);
>  	}
>  
>  	if (work) {
> 

Have you really compiled this patch ?



^ permalink raw reply

* Re: [patch net-next rfc 3/7] net: rtnetlink: add commands to add and delete alternative ifnames
From: Roopa Prabhu @ 2019-08-27 15:14 UTC (permalink / raw)
  To: Jiri Pirko
  Cc: David Miller, Jakub Kicinski, David Ahern, netdev,
	Stephen Hemminger, dcbw, Michal Kubecek, Andrew Lunn, parav,
	Saeed Mahameed, mlxsw
In-Reply-To: <20190827093525.GB2250@nanopsycho>

On Tue, Aug 27, 2019 at 2:35 AM Jiri Pirko <jiri@resnulli.us> wrote:
>
> Tue, Aug 27, 2019 at 10:22:42AM CEST, davem@davemloft.net wrote:
> >From: Jiri Pirko <jiri@resnulli.us>
> >Date: Tue, 27 Aug 2019 09:08:08 +0200
> >
> >> Okay, so if I understand correctly, on top of separate commands for
> >> add/del of alternative names, you suggest also get/dump to be separate
> >> command and don't fill this up in existing newling/getlink command.
> >
> >I'm not sure what to do yet.
> >
> >David has a point, because the only way these ifnames are useful is
> >as ways to specify and choose net devices.  So based upon that I'm
> >slightly learning towards not using separate commands.
>
> Well yeah, one can use it to handle existing commands instead of
> IFLA_NAME.
>
> But why does it rule out separate commands? I think it is cleaner than
> to put everything in poor setlink messages :/ The fact that we would
> need to add "OP" to the setlink message just feels of. Other similar
> needs may show up in the future and we may endup in ridiculous messages
> like:
>
> SETLINK
>   IFLA_NAME eth0
>   IFLA_ATLNAME_LIST (nest)
>       IFLA_ALTNAME_OP add
>       IFLA_ALTNAME somereallylongname
>       IFLA_ALTNAME_OP del
>       IFLA_ALTNAME somereallyreallylongname
>       IFLA_ALTNAME_OP add
>       IFLA_ALTNAME someotherreallylongname
>   IFLA_SOMETHING_ELSE_LIST (nest)
>       IFLA_SOMETHING_ELSE_OP add
>       ...
>       IFLA_SOMETHING_ELSE_OP del
>       ...
>       IFLA_SOMETHING_ELSE_OP add
>       ...
>
> I don't know what to think about it. Rollbacks are going to be pure hell :/

I don't see a huge problem with the above. We need a way to solve this
anyways for other list types in the future correct ?.
The approach taken by this series will not scale if we have to add a
new msg type and header for every such list attribute in the future.

A good parallel here is bridge vlan which uses RTM_SETLINK and
RTM_DELLINK for vlan add and deletes. But it does have an advantage of
a separate
msg space under AF_BRIDGE which makes it cleaner. Maybe something
closer to that  can be made to work (possibly with a msg flag) ?.

Would be good to have a consistent way to update list attributes for
future needs too.

^ permalink raw reply

* Re: BUG_ON in skb_segment, after bpf_skb_change_proto was applied
From: Eric Dumazet @ 2019-08-27 15:09 UTC (permalink / raw)
  To: Shmulik Ladkani
  Cc: Daniel Borkmann, netdev, Alexander Duyck, Alexei Starovoitov,
	Yonghong Song, Steffen Klassert, shmulik, eyal
In-Reply-To: <20190827144218.5b098eac@pixies>



On 8/27/19 1:42 PM, Shmulik Ladkani wrote:
> On Mon, 26 Aug 2019 19:47:40 +0200
> Eric Dumazet <eric.dumazet@gmail.com> wrote:
> 
>> On 8/26/19 4:07 PM, Shmulik Ladkani wrote:
>>>   - ipv4 forwarding to dummy1, where eBPF nat4-to-6 program is attached
>>>     at TC Egress (calls 'bpf_skb_change_proto()'), then redirect to ingress
>>>     on same device.
>>>     NOTE: 'bpf_skb_proto_4_to_6()' mangles 'shinfo->gso_size'  
>>
>> Doing this on an skb with a frag_list is doomed, in current gso_segment() state.
>>
>> A rewrite  would be needed (I believe I did so at some point, but Herbert Xu fought hard against it)
> 
> Thanks Eric,
> 
> - If a rewrite is still considered out of the question, how can one use
>   eBPF's bpf_skb_change_proto() safely without disabling GRO completely?
>   - e.g. is there a way to force the GROed skbs to fit into a layout that is
>     tolerated by skb_segment?
>   - alternatively can eBPF layer somehow enforce segmentation of the
>     original GROed skb before mangling the gso_size?
> 
> - Another thing that puzzles me is that we hit the BUG_ON rather rarely
>   and cannot yet reproduce synthetically. If skb_segment's handling of
>   skbs with a frag_list (that have gso_size mangled) is broken, I'd expect
>   to hit this more often... Any ideas?

skb_segment of a gro packet (especially with frag_list) is only supported 
if the geometry of the individual segments is not changed,
meaning that gso_size must remain the same.

> 
> - Suppose going for a rewrite, care to elaborate what's exactly missing
>   in skb_segment's logic?
>   I must admit I do not fully understand all the different code flows in
>   this function, it seems to support many different input skbs - any
>   assistance is highly appreciated.

Well, this is the point really.
The complexity of this function is so high that very few of us dare to touch it.

^ permalink raw reply

* Re: [PATCH v1 net-next 4/4] net: stmmac: setup higher frequency clk support for EHL & TGL
From: Florian Fainelli @ 2019-08-27 15:08 UTC (permalink / raw)
  To: Voon, Weifeng, Andrew Lunn
  Cc: David S. Miller, Maxime Coquelin, netdev@vger.kernel.org,
	linux-kernel@vger.kernel.org, Jose Abreu, Giuseppe Cavallaro,
	Alexandre Torgue, Ong, Boon Leong
In-Reply-To: <D6759987A7968C4889FDA6FA91D5CBC814758DB5@PGSMSX103.gar.corp.intel.com>



On 8/27/2019 3:38 AM, Voon, Weifeng wrote:
>>>> +#include <linux/clk-provider.h>
>>>>  #include <linux/pci.h>
>>>>  #include <linux/dmi.h>
>>>>
>>>> @@ -174,6 +175,19 @@ static int intel_mgbe_common_data(struct
>> pci_dev *pdev,
>>>>  	plat->axi->axi_blen[1] = 8;
>>>>  	plat->axi->axi_blen[2] = 16;
>>>>
>>>> +	plat->ptp_max_adj = plat->clk_ptp_rate;
>>>> +
>>>> +	/* Set system clock */
>>>> +	plat->stmmac_clk = clk_register_fixed_rate(&pdev->dev,
>>>> +						   "stmmac-clk", NULL, 0,
>>>> +						   plat->clk_ptp_rate);
>>>> +
>>>> +	if (IS_ERR(plat->stmmac_clk)) {
>>>> +		dev_warn(&pdev->dev, "Fail to register stmmac-clk\n");
>>>> +		plat->stmmac_clk = NULL;
>>>
>>> Don't you need to propagate at least EPROBE_DEFER here?
>>
>> Hi Florian
>>
>> Isn't a fixed rate clock a complete fake. There is no hardware behind it.
>> So can it return EPROBE_DEFER?
>>
>>     Andrew
> 
> Yes, there is no hardware behind it. So, I don't think we need to deferred probe
> and a warning message should be sufficient. Anyhow, please point it out if I miss
> out anything.

Looks good to me, thanks both for clarifying.
-- 
Florian

^ permalink raw reply

* Re: kernel/bpf/core.o: warning: objtool: ___bpf_prog_run.cold()+0x7: call without frame pointer save/setup
From: Josh Poimboeuf @ 2019-08-27 14:58 UTC (permalink / raw)
  To: He Zhe
  Cc: ast, daniel, kafai, songliubraving, yhs, ndesaulniers,
	miguel.ojeda.sandonis, luc.vanoostenryck, schwidefsky, gregkh,
	mst, gor, andreyknvl, liuxiaozhou, yamada.masahiro, linux-kernel,
	netdev, bpf
In-Reply-To: <2c416fe7-f6be-440b-b476-9fede1ea123c@windriver.com>

On Tue, Aug 27, 2019 at 10:43:27AM +0800, He Zhe wrote:
> 
> 
> On 8/26/19 11:18 PM, Josh Poimboeuf wrote:
> > On Mon, Aug 26, 2019 at 10:42:53PM +0800, He Zhe wrote:
> >> Hi All,
> >>
> >> Since 3193c0836f20 ("bpf: Disable GCC -fgcse optimization for ___bpf_prog_run()"),
> >> We have got the following warning,
> >> kernel/bpf/core.o: warning: objtool: ___bpf_prog_run.cold()+0x7: call without frame pointer save/setup
> >>
> >> If reverting the above commit, we will get the following warning,
> >> kernel/bpf/core.o: warning: objtool: ___bpf_prog_run()+0x8b9: sibling call from callable instruction with modified stack frame
> >> if CONFIG_RETPOLINE=n, and no warning if CONFIG_RETPOLINE=y
> > Can you please share the following:
> >
> > - core.o file
> 
> Attached.
> 
> >
> > The following would also be helpful for me to try to recreate it:
> >
> > - config file
> > - compiler version
> > - kernel version
> 
> I pasted them in the other reply.

Thanks.  I was able to recreate.  I reduced it to:

void a(b);
__attribute__((optimize(""))) c(void) { a(); }

Apparently '__attribute__((optimize()))' is overwriting GCC cmdline
flags, including -fno-omit-frame-pointer.  I had assumed it would append
instead of replace.

I'm guessing this is a GCC "feature" instead of a bug.  I'll need to
follow up.

-- 
Josh

^ permalink raw reply

* [PATCH V3 net 2/2] openvswitch: Clear the L4 portion of the key for "later" fragments.
From: Greg Rose @ 2019-08-27 14:58 UTC (permalink / raw)
  To: netdev, pshelar; +Cc: joe, Justin Pettit
In-Reply-To: <1566917890-22304-1-git-send-email-gvrose8192@gmail.com>

From: Justin Pettit <jpettit@ovn.org>

Only the first fragment in a datagram contains the L4 headers.  When the
Open vSwitch module parses a packet, it always sets the IP protocol
field in the key, but can only set the L4 fields on the first fragment.
The original behavior would not clear the L4 portion of the key, so
garbage values would be sent in the key for "later" fragments.  This
patch clears the L4 fields in that circumstance to prevent sending those
garbage values as part of the upcall.

Signed-off-by: Justin Pettit <jpettit@ovn.org>
---
 net/openvswitch/flow.c | 5 ++++-
 1 file changed, 4 insertions(+), 1 deletion(-)

diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c
index 005f762..9d81d2c 100644
--- a/net/openvswitch/flow.c
+++ b/net/openvswitch/flow.c
@@ -560,6 +560,7 @@ static int key_extract_l3l4(struct sk_buff *skb, struct sw_flow_key *key)
 		offset = nh->frag_off & htons(IP_OFFSET);
 		if (offset) {
 			key->ip.frag = OVS_FRAG_TYPE_LATER;
+			memset(&key->tp, 0, sizeof(key->tp));
 			return 0;
 		}
 		if (nh->frag_off & htons(IP_MF) ||
@@ -677,8 +678,10 @@ static int key_extract_l3l4(struct sk_buff *skb, struct sw_flow_key *key)
 			return error;
 		}
 
-		if (key->ip.frag == OVS_FRAG_TYPE_LATER)
+		if (key->ip.frag == OVS_FRAG_TYPE_LATER) {
+			memset(&key->tp, 0, sizeof(key->tp));
 			return 0;
+		}
 		if (skb_shinfo(skb)->gso_type & SKB_GSO_UDP)
 			key->ip.frag = OVS_FRAG_TYPE_FIRST;
 
-- 
1.8.3.1


^ permalink raw reply related

* [PATCH V3 net 1/2] openvswitch: Properly set L4 keys on "later" IP fragments
From: Greg Rose @ 2019-08-27 14:58 UTC (permalink / raw)
  To: netdev, pshelar; +Cc: joe, Greg Rose

When IP fragments are reassembled before being sent to conntrack, the
key from the last fragment is used.  Unless there are reordering
issues, the last fragment received will not contain the L4 ports, so the
key for the reassembled datagram won't contain them.  This patch updates
the key once we have a reassembled datagram.

The handle_fragments() function works on L3 headers so we pull the L3/L4
flow key update code from key_extract into a new function
'key_extract_l3l4'.  Then we add a another new function
ovs_flow_key_update_l3l4() and export it so that it is accessible by
handle_fragments() for conntrack packet reassembly.

Co-authored by: Justin Pettit <jpettit@ovn.org>
Signed-off-by: Greg Rose <gvrose8192@gmail.com>

---
V1 - V2: Broke out key l3l4 extraction
V2 - V3: Remove code that cleared SW_FLOW_KEY_INVALID for l3l4
         extraction
---
 net/openvswitch/conntrack.c |   5 ++
 net/openvswitch/flow.c      | 155 +++++++++++++++++++++++++-------------------
 net/openvswitch/flow.h      |   1 +
 3 files changed, 95 insertions(+), 66 deletions(-)

diff --git a/net/openvswitch/conntrack.c b/net/openvswitch/conntrack.c
index d8da647..05249eb 100644
--- a/net/openvswitch/conntrack.c
+++ b/net/openvswitch/conntrack.c
@@ -525,6 +525,11 @@ static int handle_fragments(struct net *net, struct sw_flow_key *key,
 		return -EPFNOSUPPORT;
 	}
 
+	/* The key extracted from the fragment that completed this datagram
+	 * likely didn't have an L4 header, so regenerate it.
+	 */
+	ovs_flow_key_update_l3l4(skb, key);
+
 	key->ip.frag = OVS_FRAG_TYPE_NONE;
 	skb_clear_hash(skb);
 	skb->ignore_df = 1;
diff --git a/net/openvswitch/flow.c b/net/openvswitch/flow.c
index bc89e16..005f762 100644
--- a/net/openvswitch/flow.c
+++ b/net/openvswitch/flow.c
@@ -523,78 +523,15 @@ static int parse_nsh(struct sk_buff *skb, struct sw_flow_key *key)
 }
 
 /**
- * key_extract - extracts a flow key from an Ethernet frame.
+ * key_extract_l3l4 - extracts L3/L4 header information.
  * @skb: sk_buff that contains the frame, with skb->data pointing to the
- * Ethernet header
+ *       L3 header
  * @key: output flow key
  *
- * The caller must ensure that skb->len >= ETH_HLEN.
- *
- * Returns 0 if successful, otherwise a negative errno value.
- *
- * Initializes @skb header fields as follows:
- *
- *    - skb->mac_header: the L2 header.
- *
- *    - skb->network_header: just past the L2 header, or just past the
- *      VLAN header, to the first byte of the L2 payload.
- *
- *    - skb->transport_header: If key->eth.type is ETH_P_IP or ETH_P_IPV6
- *      on output, then just past the IP header, if one is present and
- *      of a correct length, otherwise the same as skb->network_header.
- *      For other key->eth.type values it is left untouched.
- *
- *    - skb->protocol: the type of the data starting at skb->network_header.
- *      Equals to key->eth.type.
  */
-static int key_extract(struct sk_buff *skb, struct sw_flow_key *key)
+static int key_extract_l3l4(struct sk_buff *skb, struct sw_flow_key *key)
 {
 	int error;
-	struct ethhdr *eth;
-
-	/* Flags are always used as part of stats */
-	key->tp.flags = 0;
-
-	skb_reset_mac_header(skb);
-
-	/* Link layer. */
-	clear_vlan(key);
-	if (ovs_key_mac_proto(key) == MAC_PROTO_NONE) {
-		if (unlikely(eth_type_vlan(skb->protocol)))
-			return -EINVAL;
-
-		skb_reset_network_header(skb);
-		key->eth.type = skb->protocol;
-	} else {
-		eth = eth_hdr(skb);
-		ether_addr_copy(key->eth.src, eth->h_source);
-		ether_addr_copy(key->eth.dst, eth->h_dest);
-
-		__skb_pull(skb, 2 * ETH_ALEN);
-		/* We are going to push all headers that we pull, so no need to
-		* update skb->csum here.
-		*/
-
-		if (unlikely(parse_vlan(skb, key)))
-			return -ENOMEM;
-
-		key->eth.type = parse_ethertype(skb);
-		if (unlikely(key->eth.type == htons(0)))
-			return -ENOMEM;
-
-		/* Multiple tagged packets need to retain TPID to satisfy
-		 * skb_vlan_pop(), which will later shift the ethertype into
-		 * skb->protocol.
-		 */
-		if (key->eth.cvlan.tci & htons(VLAN_CFI_MASK))
-			skb->protocol = key->eth.cvlan.tpid;
-		else
-			skb->protocol = key->eth.type;
-
-		skb_reset_network_header(skb);
-		__skb_push(skb, skb->data - skb_mac_header(skb));
-	}
-	skb_reset_mac_len(skb);
 
 	/* Network layer. */
 	if (key->eth.type == htons(ETH_P_IP)) {
@@ -788,6 +725,92 @@ static int key_extract(struct sk_buff *skb, struct sw_flow_key *key)
 	return 0;
 }
 
+/**
+ * key_extract - extracts a flow key from an Ethernet frame.
+ * @skb: sk_buff that contains the frame, with skb->data pointing to the
+ * Ethernet header
+ * @key: output flow key
+ *
+ * The caller must ensure that skb->len >= ETH_HLEN.
+ *
+ * Returns 0 if successful, otherwise a negative errno value.
+ *
+ * Initializes @skb header fields as follows:
+ *
+ *    - skb->mac_header: the L2 header.
+ *
+ *    - skb->network_header: just past the L2 header, or just past the
+ *      VLAN header, to the first byte of the L2 payload.
+ *
+ *    - skb->transport_header: If key->eth.type is ETH_P_IP or ETH_P_IPV6
+ *      on output, then just past the IP header, if one is present and
+ *      of a correct length, otherwise the same as skb->network_header.
+ *      For other key->eth.type values it is left untouched.
+ *
+ *    - skb->protocol: the type of the data starting at skb->network_header.
+ *      Equals to key->eth.type.
+ */
+static int key_extract(struct sk_buff *skb, struct sw_flow_key *key)
+{
+	struct ethhdr *eth;
+
+	/* Flags are always used as part of stats */
+	key->tp.flags = 0;
+
+	skb_reset_mac_header(skb);
+
+	/* Link layer. */
+	clear_vlan(key);
+	if (ovs_key_mac_proto(key) == MAC_PROTO_NONE) {
+		if (unlikely(eth_type_vlan(skb->protocol)))
+			return -EINVAL;
+
+		skb_reset_network_header(skb);
+		key->eth.type = skb->protocol;
+	} else {
+		eth = eth_hdr(skb);
+		ether_addr_copy(key->eth.src, eth->h_source);
+		ether_addr_copy(key->eth.dst, eth->h_dest);
+
+		__skb_pull(skb, 2 * ETH_ALEN);
+		/* We are going to push all headers that we pull, so no need to
+		 * update skb->csum here.
+		 */
+
+		if (unlikely(parse_vlan(skb, key)))
+			return -ENOMEM;
+
+		key->eth.type = parse_ethertype(skb);
+		if (unlikely(key->eth.type == htons(0)))
+			return -ENOMEM;
+
+		/* Multiple tagged packets need to retain TPID to satisfy
+		 * skb_vlan_pop(), which will later shift the ethertype into
+		 * skb->protocol.
+		 */
+		if (key->eth.cvlan.tci & htons(VLAN_CFI_MASK))
+			skb->protocol = key->eth.cvlan.tpid;
+		else
+			skb->protocol = key->eth.type;
+
+		skb_reset_network_header(skb);
+		__skb_push(skb, skb->data - skb_mac_header(skb));
+	}
+
+	skb_reset_mac_len(skb);
+
+	/* Fill out L3/L4 key info, if any */
+	return key_extract_l3l4(skb, key);
+}
+
+/* In the case of conntrack fragment handling it expects L3 headers,
+ * add a helper.
+ */
+int ovs_flow_key_update_l3l4(struct sk_buff *skb, struct sw_flow_key *key)
+{
+	return key_extract_l3l4(skb, key);
+}
+
 int ovs_flow_key_update(struct sk_buff *skb, struct sw_flow_key *key)
 {
 	int res;
diff --git a/net/openvswitch/flow.h b/net/openvswitch/flow.h
index a5506e2..b830d5f 100644
--- a/net/openvswitch/flow.h
+++ b/net/openvswitch/flow.h
@@ -270,6 +270,7 @@ void ovs_flow_stats_get(const struct sw_flow *, struct ovs_flow_stats *,
 u64 ovs_flow_used_time(unsigned long flow_jiffies);
 
 int ovs_flow_key_update(struct sk_buff *skb, struct sw_flow_key *key);
+int ovs_flow_key_update_l3l4(struct sk_buff *skb, struct sw_flow_key *key);
 int ovs_flow_key_extract(const struct ip_tunnel_info *tun_info,
 			 struct sk_buff *skb,
 			 struct sw_flow_key *key);
-- 
1.8.3.1


^ permalink raw reply related

* Re: [PATCH v2 0/3] Add NETIF_F_HW_BR_CAP feature
From: Vladimir Oltean @ 2019-08-27 14:55 UTC (permalink / raw)
  To: Andrew Lunn
  Cc: Horatiu Vultur, Roopa Prabhu, nikolay, David S. Miller,
	UNGLinuxDriver, Alexandre Belloni, Allan W. Nielsen,
	Florian Fainelli, netdev, lkml, bridge
In-Reply-To: <20190827131824.GC11471@lunn.ch>

On Tue, 27 Aug 2019 at 16:20, Andrew Lunn <andrew@lunn.ch> wrote:
>
> > That sounds like a great idea. I was expecting to add this logic in the
> > set_rx_mode function of the driver. But unfortunetly, I got the calls to
> > this function before the dev->promiscuity is updated or not to get the
> > call at all. For example in case the port is member of a bridge and I try
> > to enable the promisc mode.
>
> Hi Horatiu
>
> What about the notifier? Is it called in all the conditions you need
> to know about?
>
> Or, you could consider adding a new switchdev call to pass this
> information to any switchdev driver which is interested in the
> information.
>
> At the moment, the DSA driver core does not pass onto the driver it
> should put a port into promisc mode. So pcap etc, will only see
> traffic directed to the CPU, not all the traffic ingressing the
> interface. If you put the needed core infrastructure into place, we
> could plumb it down from the DSA core to DSA drivers.
>
> Having said that, i don't actually know if the Marvell switches
> support this. Forward using the ATU and send a copy to the CPU?  What
> switches tend to support is port mirroring, sending all the traffic
> out another port. A couple of DSA drivers support that, via TC.
>

But the CPU port is not a valid destination for port mirroring in DSA,
I might add.

>         Andrew

Regards,
-Vladimir

^ permalink raw reply

* [PATCH] wil6210: Delete an unnecessary kfree() call in wil_tid_ampdu_rx_alloc()
From: Markus Elfring @ 2019-08-27 14:44 UTC (permalink / raw)
  To: linux-wireless, netdev, wil6210, David S. Miller, Kalle Valo,
	Maya Erez
  Cc: LKML, kernel-janitors

From: Markus Elfring <elfring@users.sourceforge.net>
Date: Tue, 27 Aug 2019 16:39:02 +0200

A null pointer would be passed to a call of the function “kfree”
directly after a call of the function “kcalloc” failed at one place.
Remove this superfluous function call.

This issue was detected by using the Coccinelle software.

Signed-off-by: Markus Elfring <elfring@users.sourceforge.net>
---
 drivers/net/wireless/ath/wil6210/rx_reorder.c | 1 -
 1 file changed, 1 deletion(-)

diff --git a/drivers/net/wireless/ath/wil6210/rx_reorder.c b/drivers/net/wireless/ath/wil6210/rx_reorder.c
index 784239bcb3a6..13246d216803 100644
--- a/drivers/net/wireless/ath/wil6210/rx_reorder.c
+++ b/drivers/net/wireless/ath/wil6210/rx_reorder.c
@@ -260,7 +260,6 @@ struct wil_tid_ampdu_rx *wil_tid_ampdu_rx_alloc(struct wil6210_priv *wil,
 	r->reorder_buf =
 		kcalloc(size, sizeof(struct sk_buff *), GFP_KERNEL);
 	if (!r->reorder_buf) {
-		kfree(r->reorder_buf);
 		kfree(r);
 		return NULL;
 	}
--
2.23.0


^ permalink raw reply related

* Re: [PATCH V2 net 1/2] openvswitch: Properly set L4 keys on "later" IP fragments
From: Gregory Rose @ 2019-08-27 14:27 UTC (permalink / raw)
  To: Pravin Shelar; +Cc: Linux Kernel Network Developers, Joe Stringer
In-Reply-To: <CAOrHB_B3MZF4UyZgemTYr1uG0bEg0La6ShsJ8hpeVSvjceDdEA@mail.gmail.com>


On 8/26/2019 10:13 PM, Pravin Shelar wrote:
> On Mon, Aug 26, 2019 at 1:46 PM Greg Rose <gvrose8192@gmail.com> wrote:
>> When IP fragments are reassembled before being sent to conntrack, the
>> key from the last fragment is used.  Unless there are reordering
>> issues, the last fragment received will not contain the L4 ports, so the
>> key for the reassembled datagram won't contain them.  This patch updates
>> the key once we have a reassembled datagram.
>>
>> The handle_fragments() function works on L3 headers so we pull the L3/L4
>> flow key update code from key_extract into a new function
>> 'key_extract_l3l4'.  Then we add a another new function
>> ovs_flow_key_update_l3l4() and export it so that it is accessible by
>> handle_fragments() for conntrack packet reassembly.
>>
>> Co-authored by: Justin Pettit <jpettit@ovn.org>
>> Signed-off-by: Greg Rose <gvrose8192@gmail.com>
>> ---
>>   net/openvswitch/conntrack.c |   5 ++
>>   net/openvswitch/flow.c      | 161 ++++++++++++++++++++++++++------------------
>>   net/openvswitch/flow.h      |   1 +
>>   3 files changed, 101 insertions(+), 66 deletions(-)
>>
> ...
> ...
>> +/**
>> + * key_extract - extracts a flow key from an Ethernet frame.
>> + * @skb: sk_buff that contains the frame, with skb->data pointing to the
>> + * Ethernet header
>> + * @key: output flow key
>> + *
>> + * The caller must ensure that skb->len >= ETH_HLEN.
>> + *
>> + * Returns 0 if successful, otherwise a negative errno value.
>> + *
>> + * Initializes @skb header fields as follows:
>> + *
>> + *    - skb->mac_header: the L2 header.
>> + *
>> + *    - skb->network_header: just past the L2 header, or just past the
>> + *      VLAN header, to the first byte of the L2 payload.
>> + *
>> + *    - skb->transport_header: If key->eth.type is ETH_P_IP or ETH_P_IPV6
>> + *      on output, then just past the IP header, if one is present and
>> + *      of a correct length, otherwise the same as skb->network_header.
>> + *      For other key->eth.type values it is left untouched.
>> + *
>> + *    - skb->protocol: the type of the data starting at skb->network_header.
>> + *      Equals to key->eth.type.
>> + */
>> +static int key_extract(struct sk_buff *skb, struct sw_flow_key *key)
>> +{
>> +       struct ethhdr *eth;
>> +
>> +       /* Flags are always used as part of stats */
>> +       key->tp.flags = 0;
>> +
>> +       skb_reset_mac_header(skb);
>> +
>> +       /* Link layer. */
>> +       clear_vlan(key);
>> +       if (ovs_key_mac_proto(key) == MAC_PROTO_NONE) {
>> +               if (unlikely(eth_type_vlan(skb->protocol)))
>> +                       return -EINVAL;
>> +
>> +               skb_reset_network_header(skb);
>> +               key->eth.type = skb->protocol;
>> +       } else {
>> +               eth = eth_hdr(skb);
>> +               ether_addr_copy(key->eth.src, eth->h_source);
>> +               ether_addr_copy(key->eth.dst, eth->h_dest);
>> +
>> +               __skb_pull(skb, 2 * ETH_ALEN);
>> +               /* We are going to push all headers that we pull, so no need to
>> +                * update skb->csum here.
>> +                */
>> +
>> +               if (unlikely(parse_vlan(skb, key)))
>> +                       return -ENOMEM;
>> +
>> +               key->eth.type = parse_ethertype(skb);
>> +               if (unlikely(key->eth.type == htons(0)))
>> +                       return -ENOMEM;
>> +
>> +               /* Multiple tagged packets need to retain TPID to satisfy
>> +                * skb_vlan_pop(), which will later shift the ethertype into
>> +                * skb->protocol.
>> +                */
>> +               if (key->eth.cvlan.tci & htons(VLAN_CFI_MASK))
>> +                       skb->protocol = key->eth.cvlan.tpid;
>> +               else
>> +                       skb->protocol = key->eth.type;
>> +
>> +               skb_reset_network_header(skb);
>> +               __skb_push(skb, skb->data - skb_mac_header(skb));
>> +       }
>> +
>> +       skb_reset_mac_len(skb);
>> +
>> +       /* Fill out L3/L4 key info, if any */
>> +       return key_extract_l3l4(skb, key);
>> +}
>> +
>> +/* In the case of conntrack fragment handling it expects L3 headers,
>> + * add a helper.
>> + */
>> +int ovs_flow_key_update_l3l4(struct sk_buff *skb, struct sw_flow_key *key)
>> +{
>> +       int res;
>> +
>> +       res = key_extract_l3l4(skb, key);
>> +       if (!res)
>> +               key->mac_proto &= ~SW_FLOW_KEY_INVALID;
>> +
> Since this is not full key extract, this flag can not be unset.
>
> Otherwise looks good.

Thanks Pravin,

I'll send along a V3 patch set with that change.

- Greg

^ permalink raw reply

* [net-next] net: sched: pie: enable timestamp based delay calculation
From: Gautam Ramakrishnan @ 2019-08-27 14:19 UTC (permalink / raw)
  To: netdev
  Cc: jhs, davem, xiyou.wangcong, Gautam Ramakrishnan, Leslie Monis,
	Mohit P . Tahiliani, Dave Taht

RFC 8033 suggests an alternative approach to calculate the queue
delay in PIE by using per packet timestamps. This patch enables the
PIE implementation to do this.

The calculation of queue delay is as follows:
	qdelay = now - packet_enqueue_time

To enable the use of timestamps:
	modprobe sch_pie use_timestamps=1

Signed-off-by: Gautam Ramakrishnan <gautamramk@gmail.com>
Signed-off-by: Leslie Monis <lesliemonis@gmail.com>
Signed-off-by: Mohit P. Tahiliani <tahiliani@nitk.edu.in>
Cc: Dave Taht <dave.taht@gmail.com>
---
 net/sched/sch_pie.c | 55 ++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 49 insertions(+), 6 deletions(-)

diff --git a/net/sched/sch_pie.c b/net/sched/sch_pie.c
index df98a887eb89..1a19c77e6e42 100644
--- a/net/sched/sch_pie.c
+++ b/net/sched/sch_pie.c
@@ -19,12 +19,18 @@
 #include <linux/skbuff.h>
 #include <net/pkt_sched.h>
 #include <net/inet_ecn.h>
+#include <linux/module.h>
+#include <linux/moduleparam.h>
 
 #define QUEUE_THRESHOLD 16384
 #define DQCOUNT_INVALID -1
 #define MAX_PROB 0xffffffffffffffff
 #define PIE_SCALE 8
 
+static unsigned int use_timestamps; /* to calculate delay */
+module_param(use_timestamps, int, 0644);
+MODULE_PARM_DESC(use_timestamps, "enables timestamp based delay calculation.");
+
 /* parameters used */
 struct pie_params {
 	psched_time_t target;	/* user specified target delay in pschedtime */
@@ -79,6 +85,27 @@ static void pie_params_init(struct pie_params *params)
 	params->bytemode = false;
 }
 
+/* private skb vars */
+struct pie_skb_cb {
+	psched_time_t enqueue_time;
+};
+
+static struct pie_skb_cb *get_pie_cb(const struct sk_buff *skb)
+{
+	qdisc_cb_private_validate(skb, sizeof(struct pie_skb_cb));
+	return (struct pie_skb_cb *)qdisc_skb_cb(skb)->data;
+}
+
+static psched_time_t pie_get_enqueue_time(const struct sk_buff *skb)
+{
+	return get_pie_cb(skb)->enqueue_time;
+}
+
+static void pie_set_enqueue_time(struct sk_buff *skb)
+{
+	get_pie_cb(skb)->enqueue_time = psched_get_time();
+}
+
 static void pie_vars_init(struct pie_vars *vars)
 {
 	vars->dq_count = DQCOUNT_INVALID;
@@ -172,6 +199,9 @@ static int pie_qdisc_enqueue(struct sk_buff *skb, struct Qdisc *sch,
 
 	/* we can enqueue the packet */
 	if (enqueue) {
+		if (use_timestamps)
+			pie_set_enqueue_time(skb);
+
 		q->stats.packets_in++;
 		if (qdisc_qlen(sch) > q->stats.maxq)
 			q->stats.maxq = qdisc_qlen(sch);
@@ -323,6 +353,10 @@ static void pie_process_dequeue(struct Qdisc *sch, struct sk_buff *skb)
 				else
 					q->vars.burst_time = 0;
 			}
+
+			if (use_timestamps)
+				q->vars.qdelay = now -
+						 pie_get_enqueue_time(skb);
 		}
 	}
 }
@@ -332,19 +366,25 @@ static void calculate_probability(struct Qdisc *sch)
 	struct pie_sched_data *q = qdisc_priv(sch);
 	u32 qlen = sch->qstats.backlog;	/* queue size in bytes */
 	psched_time_t qdelay = 0;	/* in pschedtime */
-	psched_time_t qdelay_old = q->vars.qdelay;	/* in pschedtime */
+	psched_time_t qdelay_old = 0;	/* in pschedtime */
 	s64 delta = 0;		/* determines the change in probability */
 	u64 oldprob;
 	u64 alpha, beta;
 	u32 power;
 	bool update_prob = true;
 
-	q->vars.qdelay_old = q->vars.qdelay;
+	if (use_timestamps) {
+		qdelay = q->vars.qdelay;
+		qdelay_old = q->vars.qdelay_old;
+	} else {
+		qdelay_old = q->vars.qdelay;
+		q->vars.qdelay_old = q->vars.qdelay;
 
-	if (q->vars.avg_dq_rate > 0)
-		qdelay = (qlen << PIE_SCALE) / q->vars.avg_dq_rate;
-	else
-		qdelay = 0;
+		if (q->vars.avg_dq_rate > 0)
+			qdelay = (qlen << PIE_SCALE) / q->vars.avg_dq_rate;
+		else
+			qdelay = 0;
+	}
 
 	/* If qdelay is zero and qlen is not, it means qlen is very small, less
 	 * than dequeue_rate, so we do not update probabilty in this round
@@ -438,6 +478,9 @@ static void calculate_probability(struct Qdisc *sch)
 	    q->vars.prob == 0 &&
 	    q->vars.avg_dq_rate > 0)
 		pie_vars_init(&q->vars);
+
+	if (use_timestamps)
+		q->vars.qdelay_old = qdelay;
 }
 
 static void pie_timer(struct timer_list *t)
-- 
2.17.1


^ permalink raw reply related

* [PATCH net-next v2 2/3] dpaa2-eth: Use stored link settings
From: Ioana Radulescu @ 2019-08-27 14:15 UTC (permalink / raw)
  To: netdev, davem; +Cc: andrew, ioana.ciornei
In-Reply-To: <1566915351-32075-1-git-send-email-ruxandra.radulescu@nxp.com>

Whenever a link state change occurs, we get notified and save
the new link settings in the device's private data. In ethtool
get_link_ksettings, use the stored state instead of interrogating
the firmware each time.

Signed-off-by: Ioana Radulescu <ruxandra.radulescu@nxp.com>
---
v2: split from main pause frames patch

 drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c     |  6 ++++--
 drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c | 15 +++------------
 2 files changed, 7 insertions(+), 14 deletions(-)

diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
index 0acb115..2c6f9b1 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
@@ -1222,9 +1222,8 @@ static int link_state_update(struct dpaa2_eth_priv *priv)
 
 	/* Chech link state; speed / duplex changes are not treated yet */
 	if (priv->link_state.up == state.up)
-		return 0;
+		goto out;
 
-	priv->link_state = state;
 	if (state.up) {
 		netif_carrier_on(priv->net_dev);
 		netif_tx_start_all_queues(priv->net_dev);
@@ -1236,6 +1235,9 @@ static int link_state_update(struct dpaa2_eth_priv *priv)
 	netdev_info(priv->net_dev, "Link Event: state %s\n",
 		    state.up ? "up" : "down");
 
+out:
+	priv->link_state = state;
+
 	return 0;
 }
 
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c
index 5c9816b..fb17042 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c
@@ -78,23 +78,14 @@ static int
 dpaa2_eth_get_link_ksettings(struct net_device *net_dev,
 			     struct ethtool_link_ksettings *link_settings)
 {
-	struct dpni_link_state state = {0};
-	int err = 0;
 	struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
 
-	err = dpni_get_link_state(priv->mc_io, 0, priv->mc_token, &state);
-	if (err) {
-		netdev_err(net_dev, "ERROR %d getting link state\n", err);
-		goto out;
-	}
-
 	link_settings->base.autoneg = AUTONEG_DISABLE;
-	if (!(state.options & DPNI_LINK_OPT_HALF_DUPLEX))
+	if (!(priv->link_state.options & DPNI_LINK_OPT_HALF_DUPLEX))
 		link_settings->base.duplex = DUPLEX_FULL;
-	link_settings->base.speed = state.rate;
+	link_settings->base.speed = priv->link_state.rate;
 
-out:
-	return err;
+	return 0;
 }
 
 static void dpaa2_eth_get_strings(struct net_device *netdev, u32 stringset,
-- 
2.7.4


^ permalink raw reply related

* [PATCH net-next v2 3/3] dpaa2-eth: Add pause frame support
From: Ioana Radulescu @ 2019-08-27 14:15 UTC (permalink / raw)
  To: netdev, davem; +Cc: andrew, ioana.ciornei
In-Reply-To: <1566915351-32075-1-git-send-email-ruxandra.radulescu@nxp.com>

Starting with firmware version MC10.18.0, we have support for
L2 flow control. Asymmetrical configuration (Rx or Tx only) is
supported, but not pause frame autonegotioation.

Pause frame configuration is done via ethtool. By default, we start
with flow control enabled on both Rx and Tx. Changes are propagated
to hardware through firmware commands.

The hardware can automatically send pause frames when the number
of buffers in the pool goes below a predefined threshold. Due to
this, flow control is incompatible with Rx frame queue taildrop
(both mechanisms target the case when processing of ingress
frames can't keep up with the Rx rate; for large frames, the number
of buffers in the pool may never get low enough to trigger pause
frames as long as taildrop is enabled). So we set pause frame
generation and Rx FQ taildrop as mutually exclusive.

Signed-off-by: Ioana Radulescu <ruxandra.radulescu@nxp.com>
---
v2: split priv->link_state changes in a separate patch
    always set pause->autoneg to false
    return -EOPNOTSUPP if user tries to set pause->autoneg

 drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c   | 79 +++++++++++++++++++---
 drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h   |  7 ++
 .../net/ethernet/freescale/dpaa2/dpaa2-ethtool.c   | 55 +++++++++++++++
 drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h    |  3 +-
 drivers/net/ethernet/freescale/dpaa2/dpni.c        | 40 ++++++++++-
 drivers/net/ethernet/freescale/dpaa2/dpni.h        |  5 ++
 6 files changed, 176 insertions(+), 13 deletions(-)

diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
index 2c6f9b1..e0816d6 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.c
@@ -1208,9 +1208,37 @@ static void disable_ch_napi(struct dpaa2_eth_priv *priv)
 	}
 }
 
+static void dpaa2_eth_set_rx_taildrop(struct dpaa2_eth_priv *priv, bool enable)
+{
+	struct dpni_taildrop td = {0};
+	int i, err;
+
+	if (priv->rx_td_enabled == enable)
+		return;
+
+	td.enable = enable;
+	td.threshold = DPAA2_ETH_TAILDROP_THRESH;
+
+	for (i = 0; i < priv->num_fqs; i++) {
+		if (priv->fq[i].type != DPAA2_RX_FQ)
+			continue;
+		err = dpni_set_taildrop(priv->mc_io, 0, priv->mc_token,
+					DPNI_CP_QUEUE, DPNI_QUEUE_RX, 0,
+					priv->fq[i].flowid, &td);
+		if (err) {
+			netdev_err(priv->net_dev,
+				   "dpni_set_taildrop() failed\n");
+			break;
+		}
+	}
+
+	priv->rx_td_enabled = enable;
+}
+
 static int link_state_update(struct dpaa2_eth_priv *priv)
 {
 	struct dpni_link_state state = {0};
+	bool tx_pause;
 	int err;
 
 	err = dpni_get_link_state(priv->mc_io, 0, priv->mc_token, &state);
@@ -1220,6 +1248,14 @@ static int link_state_update(struct dpaa2_eth_priv *priv)
 		return err;
 	}
 
+	/* If Tx pause frame settings have changed, we need to update
+	 * Rx FQ taildrop configuration as well. We configure taildrop
+	 * only when pause frame generation is disabled.
+	 */
+	tx_pause = !!(state.options & DPNI_LINK_OPT_PAUSE) ^
+		   !!(state.options & DPNI_LINK_OPT_ASYM_PAUSE);
+	dpaa2_eth_set_rx_taildrop(priv, !tx_pause);
+
 	/* Chech link state; speed / duplex changes are not treated yet */
 	if (priv->link_state.up == state.up)
 		goto out;
@@ -2445,6 +2481,32 @@ static void set_enqueue_mode(struct dpaa2_eth_priv *priv)
 		priv->enqueue = dpaa2_eth_enqueue_fq;
 }
 
+static int set_pause(struct dpaa2_eth_priv *priv)
+{
+	struct device *dev = priv->net_dev->dev.parent;
+	struct dpni_link_cfg link_cfg = {0};
+	int err;
+
+	/* Get the default link options so we don't override other flags */
+	err = dpni_get_link_cfg(priv->mc_io, 0, priv->mc_token, &link_cfg);
+	if (err) {
+		dev_err(dev, "dpni_get_link_cfg() failed\n");
+		return err;
+	}
+
+	link_cfg.options |= DPNI_LINK_OPT_PAUSE;
+	link_cfg.options &= ~DPNI_LINK_OPT_ASYM_PAUSE;
+	err = dpni_set_link_cfg(priv->mc_io, 0, priv->mc_token, &link_cfg);
+	if (err) {
+		dev_err(dev, "dpni_set_link_cfg() failed\n");
+		return err;
+	}
+
+	priv->link_state.options = link_cfg.options;
+
+	return 0;
+}
+
 /* Configure the DPNI object this interface is associated with */
 static int setup_dpni(struct fsl_mc_device *ls_dev)
 {
@@ -2500,6 +2562,13 @@ static int setup_dpni(struct fsl_mc_device *ls_dev)
 
 	set_enqueue_mode(priv);
 
+	/* Enable pause frame support */
+	if (dpaa2_eth_has_pause_support(priv)) {
+		err = set_pause(priv);
+		if (err)
+			goto close;
+	}
+
 	priv->cls_rules = devm_kzalloc(dev, sizeof(struct dpaa2_eth_cls_rule) *
 				       dpaa2_eth_fs_count(priv), GFP_KERNEL);
 	if (!priv->cls_rules)
@@ -2531,7 +2600,6 @@ static int setup_rx_flow(struct dpaa2_eth_priv *priv,
 	struct device *dev = priv->net_dev->dev.parent;
 	struct dpni_queue queue;
 	struct dpni_queue_id qid;
-	struct dpni_taildrop td;
 	int err;
 
 	err = dpni_get_queue(priv->mc_io, 0, priv->mc_token,
@@ -2556,15 +2624,6 @@ static int setup_rx_flow(struct dpaa2_eth_priv *priv,
 		return err;
 	}
 
-	td.enable = 1;
-	td.threshold = DPAA2_ETH_TAILDROP_THRESH;
-	err = dpni_set_taildrop(priv->mc_io, 0, priv->mc_token, DPNI_CP_QUEUE,
-				DPNI_QUEUE_RX, 0, fq->flowid, &td);
-	if (err) {
-		dev_err(dev, "dpni_set_threshold() failed\n");
-		return err;
-	}
-
 	/* xdp_rxq setup */
 	err = xdp_rxq_info_reg(&fq->channel->xdp_rxq, priv->net_dev,
 			       fq->flowid);
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
index 9af18c2..8a0e65b 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-eth.h
@@ -392,6 +392,7 @@ struct dpaa2_eth_priv {
 	struct dpaa2_eth_drv_stats __percpu *percpu_extras;
 
 	u16 mc_token;
+	u8 rx_td_enabled;
 
 	struct dpni_link_state link_state;
 	bool do_link_poll;
@@ -476,6 +477,12 @@ enum dpaa2_eth_rx_dist {
 #define DPAA2_ETH_DIST_L4DST		BIT(8)
 #define DPAA2_ETH_DIST_ALL		(~0ULL)
 
+#define DPNI_PAUSE_VER_MAJOR		7
+#define DPNI_PAUSE_VER_MINOR		13
+#define dpaa2_eth_has_pause_support(priv)			\
+	(dpaa2_eth_cmp_dpni_ver((priv), DPNI_PAUSE_VER_MAJOR,	\
+				DPNI_PAUSE_VER_MINOR) >= 0)
+
 static inline
 unsigned int dpaa2_eth_needed_headroom(struct dpaa2_eth_priv *priv,
 				       struct sk_buff *skb)
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c
index fb17042..93076fe 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c
@@ -88,6 +88,59 @@ dpaa2_eth_get_link_ksettings(struct net_device *net_dev,
 	return 0;
 }
 
+static void dpaa2_eth_get_pauseparam(struct net_device *net_dev,
+				     struct ethtool_pauseparam *pause)
+{
+	struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
+	u64 link_options = priv->link_state.options;
+
+	pause->rx_pause = !!(link_options & DPNI_LINK_OPT_PAUSE);
+	pause->tx_pause = pause->rx_pause ^
+			  !!(link_options & DPNI_LINK_OPT_ASYM_PAUSE);
+	pause->autoneg = AUTONEG_DISABLE;
+}
+
+static int dpaa2_eth_set_pauseparam(struct net_device *net_dev,
+				    struct ethtool_pauseparam *pause)
+{
+	struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
+	struct dpni_link_cfg cfg = {0};
+	int err;
+
+	if (!dpaa2_eth_has_pause_support(priv)) {
+		netdev_info(net_dev, "No pause frame support for DPNI version < %d.%d\n",
+			    DPNI_PAUSE_VER_MAJOR, DPNI_PAUSE_VER_MINOR);
+		return -EOPNOTSUPP;
+	}
+
+	if (pause->autoneg)
+		return -EOPNOTSUPP;
+
+	cfg.rate = priv->link_state.rate;
+	cfg.options = priv->link_state.options;
+	if (pause->rx_pause)
+		cfg.options |= DPNI_LINK_OPT_PAUSE;
+	else
+		cfg.options &= ~DPNI_LINK_OPT_PAUSE;
+	if (!!pause->rx_pause ^ !!pause->tx_pause)
+		cfg.options |= DPNI_LINK_OPT_ASYM_PAUSE;
+	else
+		cfg.options &= ~DPNI_LINK_OPT_ASYM_PAUSE;
+
+	if (cfg.options == priv->link_state.options)
+		return 0;
+
+	err = dpni_set_link_cfg(priv->mc_io, 0, priv->mc_token, &cfg);
+	if (err) {
+		netdev_err(net_dev, "dpni_set_link_state failed\n");
+		return err;
+	}
+
+	priv->link_state.options = cfg.options;
+
+	return 0;
+}
+
 static void dpaa2_eth_get_strings(struct net_device *netdev, u32 stringset,
 				  u8 *data)
 {
@@ -664,6 +717,8 @@ const struct ethtool_ops dpaa2_ethtool_ops = {
 	.get_drvinfo = dpaa2_eth_get_drvinfo,
 	.get_link = ethtool_op_get_link,
 	.get_link_ksettings = dpaa2_eth_get_link_ksettings,
+	.get_pauseparam = dpaa2_eth_get_pauseparam,
+	.set_pauseparam = dpaa2_eth_set_pauseparam,
 	.get_sset_count = dpaa2_eth_get_sset_count,
 	.get_ethtool_stats = dpaa2_eth_get_ethtool_stats,
 	.get_strings = dpaa2_eth_get_strings,
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h b/drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h
index 7b44d7d..d9b6918 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h
+++ b/drivers/net/ethernet/freescale/dpaa2/dpni-cmd.h
@@ -84,6 +84,7 @@
 
 #define DPNI_CMDID_SET_RX_FS_DIST			DPNI_CMD(0x273)
 #define DPNI_CMDID_SET_RX_HASH_DIST			DPNI_CMD(0x274)
+#define DPNI_CMDID_GET_LINK_CFG				DPNI_CMD(0x278)
 
 /* Macros for accessing command fields smaller than 1byte */
 #define DPNI_MASK(field)	\
@@ -284,7 +285,7 @@ struct dpni_rsp_get_statistics {
 	__le64 counter[DPNI_STATISTICS_CNT];
 };
 
-struct dpni_cmd_set_link_cfg {
+struct dpni_cmd_link_cfg {
 	/* cmd word 0 */
 	__le64 pad0;
 	/* cmd word 1 */
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpni.c b/drivers/net/ethernet/freescale/dpaa2/dpni.c
index 220dfc8..05e3089 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpni.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpni.c
@@ -838,13 +838,13 @@ int dpni_set_link_cfg(struct fsl_mc_io *mc_io,
 		      const struct dpni_link_cfg *cfg)
 {
 	struct fsl_mc_command cmd = { 0 };
-	struct dpni_cmd_set_link_cfg *cmd_params;
+	struct dpni_cmd_link_cfg *cmd_params;
 
 	/* prepare command */
 	cmd.header = mc_encode_cmd_header(DPNI_CMDID_SET_LINK_CFG,
 					  cmd_flags,
 					  token);
-	cmd_params = (struct dpni_cmd_set_link_cfg *)cmd.params;
+	cmd_params = (struct dpni_cmd_link_cfg *)cmd.params;
 	cmd_params->rate = cpu_to_le32(cfg->rate);
 	cmd_params->options = cpu_to_le64(cfg->options);
 
@@ -853,6 +853,42 @@ int dpni_set_link_cfg(struct fsl_mc_io *mc_io,
 }
 
 /**
+ * dpni_get_link_cfg() - return the link configuration
+ * @mc_io:	Pointer to MC portal's I/O object
+ * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
+ * @token:	Token of DPNI object
+ * @cfg:	Link configuration from dpni object
+ *
+ * Return:	'0' on Success; Error code otherwise.
+ */
+int dpni_get_link_cfg(struct fsl_mc_io *mc_io,
+		      u32 cmd_flags,
+		      u16 token,
+		      struct dpni_link_cfg *cfg)
+{
+	struct fsl_mc_command cmd = { 0 };
+	struct dpni_cmd_link_cfg *rsp_params;
+	int err;
+
+	/* prepare command */
+	cmd.header = mc_encode_cmd_header(DPNI_CMDID_GET_LINK_CFG,
+					  cmd_flags,
+					  token);
+
+	/* send command to mc*/
+	err = mc_send_command(mc_io, &cmd);
+	if (err)
+		return err;
+
+	/* retrieve response parameters */
+	rsp_params = (struct dpni_cmd_link_cfg *)cmd.params;
+	cfg->rate = le32_to_cpu(rsp_params->rate);
+	cfg->options = le64_to_cpu(rsp_params->options);
+
+	return err;
+}
+
+/**
  * dpni_get_link_state() - Return the link state (either up or down)
  * @mc_io:	Pointer to MC portal's I/O object
  * @cmd_flags:	Command flags; one or more of 'MC_CMD_FLAG_'
diff --git a/drivers/net/ethernet/freescale/dpaa2/dpni.h b/drivers/net/ethernet/freescale/dpaa2/dpni.h
index a521242..3e8fc6c 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpni.h
+++ b/drivers/net/ethernet/freescale/dpaa2/dpni.h
@@ -485,6 +485,11 @@ int dpni_set_link_cfg(struct fsl_mc_io			*mc_io,
 		      u16				token,
 		      const struct dpni_link_cfg	*cfg);
 
+int dpni_get_link_cfg(struct fsl_mc_io			*mc_io,
+		      u32				cmd_flags,
+		      u16				token,
+		      struct dpni_link_cfg		*cfg);
+
 /**
  * struct dpni_link_state - Structure representing DPNI link state
  * @rate: Rate
-- 
2.7.4


^ permalink raw reply related

* [PATCH net-next v2 1/3] dpaa2-eth: Remove support for changing link settings
From: Ioana Radulescu @ 2019-08-27 14:15 UTC (permalink / raw)
  To: netdev, davem; +Cc: andrew, ioana.ciornei

We only support fixed-link for now, so there is no point in
offering users the option to change link settings via ethtool.

Functionally there is no change, since firmware prevents us from
changing link parameters anyway.

Signed-off-by: Ioana Radulescu <ruxandra.radulescu@nxp.com>
---
v2: new patch

 .../net/ethernet/freescale/dpaa2/dpaa2-ethtool.c   | 51 +---------------------
 1 file changed, 1 insertion(+), 50 deletions(-)

diff --git a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c
index 7b182f4..5c9816b 100644
--- a/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c
+++ b/drivers/net/ethernet/freescale/dpaa2/dpaa2-ethtool.c
@@ -88,13 +88,7 @@ dpaa2_eth_get_link_ksettings(struct net_device *net_dev,
 		goto out;
 	}
 
-	/* At the moment, we have no way of interrogating the DPMAC
-	 * from the DPNI side - and for that matter there may exist
-	 * no DPMAC at all. So for now we just don't report anything
-	 * beyond the DPNI attributes.
-	 */
-	if (state.options & DPNI_LINK_OPT_AUTONEG)
-		link_settings->base.autoneg = AUTONEG_ENABLE;
+	link_settings->base.autoneg = AUTONEG_DISABLE;
 	if (!(state.options & DPNI_LINK_OPT_HALF_DUPLEX))
 		link_settings->base.duplex = DUPLEX_FULL;
 	link_settings->base.speed = state.rate;
@@ -103,48 +97,6 @@ dpaa2_eth_get_link_ksettings(struct net_device *net_dev,
 	return err;
 }
 
-#define DPNI_DYNAMIC_LINK_SET_VER_MAJOR		7
-#define DPNI_DYNAMIC_LINK_SET_VER_MINOR		1
-static int
-dpaa2_eth_set_link_ksettings(struct net_device *net_dev,
-			     const struct ethtool_link_ksettings *link_settings)
-{
-	struct dpni_link_cfg cfg = {0};
-	struct dpaa2_eth_priv *priv = netdev_priv(net_dev);
-	int err = 0;
-
-	/* If using an older MC version, the DPNI must be down
-	 * in order to be able to change link settings. Taking steps to let
-	 * the user know that.
-	 */
-	if (dpaa2_eth_cmp_dpni_ver(priv, DPNI_DYNAMIC_LINK_SET_VER_MAJOR,
-				   DPNI_DYNAMIC_LINK_SET_VER_MINOR) < 0) {
-		if (netif_running(net_dev)) {
-			netdev_info(net_dev, "Interface must be brought down first.\n");
-			return -EACCES;
-		}
-	}
-
-	cfg.rate = link_settings->base.speed;
-	if (link_settings->base.autoneg == AUTONEG_ENABLE)
-		cfg.options |= DPNI_LINK_OPT_AUTONEG;
-	else
-		cfg.options &= ~DPNI_LINK_OPT_AUTONEG;
-	if (link_settings->base.duplex  == DUPLEX_HALF)
-		cfg.options |= DPNI_LINK_OPT_HALF_DUPLEX;
-	else
-		cfg.options &= ~DPNI_LINK_OPT_HALF_DUPLEX;
-
-	err = dpni_set_link_cfg(priv->mc_io, 0, priv->mc_token, &cfg);
-	if (err)
-		/* ethtool will be loud enough if we return an error; no point
-		 * in putting our own error message on the console by default
-		 */
-		netdev_dbg(net_dev, "ERROR %d setting link cfg\n", err);
-
-	return err;
-}
-
 static void dpaa2_eth_get_strings(struct net_device *netdev, u32 stringset,
 				  u8 *data)
 {
@@ -721,7 +673,6 @@ const struct ethtool_ops dpaa2_ethtool_ops = {
 	.get_drvinfo = dpaa2_eth_get_drvinfo,
 	.get_link = ethtool_op_get_link,
 	.get_link_ksettings = dpaa2_eth_get_link_ksettings,
-	.set_link_ksettings = dpaa2_eth_set_link_ksettings,
 	.get_sset_count = dpaa2_eth_get_sset_count,
 	.get_ethtool_stats = dpaa2_eth_get_ethtool_stats,
 	.get_strings = dpaa2_eth_get_strings,
-- 
2.7.4


^ permalink raw reply related

* Re: [PATCH net-next v5 6/6] net: dsa: mv88e6xxx: fully support SERDES on Topaz family
From: Andrew Lunn @ 2019-08-27 13:57 UTC (permalink / raw)
  To: Marek Behún
  Cc: Vivien Didelot, netdev, Florian Fainelli, Vladimir Oltean
In-Reply-To: <20190826213155.14685-7-marek.behun@nic.cz>

On Mon, Aug 26, 2019 at 11:31:55PM +0200, Marek Behún wrote:
> Currently we support SERDES on the Topaz family in a limited way: no
> IRQs and the cmode is not writable, thus the mode is determined by
> strapping pins.
> 
> Marvell's examples though show how to make cmode writable on port 5 and
> support SGMII autonegotiation. It is done by writing hidden registers,
> for which we already have code.
> 
> This patch adds support for making the cmode for the SERDES port
> writable on the Topaz family, via a new chip operation,
> .port_set_cmode_writable, which is called from mv88e6xxx_port_setup_mac
> just before .port_set_cmode.
> 
> SERDES IRQs are also enabled for Topaz.
> 
> Tested on Turris Mox.
> 
> Signed-off-by: Marek Behún <marek.behun@nic.cz>

Reviewed-by: Andrew Lunn <andrew@lunn.ch>

    Andrew

^ permalink raw reply

* Re: [PATCH net-next v5 4/6] net: dsa: mv88e6xxx: simplify SERDES code for Topaz and Peridot
From: Andrew Lunn @ 2019-08-27 13:54 UTC (permalink / raw)
  To: Marek Behún
  Cc: Vivien Didelot, netdev, Florian Fainelli, Vladimir Oltean
In-Reply-To: <20190826213155.14685-5-marek.behun@nic.cz>

On Mon, Aug 26, 2019 at 11:31:53PM +0200, Marek Behún wrote:
> By adding an additional serdes_get_lane implementation (for Topaz), we
> can merge the implementations of other SERDES functions (powering and
> IRQs). We can skip checking port numbers, since the serdes_get_lane()
> methods inform if there is no lane on a port or if the lane cannot be
> used for given cmode.
> 
> Signed-off-by: Marek Behún <marek.behun@nic.cz>

Reviewed-by: Andrew Lunn <andrew@lunn.ch>

    Andrew

^ permalink raw reply

* Re: [PATCH net-next v5 3/6] net: dsa: mv88e6xxx: create serdes_get_lane chip operation
From: Andrew Lunn @ 2019-08-27 13:52 UTC (permalink / raw)
  To: Marek Behún
  Cc: Vivien Didelot, netdev, Florian Fainelli, Vladimir Oltean
In-Reply-To: <20190826213155.14685-4-marek.behun@nic.cz>

On Mon, Aug 26, 2019 at 11:31:52PM +0200, Marek Behún wrote:
> Create a serdes_get_lane() method in the mv88e6xxx operations structure.
> Use it instead of calling the different implementations.
> Also change the methods so that their return value is used only for
> error. The lane number is put into a place referred to by a pointer
> given as argument. If the port does not have a lane, return -ENODEV.
> Lanes are phy addresses, so use u8 as their type.
> 
> Signed-off-by: Marek Behún <marek.behun@nic.cz>

Reviewed-by: Andrew Lunn <andrew@lunn.ch>

    Andrew

^ permalink raw reply

* [PATCH net-next] phy: mdio-sun4i: use devm_platform_ioremap_resource() to simplify code
From: YueHaibing @ 2019-08-27 13:50 UTC (permalink / raw)
  To: andrew, f.fainelli, hkallweit1, davem, mripard, wens
  Cc: netdev, linux-arm-kernel, linux-kernel, YueHaibing

Use devm_platform_ioremap_resource() to simplify the code a bit.
This is detected by coccinelle.

Reported-by: Hulk Robot <hulkci@huawei.com>
Signed-off-by: YueHaibing <yuehaibing@huawei.com>
---
 drivers/net/phy/mdio-sun4i.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/net/phy/mdio-sun4i.c b/drivers/net/phy/mdio-sun4i.c
index 20ffd8f..58d6504 100644
--- a/drivers/net/phy/mdio-sun4i.c
+++ b/drivers/net/phy/mdio-sun4i.c
@@ -92,7 +92,6 @@ static int sun4i_mdio_probe(struct platform_device *pdev)
 	struct device_node *np = pdev->dev.of_node;
 	struct mii_bus *bus;
 	struct sun4i_mdio_data *data;
-	struct resource *res;
 	int ret;
 
 	bus = mdiobus_alloc_size(sizeof(*data));
@@ -106,8 +105,7 @@ static int sun4i_mdio_probe(struct platform_device *pdev)
 	bus->parent = &pdev->dev;
 
 	data = bus->priv;
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	data->membase = devm_ioremap_resource(&pdev->dev, res);
+	data->membase = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(data->membase)) {
 		ret = PTR_ERR(data->membase);
 		goto err_out_free_mdiobus;
-- 
2.7.4



^ permalink raw reply related

* [PATCH net-next] phy: mdio-mux-meson-g12a: use devm_platform_ioremap_resource() to simplify code
From: YueHaibing @ 2019-08-27 13:49 UTC (permalink / raw)
  To: andrew, f.fainelli, hkallweit1, davem, khilman
  Cc: netdev, linux-arm-kernel, linux-amlogic, linux-kernel, YueHaibing

Use devm_platform_ioremap_resource() to simplify the code a bit.
This is detected by coccinelle.

Reported-by: Hulk Robot <hulkci@huawei.com>
Signed-off-by: YueHaibing <yuehaibing@huawei.com>
---
 drivers/net/phy/mdio-mux-meson-g12a.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/net/phy/mdio-mux-meson-g12a.c b/drivers/net/phy/mdio-mux-meson-g12a.c
index 6644762..7a9ad54 100644
--- a/drivers/net/phy/mdio-mux-meson-g12a.c
+++ b/drivers/net/phy/mdio-mux-meson-g12a.c
@@ -302,7 +302,6 @@ static int g12a_mdio_mux_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
 	struct g12a_mdio_mux *priv;
-	struct resource *res;
 	int ret;
 
 	priv = devm_kzalloc(dev, sizeof(*priv), GFP_KERNEL);
@@ -311,8 +310,7 @@ static int g12a_mdio_mux_probe(struct platform_device *pdev)
 
 	platform_set_drvdata(pdev, priv);
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	priv->regs = devm_ioremap_resource(dev, res);
+	priv->regs = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(priv->regs))
 		return PTR_ERR(priv->regs);
 
-- 
2.7.4



^ permalink raw reply related

* [PATCH net-next] phy: mdio-moxart: use devm_platform_ioremap_resource() to simplify code
From: YueHaibing @ 2019-08-27 13:48 UTC (permalink / raw)
  To: andrew, f.fainelli, hkallweit1, davem; +Cc: netdev, linux-kernel, YueHaibing

Use devm_platform_ioremap_resource() to simplify the code a bit.
This is detected by coccinelle.

Reported-by: Hulk Robot <hulkci@huawei.com>
Signed-off-by: YueHaibing <yuehaibing@huawei.com>
---
 drivers/net/phy/mdio-moxart.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/net/phy/mdio-moxart.c b/drivers/net/phy/mdio-moxart.c
index af3910f..2d16fc4 100644
--- a/drivers/net/phy/mdio-moxart.c
+++ b/drivers/net/phy/mdio-moxart.c
@@ -113,7 +113,6 @@ static int moxart_mdio_probe(struct platform_device *pdev)
 	struct device_node *np = pdev->dev.of_node;
 	struct mii_bus *bus;
 	struct moxart_mdio_data *data;
-	struct resource *res;
 	int ret, i;
 
 	bus = mdiobus_alloc_size(sizeof(*data));
@@ -138,8 +137,7 @@ static int moxart_mdio_probe(struct platform_device *pdev)
 		bus->irq[i] = PHY_IGNORE_INTERRUPT;
 
 	data = bus->priv;
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	data->base = devm_ioremap_resource(&pdev->dev, res);
+	data->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(data->base)) {
 		ret = PTR_ERR(data->base);
 		goto err_out_free_mdiobus;
-- 
2.7.4



^ permalink raw reply related

* [PATCH net-next] phy: mdio-hisi-femac: use devm_platform_ioremap_resource() to simplify code
From: YueHaibing @ 2019-08-27 13:47 UTC (permalink / raw)
  To: andrew, f.fainelli, hkallweit1, davem; +Cc: netdev, linux-kernel, YueHaibing

Use devm_platform_ioremap_resource() to simplify the code a bit.
This is detected by coccinelle.

Reported-by: Hulk Robot <hulkci@huawei.com>
Signed-off-by: YueHaibing <yuehaibing@huawei.com>
---
 drivers/net/phy/mdio-hisi-femac.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/net/phy/mdio-hisi-femac.c b/drivers/net/phy/mdio-hisi-femac.c
index 287f3cc..f231c2f 100644
--- a/drivers/net/phy/mdio-hisi-femac.c
+++ b/drivers/net/phy/mdio-hisi-femac.c
@@ -74,7 +74,6 @@ static int hisi_femac_mdio_probe(struct platform_device *pdev)
 	struct device_node *np = pdev->dev.of_node;
 	struct mii_bus *bus;
 	struct hisi_femac_mdio_data *data;
-	struct resource *res;
 	int ret;
 
 	bus = mdiobus_alloc_size(sizeof(*data));
@@ -88,8 +87,7 @@ static int hisi_femac_mdio_probe(struct platform_device *pdev)
 	bus->parent = &pdev->dev;
 
 	data = bus->priv;
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	data->membase = devm_ioremap_resource(&pdev->dev, res);
+	data->membase = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(data->membase)) {
 		ret = PTR_ERR(data->membase);
 		goto err_out_free_mdiobus;
-- 
2.7.4



^ permalink raw reply related

* [PATCH net-next] phy: mdio-bcm-iproc: use devm_platform_ioremap_resource() to simplify code
From: YueHaibing @ 2019-08-27 13:46 UTC (permalink / raw)
  To: andrew, f.fainelli, hkallweit1, davem, rjui, sbranden
  Cc: bcm-kernel-feedback-list, netdev, linux-arm-kernel, linux-kernel,
	YueHaibing

Use devm_platform_ioremap_resource() to simplify the code a bit.
This is detected by coccinelle.

Reported-by: Hulk Robot <hulkci@huawei.com>
Signed-off-by: YueHaibing <yuehaibing@huawei.com>
---
 drivers/net/phy/mdio-bcm-iproc.c | 4 +---
 1 file changed, 1 insertion(+), 3 deletions(-)

diff --git a/drivers/net/phy/mdio-bcm-iproc.c b/drivers/net/phy/mdio-bcm-iproc.c
index 7d0f388..7e9975d 100644
--- a/drivers/net/phy/mdio-bcm-iproc.c
+++ b/drivers/net/phy/mdio-bcm-iproc.c
@@ -123,15 +123,13 @@ static int iproc_mdio_probe(struct platform_device *pdev)
 {
 	struct iproc_mdio_priv *priv;
 	struct mii_bus *bus;
-	struct resource *res;
 	int rc;
 
 	priv = devm_kzalloc(&pdev->dev, sizeof(*priv), GFP_KERNEL);
 	if (!priv)
 		return -ENOMEM;
 
-	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
-	priv->base = devm_ioremap_resource(&pdev->dev, res);
+	priv->base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(priv->base)) {
 		dev_err(&pdev->dev, "failed to ioremap register\n");
 		return PTR_ERR(priv->base);
-- 
2.7.4



^ permalink raw reply related

* [PATCH] mt76: mt7603: use devm_platform_ioremap_resource() to simplify code
From: YueHaibing @ 2019-08-27 13:44 UTC (permalink / raw)
  To: nbd, lorenzo.bianconi83, ryder.lee, royluo, kvalo, davem,
	matthias.bgg, swboyd, yuehaibing, weiyongjun1
  Cc: linux-wireless, netdev, linux-arm-kernel, linux-mediatek,
	linux-kernel

Use devm_platform_ioremap_resource() to simplify the code a bit.
This is detected by coccinelle.

Reported-by: Hulk Robot <hulkci@huawei.com>
Signed-off-by: YueHaibing <yuehaibing@huawei.com>
---
 drivers/net/wireless/mediatek/mt76/mt7603/soc.c | 3 +--
 1 file changed, 1 insertion(+), 2 deletions(-)

diff --git a/drivers/net/wireless/mediatek/mt76/mt7603/soc.c b/drivers/net/wireless/mediatek/mt76/mt7603/soc.c
index c6c1ce6..c22715e 100644
--- a/drivers/net/wireless/mediatek/mt76/mt7603/soc.c
+++ b/drivers/net/wireless/mediatek/mt76/mt7603/soc.c
@@ -9,7 +9,6 @@
 static int
 mt76_wmac_probe(struct platform_device *pdev)
 {
-	struct resource *res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
 	struct mt7603_dev *dev;
 	void __iomem *mem_base;
 	struct mt76_dev *mdev;
@@ -20,7 +19,7 @@ mt76_wmac_probe(struct platform_device *pdev)
 	if (irq < 0)
 		return irq;
 
-	mem_base = devm_ioremap_resource(&pdev->dev, res);
+	mem_base = devm_platform_ioremap_resource(pdev, 0);
 	if (IS_ERR(mem_base)) {
 		dev_err(&pdev->dev, "Failed to get memory resource\n");
 		return PTR_ERR(mem_base);
-- 
2.7.4



^ permalink raw reply related

* Re: [patch net-next rfc 3/7] net: rtnetlink: add commands to add and delete alternative ifnames
From: David Ahern @ 2019-08-27 13:43 UTC (permalink / raw)
  To: Michal Kubecek, netdev
  Cc: Jakub Kicinski, Jiri Pirko, Roopa Prabhu, David Miller,
	Stephen Hemminger, dcbw, Andrew Lunn, parav, Saeed Mahameed,
	mlxsw
In-Reply-To: <20190827045542.GE29594@unicorn.suse.cz>

On 8/26/19 10:55 PM, Michal Kubecek wrote:
> On Mon, Aug 26, 2019 at 03:46:43PM -0600, David Ahern wrote:
>> On 8/26/19 10:55 AM, Jakub Kicinski wrote:
>>> On Mon, 26 Aug 2019 18:09:16 +0200, Jiri Pirko wrote:
>>>> DaveA, Roopa. Do you insist on doing add/remove of altnames in the
>>>> existing setlist command using embedded message op attrs? I'm asking
>>>> because after some time thinking about it, it still feels wrong to me :/
>>>>
>>>> If this would be a generic netlink api, we would just add another couple
>>>> of commands. What is so different we can't add commands here?
>>>> It is also much simpler code. Easy error handling, no need for
>>>> rollback, no possibly inconsistent state, etc.
>>>
>>> +1 the separate op feels like a better uapi to me as well.
>>>
>>> Perhaps we could redo the iproute2 command line interface to make the
>>> name the primary object? Would that address your concern Dave and Roopa?
>>>
>>
>> No, my point is exactly that a name is not a primary object. A name is
>> an attribute of a link - something that exists for the convenience of
>> userspace only. (Like the 'protocol' for routes, rules and neighbors.)
>>
>> Currently, names are changed by RTM_NEWLINK/RTM_SETLINK. Aliases are
>> added and deleted by RTM_NEWLINK/RTM_SETLINK. Why is an alternative name
>> so special that it should have its own API?
> 
> There is only one alias so that it makes perfect sense to set it like
> any other attribute. But the series introduces a list of alternative
> names. So IMHO better analogy would be network addresses - and we do
> have RTM_NEWADDR/RTM_DELADDR for them.

RTM_*ADDR manage network layer addresses. Those are anchored to a device
but not direct attributes describing the device.

The device names are just alternative (human friendly) references to a
specific device hence they should be direct link attributes.

^ 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